@viasat/beam-react 2.10.1 → 2.11.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.
Files changed (43) hide show
  1. package/chunks/{FloatingUI.context.2kPXcTvi.js → FloatingUI.context.DtJA57si.js} +123 -109
  2. package/chunks/FloatingUI.context.Du9g2lSg.js +1 -0
  3. package/lib/Dialog/Dialog.Header.cjs.js +1 -1
  4. package/lib/Dialog/Dialog.Header.es.js +1 -1
  5. package/lib/Dialog/Dialog.Trigger.cjs.js +1 -1
  6. package/lib/Dialog/Dialog.Trigger.es.js +1 -1
  7. package/lib/Dialog/Dialog.d.ts +1 -1
  8. package/lib/FloatingUI/FloatingUI.content.cjs.js +1 -1
  9. package/lib/FloatingUI/FloatingUI.content.es.js +1 -2
  10. package/lib/FloatingUI/FloatingUI.context.cjs.js +1 -1
  11. package/lib/FloatingUI/FloatingUI.context.d.ts +7 -2
  12. package/lib/FloatingUI/FloatingUI.context.es.js +1 -1
  13. package/lib/FloatingUI/FloatingUI.root.cjs.js +1 -1
  14. package/lib/FloatingUI/FloatingUI.root.es.js +1 -1
  15. package/lib/FloatingUI/FloatingUI.trigger.cjs.js +1 -1
  16. package/lib/FloatingUI/FloatingUI.trigger.close.cjs.js +1 -1
  17. package/lib/FloatingUI/FloatingUI.trigger.close.es.js +1 -1
  18. package/lib/FloatingUI/FloatingUI.trigger.es.js +1 -1
  19. package/lib/Menu/ActionListContextWrapper.cjs.js +1 -1
  20. package/lib/Menu/ActionListContextWrapper.es.js +1 -1
  21. package/lib/Menu/Menu.cjs.js +1 -1
  22. package/lib/Menu/Menu.d.ts +1 -1
  23. package/lib/Menu/Menu.es.js +42 -40
  24. package/lib/Popover/Popover.content.cjs.js +1 -1
  25. package/lib/Popover/Popover.content.es.js +1 -1
  26. package/lib/Popover/Popover.d.ts +6 -1
  27. package/lib/Popover/Popover.trigger.cjs.js +1 -1
  28. package/lib/Popover/Popover.trigger.es.js +1 -1
  29. package/lib/Tooltip/Tooltip.cjs.js +1 -1
  30. package/lib/Tooltip/Tooltip.es.js +1 -1
  31. package/lib/wip/Panel/Panel.Header.Row.cjs.js +1 -1
  32. package/lib/wip/Panel/Panel.Header.Row.es.js +17 -17
  33. package/lib/wip/Panel/Panel.cjs.js +1 -1
  34. package/lib/wip/Panel/Panel.context.d.ts +6 -5
  35. package/lib/wip/Panel/Panel.d.ts +1 -1
  36. package/lib/wip/Panel/Panel.es.js +69 -68
  37. package/lib/wip/Panel/Panel.helpers.cjs.js +1 -1
  38. package/lib/wip/Panel/Panel.helpers.d.ts +6 -1
  39. package/lib/wip/Panel/Panel.helpers.es.js +49 -27
  40. package/lib/wip/Panel/Panel.types.d.ts +34 -0
  41. package/lib/wip/Panel/index.d.ts +1 -1
  42. package/package.json +6 -6
  43. package/chunks/FloatingUI.context.BULqADss.js +0 -1
@@ -1,40 +1,62 @@
1
- import { useState as o, useEffect as u } from "react";
2
- const c = 400, m = (e) => e || "end", f = (e, t) => {
3
- const n = e && t !== "full";
1
+ import { useState as c, useEffect as m, useCallback as f } from "react";
2
+ const a = 400, I = (s) => s || "end", A = (s, t) => {
3
+ const r = s && t !== "full";
4
4
  return {
5
- showDivider: n,
6
- dividerBefore: n && t !== "start" && t !== "bottom",
7
- dividerAfter: n && t === "start"
5
+ showDivider: r,
6
+ dividerBefore: r && t !== "start" && t !== "bottom",
7
+ dividerAfter: r && t === "start"
8
8
  };
9
- }, I = (e, t) => {
10
- const [n, i] = o(void 0), [a, s] = o(e !== !1);
11
- return u(() => {
9
+ }, v = (s) => s === "escape-key" ? "escapeKey" : s === "outside-press" ? "outsidePress" : "programmatic", P = (s, t) => {
10
+ const r = f(
11
+ (u) => {
12
+ if (!s) {
13
+ t == null || t(!1);
14
+ return;
15
+ }
16
+ const e = s(u);
17
+ e instanceof Promise ? e.then((i) => {
18
+ i && (t == null || t(!1));
19
+ }).catch(() => {
20
+ }) : e && (t == null || t(!1));
21
+ },
22
+ [s, t]
23
+ ), l = f(
24
+ (u, e, i) => {
25
+ u ? t == null || t(!0) : r(v(i));
26
+ },
27
+ [t, r]
28
+ );
29
+ return { requestClose: r, handleOverlayOpenChange: l };
30
+ }, S = (s, t) => {
31
+ const [r, l] = c(void 0), [u, e] = c(s !== !1);
32
+ return m(() => {
12
33
  if (!t) {
13
- s(e !== !1), i(void 0);
34
+ e(s !== !1), l(void 0);
14
35
  return;
15
36
  }
16
- if (e !== void 0)
17
- if (e) {
18
- s(!0), i("close");
19
- let r;
20
- const l = requestAnimationFrame(() => {
21
- r = requestAnimationFrame(() => i("open"));
37
+ if (s !== void 0)
38
+ if (s) {
39
+ e(!0), l("close");
40
+ let i;
41
+ const d = requestAnimationFrame(() => {
42
+ i = requestAnimationFrame(() => l("open"));
22
43
  });
23
44
  return () => {
24
- cancelAnimationFrame(l), cancelAnimationFrame(r);
45
+ cancelAnimationFrame(d), cancelAnimationFrame(i);
25
46
  };
26
47
  } else {
27
- i("close");
28
- const r = setTimeout(() => {
29
- s(!1), i(void 0);
30
- }, c);
31
- return () => clearTimeout(r);
48
+ l("close");
49
+ const i = setTimeout(() => {
50
+ e(!1), l(void 0);
51
+ }, a);
52
+ return () => clearTimeout(i);
32
53
  }
33
- }, [t, e]), { inlineStatus: n, isInlineVisible: a };
54
+ }, [t, s]), { inlineStatus: r, isInlineVisible: u };
34
55
  };
35
56
  export {
36
- c as PANEL_TRANSITION_DURATION_MS,
37
- f as getPanelDividerState,
38
- m as getResolvedPanelPosition,
39
- I as useInlineTransition
57
+ a as PANEL_TRANSITION_DURATION_MS,
58
+ A as getPanelDividerState,
59
+ I as getResolvedPanelPosition,
60
+ S as useInlineTransition,
61
+ P as usePanelClose
40
62
  };
@@ -4,6 +4,15 @@ export type PanelPosition = 'start' | 'end' | 'bottom' | 'full';
4
4
  export type PanelModalType = 'nonModal' | 'isModal' | 'alert';
5
5
  export type PanelSize = 'sm' | 'md' | 'lg' | 'full' | 'custom';
6
6
  export type PanelPadding = 'sm' | 'md';
7
+ /**
8
+ * The reason a Panel close was requested via user interaction.
9
+ *
10
+ * - `'escapeKey'` — user pressed Escape (overlay panels only)
11
+ * - `'outsidePress'` — user clicked outside the panel (overlay panels only)
12
+ * - `'closeButton'` — user clicked the header close button
13
+ * - `'programmatic'` — close was triggered by another interaction not covered above
14
+ */
15
+ export type PanelCloseReason = 'escapeKey' | 'outsidePress' | 'closeButton' | 'programmatic';
7
16
  interface BasePanelProps extends ComponentPropsWithoutRef<'aside'> {
8
17
  /**
9
18
  * Specify the content of the Panel
@@ -54,6 +63,31 @@ interface BasePanelProps extends ComponentPropsWithoutRef<'aside'> {
54
63
  * @default 'end'
55
64
  */
56
65
  position?: PanelPosition;
66
+ /**
67
+ * Called before the Panel closes due to a user interaction. Return `false` (or
68
+ * `Promise<false>`) to cancel the close — for example, when the panel contains
69
+ * a form with unsaved changes.
70
+ *
71
+ * This callback is **not** invoked when the `open` prop is changed programmatically
72
+ * by the parent; it only fires for UI-triggered close events (close button, Escape
73
+ * key, or outside press).
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * // Use a stateful confirmation dialog — avoid window.confirm (blocking, breaks iframes).
78
+ * // See the `onBeforeClose (Unsaved Changes Guard)` story for a full reference implementation.
79
+ * <Panel
80
+ * onBeforeClose={(reason) => {
81
+ * if (!isDirty) return true;
82
+ * return new Promise(resolve => {
83
+ * setResolveClose(() => resolve);
84
+ * setShowConfirmDialog(true);
85
+ * });
86
+ * }}
87
+ * />
88
+ * ```
89
+ */
90
+ onBeforeClose?: (reason: PanelCloseReason) => boolean | Promise<boolean>;
57
91
  }
58
92
  export interface InlinePanelProps extends BasePanelProps {
59
93
  /**
@@ -1,5 +1,5 @@
1
1
  export { Panel } from './Panel';
2
- export type { PanelProps, InlinePanelProps, OverlayPanelProps, PanelKind, PanelPosition, PanelModalType, PanelSize, PanelPadding, } from './Panel.types';
2
+ export type { PanelProps, InlinePanelProps, OverlayPanelProps, PanelKind, PanelPosition, PanelModalType, PanelSize, PanelPadding, PanelCloseReason, } from './Panel.types';
3
3
  export type { PanelHeaderProps } from './Panel.Header';
4
4
  export type { PanelHeaderRowProps } from './Panel.Header.Row';
5
5
  export type { PanelHeaderContentBeforeProps } from './Panel.Header.ContentBefore';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viasat/beam-react",
3
- "version": "2.10.1",
3
+ "version": "2.11.0",
4
4
  "description": "React component library for the Beam design system",
5
5
  "license": "MIT",
6
6
  "author": "Viasat",
@@ -59,11 +59,11 @@
59
59
  "access": "public"
60
60
  },
61
61
  "dependencies": {
62
- "@viasat/beam-fonts": "2.10.1",
63
- "@viasat/beam-shared": "2.10.1",
64
- "@viasat/beam-styles": "2.10.1",
65
- "@viasat/beam-tokens": "2.10.1",
66
- "@viasat/beam-icons": "2.10.1",
62
+ "@viasat/beam-fonts": "2.11.0",
63
+ "@viasat/beam-shared": "2.11.0",
64
+ "@viasat/beam-styles": "2.11.0",
65
+ "@viasat/beam-tokens": "2.11.0",
66
+ "@viasat/beam-icons": "2.11.0",
67
67
  "clsx": "^1.2.1",
68
68
  "@floating-ui/react": "^0.26.18",
69
69
  "@stepperize/react": "^5.1.5",
@@ -1 +0,0 @@
1
- "use strict";const h=require("react"),$=require("@floating-ui/dom"),H=require("@floating-ui/react"),K=require("../lib/FloatingUI/FloatingUI.interactions.cjs.js"),N=Math.min,Q=Math.max,V={left:"right",right:"left",bottom:"top",top:"bottom"};function Z(t,e,i){return Q(t,N(e,i))}function w(t,e){return typeof t=="function"?t(e):t}function T(t){return t.split("-")[0]}function tt(t){return t.split("-")[1]}function k(t){return t==="x"?"y":"x"}function et(t){return t==="y"?"height":"width"}function nt(t){return["top","bottom"].includes(T(t))?"y":"x"}function ot(t){return k(nt(t))}function st(t){return t.replace(/left|right|bottom|top/g,e=>V[e])}function it(t){return{top:0,right:0,bottom:0,left:0,...t}}function ct(t){return typeof t!="number"?it(t):{top:t,right:t,bottom:t,left:t}}const lt=t=>{var e;return{visibility:(e=t.hide)!=null&&e.referenceHidden?"hidden":"visible"}},rt=t=>({name:"arrowStyles",options:t,async fn(e){var W,Y;const{x:i,y:c,placement:r,rects:s,platform:n,elements:a,middlewareData:O}=e,{element:d,padding:g=0}=w(t,e)||{};if(d==null)return{};const P=ct(g),m={x:i,y:c},l=ot(r),S=k(l),x=et(l),f=await n.getDimensions(d),o=l==="y",B=o?"top":"left",D=o?"bottom":"right",M=o?"clientHeight":"clientWidth",j=s.reference[x]+s.reference[l]-m[l]-s.floating[x],X=m[l]-s.reference[l],A=await((W=n.getOffsetParent)==null?void 0:W.call(n,d));let p=A?A[M]:0;(!p||!await((Y=n.isElement)==null?void 0:Y.call(n,A)))&&(p=a.floating[M]||s.floating[x]);const _=j/2-X/2,F=p/2-f.width/2-1,v=N(P[B],F),U=N(P[D],F),y=v,b=p-f.width-U,u=p/2-f.width/2+_,I=Z(y,u,b),E=!O.arrow&&tt(r)!=null&&u!==I&&s.reference[x]/2-(u<y?v:U)-f.width/2<0,C=E?u<y?u-y:u-b:0,q=T(r),R=["top","left"].includes(q)?-1:1,z=f.height*R,J=ft({placement:q,arrowHeight:f.height,arrowWidth:f.width,[l]:I});return{[l]:m[l]+C,[S]:m[S]+z,data:J,reset:E}}}),L=(t,e,i,c)=>{if(c){const r=c===!0?i():i(c);t[e](r)}},ut=({baseConfig:t,middleware:e,offset:i,arrow:c,placement:r="top"})=>{const s={...t,placement:r};let n=[];if(typeof e.overrides!="object"){n.push($.offset(i));let a=e.flip??!0;e.autoPlacement&&(a=!1),L(n,"unshift",$.autoPlacement,e.autoPlacement),L(n,"push",$.shift,e.shift??!0),L(n,"unshift",$.flip,a),L(n,"push",$.hide,e.hide??!0)}else n.push(...e.overrides);return c.hide||n.push(rt(c.options)),typeof e.overrides=="function"&&(n=e.overrides(n)),s.middleware=n,s},ft=({placement:t,arrowHeight:e,arrowWidth:i,x:c,y:r})=>{const s=T(t),n=i/2-e,a={top:"rotate(0deg)",bottom:"rotate(180deg)",left:`rotate(-90deg) translateX(${-n}px)`,right:`rotate(90deg) translateX(${n}px)`}[s],O=-i/2-e,d={top:`${-e}px`,bottom:`${-e*2}px`,left:`${O}px`,right:`${O}px`}[s],g={transform:a};g.left=c!=null?`${c}px`:"",g.top=r!=null?`${r}px`:"";const P=st(s);return g[P]=d,g},at=({defaultOpen:t=!1,open:e,placement:i="top",offset:c,onOpenChange:r,openOnClick:s,openOnHover:n,openOnFocus:a,openOnSelected:O,focusConfiguration:d,listNavigation:g,typeahead:P,middleware:m,autoPlacement:l,flip:S=!0,shift:x=!0,autoHiding:f,arrow:o,transitionConfig:B,portalled:D,role:M,rootContext:j})=>{const[X,A]=h.useState(t),[p,_]=h.useState(),[F,v]=h.useState(),[U,y]=h.useState(null),b=e??X,u=r??A,I=H.useFloatingNodeId(),E=h.useMemo(()=>{const z={open:b,onOpenChange:u,whileElementsMounted:H.autoUpdate,nodeId:I,rootContext:j};return{...ut({baseConfig:z,middleware:{overrides:m,autoPlacement:l,flip:S,shift:x,hide:f},arrow:{hide:(o==null?void 0:o.hide)??!1,options:{element:U||null,padding:o==null?void 0:o.edgePadding}},placement:i,offset:c??0})}},[I,b,u,m,l,S,x,f,o==null?void 0:o.hide,o==null?void 0:o.edgePadding,U,i,c,j]),C=H.useFloating(E),q=C.context,R=K.useConfigurableInteractions({context:q,openOnClick:s,openOnHover:n,openOnFocus:a,openOnSelected:O,role:M,listNavigation:g,typeahead:P});return h.useMemo(()=>({open:b,setOpen:u,...R,...C,portalled:D,focusConfiguration:d,transitionConfig:B,labelId:p,descriptionId:F,arrow:o,setLabelId:_,setDescriptionId:v,setArrowEl:y,nodeId:I}),[b,u,R,C,D,d,B,p,F,o,I])},G=h.createContext(null),dt=()=>{const t=h.useContext(G);if(t==null)throw new Error("FloatingUI components must be wrapped in <FloatingUI />");return t};exports.BmFloatingUIContext=G;exports.useBmFloatingUI=at;exports.useBmFloatingUIContext=dt;exports.visibilityHandler=lt;