@forgeax/app-shell 0.48.0 → 0.50.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/react.d.ts CHANGED
@@ -161,6 +161,36 @@ interface TabPinnedStateSource {
161
161
  /** Observe whether one product-supplied panel identity is pinned in a group. */
162
162
  declare function useTabPinnedState(source: TabPinnedStateSource, groupId: string, panelId: string): boolean;
163
163
 
164
+ interface DockTabFrameProps extends HTMLAttributes<HTMLDivElement> {
165
+ /** Caller-owned leading presentation, such as a product icon. */
166
+ leading?: ReactNode;
167
+ /** Caller-owned trailing action; App Shell only fixes its slot position. */
168
+ action?: ReactNode;
169
+ }
170
+ type DockTabActionProps = HTMLAttributes<HTMLDivElement>;
171
+ /** Product-neutral Dock tab frame with stable Dockview-compatible DOM hooks. */
172
+ declare const DockTabFrame: react.ForwardRefExoticComponent<DockTabFrameProps & react.RefAttributes<HTMLDivElement>>;
173
+ /** Product-neutral trailing-action wrapper for a Dock tab frame. */
174
+ declare const DockTabAction: react.ForwardRefExoticComponent<DockTabActionProps & react.RefAttributes<HTMLDivElement>>;
175
+
176
+ type DockTabStatusTone = 'neutral' | 'error' | 'warning';
177
+ interface DockTabStatusSummaryItem {
178
+ id: string;
179
+ icon?: ReactNode;
180
+ tone?: DockTabStatusTone;
181
+ value: ReactNode;
182
+ }
183
+ interface DockTabStatusSummaryProps extends HTMLAttributes<HTMLSpanElement> {
184
+ items: readonly DockTabStatusSummaryItem[];
185
+ }
186
+ /**
187
+ * Product-neutral status-count presentation for a Dock tab.
188
+ *
189
+ * The caller owns the status source, labels, visibility policy, and product
190
+ * styling. App Shell only owns stable DOM hooks and item ordering.
191
+ */
192
+ declare const DockTabStatusSummary: react.ForwardRefExoticComponent<DockTabStatusSummaryProps & react.RefAttributes<HTMLSpanElement>>;
193
+
164
194
  type PanelContentPadding = 'none' | 'sm' | 'md';
165
195
  type PanelContentScroll = 'none' | 'auto';
166
196
  type PanelContentTone = 'default' | 'surface' | 'tool';
@@ -302,4 +332,4 @@ interface ShellSlotProps extends HTMLAttributes<HTMLElement> {
302
332
  /** Structural shell marker that preserves the caller's semantic element. */
303
333
  declare function ShellSlot({ as, name, ...props }: ShellSlotProps): ReactElement;
304
334
 
305
- export { type AnchoredResizeDirection, AnchoredResizeHandle, type AnchoredResizeHandleProps, type AnchoredResizeSession, DetachedPanelBoundary, type DetachedPanelBoundaryProps, DetachedSurfaceFrame, type DetachedSurfaceFrameProps, DetachedSurfaceStatus, type DetachedSurfaceStatusProps, type DetachedSurfaceStatusTone, type DockLayoutControlBinding, type DockLayoutControlBindingOptions, DockLayoutMenu, type DockLayoutMenuPanel, type DockLayoutMenuProps, FloatingMenu, type FloatingMenuAnchor, type FloatingMenuPoint, type FloatingMenuProps, type LiveTabPlacement, type LiveTabPlacementSource, type LiveTabTitleSource, type PanelContentPadding, type PanelContentPolicy, type PanelContentScroll, type PanelContentTone, PanelEmptyState, type PanelEmptyStateProps, PanelSurface, type PanelSurfaceProps, type PersistentSizeStorage, type PersistentSizeStore, type PersistentSizeStoreOptions, type PersistentSizeUpdate, type PointerDragFinishReason, type PointerDragSessionOptions, type PointerReorderFinishReason, type PointerReorderSession, type PointerReorderSessionOptions, ResizeHandle, type ResizeHandleProps, ShellSlot, type ShellSlotElement, type ShellSlotProps, SlotDebugOverlay, SurfacePlaceholder, type SurfacePlaceholderProps, SurfaceRegion, type SurfaceRegionProps, type TabCloseInteractions, type TabCloseInteractionsOptions, type TabPinnedStateSource, type ThresholdPointerDragFinishReason, type ThresholdPointerDragSession, type ThresholdPointerDragSessionOptions, applyAnchoredResizeDelta, beginAnchoredResize, createPersistentSizeStore, hashSlotHue, installPointerDragSession, installPointerReorderSession, installThresholdPointerDragSession, isSlotDebugEnabled, useDockLayoutControlBinding, useLiveTabPlacement, useLiveTabTitle, useLocalSize, usePersistentSizeStore, useTabCloseInteractions, useTabPinnedState };
335
+ export { type AnchoredResizeDirection, AnchoredResizeHandle, type AnchoredResizeHandleProps, type AnchoredResizeSession, DetachedPanelBoundary, type DetachedPanelBoundaryProps, DetachedSurfaceFrame, type DetachedSurfaceFrameProps, DetachedSurfaceStatus, type DetachedSurfaceStatusProps, type DetachedSurfaceStatusTone, type DockLayoutControlBinding, type DockLayoutControlBindingOptions, DockLayoutMenu, type DockLayoutMenuPanel, type DockLayoutMenuProps, DockTabAction, type DockTabActionProps, DockTabFrame, type DockTabFrameProps, DockTabStatusSummary, type DockTabStatusSummaryItem, type DockTabStatusSummaryProps, type DockTabStatusTone, FloatingMenu, type FloatingMenuAnchor, type FloatingMenuPoint, type FloatingMenuProps, type LiveTabPlacement, type LiveTabPlacementSource, type LiveTabTitleSource, type PanelContentPadding, type PanelContentPolicy, type PanelContentScroll, type PanelContentTone, PanelEmptyState, type PanelEmptyStateProps, PanelSurface, type PanelSurfaceProps, type PersistentSizeStorage, type PersistentSizeStore, type PersistentSizeStoreOptions, type PersistentSizeUpdate, type PointerDragFinishReason, type PointerDragSessionOptions, type PointerReorderFinishReason, type PointerReorderSession, type PointerReorderSessionOptions, ResizeHandle, type ResizeHandleProps, ShellSlot, type ShellSlotElement, type ShellSlotProps, SlotDebugOverlay, SurfacePlaceholder, type SurfacePlaceholderProps, SurfaceRegion, type SurfaceRegionProps, type TabCloseInteractions, type TabCloseInteractionsOptions, type TabPinnedStateSource, type ThresholdPointerDragFinishReason, type ThresholdPointerDragSession, type ThresholdPointerDragSessionOptions, applyAnchoredResizeDelta, beginAnchoredResize, createPersistentSizeStore, hashSlotHue, installPointerDragSession, installPointerReorderSession, installThresholdPointerDragSession, isSlotDebugEnabled, useDockLayoutControlBinding, useLiveTabPlacement, useLiveTabTitle, useLocalSize, usePersistentSizeStore, useTabCloseInteractions, useTabPinnedState };
package/dist/react.js CHANGED
@@ -1440,22 +1440,100 @@ function useTabPinnedState(source, groupId, panelId) {
1440
1440
  );
1441
1441
  }
1442
1442
 
1443
- // src/panel.tsx
1443
+ // src/dock-tab-frame.tsx
1444
+ import {
1445
+ forwardRef
1446
+ } from "react";
1444
1447
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1448
+ function joinClassName(owned, caller) {
1449
+ return caller ? `${owned} ${caller}` : owned;
1450
+ }
1451
+ var DockTabFrame = forwardRef(
1452
+ function DockTabFrame2({
1453
+ leading,
1454
+ action,
1455
+ children,
1456
+ className,
1457
+ ...props
1458
+ }, ref) {
1459
+ return /* @__PURE__ */ jsxs(
1460
+ "div",
1461
+ {
1462
+ ...props,
1463
+ ref,
1464
+ className: joinClassName("dv-default-tab", className),
1465
+ children: [
1466
+ leading,
1467
+ /* @__PURE__ */ jsx3("span", { className: "dv-default-tab-content", children }),
1468
+ action
1469
+ ]
1470
+ }
1471
+ );
1472
+ }
1473
+ );
1474
+ DockTabFrame.displayName = "DockTabFrame";
1475
+ var DockTabAction = forwardRef(
1476
+ function DockTabAction2({ className, ...props }, ref) {
1477
+ return /* @__PURE__ */ jsx3(
1478
+ "div",
1479
+ {
1480
+ ...props,
1481
+ ref,
1482
+ className: joinClassName("dv-default-tab-action", className)
1483
+ }
1484
+ );
1485
+ }
1486
+ );
1487
+ DockTabAction.displayName = "DockTabAction";
1488
+
1489
+ // src/dock-tab-status-summary.tsx
1490
+ import {
1491
+ forwardRef as forwardRef2
1492
+ } from "react";
1493
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1494
+ var DockTabStatusSummary = forwardRef2(function DockTabStatusSummary2({ className, items, ...props }, ref) {
1495
+ return /* @__PURE__ */ jsx4(
1496
+ "span",
1497
+ {
1498
+ ref,
1499
+ className: [
1500
+ "fx-dock-tab-status-summary",
1501
+ className
1502
+ ].filter(Boolean).join(" "),
1503
+ ...props,
1504
+ children: items.map(({ id, icon, tone = "neutral", value }) => /* @__PURE__ */ jsxs2(
1505
+ "span",
1506
+ {
1507
+ className: `fx-dock-tab-status-item fx-dock-tab-status-item--${tone}`,
1508
+ "data-status-id": id,
1509
+ children: [
1510
+ icon !== void 0 && /* @__PURE__ */ jsx4("span", { className: "fx-dock-tab-status-icon", "aria-hidden": true, children: icon }),
1511
+ /* @__PURE__ */ jsx4("span", { className: "fx-dock-tab-status-value", children: value })
1512
+ ]
1513
+ },
1514
+ id
1515
+ ))
1516
+ }
1517
+ );
1518
+ });
1519
+ DockTabStatusSummary.displayName = "DockTabStatusSummary";
1520
+
1521
+ // src/panel.tsx
1522
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1445
1523
  function PanelEmptyState({
1446
1524
  title,
1447
1525
  detail,
1448
1526
  className,
1449
1527
  ...props
1450
1528
  }) {
1451
- return /* @__PURE__ */ jsxs(
1529
+ return /* @__PURE__ */ jsxs3(
1452
1530
  "div",
1453
1531
  {
1454
1532
  ...props,
1455
1533
  className: className ? `fx-panel-empty ${className}` : "fx-panel-empty",
1456
1534
  children: [
1457
- /* @__PURE__ */ jsx3("div", { className: "fx-panel-empty-title", children: title }),
1458
- detail == null ? null : /* @__PURE__ */ jsx3("div", { className: "fx-panel-empty-detail", children: detail })
1535
+ /* @__PURE__ */ jsx5("div", { className: "fx-panel-empty-title", children: title }),
1536
+ detail == null ? null : /* @__PURE__ */ jsx5("div", { className: "fx-panel-empty-detail", children: detail })
1459
1537
  ]
1460
1538
  }
1461
1539
  );
@@ -1470,7 +1548,7 @@ function PanelSurface({
1470
1548
  className,
1471
1549
  ...props
1472
1550
  }) {
1473
- return /* @__PURE__ */ jsxs(
1551
+ return /* @__PURE__ */ jsxs3(
1474
1552
  "section",
1475
1553
  {
1476
1554
  ...props,
@@ -1481,7 +1559,7 @@ function PanelSurface({
1481
1559
  "data-fx-slot": `DockPanel:${id}`,
1482
1560
  children: [
1483
1561
  header,
1484
- /* @__PURE__ */ jsx3(
1562
+ /* @__PURE__ */ jsx5(
1485
1563
  "div",
1486
1564
  {
1487
1565
  className: "fx-panel-content",
@@ -1515,7 +1593,7 @@ function DetachedPanelBoundary({
1515
1593
  }
1516
1594
 
1517
1595
  // src/detached-surface-frame.tsx
1518
- import { jsx as jsx4 } from "react/jsx-runtime";
1596
+ import { jsx as jsx6 } from "react/jsx-runtime";
1519
1597
  var fill = { position: "fixed", inset: 0 };
1520
1598
  var centeredContent = {
1521
1599
  display: "flex",
@@ -1527,12 +1605,12 @@ function DetachedSurfaceFrame({
1527
1605
  panel = false,
1528
1606
  centered = false
1529
1607
  }) {
1530
- return /* @__PURE__ */ jsx4(
1608
+ return /* @__PURE__ */ jsx6(
1531
1609
  "div",
1532
1610
  {
1533
1611
  className: panel ? "fx-detached-surface fx-detached-panel main-area" : "fx-detached-surface",
1534
1612
  style: fill,
1535
- children: centered ? /* @__PURE__ */ jsx4("div", { className: "fx-detached-surface-status", style: centeredContent, children }) : children
1613
+ children: centered ? /* @__PURE__ */ jsx6("div", { className: "fx-detached-surface-status", style: centeredContent, children }) : children
1536
1614
  }
1537
1615
  );
1538
1616
  }
@@ -1540,25 +1618,25 @@ function DetachedSurfaceStatus({
1540
1618
  children,
1541
1619
  tone = "neutral"
1542
1620
  }) {
1543
- return /* @__PURE__ */ jsx4("span", { className: "fx-detached-surface-status-text", "data-tone": tone, children });
1621
+ return /* @__PURE__ */ jsx6("span", { className: "fx-detached-surface-status-text", "data-tone": tone, children });
1544
1622
  }
1545
1623
 
1546
1624
  // src/surface-placeholder.tsx
1547
- import { jsx as jsx5 } from "react/jsx-runtime";
1625
+ import { jsx as jsx7 } from "react/jsx-runtime";
1548
1626
  function SurfacePlaceholder({
1549
1627
  title,
1550
1628
  className
1551
1629
  }) {
1552
- return /* @__PURE__ */ jsx5("div", { className: className ? `surface-placeholder ${className}` : "surface-placeholder", children: /* @__PURE__ */ jsx5("div", { className: "surface-placeholder-title", children: title }) });
1630
+ return /* @__PURE__ */ jsx7("div", { className: className ? `surface-placeholder ${className}` : "surface-placeholder", children: /* @__PURE__ */ jsx7("div", { className: "surface-placeholder-title", children: title }) });
1553
1631
  }
1554
1632
 
1555
1633
  // src/surface-region.tsx
1556
1634
  import {
1557
- forwardRef
1635
+ forwardRef as forwardRef3
1558
1636
  } from "react";
1559
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
1637
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1560
1638
  var joinClassNames = (base, modifier) => modifier ? `${base} ${modifier}` : base;
1561
- var SurfaceRegion = forwardRef(
1639
+ var SurfaceRegion = forwardRef3(
1562
1640
  function SurfaceRegion2({
1563
1641
  children,
1564
1642
  overlay,
@@ -1566,15 +1644,15 @@ var SurfaceRegion = forwardRef(
1566
1644
  bodyClassName,
1567
1645
  ...props
1568
1646
  }, ref) {
1569
- return /* @__PURE__ */ jsxs2(
1647
+ return /* @__PURE__ */ jsxs4(
1570
1648
  "div",
1571
1649
  {
1572
1650
  ...props,
1573
1651
  ref,
1574
1652
  className: joinClassNames("fx-surface-region", className),
1575
1653
  children: [
1576
- overlay == null ? null : /* @__PURE__ */ jsx6("div", { className: "fx-surface-region-overlay", children: overlay }),
1577
- /* @__PURE__ */ jsx6("div", { className: joinClassNames("fx-surface-region-body", bodyClassName), children })
1654
+ overlay == null ? null : /* @__PURE__ */ jsx8("div", { className: "fx-surface-region-overlay", children: overlay }),
1655
+ /* @__PURE__ */ jsx8("div", { className: joinClassNames("fx-surface-region-body", bodyClassName), children })
1578
1656
  ]
1579
1657
  }
1580
1658
  );
@@ -1607,7 +1685,7 @@ function useDockLayoutControlBinding({
1607
1685
  // src/floating-menu.tsx
1608
1686
  var import_react_dom = __toESM(require_react_dom(), 1);
1609
1687
  import { useEffect as useEffect5, useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
1610
- import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1688
+ import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1611
1689
  var VIEWPORT_PADDING = 8;
1612
1690
  function FloatingMenu({
1613
1691
  open,
@@ -1666,8 +1744,8 @@ function FloatingMenu({
1666
1744
  }, [onClose, open]);
1667
1745
  if (!open) return null;
1668
1746
  return (0, import_react_dom.createPortal)(
1669
- /* @__PURE__ */ jsxs3(Fragment, { children: [
1670
- /* @__PURE__ */ jsx7(
1747
+ /* @__PURE__ */ jsxs5(Fragment, { children: [
1748
+ /* @__PURE__ */ jsx9(
1671
1749
  "div",
1672
1750
  {
1673
1751
  "data-app-shell-floating-menu-backdrop": "",
@@ -1679,7 +1757,7 @@ function FloatingMenu({
1679
1757
  }
1680
1758
  }
1681
1759
  ),
1682
- /* @__PURE__ */ jsx7(
1760
+ /* @__PURE__ */ jsx9(
1683
1761
  "div",
1684
1762
  {
1685
1763
  ref: menuRef,
@@ -1703,7 +1781,7 @@ function FloatingMenu({
1703
1781
  }
1704
1782
 
1705
1783
  // src/dock-layout-menu.tsx
1706
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1784
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1707
1785
  function DockLayoutMenu({
1708
1786
  state,
1709
1787
  onToggle,
@@ -1724,7 +1802,7 @@ function DockLayoutMenu({
1724
1802
  closePanel,
1725
1803
  reopenPanel
1726
1804
  });
1727
- return /* @__PURE__ */ jsxs4(
1805
+ return /* @__PURE__ */ jsxs6(
1728
1806
  FloatingMenu,
1729
1807
  {
1730
1808
  open: snapshot.open,
@@ -1733,7 +1811,7 @@ function DockLayoutMenu({
1733
1811
  align: "end",
1734
1812
  className: "fx-dl-menu",
1735
1813
  children: [
1736
- /* @__PURE__ */ jsxs4(
1814
+ /* @__PURE__ */ jsxs6(
1737
1815
  "button",
1738
1816
  {
1739
1817
  type: "button",
@@ -1748,16 +1826,16 @@ function DockLayoutMenu({
1748
1826
  }
1749
1827
  },
1750
1828
  children: [
1751
- resetIcon ? /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: resetIcon }) : null,
1829
+ resetIcon ? /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: resetIcon }) : null,
1752
1830
  resetLabel
1753
1831
  ]
1754
1832
  }
1755
1833
  ),
1756
- /* @__PURE__ */ jsx8("div", { className: "fx-dl-sep", role: "separator" }),
1757
- /* @__PURE__ */ jsx8("div", { className: "fx-dl-head", children: sectionLabel }),
1758
- panels.length === 0 ? /* @__PURE__ */ jsx8("div", { className: "fx-dl-head", "data-app-shell-dock-layout-empty": "", children: emptyLabel }) : panels.map((panel) => {
1834
+ /* @__PURE__ */ jsx10("div", { className: "fx-dl-sep", role: "separator" }),
1835
+ /* @__PURE__ */ jsx10("div", { className: "fx-dl-head", children: sectionLabel }),
1836
+ panels.length === 0 ? /* @__PURE__ */ jsx10("div", { className: "fx-dl-head", "data-app-shell-dock-layout-empty": "", children: emptyLabel }) : panels.map((panel) => {
1759
1837
  const isOpen = panelControl.isOpen(panel.id);
1760
- return /* @__PURE__ */ jsxs4(
1838
+ return /* @__PURE__ */ jsxs6(
1761
1839
  "button",
1762
1840
  {
1763
1841
  type: "button",
@@ -1768,8 +1846,8 @@ function DockLayoutMenu({
1768
1846
  panelControl.toggle(panel.id);
1769
1847
  },
1770
1848
  children: [
1771
- /* @__PURE__ */ jsx8("span", { className: "fx-dl-check", "aria-hidden": "true", children: isOpen ? "\u2713" : "\uFF0B" }),
1772
- panel.icon ? /* @__PURE__ */ jsx8("span", { className: "fx-dl-icon", "aria-hidden": "true", children: panel.icon }) : null,
1849
+ /* @__PURE__ */ jsx10("span", { className: "fx-dl-check", "aria-hidden": "true", children: isOpen ? "\u2713" : "\uFF0B" }),
1850
+ panel.icon ? /* @__PURE__ */ jsx10("span", { className: "fx-dl-icon", "aria-hidden": "true", children: panel.icon }) : null,
1773
1851
  panel.title
1774
1852
  ]
1775
1853
  },
@@ -1795,6 +1873,9 @@ export {
1795
1873
  DetachedSurfaceFrame,
1796
1874
  DetachedSurfaceStatus,
1797
1875
  DockLayoutMenu,
1876
+ DockTabAction,
1877
+ DockTabFrame,
1878
+ DockTabStatusSummary,
1798
1879
  FloatingMenu,
1799
1880
  PanelEmptyState,
1800
1881
  PanelSurface,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/app-shell",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
4
  "description": "Generic Dock, Panel, Window, and Slot composition primitives",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",