@khanacademy/wonder-blocks-floating 0.0.0-PR2846-20251118194448 → 0.0.0-PR2846-20251119173805
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/CHANGELOG.md +1 -1
- package/dist/components/floating.d.ts +16 -12
- package/dist/es/index.js +2 -4
- package/dist/index.js +1 -3
- package/package.json +3 -3
- package/dist/components/focus-manager.d.ts +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -87,32 +87,36 @@ type FloatingProps = {
|
|
|
87
87
|
};
|
|
88
88
|
type FocusManagerProps = {
|
|
89
89
|
/**
|
|
90
|
-
* Whether to enable the FocusManager component to manage the focus of
|
|
91
|
-
* floating element.
|
|
90
|
+
* Whether to enable the FocusManager component to manage the focus of
|
|
91
|
+
* the floating element.
|
|
92
92
|
*
|
|
93
|
-
* When enabled, the focus will continue flowing from the reference
|
|
94
|
-
* to the floating element and back to the reference element
|
|
95
|
-
* floating element is closed.
|
|
93
|
+
* When enabled, the focus will continue flowing from the reference
|
|
94
|
+
* element to the floating element and back to the reference element
|
|
95
|
+
* when the floating element is closed.
|
|
96
96
|
*
|
|
97
|
-
* This should be enabled in most cases, but it can be disabled if you
|
|
98
|
-
* to handle the focus manually or use it in a non-interactive
|
|
99
|
-
* tooltips).
|
|
97
|
+
* This should be enabled in most cases, but it can be disabled if you
|
|
98
|
+
* want to handle the focus manually or use it in a non-interactive
|
|
99
|
+
* context (e.g. tooltips).
|
|
100
|
+
*
|
|
101
|
+
* NOTE: FloatingUI might not preserve tab order with FloatingPortal.
|
|
102
|
+
* @see https://github.com/floating-ui/floating-ui/issues/2988
|
|
100
103
|
*
|
|
101
104
|
* @default true
|
|
102
105
|
*/
|
|
103
106
|
focusManagerEnabled?: true;
|
|
104
107
|
/**
|
|
105
|
-
* The element that will receive focus when the floating element is
|
|
108
|
+
* The element that will receive focus when the floating element is
|
|
109
|
+
* opened.
|
|
106
110
|
*
|
|
107
111
|
* This is useful when you want to set the initial focus to an element
|
|
108
112
|
* inside the floating element when it is opened.
|
|
109
113
|
*
|
|
110
|
-
* If not provided, the first focusable element inside the floating
|
|
111
|
-
* will receive focus when it is opened.
|
|
114
|
+
* If not provided, the first focusable element inside the floating
|
|
115
|
+
* element will receive focus when it is opened.
|
|
112
116
|
*/
|
|
113
117
|
initialFocusRef?: React.RefObject<HTMLElement>;
|
|
114
118
|
} | {
|
|
115
|
-
focusManagerEnabled: false
|
|
119
|
+
focusManagerEnabled: false;
|
|
116
120
|
initialFocusRef?: never;
|
|
117
121
|
};
|
|
118
122
|
type Props = FloatingProps & FocusManagerProps;
|
package/dist/es/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
|
-
import { FloatingArrow, FloatingPortal,
|
|
4
|
+
import { FloatingArrow, FloatingPortal, useFloating, autoUpdate, offset, flip, shift, arrow, hide, useDismiss, useInteractions, FloatingFocusManager } from '@floating-ui/react';
|
|
5
5
|
import { StyleSheet, css } from 'aphrodite';
|
|
6
6
|
import { semanticColor, border, boxShadow } from '@khanacademy/wonder-blocks-tokens';
|
|
7
7
|
|
|
@@ -15,8 +15,6 @@ function maybeGetNextAncestorModalLauncherPortal(element){let candidateElement=e
|
|
|
15
15
|
|
|
16
16
|
function Portal({portal,children,reference}){if(portal){const modalHost=maybeGetPortalMountedModalHostElement(reference)||document.body;return jsx(FloatingPortal,{root:modalHost,children:children})}return children}
|
|
17
17
|
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
const StyledDiv=addStyle("div");const SHIFT_PADDING=12;function Floating({content,children,placement="top",open=false,onOpenChange,portal=true,strategy="absolute",testId,focusManagerEnabled=true,initialFocusRef,dismissEnabled=false,hide:hideProp=true,offset:offsetProp=20,flip:flipProp=true,shift:shiftProp=true,showArrow=true}){const arrowRef=React.useRef(null);const prevOpenRef=React.useRef(open??false);const{elements,refs,floatingStyles,context,middlewareData}=useFloating({open,onOpenChange,placement,strategy,whileElementsMounted:autoUpdate,middleware:[offset({mainAxis:offsetProp}),flipProp?flip():undefined,shiftProp?shift({padding:SHIFT_PADDING,crossAxis:true}):undefined,showArrow?arrow({element:arrowRef}):undefined,hideProp?hide():undefined]});const dismiss=useDismiss(context,{enabled:dismissEnabled});const{getReferenceProps,getFloatingProps}=useInteractions([dismiss]);React.useEffect(()=>{if(prevOpenRef.current!==open){onOpenChange?.(open);prevOpenRef.current=open;}},[onOpenChange,open]);const trigger=React.useMemo(()=>{return React.cloneElement(children,{ref:refs.setReference,...getReferenceProps()})},[children,refs.setReference,getReferenceProps]);return jsxs(Fragment,{children:[trigger,open&&elements.reference&&jsx(Portal,{portal:portal,reference:elements.reference,children:jsx(FocusManager,{focusManagerEnabled:focusManagerEnabled,context:context,dismissEnabled:dismissEnabled,initialFocusRef:initialFocusRef,children:jsxs(StyledDiv,{"data-testid":testId,"data-placement":placement,ref:refs.setFloating,style:[styles.floating,floatingStyles,{visibility:middlewareData.hide?.referenceHidden?"hidden":"visible"}],...getFloatingProps(),children:[content,showArrow&&jsx(Arrow,{ref:arrowRef,context:context})]})})})]})}const styles=StyleSheet.create({floating:{background:semanticColor.core.background.base.default,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,borderRadius:border.radius.radius_040,maxInlineSize:472,minBlockSize:ARROW_SIZE_INLINE,boxShadow:boxShadow.mid,justifyContent:"center",outline:"none"}});
|
|
18
|
+
const StyledDiv=addStyle("div");const SHIFT_PADDING=12;function Floating({content,children,placement="top",open=false,onOpenChange,portal=true,strategy="absolute",testId,focusManagerEnabled=true,initialFocusRef,dismissEnabled=false,hide:hideProp=true,offset:offsetProp=20,flip:flipProp=true,shift:shiftProp=true,showArrow=true}){const arrowRef=React.useRef(null);const prevOpenRef=React.useRef(open??false);const{elements,refs,floatingStyles,context,middlewareData}=useFloating({open,onOpenChange,placement,strategy,whileElementsMounted:autoUpdate,middleware:[offset({mainAxis:offsetProp}),flipProp?flip():undefined,shiftProp?shift({padding:SHIFT_PADDING,crossAxis:true}):undefined,showArrow?arrow({element:arrowRef}):undefined,hideProp?hide():undefined]});const dismiss=useDismiss(context,{enabled:dismissEnabled});const{getReferenceProps,getFloatingProps}=useInteractions([dismiss]);React.useEffect(()=>{if(prevOpenRef.current!==open){onOpenChange?.(open);prevOpenRef.current=open;}},[onOpenChange,open]);const trigger=React.useMemo(()=>{return React.cloneElement(children,{ref:refs.setReference,...getReferenceProps()})},[children,refs.setReference,getReferenceProps]);return jsxs(Fragment,{children:[trigger,open&&elements.reference&&jsx(Portal,{portal:portal,reference:elements.reference,children:jsx(FloatingFocusManager,{disabled:!focusManagerEnabled,context:context,modal:false,initialFocus:initialFocusRef,closeOnFocusOut:false,visuallyHiddenDismiss:dismissEnabled,children:jsxs(StyledDiv,{"data-testid":testId,"data-placement":placement,ref:refs.setFloating,style:[styles.floating,floatingStyles,{visibility:middlewareData.hide?.referenceHidden?"hidden":"visible"}],...getFloatingProps(),children:[content,showArrow&&jsx(Arrow,{ref:arrowRef,context:context})]})})})]})}const styles=StyleSheet.create({floating:{background:semanticColor.core.background.base.default,border:`solid ${border.width.thin} ${semanticColor.core.border.neutral.subtle}`,borderRadius:border.radius.radius_040,maxInlineSize:472,minBlockSize:ARROW_SIZE_INLINE,boxShadow:boxShadow.mid,justifyContent:"center",outline:"none"}});
|
|
21
19
|
|
|
22
20
|
export { Floating };
|
package/dist/index.js
CHANGED
|
@@ -38,8 +38,6 @@ function maybeGetNextAncestorModalLauncherPortal(element){let candidateElement=e
|
|
|
38
38
|
|
|
39
39
|
function Portal({portal,children,reference}){if(portal){const modalHost=maybeGetPortalMountedModalHostElement(reference)||document.body;return jsxRuntime.jsx(react.FloatingPortal,{root:modalHost,children:children})}return children}
|
|
40
40
|
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
const StyledDiv=addStyle("div");const SHIFT_PADDING=12;function Floating({content,children,placement="top",open=false,onOpenChange,portal=true,strategy="absolute",testId,focusManagerEnabled=true,initialFocusRef,dismissEnabled=false,hide:hideProp=true,offset:offsetProp=20,flip:flipProp=true,shift:shiftProp=true,showArrow=true}){const arrowRef=React__namespace.useRef(null);const prevOpenRef=React__namespace.useRef(open??false);const{elements,refs,floatingStyles,context,middlewareData}=react.useFloating({open,onOpenChange,placement,strategy,whileElementsMounted:react.autoUpdate,middleware:[react.offset({mainAxis:offsetProp}),flipProp?react.flip():undefined,shiftProp?react.shift({padding:SHIFT_PADDING,crossAxis:true}):undefined,showArrow?react.arrow({element:arrowRef}):undefined,hideProp?react.hide():undefined]});const dismiss=react.useDismiss(context,{enabled:dismissEnabled});const{getReferenceProps,getFloatingProps}=react.useInteractions([dismiss]);React__namespace.useEffect(()=>{if(prevOpenRef.current!==open){onOpenChange?.(open);prevOpenRef.current=open;}},[onOpenChange,open]);const trigger=React__namespace.useMemo(()=>{return React__namespace.cloneElement(children,{ref:refs.setReference,...getReferenceProps()})},[children,refs.setReference,getReferenceProps]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[trigger,open&&elements.reference&&jsxRuntime.jsx(Portal,{portal:portal,reference:elements.reference,children:jsxRuntime.jsx(FocusManager,{focusManagerEnabled:focusManagerEnabled,context:context,dismissEnabled:dismissEnabled,initialFocusRef:initialFocusRef,children:jsxRuntime.jsxs(StyledDiv,{"data-testid":testId,"data-placement":placement,ref:refs.setFloating,style:[styles.floating,floatingStyles,{visibility:middlewareData.hide?.referenceHidden?"hidden":"visible"}],...getFloatingProps(),children:[content,showArrow&&jsxRuntime.jsx(Arrow,{ref:arrowRef,context:context})]})})})]})}const styles=aphrodite.StyleSheet.create({floating:{background:wonderBlocksTokens.semanticColor.core.background.base.default,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderRadius:wonderBlocksTokens.border.radius.radius_040,maxInlineSize:472,minBlockSize:ARROW_SIZE_INLINE,boxShadow:wonderBlocksTokens.boxShadow.mid,justifyContent:"center",outline:"none"}});
|
|
41
|
+
const StyledDiv=addStyle("div");const SHIFT_PADDING=12;function Floating({content,children,placement="top",open=false,onOpenChange,portal=true,strategy="absolute",testId,focusManagerEnabled=true,initialFocusRef,dismissEnabled=false,hide:hideProp=true,offset:offsetProp=20,flip:flipProp=true,shift:shiftProp=true,showArrow=true}){const arrowRef=React__namespace.useRef(null);const prevOpenRef=React__namespace.useRef(open??false);const{elements,refs,floatingStyles,context,middlewareData}=react.useFloating({open,onOpenChange,placement,strategy,whileElementsMounted:react.autoUpdate,middleware:[react.offset({mainAxis:offsetProp}),flipProp?react.flip():undefined,shiftProp?react.shift({padding:SHIFT_PADDING,crossAxis:true}):undefined,showArrow?react.arrow({element:arrowRef}):undefined,hideProp?react.hide():undefined]});const dismiss=react.useDismiss(context,{enabled:dismissEnabled});const{getReferenceProps,getFloatingProps}=react.useInteractions([dismiss]);React__namespace.useEffect(()=>{if(prevOpenRef.current!==open){onOpenChange?.(open);prevOpenRef.current=open;}},[onOpenChange,open]);const trigger=React__namespace.useMemo(()=>{return React__namespace.cloneElement(children,{ref:refs.setReference,...getReferenceProps()})},[children,refs.setReference,getReferenceProps]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[trigger,open&&elements.reference&&jsxRuntime.jsx(Portal,{portal:portal,reference:elements.reference,children:jsxRuntime.jsx(react.FloatingFocusManager,{disabled:!focusManagerEnabled,context:context,modal:false,initialFocus:initialFocusRef,closeOnFocusOut:false,visuallyHiddenDismiss:dismissEnabled,children:jsxRuntime.jsxs(StyledDiv,{"data-testid":testId,"data-placement":placement,ref:refs.setFloating,style:[styles.floating,floatingStyles,{visibility:middlewareData.hide?.referenceHidden?"hidden":"visible"}],...getFloatingProps(),children:[content,showArrow&&jsxRuntime.jsx(Arrow,{ref:arrowRef,context:context})]})})})]})}const styles=aphrodite.StyleSheet.create({floating:{background:wonderBlocksTokens.semanticColor.core.background.base.default,border:`solid ${wonderBlocksTokens.border.width.thin} ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderRadius:wonderBlocksTokens.border.radius.radius_040,maxInlineSize:472,minBlockSize:ARROW_SIZE_INLINE,boxShadow:wonderBlocksTokens.boxShadow.mid,justifyContent:"center",outline:"none"}});
|
|
44
42
|
|
|
45
43
|
exports.Floating = Floating;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A package that provides support for floating UI components in our UIs, including portal and focus management support.",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.0.0-PR2846-
|
|
6
|
+
"version": "0.0.0-PR2846-20251119173805",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"react": "18.2.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@khanacademy/
|
|
31
|
-
"@khanacademy/
|
|
30
|
+
"@khanacademy/wonder-blocks-modal": "8.5.5",
|
|
31
|
+
"@khanacademy/wb-dev-build-settings": "3.2.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { FloatingRootContext } from "@floating-ui/react";
|
|
3
|
-
/**
|
|
4
|
-
* Renders the floating element with the focus manager if enabled.
|
|
5
|
-
*/
|
|
6
|
-
export declare function FocusManager({ context, dismissEnabled, focusManagerEnabled, initialFocusRef, children, }: {
|
|
7
|
-
context: FloatingRootContext;
|
|
8
|
-
dismissEnabled: boolean;
|
|
9
|
-
focusManagerEnabled: boolean;
|
|
10
|
-
initialFocusRef: React.RefObject<HTMLElement> | undefined;
|
|
11
|
-
children: React.JSX.Element;
|
|
12
|
-
}): React.JSX.Element;
|