@l3mpire/ui 2.25.1 → 2.25.2

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/USAGE.md CHANGED
@@ -794,26 +794,39 @@ import { Tabs, TabList, TabTrigger, TabContent } from "@l3mpire/ui";
794
794
 
795
795
  ```tsx
796
796
  import { BrowserTab, BrowserTabItem } from "@l3mpire/ui";
797
-
798
- <BrowserTab activeTabId="1" onTabSelect={(id) => {}}>
799
- <BrowserTabItem id="1" label="Page 1" onClose={(id) => {}} />
800
- <BrowserTabItem id="2" label="Page 2" onClose={(id) => {}} />
797
+ import { faRocketOutline } from "@l3mpire/icons";
798
+
799
+ <BrowserTab draggable onReorder={(from, to) => {}} onAddTab={() => {}}>
800
+ <BrowserTabItem
801
+ icon={faRocketOutline}
802
+ label="Campaigns"
803
+ badge="99"
804
+ isActive
805
+ onClick={() => setActive(0)}
806
+ onClose={() => removeTab(0)}
807
+ onRename={(newLabel) => renameTab(0, newLabel)}
808
+ />
809
+ <BrowserTabItem label="Leads" onClick={() => setActive(1)} onClose={() => removeTab(1)} />
801
810
  </BrowserTab>
802
811
  ```
803
812
 
813
+ Active tabs render with concave bottom corners that fuse into the bar divider (real browser-tab look). Inactive tabs get a hover fill + soft shadow on the inner pill (active tabs keep their bg on hover).
814
+
804
815
  | Prop (BrowserTab) | Values |
805
816
  |---|---|
806
- | `activeTabId` | `string` |
807
- | `onTabSelect` | `(id: string) => void` |
808
- | `onNewTab` | `() => void` (shows + button) |
809
- | `onReorder` | `(ids: string[]) => void` |
817
+ | `onAddTab` | `() => void` (shows + button) |
818
+ | `draggable` | `boolean` |
819
+ | `onReorder` | `(from: number, to: number) => void` |
820
+ | `onOverflowSelect` | `(hiddenIndex: number, lastVisibleIndex: number) => void` |
810
821
 
811
822
  | Prop (BrowserTabItem) | Values |
812
823
  |---|---|
813
- | `id` | `string` (required) |
814
- | `label` | `string` |
824
+ | `label` | `string` (required) |
815
825
  | `icon` | `IconDefinition` |
816
- | `onClose` | `(id: string) => void` |
826
+ | `badge` | `string` |
827
+ | `isActive` | `boolean` |
828
+ | `onClose` | `(e) => void` |
829
+ | `onRename` | `(newLabel: string) => void` (enables dbl-click rename) |
817
830
 
818
831
  ---
819
832
 
package/dist/index.js CHANGED
@@ -564,6 +564,7 @@ var BrowserTabItem = React3.forwardRef(
564
564
  } : {};
565
565
  const isDragged = ctx?.draggable && ctx.dragIndex === ctx.itemIndex;
566
566
  const isDropTarget = ctx?.draggable && ctx.dropIndex === ctx.itemIndex && ctx.dragIndex !== ctx.itemIndex;
567
+ const showGrip = ctx?.draggable && isHovered;
567
568
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
568
569
  "div",
569
570
  {
@@ -571,78 +572,101 @@ var BrowserTabItem = React3.forwardRef(
571
572
  onMouseEnter: () => setIsHovered(true),
572
573
  onMouseLeave: () => setIsHovered(false),
573
574
  className: cn(
574
- "flex items-center gap-base px-base py-sm rounded-t-base cursor-pointer select-none transition-opacity shrink-0",
575
- "bg-browser-tab-item-bg border-browser-tab-item-border border-solid",
576
- isActive ? "border-l border-r border-t border-b-0 mb-[-1px] z-10" : "border-0",
575
+ "relative shrink-0 p-xs rounded-tl-base rounded-tr-base cursor-pointer select-none transition-opacity",
576
+ "border-solid border-browser-tab-item-border",
577
+ isActive ? "bg-browser-tab-item-bg border-l border-r border-t mb-[-1px] z-10" : "border-0",
577
578
  isDragged && "opacity-40",
578
- isDropTarget && "ring-2 ring-inset ring-blue-400 rounded-t-base",
579
+ isDropTarget && "ring-2 ring-inset ring-blue-400",
579
580
  className
580
581
  ),
581
582
  ...dragProps,
582
583
  ...props,
583
584
  children: [
584
- icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
585
- import_icons3.Icon,
586
- {
587
- icon: ctx?.draggable && isHovered ? import_icons3.faGripDotsVerticalSolid : icon,
588
- size: "xs",
589
- className: cn(
590
- ctx?.draggable && isHovered ? "text-browser-tab-item-hover-icon cursor-grab" : isActive ? "text-browser-tab-item-active-icon" : "text-browser-tab-item-inactive-icon"
591
- )
592
- }
593
- ) }),
594
- isEditing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
595
- "input",
596
- {
597
- ref: inputRef,
598
- value: editValue,
599
- onChange: (e) => setEditValue(e.target.value),
600
- onBlur: commitRename,
601
- onKeyDown: (e) => {
602
- if (e.key === "Enter") commitRename();
603
- if (e.key === "Escape") cancelRename();
604
- },
605
- onClick: (e) => e.stopPropagation(),
606
- className: cn(
607
- "text-sm font-medium leading-sm bg-transparent outline-none p-0 m-0",
608
- "border-b border-browser-tab-item-border border-dashed border-t-0 border-l-0 border-r-0",
609
- isActive ? "text-browser-tab-item-active-text" : "text-browser-tab-item-inactive-text"
610
- ),
611
- style: { width: `${Math.max(editValue.length + 1, 2)}ch` }
612
- }
613
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
614
- "span",
585
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
586
+ "div",
615
587
  {
616
588
  className: cn(
617
- "text-sm font-medium leading-sm whitespace-nowrap",
618
- isActive ? "text-browser-tab-item-active-text" : "text-browser-tab-item-inactive-text"
589
+ "flex items-center gap-base px-xs py-2xs transition-[background-color,border-radius,box-shadow]",
590
+ isHovered && !isActive ? "bg-browser-tab-item-hover-bg rounded-sm shadow-sm" : "bg-browser-tab-item-bg rounded-base"
619
591
  ),
620
- onDoubleClick: (e) => {
621
- if (onRename) {
622
- e.stopPropagation();
623
- setEditValue(label);
624
- setIsEditing(true);
625
- }
626
- },
627
- children: label
592
+ children: [
593
+ icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
594
+ import_icons3.Icon,
595
+ {
596
+ icon: showGrip ? import_icons3.faGripDotsVerticalSolid : icon,
597
+ size: "xs",
598
+ className: cn(
599
+ showGrip ? "text-browser-tab-item-hover-icon cursor-grab" : isActive ? "text-browser-tab-item-active-icon" : "text-browser-tab-item-inactive-icon"
600
+ )
601
+ }
602
+ ) }),
603
+ isEditing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
604
+ "input",
605
+ {
606
+ ref: inputRef,
607
+ value: editValue,
608
+ onChange: (e) => setEditValue(e.target.value),
609
+ onBlur: commitRename,
610
+ onKeyDown: (e) => {
611
+ if (e.key === "Enter") commitRename();
612
+ if (e.key === "Escape") cancelRename();
613
+ },
614
+ onClick: (e) => e.stopPropagation(),
615
+ className: cn(
616
+ "text-sm font-medium leading-sm bg-transparent outline-none p-0 m-0",
617
+ "border-b border-browser-tab-item-border border-dashed border-t-0 border-l-0 border-r-0",
618
+ isActive ? "text-browser-tab-item-active-text" : "text-browser-tab-item-inactive-text"
619
+ ),
620
+ style: { width: `${Math.max(editValue.length + 1, 2)}ch` }
621
+ }
622
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
623
+ "span",
624
+ {
625
+ className: cn(
626
+ "text-sm font-medium leading-sm whitespace-nowrap",
627
+ isActive ? "text-browser-tab-item-active-text" : "text-browser-tab-item-inactive-text"
628
+ ),
629
+ onDoubleClick: (e) => {
630
+ if (onRename) {
631
+ e.stopPropagation();
632
+ setEditValue(label);
633
+ setIsEditing(true);
634
+ }
635
+ },
636
+ children: label
637
+ }
638
+ ),
639
+ badge && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Badge, { variant: "light", type: "neutral", size: "sm", children: badge }),
640
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
641
+ "button",
642
+ {
643
+ onClick: (e) => {
644
+ e.stopPropagation();
645
+ onClose(e);
646
+ },
647
+ className: cn(
648
+ "shrink-0 flex items-center justify-center cursor-pointer",
649
+ isActive ? "text-browser-tab-item-active-icon" : "text-browser-tab-item-inactive-icon"
650
+ ),
651
+ "aria-label": `Close ${label}`,
652
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons3.Icon, { icon: import_icons3.faXmarkOutline, size: "xs" })
653
+ }
654
+ )
655
+ ]
628
656
  }
629
657
  ),
630
- badge && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Badge, { variant: "light", type: "neutral", size: "sm", children: badge }),
631
- onClose && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
632
- "button",
633
- {
634
- onClick: (e) => {
635
- e.stopPropagation();
636
- onClose(e);
637
- },
638
- className: cn(
639
- "shrink-0 flex items-center justify-center cursor-pointer",
640
- isActive ? "text-browser-tab-item-active-icon" : "text-browser-tab-item-inactive-icon"
641
- ),
642
- "aria-label": `Close ${label}`,
643
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons3.Icon, { icon: import_icons3.faXmarkOutline, size: "xs" })
644
- }
645
- )
658
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
659
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, className: "pointer-events-none absolute bottom-0 left-[-1px] w-px h-[8px] bg-browser-tab-item-bg" }),
660
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, className: "pointer-events-none absolute bottom-0 right-[-1px] w-px h-[8px] bg-browser-tab-item-bg" }),
661
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "aria-hidden": true, className: "pointer-events-none absolute bottom-0 left-[-8px] size-[8px]", children: [
662
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute bottom-0 left-0 right-0 h-px bg-browser-tab-item-bg" }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute inset-0 rounded-br-[8px] border-b border-r border-solid border-browser-tab-item-border" })
664
+ ] }),
665
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "aria-hidden": true, className: "pointer-events-none absolute bottom-0 right-[-8px] size-[8px]", children: [
666
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute bottom-0 left-0 right-0 h-px bg-browser-tab-item-bg" }),
667
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute inset-0 rounded-bl-[8px] border-b border-l border-solid border-browser-tab-item-border" })
668
+ ] })
669
+ ] })
646
670
  ]
647
671
  }
648
672
  );
@@ -723,7 +747,7 @@ var BrowserTab = React3.forwardRef(
723
747
  {
724
748
  ref,
725
749
  className: cn(
726
- "flex items-end w-full h-[44px] border-b border-browser-tab-border px-lg",
750
+ "flex items-end w-full h-[44px] border-b border-browser-tab-border pl-base pr-lg",
727
751
  className
728
752
  ),
729
753
  ...props,
@@ -732,7 +756,7 @@ var BrowserTab = React3.forwardRef(
732
756
  "div",
733
757
  {
734
758
  ref: tabsContainerRef,
735
- className: "flex items-center flex-1 min-w-0",
759
+ className: "flex items-center flex-1 min-w-0 pl-base",
736
760
  style: { overflowX: "clip", overflowY: "visible" },
737
761
  children: [
738
762
  childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BrowserTabContext.Provider, { value: { ...ctxBase, itemIndex: index }, children: child }, index)),