@mieweb/ui 0.5.0 → 0.6.1-dev.120

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/index.cjs CHANGED
@@ -3869,7 +3869,7 @@ var MessageBubble = React48__namespace.forwardRef(
3869
3869
  "div",
3870
3870
  {
3871
3871
  className: chunkOR5DRJCW_cjs.cn(
3872
- "flex flex-col",
3872
+ "flex min-w-0 flex-1 flex-col",
3873
3873
  isOutgoing ? "items-end" : "items-start"
3874
3874
  ),
3875
3875
  children: [
@@ -8648,11 +8648,17 @@ function CommandPalette({
8648
8648
  placeholder = "Search...",
8649
8649
  isLoading = false,
8650
8650
  onSelect,
8651
+ onQueryChange,
8652
+ pinnedItems,
8653
+ pinnedCategoryLabel = "Actions",
8654
+ recentItems,
8655
+ recentCategoryLabel = "Recent",
8651
8656
  emptyState,
8652
8657
  renderItem,
8653
8658
  footer,
8654
8659
  className,
8655
- "data-testid": testId = "command-palette"
8660
+ "data-testid": testId = "command-palette",
8661
+ serverFiltered = false
8656
8662
  }) {
8657
8663
  const {
8658
8664
  isOpen,
@@ -8669,29 +8675,47 @@ function CommandPalette({
8669
8675
  const inputRef = React48.useRef(null);
8670
8676
  const containerRef = React48.useRef(null);
8671
8677
  const listRef = React48.useRef(null);
8678
+ React48.useEffect(() => {
8679
+ if (!isOpen) return;
8680
+ onQueryChange?.(query);
8681
+ }, [query, isOpen, onQueryChange]);
8682
+ const PINNED_CATEGORY_ID = "__palette_pinned__";
8683
+ const RECENT_CATEGORY_ID = "__palette_recent__";
8672
8684
  const filteredItems = React48.useMemo(() => {
8673
8685
  let result = items;
8674
8686
  if (activeCategory) {
8675
8687
  result = result.filter((item) => item.category === activeCategory);
8676
8688
  }
8677
- if (query.trim()) {
8689
+ if (query.trim() && !serverFiltered) {
8678
8690
  const lowerQuery = query.toLowerCase();
8679
8691
  result = result.filter(
8680
8692
  (item) => item.label.toLowerCase().includes(lowerQuery) || item.subtitle?.toLowerCase().includes(lowerQuery) || item.description?.toLowerCase().includes(lowerQuery)
8681
8693
  );
8682
8694
  }
8683
8695
  return result;
8684
- }, [items, query, activeCategory]);
8696
+ }, [items, query, activeCategory, serverFiltered]);
8697
+ const effectiveItems = React48.useMemo(() => {
8698
+ const pinned = !activeCategory && pinnedItems?.length ? pinnedItems.map((it) => ({
8699
+ ...it,
8700
+ category: it.category ?? PINNED_CATEGORY_ID
8701
+ })) : [];
8702
+ const showRecents = !activeCategory && !query.trim() && filteredItems.length === 0 && !!recentItems?.length;
8703
+ const recents = showRecents ? recentItems.map((it) => ({
8704
+ ...it,
8705
+ category: it.category ?? RECENT_CATEGORY_ID
8706
+ })) : [];
8707
+ return [...pinned, ...filteredItems, ...recents];
8708
+ }, [pinnedItems, recentItems, filteredItems, activeCategory, query]);
8685
8709
  const groupedItems = React48.useMemo(() => {
8686
8710
  const groups = /* @__PURE__ */ new Map();
8687
- filteredItems.forEach((item) => {
8711
+ effectiveItems.forEach((item) => {
8688
8712
  const category = item.category ?? "Other";
8689
8713
  const group = groups.get(category) ?? [];
8690
8714
  group.push(item);
8691
8715
  groups.set(category, group);
8692
8716
  });
8693
8717
  return groups;
8694
- }, [filteredItems]);
8718
+ }, [effectiveItems]);
8695
8719
  chunkFHY3K6PL_cjs.useEscapeKey(close, isOpen);
8696
8720
  chunkIKMR2ADM_cjs.useClickOutside(containerRef, close);
8697
8721
  React48.useEffect(() => {
@@ -8700,8 +8724,8 @@ function CommandPalette({
8700
8724
  }
8701
8725
  }, [isOpen]);
8702
8726
  React48.useEffect(() => {
8703
- setSelectedIndex(filteredItems.length > 0 ? 0 : -1);
8704
- }, [filteredItems.length, setSelectedIndex]);
8727
+ setSelectedIndex(effectiveItems.length > 0 ? 0 : -1);
8728
+ }, [effectiveItems.length, setSelectedIndex]);
8705
8729
  React48.useEffect(() => {
8706
8730
  if (selectedIndex >= 0 && listRef.current) {
8707
8731
  const selectedElement = listRef.current.querySelector(
@@ -8716,7 +8740,7 @@ function CommandPalette({
8716
8740
  case "ArrowDown":
8717
8741
  e.preventDefault();
8718
8742
  setSelectedIndex(
8719
- Math.min(selectedIndex + 1, filteredItems.length - 1)
8743
+ Math.min(selectedIndex + 1, effectiveItems.length - 1)
8720
8744
  );
8721
8745
  break;
8722
8746
  case "ArrowUp":
@@ -8725,8 +8749,8 @@ function CommandPalette({
8725
8749
  break;
8726
8750
  case "Enter":
8727
8751
  e.preventDefault();
8728
- if (selectedIndex >= 0 && filteredItems[selectedIndex]) {
8729
- const item = filteredItems[selectedIndex];
8752
+ if (selectedIndex >= 0 && effectiveItems[selectedIndex]) {
8753
+ const item = effectiveItems[selectedIndex];
8730
8754
  if (!item.disabled) {
8731
8755
  onSelect?.(item);
8732
8756
  close();
@@ -8744,7 +8768,7 @@ function CommandPalette({
8744
8768
  }
8745
8769
  },
8746
8770
  [
8747
- filteredItems,
8771
+ effectiveItems,
8748
8772
  selectedIndex,
8749
8773
  setSelectedIndex,
8750
8774
  onSelect,
@@ -8765,9 +8789,15 @@ function CommandPalette({
8765
8789
  );
8766
8790
  const getCategoryInfo = React48.useCallback(
8767
8791
  (categoryId) => {
8792
+ if (categoryId === PINNED_CATEGORY_ID) {
8793
+ return { id: PINNED_CATEGORY_ID, label: pinnedCategoryLabel };
8794
+ }
8795
+ if (categoryId === RECENT_CATEGORY_ID) {
8796
+ return { id: RECENT_CATEGORY_ID, label: recentCategoryLabel };
8797
+ }
8768
8798
  return categories.find((c) => c.id === categoryId);
8769
8799
  },
8770
- [categories]
8800
+ [categories, pinnedCategoryLabel, recentCategoryLabel]
8771
8801
  );
8772
8802
  if (!isOpen) return null;
8773
8803
  let globalIndex = -1;
@@ -8873,14 +8903,14 @@ function CommandPalette({
8873
8903
  ref: listRef,
8874
8904
  "data-slot": "command-palette-results",
8875
8905
  className: "max-h-[60vh] overflow-y-auto",
8876
- children: filteredItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
8906
+ children: effectiveItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
8877
8907
  "div",
8878
8908
  {
8879
8909
  "data-slot": "command-palette-empty",
8880
8910
  className: "text-muted-foreground p-8 text-center",
8881
8911
  children: emptyState ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8882
8912
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto mb-2 h-8 w-8 opacity-50", children: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon2, {}) }),
8883
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: query.trim() ? `No results for "${query}"` : "Start typing to search..." })
8913
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: isLoading && query.trim() ? `Searching for "${query}"\u2026` : query.trim() ? `No results for "${query}"` : "Start typing to search..." })
8884
8914
  ] })
8885
8915
  }
8886
8916
  ) : Array.from(groupedItems.entries()).map(
@@ -9013,7 +9043,7 @@ function CommandPalette({
9013
9043
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "close" })
9014
9044
  ] }),
9015
9045
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9016
- filteredItems.length,
9046
+ effectiveItems.length,
9017
9047
  " results"
9018
9048
  ] })
9019
9049
  ]
@@ -11463,32 +11493,103 @@ function getDefaultPresets(labels = {}) {
11463
11493
  { key: "last-30-days", label: last30Days }
11464
11494
  ];
11465
11495
  }
11496
+ function getExtendedPresets(labels = {}) {
11497
+ const {
11498
+ today = "Today",
11499
+ yesterday = "Yesterday",
11500
+ thisWeek = "This Week",
11501
+ lastWeek = "Last Week",
11502
+ thisMonth = "This Month",
11503
+ lastMonth = "Last Month",
11504
+ thisQuarter = "This Quarter",
11505
+ lastQuarter = "Last Quarter",
11506
+ thisYear = "This Year",
11507
+ lastYear = "Last Year",
11508
+ last24Hours = "Last 24 Hours",
11509
+ last7Days = "Last 7 Days",
11510
+ last30Days = "Last 30 Days",
11511
+ last90Days = "Last 90 Days",
11512
+ last365Days = "Last 365 Days"
11513
+ } = labels;
11514
+ return [
11515
+ { key: "today", label: today },
11516
+ { key: "yesterday", label: yesterday },
11517
+ { key: "last-24-hours", label: last24Hours },
11518
+ { key: "this-week", label: thisWeek },
11519
+ { key: "last-week", label: lastWeek },
11520
+ { key: "last-7-days", label: last7Days },
11521
+ { key: "this-month", label: thisMonth },
11522
+ { key: "last-month", label: lastMonth },
11523
+ { key: "last-30-days", label: last30Days },
11524
+ { key: "this-quarter", label: thisQuarter },
11525
+ { key: "last-quarter", label: lastQuarter },
11526
+ { key: "last-90-days", label: last90Days },
11527
+ { key: "this-year", label: thisYear },
11528
+ { key: "last-year", label: lastYear },
11529
+ { key: "last-365-days", label: last365Days }
11530
+ ];
11531
+ }
11532
+ function endOfDay(d) {
11533
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
11534
+ }
11466
11535
  function calculateDateRange(presetKey) {
11467
11536
  const now = /* @__PURE__ */ new Date();
11468
11537
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
11469
11538
  switch (presetKey) {
11470
11539
  case "today":
11471
- return {
11472
- start: today,
11473
- end: new Date(today.getTime() + 24 * 60 * 60 * 1e3 - 1)
11474
- };
11540
+ return { start: today, end: endOfDay(today) };
11541
+ case "yesterday": {
11542
+ const yesterday = new Date(today);
11543
+ yesterday.setDate(today.getDate() - 1);
11544
+ return { start: yesterday, end: endOfDay(yesterday) };
11545
+ }
11475
11546
  case "this-week": {
11476
11547
  const dayOfWeek = today.getDay();
11477
11548
  const sunday = new Date(today);
11478
11549
  sunday.setDate(today.getDate() - dayOfWeek);
11479
11550
  const saturday = new Date(sunday);
11480
11551
  saturday.setDate(sunday.getDate() + 6);
11481
- return { start: sunday, end: saturday };
11552
+ return { start: sunday, end: endOfDay(saturday) };
11553
+ }
11554
+ case "last-week": {
11555
+ const dayOfWeek = today.getDay();
11556
+ const lastSunday = new Date(today);
11557
+ lastSunday.setDate(today.getDate() - dayOfWeek - 7);
11558
+ const lastSaturday = new Date(lastSunday);
11559
+ lastSaturday.setDate(lastSunday.getDate() + 6);
11560
+ return { start: lastSunday, end: endOfDay(lastSaturday) };
11482
11561
  }
11483
11562
  case "this-month": {
11484
11563
  const firstDay = new Date(now.getFullYear(), now.getMonth(), 1);
11485
11564
  const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
11486
- return { start: firstDay, end: lastDay };
11565
+ return { start: firstDay, end: endOfDay(lastDay) };
11487
11566
  }
11488
11567
  case "last-month": {
11489
11568
  const firstDay = new Date(now.getFullYear(), now.getMonth() - 1, 1);
11490
11569
  const lastDay = new Date(now.getFullYear(), now.getMonth(), 0);
11491
- return { start: firstDay, end: lastDay };
11570
+ return { start: firstDay, end: endOfDay(lastDay) };
11571
+ }
11572
+ case "this-quarter": {
11573
+ const quarter = Math.floor(now.getMonth() / 3);
11574
+ const firstDay = new Date(now.getFullYear(), quarter * 3, 1);
11575
+ const lastDay = new Date(now.getFullYear(), quarter * 3 + 3, 0);
11576
+ return { start: firstDay, end: endOfDay(lastDay) };
11577
+ }
11578
+ case "last-quarter": {
11579
+ const quarter = Math.floor(now.getMonth() / 3);
11580
+ const firstDay = new Date(now.getFullYear(), (quarter - 1) * 3, 1);
11581
+ const lastDay = new Date(now.getFullYear(), quarter * 3, 0);
11582
+ return { start: firstDay, end: endOfDay(lastDay) };
11583
+ }
11584
+ case "this-year": {
11585
+ const firstDay = new Date(now.getFullYear(), 0, 1);
11586
+ const lastDay = new Date(now.getFullYear(), 11, 31);
11587
+ return { start: firstDay, end: endOfDay(lastDay) };
11588
+ }
11589
+ case "last-year": {
11590
+ const firstDay = new Date(now.getFullYear() - 1, 0, 1);
11591
+ const lastDay = new Date(now.getFullYear() - 1, 11, 31);
11592
+ return { start: firstDay, end: endOfDay(lastDay) };
11492
11593
  }
11493
11594
  case "last-24-hours":
11494
11595
  return {
@@ -11505,6 +11606,16 @@ function calculateDateRange(presetKey) {
11505
11606
  start: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3),
11506
11607
  end: now
11507
11608
  };
11609
+ case "last-90-days":
11610
+ return {
11611
+ start: new Date(now.getTime() - 90 * 24 * 60 * 60 * 1e3),
11612
+ end: now
11613
+ };
11614
+ case "last-365-days":
11615
+ return {
11616
+ start: new Date(now.getTime() - 365 * 24 * 60 * 60 * 1e3),
11617
+ end: now
11618
+ };
11508
11619
  default:
11509
11620
  return { start: null, end: null };
11510
11621
  }
@@ -11531,6 +11642,7 @@ function DateRangePicker({
11531
11642
  activePreset,
11532
11643
  placeholder = "Pick a date range",
11533
11644
  className,
11645
+ align = "auto",
11534
11646
  showPresets = true,
11535
11647
  variant = "desktop",
11536
11648
  labels = {}
@@ -11553,6 +11665,9 @@ function DateRangePicker({
11553
11665
  const [hoverDate, setHoverDate] = React48__namespace.useState(null);
11554
11666
  const calendarRef = React48__namespace.useRef(null);
11555
11667
  const triggerRef = React48__namespace.useRef(null);
11668
+ const [resolvedAlign, setResolvedAlign] = React48__namespace.useState(
11669
+ align === "end" ? "end" : "start"
11670
+ );
11556
11671
  const isMobileVariant = variant === "mobile";
11557
11672
  const isResponsive = variant === "responsive";
11558
11673
  const focusTrapRef = chunkNNEFAUHV_cjs.useFocusTrap(
@@ -11591,6 +11706,22 @@ function DateRangePicker({
11591
11706
  };
11592
11707
  }
11593
11708
  }, [isMobileVariant, isCalendarOpen]);
11709
+ React48__namespace.useLayoutEffect(() => {
11710
+ if (isMobileVariant || !isCalendarOpen) return;
11711
+ if (align === "start" || align === "end") {
11712
+ setResolvedAlign(align);
11713
+ return;
11714
+ }
11715
+ if (typeof window === "undefined") return;
11716
+ const trigger = triggerRef.current;
11717
+ if (!trigger) return;
11718
+ const rect = trigger.getBoundingClientRect();
11719
+ const estimatedPopupWidth = showPresets ? 840 : 640;
11720
+ const margin = 8;
11721
+ const overflowsRight = rect.left + estimatedPopupWidth > window.innerWidth - margin;
11722
+ const fitsLeftAligned = rect.right - estimatedPopupWidth >= margin;
11723
+ setResolvedAlign(overflowsRight && fitsLeftAligned ? "end" : "start");
11724
+ }, [align, isCalendarOpen, isMobileVariant, showPresets]);
11594
11725
  const handlePresetSelect = (presetKey) => {
11595
11726
  const range = calculateDateRange(presetKey);
11596
11727
  setRangeStart(range.start);
@@ -11930,7 +12061,8 @@ function DateRangePicker({
11930
12061
  {
11931
12062
  ref: calendarRef,
11932
12063
  className: chunkOR5DRJCW_cjs.cn(
11933
- "absolute top-full left-0 z-50 mt-1",
12064
+ "absolute top-full z-50 mt-1",
12065
+ resolvedAlign === "end" ? "right-0" : "left-0",
11934
12066
  "bg-background border-border rounded-lg border shadow-lg"
11935
12067
  ),
11936
12068
  role: "dialog",
@@ -40238,6 +40370,7 @@ exports.WebcamModal = WebcamModal;
40238
40370
  exports.WebsiteInput = WebsiteInput;
40239
40371
  exports.WebsiteInputGroup = WebsiteInputGroup;
40240
40372
  exports.bubbleVariants = bubbleVariants2;
40373
+ exports.calculateDateRange = calculateDateRange;
40241
40374
  exports.countBadgeVariants = countBadgeVariants;
40242
40375
  exports.countChipVariants = countChipVariants;
40243
40376
  exports.create24HourSchedule = create24HourSchedule;
@@ -40255,6 +40388,8 @@ exports.generateAttachmentId = generateAttachmentId;
40255
40388
  exports.generateId = generateId;
40256
40389
  exports.getConversationSubtitle = getConversationSubtitle;
40257
40390
  exports.getConversationTitle = getConversationTitle;
40391
+ exports.getDefaultPresets = getDefaultPresets;
40392
+ exports.getExtendedPresets = getExtendedPresets;
40258
40393
  exports.getFileType = getFileType;
40259
40394
  exports.getGoogleMapsSearchUrl = getGoogleMapsSearchUrl;
40260
40395
  exports.getGoogleMapsUrl = getGoogleMapsUrl;