@assure-one/design-system 0.5.0 → 0.7.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import * as React36 from 'react';
3
- import { forwardRef, useState, useCallback, useId, useRef, useImperativeHandle, useEffect, createContext, useContext, useMemo } from 'react';
3
+ import { forwardRef, useState, useCallback, useId, useRef, useImperativeHandle, useEffect, createContext, Fragment as Fragment$1, useContext, useMemo } from 'react';
4
4
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
@@ -28,6 +28,7 @@ import { OTPInput as OTPInput$1, REGEXP_ONLY_DIGITS } from 'input-otp';
28
28
  import * as ProgressPrimitive from '@radix-ui/react-progress';
29
29
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
30
30
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
31
+ import { RemoveScroll } from 'react-remove-scroll';
31
32
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
32
33
  import * as SliderPrimitive from '@radix-ui/react-slider';
33
34
  import { useFormStatus } from 'react-dom';
@@ -5491,15 +5492,46 @@ function SearchSelect({
5491
5492
  onCreate,
5492
5493
  placeholder = "Search...",
5493
5494
  className,
5494
- disabled = false
5495
+ disabled = false,
5496
+ groupFilter = false,
5497
+ pinnedGroups,
5498
+ closeOnSelect = false,
5499
+ showGroupCounts = false,
5500
+ onCreateNew,
5501
+ createNewLabel = "Create new"
5495
5502
  }) {
5496
5503
  const [search, setSearch] = React36.useState("");
5497
5504
  const [open, setOpen] = React36.useState(false);
5505
+ const [activeChip, setActiveChip] = React36.useState(null);
5498
5506
  const selectedIds = React36.useMemo(() => new Set(selected.map((s) => s.id)), [selected]);
5499
5507
  const filtered = React36.useMemo(
5500
5508
  () => options.filter((opt) => !selectedIds.has(opt.id)),
5501
5509
  [options, selectedIds]
5502
5510
  );
5511
+ const groups = React36.useMemo(() => {
5512
+ const order = [];
5513
+ const byGroup = /* @__PURE__ */ new Map();
5514
+ for (const opt of filtered) {
5515
+ if (!byGroup.has(opt.group)) {
5516
+ byGroup.set(opt.group, []);
5517
+ order.push(opt.group);
5518
+ }
5519
+ byGroup.get(opt.group).push(opt);
5520
+ }
5521
+ return order.map((g) => [g, byGroup.get(g)]);
5522
+ }, [filtered]);
5523
+ const hasGroups = React36.useMemo(() => groups.some(([g]) => g != null), [groups]);
5524
+ const pinnedSet = React36.useMemo(() => new Set(pinnedGroups ?? []), [pinnedGroups]);
5525
+ const chips = React36.useMemo(() => {
5526
+ if (!groupFilter || !hasGroups) return [];
5527
+ return groups.map(([g]) => g).filter((g) => g != null && !pinnedSet.has(g));
5528
+ }, [groupFilter, hasGroups, groups, pinnedSet]);
5529
+ const visibleGroups = React36.useMemo(() => {
5530
+ if (chips.length > 0 && activeChip) {
5531
+ return groups.filter(([g]) => g === activeChip);
5532
+ }
5533
+ return groups;
5534
+ }, [groups, chips.length, activeChip]);
5503
5535
  const trimmedSearch = search.trim();
5504
5536
  const hasExactMatch = React36.useMemo(
5505
5537
  () => options.some((opt) => opt.label.toLowerCase() === trimmedSearch.toLowerCase()),
@@ -5510,8 +5542,9 @@ function SearchSelect({
5510
5542
  (option) => {
5511
5543
  onSelect(option);
5512
5544
  setSearch("");
5545
+ if (closeOnSelect) setOpen(false);
5513
5546
  },
5514
- [onSelect]
5547
+ [onSelect, closeOnSelect]
5515
5548
  );
5516
5549
  const handleCreate = React36.useCallback(() => {
5517
5550
  if (onCreate && trimmedSearch) {
@@ -5520,8 +5553,17 @@ function SearchSelect({
5520
5553
  setOpen(false);
5521
5554
  }
5522
5555
  }, [onCreate, trimmedSearch]);
5556
+ const inputRef = React36.useRef(null);
5557
+ const singleValue = closeOnSelect ? selected[0] ?? null : null;
5558
+ const showValue = singleValue !== null && !open;
5559
+ React36.useEffect(() => {
5560
+ if (open && closeOnSelect) {
5561
+ const raf = requestAnimationFrame(() => inputRef.current?.focus());
5562
+ return () => cancelAnimationFrame(raf);
5563
+ }
5564
+ }, [open, closeOnSelect]);
5523
5565
  return /* @__PURE__ */ jsxs("div", { className: cn("relative w-full", className), children: [
5524
- selected.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", children: selected.map((item) => /* @__PURE__ */ jsxs(
5566
+ !closeOnSelect && selected.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", children: selected.map((item) => /* @__PURE__ */ jsxs(
5525
5567
  "span",
5526
5568
  {
5527
5569
  className: cn(
@@ -5564,7 +5606,7 @@ function SearchSelect({
5564
5606
  }
5565
5607
  },
5566
5608
  children: [
5567
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
5609
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx(
5568
5610
  "div",
5569
5611
  {
5570
5612
  className: cn(
@@ -5572,9 +5614,76 @@ function SearchSelect({
5572
5614
  "transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5573
5615
  "motion-reduce:transition-none",
5574
5616
  "focus-within:border-accent focus-within:[box-shadow:var(--shadow-focus-ring)]",
5617
+ showValue && "hover:bg-bg-2 gap-2 pr-2 pl-3",
5575
5618
  disabled && "bg-bg-disabled cursor-not-allowed"
5576
5619
  ),
5577
- children: [
5620
+ children: showValue && singleValue ? /* @__PURE__ */ jsxs(Fragment, { children: [
5621
+ /* @__PURE__ */ jsxs(
5622
+ "button",
5623
+ {
5624
+ type: "button",
5625
+ onClick: () => !disabled && setOpen(true),
5626
+ disabled,
5627
+ className: "flex h-full flex-1 items-center gap-2 text-left outline-none disabled:cursor-not-allowed",
5628
+ children: [
5629
+ singleValue.icon && /* @__PURE__ */ jsx(
5630
+ "span",
5631
+ {
5632
+ className: cn(
5633
+ "flex size-5 shrink-0 items-center justify-center rounded-full [&_svg]:size-3",
5634
+ singleValue.iconClassName
5635
+ ),
5636
+ "aria-hidden": "true",
5637
+ children: singleValue.icon
5638
+ }
5639
+ ),
5640
+ /* @__PURE__ */ jsxs("span", { className: "text-fg flex-1 truncate text-[13px]", children: [
5641
+ singleValue.label,
5642
+ singleValue.description && /* @__PURE__ */ jsxs("span", { className: "text-fg-4", children: [
5643
+ " \xB7 ",
5644
+ singleValue.description
5645
+ ] })
5646
+ ] })
5647
+ ]
5648
+ }
5649
+ ),
5650
+ /* @__PURE__ */ jsx(
5651
+ "button",
5652
+ {
5653
+ type: "button",
5654
+ onClick: () => onRemove(singleValue),
5655
+ disabled,
5656
+ className: cn(
5657
+ "text-fg-3 shrink-0 rounded-full p-0.5",
5658
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5659
+ "motion-reduce:transition-none",
5660
+ "hover:bg-overlay-hover hover:text-fg",
5661
+ "disabled:text-fg-disabled disabled:cursor-not-allowed disabled:hover:bg-transparent",
5662
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
5663
+ ),
5664
+ "aria-label": `Clear ${singleValue.label}`,
5665
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-3.5", "aria-hidden": "true" })
5666
+ }
5667
+ ),
5668
+ /* @__PURE__ */ jsx(
5669
+ "button",
5670
+ {
5671
+ type: "button",
5672
+ onClick: () => !disabled && setOpen(true),
5673
+ disabled,
5674
+ "aria-label": `Change ${singleValue.label}`,
5675
+ className: cn(
5676
+ "text-fg-4 shrink-0 rounded-full p-0.5 outline-none",
5677
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5678
+ "motion-reduce:transition-none",
5679
+ "hover:text-fg",
5680
+ "disabled:text-fg-disabled disabled:cursor-not-allowed",
5681
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)]"
5682
+ ),
5683
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4", "aria-hidden": "true" })
5684
+ }
5685
+ )
5686
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5578
5687
  /* @__PURE__ */ jsx(
5579
5688
  SearchIcon,
5580
5689
  {
@@ -5585,6 +5694,7 @@ function SearchSelect({
5585
5694
  /* @__PURE__ */ jsx(
5586
5695
  Command.Input,
5587
5696
  {
5697
+ ref: inputRef,
5588
5698
  value: search,
5589
5699
  onValueChange: (v) => {
5590
5700
  setSearch(v);
@@ -5602,7 +5712,7 @@ function SearchSelect({
5602
5712
  )
5603
5713
  }
5604
5714
  )
5605
- ]
5715
+ ] })
5606
5716
  }
5607
5717
  ) }),
5608
5718
  /* @__PURE__ */ jsx(
@@ -5610,56 +5720,156 @@ function SearchSelect({
5610
5720
  {
5611
5721
  align: "start",
5612
5722
  sideOffset: 4,
5723
+ avoidCollisions: false,
5613
5724
  onOpenAutoFocus: (e) => e.preventDefault(),
5614
5725
  onInteractOutside: (e) => {
5615
5726
  const target = e.target;
5616
5727
  if (target.closest("[cmdk-input]")) e.preventDefault();
5617
5728
  },
5618
- className: cn("w-(--radix-popover-trigger-width) p-0", "min-w-[12rem]"),
5619
- children: /* @__PURE__ */ jsxs(Command.List, { className: "scrollbar-thin max-h-60 overflow-y-auto p-1", children: [
5620
- filtered.length === 0 && !showCreate && /* @__PURE__ */ jsx(Command.Empty, { className: "text-fg-3 px-3 py-2 text-xs", children: search ? "No results found." : "No options available." }),
5621
- filtered.map((option) => /* @__PURE__ */ jsxs(
5622
- Command.Item,
5729
+ style: {
5730
+ width: "var(--radix-popover-trigger-width)",
5731
+ maxHeight: "var(--radix-popover-content-available-height)"
5732
+ },
5733
+ className: cn("p-0", "flex flex-col", "min-w-[12rem] overflow-hidden"),
5734
+ children: /* @__PURE__ */ jsxs(RemoveScroll, { removeScrollBar: false, className: "contents", children: [
5735
+ chips.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-rule flex flex-wrap gap-1 border-b p-1.5", children: [null, ...chips].map((chip) => {
5736
+ const active = activeChip === chip;
5737
+ return /* @__PURE__ */ jsx(
5738
+ "button",
5739
+ {
5740
+ type: "button",
5741
+ onClick: () => setActiveChip(chip),
5742
+ className: cn(
5743
+ "rounded-pill px-2.5 py-0.5 text-[12px] font-medium",
5744
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
5745
+ active ? "bg-pro-fg text-fg-on-pro" : "border-rule text-fg-2 hover:bg-bg-2 border bg-transparent"
5746
+ ),
5747
+ children: chip ?? "All"
5748
+ },
5749
+ chip ?? "__all"
5750
+ );
5751
+ }) }),
5752
+ /* @__PURE__ */ jsxs(
5753
+ Command.List,
5623
5754
  {
5624
- value: option.label,
5625
- onSelect: () => handleSelect(option),
5626
5755
  className: cn(
5627
- "rounded-pill flex cursor-default items-center gap-2 px-2 py-1.5 text-[13px] outline-none select-none",
5628
- "text-fg-2 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5756
+ // No top padding: a sticky group heading pins at top-0, so any
5757
+ // top padding would leave a strip above it where the previous
5758
+ // group's last item peeks through. Top spacing comes from the
5759
+ // heading's own pt-2 instead.
5760
+ "scrollbar-thin min-h-0 flex-1 max-h-[min(20rem,60vh)] overflow-y-auto px-1 pb-1",
5761
+ // Quiet sentence-case section labels (only shown when grouped)
5762
+ "[&_[cmdk-group-heading]]:bg-surface [&_[cmdk-group-heading]]:sticky [&_[cmdk-group-heading]]:top-0 [&_[cmdk-group-heading]]:z-10",
5763
+ "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pt-2 [&_[cmdk-group-heading]]:pb-1",
5764
+ "[&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:font-medium",
5765
+ "[&_[cmdk-group-heading]]:text-fg-3"
5766
+ ),
5767
+ children: [
5768
+ filtered.length === 0 && !showCreate && /* @__PURE__ */ jsx(Command.Empty, { className: "text-fg-3 px-3 py-2 text-xs", children: search ? "No results found." : "No options available." }),
5769
+ visibleGroups.map(([group, groupOptions]) => {
5770
+ const baseHeading = activeChip ? void 0 : group || void 0;
5771
+ const heading = baseHeading && showGroupCounts && !trimmedSearch ? `${baseHeading} \xB7 ${groupOptions.length}` : baseHeading;
5772
+ return /* @__PURE__ */ jsx(Command.Group, { heading, children: groupOptions.map((option) => {
5773
+ const isRich = !!option.icon || !!option.description;
5774
+ return /* @__PURE__ */ jsx(
5775
+ Command.Item,
5776
+ {
5777
+ value: hasGroups && group ? `${option.label} ${group} ${option.id}` : `${option.label} ${option.id}`,
5778
+ onSelect: () => handleSelect(option),
5779
+ className: cn(
5780
+ "flex cursor-default items-center outline-none select-none",
5781
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5782
+ "motion-reduce:transition-none",
5783
+ isRich ? "rounded-md text-fg gap-2.5 px-2 py-1.5" : "rounded-pill text-fg-2 gap-2 px-2 py-1.5 text-[13px]",
5784
+ "data-[selected=true]:bg-bg-2 data-[selected=true]:text-fg"
5785
+ ),
5786
+ children: isRich ? /* @__PURE__ */ jsxs(Fragment, { children: [
5787
+ option.icon && /* @__PURE__ */ jsx(
5788
+ "span",
5789
+ {
5790
+ className: cn(
5791
+ "flex size-7 shrink-0 items-center justify-center rounded-full [&_svg]:size-3.5",
5792
+ option.iconClassName
5793
+ ),
5794
+ "aria-hidden": "true",
5795
+ children: option.icon
5796
+ }
5797
+ ),
5798
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
5799
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-[13px] font-medium", children: option.label }),
5800
+ option.description && /* @__PURE__ */ jsx("span", { className: "text-fg-4 block truncate text-[11px]", children: option.description })
5801
+ ] })
5802
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5803
+ option.color ? /* @__PURE__ */ jsx(
5804
+ "span",
5805
+ {
5806
+ className: "size-2 shrink-0 rounded-full",
5807
+ style: { backgroundColor: option.color },
5808
+ "aria-hidden": "true"
5809
+ }
5810
+ ) : /* @__PURE__ */ jsx(
5811
+ CheckIcon,
5812
+ {
5813
+ className: "size-4 shrink-0 text-transparent",
5814
+ "aria-hidden": "true"
5815
+ }
5816
+ ),
5817
+ /* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: option.label })
5818
+ ] })
5819
+ },
5820
+ option.id
5821
+ );
5822
+ }) }, group ?? "__ungrouped");
5823
+ }),
5824
+ showCreate && /* @__PURE__ */ jsxs(Fragment, { children: [
5825
+ filtered.length > 0 && /* @__PURE__ */ jsx("div", { className: "bg-rule -mx-1 my-1 h-px", "aria-hidden": "true" }),
5826
+ /* @__PURE__ */ jsxs(
5827
+ Command.Item,
5828
+ {
5829
+ value: `__create_${trimmedSearch}`,
5830
+ onSelect: handleCreate,
5831
+ className: cn(
5832
+ "rounded-pill flex cursor-default items-center gap-2 px-2 py-1.5 text-[13px] outline-none select-none",
5833
+ "text-pro-fg transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5834
+ "motion-reduce:transition-none",
5835
+ "data-[selected=true]:bg-pro-bg"
5836
+ ),
5837
+ children: [
5838
+ /* @__PURE__ */ jsx(PlusIcon, { className: "size-4 shrink-0", "aria-hidden": "true" }),
5839
+ /* @__PURE__ */ jsxs("span", { className: "line-clamp-1", children: [
5840
+ "Create \u201C",
5841
+ trimmedSearch,
5842
+ "\u201D"
5843
+ ] })
5844
+ ]
5845
+ }
5846
+ )
5847
+ ] })
5848
+ ]
5849
+ }
5850
+ ),
5851
+ onCreateNew && /* @__PURE__ */ jsxs(
5852
+ "button",
5853
+ {
5854
+ type: "button",
5855
+ onMouseDown: (e) => e.preventDefault(),
5856
+ onClick: () => {
5857
+ onCreateNew();
5858
+ setOpen(false);
5859
+ },
5860
+ className: cn(
5861
+ "border-rule text-pro-fg flex w-full shrink-0 items-center gap-2 border-t px-3 py-2.5 text-[13px] font-medium",
5862
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5629
5863
  "motion-reduce:transition-none",
5630
- "data-[selected=true]:bg-bg-2 data-[selected=true]:text-fg"
5864
+ "hover:bg-pro-bg",
5865
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
5631
5866
  ),
5632
5867
  children: [
5633
- /* @__PURE__ */ jsx(CheckIcon, { className: "size-4 shrink-0 text-transparent", "aria-hidden": "true" }),
5634
- /* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: option.label })
5868
+ /* @__PURE__ */ jsx(PlusIcon, { className: "size-4 shrink-0", "aria-hidden": "true" }),
5869
+ createNewLabel
5635
5870
  ]
5636
- },
5637
- option.id
5638
- )),
5639
- showCreate && /* @__PURE__ */ jsxs(Fragment, { children: [
5640
- filtered.length > 0 && /* @__PURE__ */ jsx("div", { className: "bg-rule -mx-1 my-1 h-px", "aria-hidden": "true" }),
5641
- /* @__PURE__ */ jsxs(
5642
- Command.Item,
5643
- {
5644
- value: `__create_${trimmedSearch}`,
5645
- onSelect: handleCreate,
5646
- className: cn(
5647
- "rounded-pill flex cursor-default items-center gap-2 px-2 py-1.5 text-[13px] outline-none select-none",
5648
- "text-pro-fg transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)]",
5649
- "motion-reduce:transition-none",
5650
- "data-[selected=true]:bg-pro-bg"
5651
- ),
5652
- children: [
5653
- /* @__PURE__ */ jsx(PlusIcon, { className: "size-4 shrink-0", "aria-hidden": "true" }),
5654
- /* @__PURE__ */ jsxs("span", { className: "line-clamp-1", children: [
5655
- "Create \u201C",
5656
- trimmedSearch,
5657
- "\u201D"
5658
- ] })
5659
- ]
5660
- }
5661
- )
5662
- ] })
5871
+ }
5872
+ )
5663
5873
  ] })
5664
5874
  }
5665
5875
  )
@@ -8310,6 +8520,149 @@ var KanbanCard = forwardRef(function KanbanCard2({ className, label, title, clie
8310
8520
  ] }) : children });
8311
8521
  });
8312
8522
  KanbanCard.displayName = "KanbanCard";
8523
+ var NotificationPanel = forwardRef(
8524
+ function NotificationPanel2({ className, children, ...props }, ref) {
8525
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("bg-surface text-fg flex w-full flex-col", className), ...props, children });
8526
+ }
8527
+ );
8528
+ NotificationPanel.displayName = "NotificationPanel";
8529
+ var NotificationPanelHeader = forwardRef(
8530
+ function NotificationPanelHeader2({ title = "Notifications", unreadCount = 0, onMarkAllRead, onSettings, className, ...props }, ref) {
8531
+ return /* @__PURE__ */ jsxs(
8532
+ "div",
8533
+ {
8534
+ ref,
8535
+ className: cn("border-rule flex items-center justify-between border-b px-4 py-3", className),
8536
+ ...props,
8537
+ children: [
8538
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
8539
+ /* @__PURE__ */ jsx("h3", { className: "text-fg text-sm font-semibold", children: title }),
8540
+ unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "bg-accent/10 text-accent rounded-pill px-1.5 py-0.5 text-[11px] font-semibold tabular-nums", children: unreadCount > 99 ? "99+" : unreadCount })
8541
+ ] }),
8542
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8543
+ onMarkAllRead && unreadCount > 0 && /* @__PURE__ */ jsx(
8544
+ "button",
8545
+ {
8546
+ type: "button",
8547
+ onClick: onMarkAllRead,
8548
+ className: "text-fg-3 hover:text-fg text-xs font-medium",
8549
+ children: "Mark all read"
8550
+ }
8551
+ ),
8552
+ onSettings && /* @__PURE__ */ jsx(
8553
+ "button",
8554
+ {
8555
+ type: "button",
8556
+ onClick: onSettings,
8557
+ "aria-label": "Notification settings",
8558
+ className: "text-fg-3 hover:text-fg hover:bg-bg-2 rounded-md p-1 [&_svg]:size-[15px]",
8559
+ children: /* @__PURE__ */ jsx(SettingsIcon, {})
8560
+ }
8561
+ )
8562
+ ] })
8563
+ ]
8564
+ }
8565
+ );
8566
+ }
8567
+ );
8568
+ NotificationPanelHeader.displayName = "NotificationPanelHeader";
8569
+ var FILTER_OPTIONS = ["all", "unread"];
8570
+ var NotificationFilter = forwardRef(
8571
+ function NotificationFilter2({ value, onValueChange, actions, className, ...props }, ref) {
8572
+ return /* @__PURE__ */ jsxs(
8573
+ "div",
8574
+ {
8575
+ ref,
8576
+ className: cn(
8577
+ "border-rule flex items-center justify-between gap-2 border-b px-3 py-2",
8578
+ className
8579
+ ),
8580
+ ...props,
8581
+ children: [
8582
+ /* @__PURE__ */ jsx("div", { className: "bg-bg-2 inline-flex rounded-md p-0.5 text-xs font-medium", children: FILTER_OPTIONS.map((option) => /* @__PURE__ */ jsx(
8583
+ "button",
8584
+ {
8585
+ type: "button",
8586
+ onClick: () => onValueChange(option),
8587
+ "aria-pressed": value === option,
8588
+ className: cn(
8589
+ "rounded-[6px] px-2.5 py-1 capitalize transition-colors",
8590
+ "focus-visible:ring-accent outline-none focus-visible:ring-2",
8591
+ value === option ? "bg-surface text-fg shadow-quiet" : "text-fg-3 hover:text-fg"
8592
+ ),
8593
+ children: option
8594
+ },
8595
+ option
8596
+ )) }),
8597
+ actions
8598
+ ]
8599
+ }
8600
+ );
8601
+ }
8602
+ );
8603
+ NotificationFilter.displayName = "NotificationFilter";
8604
+ var NotificationList = forwardRef(
8605
+ function NotificationList2({ className, children, ...props }, ref) {
8606
+ return /* @__PURE__ */ jsx(
8607
+ "div",
8608
+ {
8609
+ ref,
8610
+ className: cn("divide-rule-soft max-h-[460px] divide-y overflow-y-auto", className),
8611
+ ...props,
8612
+ children
8613
+ }
8614
+ );
8615
+ }
8616
+ );
8617
+ NotificationList.displayName = "NotificationList";
8618
+ var NotificationItem = forwardRef(
8619
+ function NotificationItem2({ title, body, typeLabel, client, time, sender, icon, unread, className, ...props }, ref) {
8620
+ const meta = [typeLabel, client, time].filter(Boolean);
8621
+ return /* @__PURE__ */ jsxs(
8622
+ "button",
8623
+ {
8624
+ ref,
8625
+ type: "button",
8626
+ className: cn(
8627
+ "flex w-full gap-3 px-4 py-3 text-left outline-none",
8628
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
8629
+ "hover:bg-bg-2/60 focus-visible:bg-bg-2/60",
8630
+ unread && "bg-accent/[0.06]",
8631
+ className
8632
+ ),
8633
+ ...props,
8634
+ children: [
8635
+ sender ? /* @__PURE__ */ jsx(Avatar, { size: "sm", name: sender.name, src: sender.src, className: "mt-0.5" }) : /* @__PURE__ */ jsx(
8636
+ "div",
8637
+ {
8638
+ "aria-hidden": "true",
8639
+ className: "bg-bg-2 text-fg-3 mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full [&_svg]:size-3.5",
8640
+ children: icon
8641
+ }
8642
+ ),
8643
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
8644
+ unread && /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Unread. " }),
8645
+ /* @__PURE__ */ jsx("p", { className: cn("text-fg text-sm leading-snug", unread ? "font-semibold" : "font-medium"), children: title }),
8646
+ body && /* @__PURE__ */ jsx("p", { className: "text-fg-3 mt-0.5 truncate text-xs", children: body }),
8647
+ meta.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-fg-4 mt-1 flex flex-wrap items-center gap-1.5 text-[11px]", children: meta.map((part, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
8648
+ i > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
8649
+ /* @__PURE__ */ jsx(
8650
+ "span",
8651
+ {
8652
+ className: cn(
8653
+ i === 0 && typeLabel ? "font-medium tracking-wide uppercase" : "tabular-nums"
8654
+ ),
8655
+ children: part
8656
+ }
8657
+ )
8658
+ ] }, i)) })
8659
+ ] })
8660
+ ]
8661
+ }
8662
+ );
8663
+ }
8664
+ );
8665
+ NotificationItem.displayName = "NotificationItem";
8313
8666
  var Toolbar = forwardRef(function Toolbar2({ className, children, ...props }, ref) {
8314
8667
  return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center gap-2", className), ...props, children });
8315
8668
  });
@@ -8437,6 +8790,6 @@ var KbdHint = forwardRef(function KbdHint2({ className, children, ...props }, re
8437
8790
  });
8438
8791
  KbdHint.displayName = "KbdHint";
8439
8792
 
8440
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityItem, ActivityList, Alert, AlertCircleIcon, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlertTriangleIcon, AlertTriangleSolidIcon, AppHeader, AppHeaderActions, AppHeaderBreadcrumb, AppHeaderSearch, AppHeaderTitle, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowRightSmallIcon, ArrowUpIcon, AspectRatio, AtSignIcon, Avatar, Badge, BarChartIcon, BellIcon, Blockquote, BoldIcon, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BriefcaseIcon, Building2Icon, BuildingIcon, Button, Calendar, CalendarIcon, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatBubbleIcon, CheckCircle2Icon, CheckCircleSolidIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CircleDotIcon, CircleIcon, ClientSelect, ClipboardCheckIcon, ClockIcon, CloseIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, ComingSoon, CommandIcon, CommandPalette, ConfirmActionButton, Content15 as Content, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CopyIcon, CornerDownLeftIcon, CreditCardIcon, DATE_DISPLAY_PLACEHOLDER, DangerAction, DataItem, DataTable, DataTableBody, DataTableCell, DataTableCellDue, DataTableCellId, DataTableCellMono, DataTableCellName, DataTableCheckbox, DataTableHead, DataTableHeader, DataTablePagination, DataTableResultsCount, DataTableRow, DataTableSearch, DataTableSpacer, DataTableToolbar, DatePicker, DetailGrid, DetailMain, DetailSpine, DetailSpineHeader, DetailSpineSection, DetailSpineStats, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DismissibleChip, DocumentIcon, DollarSignIcon, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EyeIcon, EyeOffIcon, Eyebrow, FileIcon, FileReturnIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FlagIcon, FolderClosedIcon, FolderOpenIcon, FolderPlusIcon, FormError, FormSection, FormSuccess, GlobeIcon, GoogleBrandIcon, HelpCircleIcon, HistoryIcon, HomeIcon, HoverCard, HoverCardContent, HoverCardPortal, HoverCardTrigger, IconAction, InboxIcon, InfoCircleSolidIcon, InfoIcon, Input, ItalicIcon, Kanban, KanbanCard, KanbanColumn, KanbanIcon, KbdHint, KeyIcon, KeyboardShortcutsDialog, KpiCard, Label4 as Label, LayoutDashboardIcon, LayoutGridIcon, LayoutListIcon, LightningIcon, Link2Icon, LinkAction, LinkButton, LinkIcon, ListChecksIcon, ListIcon, ListOrderedIcon, LoaderIcon, LoadingRows, LockIcon, LockKeyholeIcon, LockOpenIcon, LogOutIcon, Logo, MailIcon, Main, MapPinIcon, MenuIcon, MessageCircleIcon, MessageCircleWarningIcon, MetadataGrid, MicrosoftBrandIcon, MinusIcon, MonitorIcon, MoonIcon, MoreHorizontalIcon, MoveIcon, MultiFilterPill, MultiSelectField, MutedSpec, Numeric, OTPInput, PageHeader, PageHeaderSep, PageHeaderSpec, Pagination, PaletteIcon, PanelLeftCloseIcon, PanelLeftIcon, PaperclipIcon, PenSignIcon, PencilIcon, PhoneIcon, PhoneInput, PlusIcon, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, PrimaryAction, ProgressBar, ProgressRing, RadioGroup3 as RadioGroup, RadioGroupItem, ReceiptIcon, ReplyIcon, RotateCcwIcon, SaveIcon, ScrollArea, ScrollBar, SearchIcon, SearchInput, SearchSelect, SecondaryAction, Section, SectionHead, SectionHeader, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SendIcon, Separator4 as Separator, SettingsIcon, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Shell, ShieldIcon, SideDrawer, Sidebar, SidebarBrand, SidebarBrandText, SidebarFooter, SidebarLink, SidebarLinkAction, SidebarLinkBadge, SidebarLinkGroup, SidebarLinkLabel, SidebarProvider, SidebarSection, SidebarTrigger, SidebarUser, Skeleton, SkeletonCircle, SkeletonText, SlashIcon, Slider, SmartphoneIcon, SparkleIcon, SparklesIcon, StarIcon, StarRating, Stat, Stepper, StrikethroughIcon, SubmitButton, SunIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableIcon, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagIcon, TeamIcon, TeamMemberSelect, Textarea, ToastProvider, ToggleGroup, ToggleGroupItem, Toolbar, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, Trash2Icon, TrashIcon, TrendingDownIcon, TrendingUpIcon, UnderlineIcon, UploadIcon, UserCircleIcon, UserIcon, UsersIcon, VisuallyHidden, WorkflowIcon, XCircleSolidIcon, XIcon, ZoomInIcon, ZoomOutIcon, alertVariants, badgeVariants, buttonVariants, cardVariants, cn, colors, displayToIso, filterChipVariants, inputVariants, isoToDisplay, labelVariants, progressBarVariants, progressRingVariants, radii, reference, searchInputVariants, shadows, sidebarLinkBadgeVariants, spacing, starRatingVariants, surfaces, systemTokens, textareaVariants, typography, useSidebarState, useToast };
8793
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityItem, ActivityList, Alert, AlertCircleIcon, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlertTriangleIcon, AlertTriangleSolidIcon, AppHeader, AppHeaderActions, AppHeaderBreadcrumb, AppHeaderSearch, AppHeaderTitle, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowRightSmallIcon, ArrowUpIcon, AspectRatio, AtSignIcon, Avatar, Badge, BarChartIcon, BellIcon, Blockquote, BoldIcon, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BriefcaseIcon, Building2Icon, BuildingIcon, Button, Calendar, CalendarIcon, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatBubbleIcon, CheckCircle2Icon, CheckCircleSolidIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CircleDotIcon, CircleIcon, ClientSelect, ClipboardCheckIcon, ClockIcon, CloseIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, ComingSoon, CommandIcon, CommandPalette, ConfirmActionButton, Content15 as Content, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, CopyIcon, CornerDownLeftIcon, CreditCardIcon, DATE_DISPLAY_PLACEHOLDER, DangerAction, DataItem, DataTable, DataTableBody, DataTableCell, DataTableCellDue, DataTableCellId, DataTableCellMono, DataTableCellName, DataTableCheckbox, DataTableHead, DataTableHeader, DataTablePagination, DataTableResultsCount, DataTableRow, DataTableSearch, DataTableSpacer, DataTableToolbar, DatePicker, DetailGrid, DetailMain, DetailSpine, DetailSpineHeader, DetailSpineSection, DetailSpineStats, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DismissibleChip, DocumentIcon, DollarSignIcon, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EyeIcon, EyeOffIcon, Eyebrow, FileIcon, FileReturnIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FlagIcon, FolderClosedIcon, FolderOpenIcon, FolderPlusIcon, FormError, FormSection, FormSuccess, GlobeIcon, GoogleBrandIcon, HelpCircleIcon, HistoryIcon, HomeIcon, HoverCard, HoverCardContent, HoverCardPortal, HoverCardTrigger, IconAction, InboxIcon, InfoCircleSolidIcon, InfoIcon, Input, ItalicIcon, Kanban, KanbanCard, KanbanColumn, KanbanIcon, KbdHint, KeyIcon, KeyboardShortcutsDialog, KpiCard, Label4 as Label, LayoutDashboardIcon, LayoutGridIcon, LayoutListIcon, LightningIcon, Link2Icon, LinkAction, LinkButton, LinkIcon, ListChecksIcon, ListIcon, ListOrderedIcon, LoaderIcon, LoadingRows, LockIcon, LockKeyholeIcon, LockOpenIcon, LogOutIcon, Logo, MailIcon, Main, MapPinIcon, MenuIcon, MessageCircleIcon, MessageCircleWarningIcon, MetadataGrid, MicrosoftBrandIcon, MinusIcon, MonitorIcon, MoonIcon, MoreHorizontalIcon, MoveIcon, MultiFilterPill, MultiSelectField, MutedSpec, NotificationFilter, NotificationItem, NotificationList, NotificationPanel, NotificationPanelHeader, Numeric, OTPInput, PageHeader, PageHeaderSep, PageHeaderSpec, Pagination, PaletteIcon, PanelLeftCloseIcon, PanelLeftIcon, PaperclipIcon, PenSignIcon, PencilIcon, PhoneIcon, PhoneInput, PlusIcon, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, PrimaryAction, ProgressBar, ProgressRing, RadioGroup3 as RadioGroup, RadioGroupItem, ReceiptIcon, ReplyIcon, RotateCcwIcon, SaveIcon, ScrollArea, ScrollBar, SearchIcon, SearchInput, SearchSelect, SecondaryAction, Section, SectionHead, SectionHeader, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SendIcon, Separator4 as Separator, SettingsIcon, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Shell, ShieldIcon, SideDrawer, Sidebar, SidebarBrand, SidebarBrandText, SidebarFooter, SidebarLink, SidebarLinkAction, SidebarLinkBadge, SidebarLinkGroup, SidebarLinkLabel, SidebarProvider, SidebarSection, SidebarTrigger, SidebarUser, Skeleton, SkeletonCircle, SkeletonText, SlashIcon, Slider, SmartphoneIcon, SparkleIcon, SparklesIcon, StarIcon, StarRating, Stat, Stepper, StrikethroughIcon, SubmitButton, SunIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableIcon, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagIcon, TeamIcon, TeamMemberSelect, Textarea, ToastProvider, ToggleGroup, ToggleGroupItem, Toolbar, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, Trash2Icon, TrashIcon, TrendingDownIcon, TrendingUpIcon, UnderlineIcon, UploadIcon, UserCircleIcon, UserIcon, UsersIcon, VisuallyHidden, WorkflowIcon, XCircleSolidIcon, XIcon, ZoomInIcon, ZoomOutIcon, alertVariants, badgeVariants, buttonVariants, cardVariants, cn, colors, displayToIso, filterChipVariants, inputVariants, isoToDisplay, labelVariants, progressBarVariants, progressRingVariants, radii, reference, searchInputVariants, shadows, sidebarLinkBadgeVariants, spacing, starRatingVariants, surfaces, systemTokens, textareaVariants, typography, useSidebarState, useToast };
8441
8794
  //# sourceMappingURL=index.js.map
8442
8795
  //# sourceMappingURL=index.js.map