@khanacademy/wonder-blocks-popover 7.0.1 → 7.0.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-popover
|
|
2
2
|
|
|
3
|
+
## 7.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 248e2f5: Make popover content scroll when it doesn't fit in the available space (e.g. on small screens or at up to 400% zoom). The content fades out at the edges to indicate there's more content, and the scrollable area becomes keyboard focusable while it overflows. It is named after the popover (its title or `aria-label`), so screen readers announce it when it receives focus.
|
|
8
|
+
- Updated dependencies [7d414bb]
|
|
9
|
+
- Updated dependencies [248e2f5]
|
|
10
|
+
- Updated dependencies [8b93331]
|
|
11
|
+
- @khanacademy/wonder-blocks-floating@0.2.0
|
|
12
|
+
- @khanacademy/wonder-blocks-layout@3.2.0
|
|
13
|
+
|
|
3
14
|
## 7.0.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -16,6 +16,17 @@ import type { StyleType } from "@khanacademy/wonder-blocks-core";
|
|
|
16
16
|
* no bubble around it and you need to supply your own container styling. Inside
|
|
17
17
|
* a `Popover` it looks like a popover with no extra work.
|
|
18
18
|
*
|
|
19
|
+
* ### Overflow
|
|
20
|
+
*
|
|
21
|
+
* Inside a `Popover`, the content is constrained to the space available in the
|
|
22
|
+
* viewport (or document). When it doesn't fit (e.g. on small screens or at
|
|
23
|
+
* high zoom levels), the content (including the close button) scrolls, and
|
|
24
|
+
* it fades out at the edges to hint that there's more content to scroll to.
|
|
25
|
+
* The scrollable area becomes keyboard focusable while it overflows, so
|
|
26
|
+
* keyboard users can scroll it too. It's named after the popover (via its
|
|
27
|
+
* title or `aria-label`), so screen readers announce it when it's focused.
|
|
28
|
+
* Pass an `aria-label` to `PopoverContentCore` to use a different name.
|
|
29
|
+
*
|
|
19
30
|
* ### Usage
|
|
20
31
|
*
|
|
21
32
|
* ```jsx
|
|
@@ -13,6 +13,14 @@ export type PopoverContextType = {
|
|
|
13
13
|
* element changes its placement.
|
|
14
14
|
*/
|
|
15
15
|
placement?: Placement;
|
|
16
|
+
/**
|
|
17
|
+
* The accessible name of the popover dialog (either an `aria-label`, or
|
|
18
|
+
* the id of the element that labels it). This is used to name the
|
|
19
|
+
* scrollable area of the popover content, so screen readers can announce
|
|
20
|
+
* it when it receives focus.
|
|
21
|
+
*/
|
|
22
|
+
"aria-label"?: string;
|
|
23
|
+
"aria-labelledby"?: string;
|
|
16
24
|
};
|
|
17
25
|
/**
|
|
18
26
|
* This context is being used for two reasons:
|
|
@@ -23,6 +31,9 @@ export type PopoverContextType = {
|
|
|
23
31
|
*
|
|
24
32
|
* 2. Keeps a reference of the TooltipPopper's `placement` value. It can be one
|
|
25
33
|
* of the following values: "top", "bottom", "left" or "right".
|
|
34
|
+
*
|
|
35
|
+
* 3. Passes down the accessible name of the popover dialog, so
|
|
36
|
+
* `PopoverContentCore` can name its scrollable area.
|
|
26
37
|
*/
|
|
27
38
|
declare const PopoverContext: React.Context<PopoverContextType>;
|
|
28
39
|
export default PopoverContext;
|
package/dist/es/index.js
CHANGED
|
@@ -3,8 +3,9 @@ import * as React from 'react';
|
|
|
3
3
|
import { useMergeRefs, getElementRef, FloatingReferenceAttributeName, canAcceptRef, Floating } from '@khanacademy/wonder-blocks-floating';
|
|
4
4
|
import { View, addStyle } from '@khanacademy/wonder-blocks-core';
|
|
5
5
|
import { StyleSheet } from 'aphrodite';
|
|
6
|
-
import { sizing } from '@khanacademy/wonder-blocks-tokens';
|
|
6
|
+
import { border, sizing } from '@khanacademy/wonder-blocks-tokens';
|
|
7
7
|
import { Heading, BodyText } from '@khanacademy/wonder-blocks-typography';
|
|
8
|
+
import { ScrollableView } from '@khanacademy/wonder-blocks-layout';
|
|
8
9
|
import { actionStyles } from '@khanacademy/wonder-blocks-styles';
|
|
9
10
|
import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
10
11
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
@@ -15,11 +16,11 @@ const PopoverAnchor=React.forwardRef(function PopoverAnchor(props,ref){const{chi
|
|
|
15
16
|
|
|
16
17
|
const PopoverDialog=React.forwardRef(function PopoverDialog(props,ref){const{children,id,placement,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,"aria-label":ariaLabel}=props;return jsx(View,{"aria-label":ariaLabel,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,id:id,role:"dialog",ref:ref,"data-placement":placement,children:children})});PopoverDialog.displayName="PopoverDialog";
|
|
17
18
|
|
|
18
|
-
function Popover(props){const{children,content,placement:placementProp="top",dismissEnabled,id,closedFocusId,initialFocusId,opened:openedProp,onClose,showTail=true,portal=true,rootBoundary="viewport",viewportPadding,testId,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy}=props;const isControlled=typeof openedProp==="boolean";const[internalOpened,setInternalOpened]=React.useState(!!openedProp);const opened=isControlled?openedProp:internalOpened;const[placement,setPlacement]=React.useState(placementProp);const initialFocusRef=React.useRef(null);const returnFocusRef=React.useRef(null);const closeFiredRef=React.useRef(false);const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;React.useEffect(()=>{if(opened&&closedFocusId){returnFocusRef.current=document.getElementById(closedFocusId);}},[opened,closedFocusId]);const handleOpenChange=React.useCallback(nextOpened=>{if(!isControlled){setInternalOpened(nextOpened);}if(nextOpened){closeFiredRef.current=false;}else if(!closeFiredRef.current){closeFiredRef.current=true;onClose?.();}},[isControlled,onClose]);const handleClose=React.useCallback(()=>{handleOpenChange(false);},[handleOpenChange]);const handleAnchorClick=React.useCallback(()=>{if(!opened){handleOpenChange(true);}else if(dismissEnabled){handleOpenChange(false);}},[opened,dismissEnabled,handleOpenChange]);const handlePlacementChange=React.useCallback(nextPlacement=>{setPlacement(nextPlacement.split("-")[0]);},[]);const handleDialogRef=React.useCallback(node=>{if(node&&initialFocusId){initialFocusRef.current=node.querySelector(`#${initialFocusId}`);}},[initialFocusId]);const renderContent=()=>{const popoverContents=typeof content==="function"?content({close:handleClose}):content;return React.cloneElement(popoverContents,{uniqueId})};const describedBy=ariaDescribedBy||`${uniqueId}-content`;const ariaLabelledBy=ariaLabel?undefined:`${uniqueId}-title`;const dialog=jsx(PopoverDialog,{ref:handleDialogRef,id:uniqueId,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-describedby":describedBy,children:renderContent()});return jsx(PopoverContext.Provider,{value:{close:handleClose,placement:placement},children:jsx(Floating,{open:opened,strategy:"fixed",onOpenChange:handleOpenChange,placement:placementProp,onPlacementChange:handlePlacementChange,content:dialog,dismissEnabled:!!dismissEnabled,closeOnFocusOut:!!dismissEnabled,showArrow:showTail,portal:portal,rootBoundary:rootBoundary,shiftPadding:viewportPadding,initialFocusRef:initialFocusId?initialFocusRef:undefined,returnFocus:closedFocusId?returnFocusRef:true,testId:testId,children:jsx(PopoverAnchor,{id:`${uniqueId}-anchor`,"aria-controls":uniqueId,"aria-expanded":opened?"true":"false",onClick:handleAnchorClick,children:children})})})}
|
|
19
|
+
function Popover(props){const{children,content,placement:placementProp="top",dismissEnabled,id,closedFocusId,initialFocusId,opened:openedProp,onClose,showTail=true,portal=true,rootBoundary="viewport",viewportPadding,testId,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy}=props;const isControlled=typeof openedProp==="boolean";const[internalOpened,setInternalOpened]=React.useState(!!openedProp);const opened=isControlled?openedProp:internalOpened;const[placement,setPlacement]=React.useState(placementProp);const initialFocusRef=React.useRef(null);const returnFocusRef=React.useRef(null);const closeFiredRef=React.useRef(false);const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;React.useEffect(()=>{if(opened&&closedFocusId){returnFocusRef.current=document.getElementById(closedFocusId);}},[opened,closedFocusId]);const handleOpenChange=React.useCallback(nextOpened=>{if(!isControlled){setInternalOpened(nextOpened);}if(nextOpened){closeFiredRef.current=false;}else if(!closeFiredRef.current){closeFiredRef.current=true;onClose?.();}},[isControlled,onClose]);const handleClose=React.useCallback(()=>{handleOpenChange(false);},[handleOpenChange]);const handleAnchorClick=React.useCallback(()=>{if(!opened){handleOpenChange(true);}else if(dismissEnabled){handleOpenChange(false);}},[opened,dismissEnabled,handleOpenChange]);const handlePlacementChange=React.useCallback(nextPlacement=>{setPlacement(nextPlacement.split("-")[0]);},[]);const handleDialogRef=React.useCallback(node=>{if(node&&initialFocusId){initialFocusRef.current=node.querySelector(`#${initialFocusId}`);}},[initialFocusId]);const renderContent=()=>{const popoverContents=typeof content==="function"?content({close:handleClose}):content;return React.cloneElement(popoverContents,{uniqueId})};const describedBy=ariaDescribedBy||`${uniqueId}-content`;const ariaLabelledBy=ariaLabel?undefined:`${uniqueId}-title`;const dialog=jsx(PopoverDialog,{ref:handleDialogRef,id:uniqueId,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-describedby":describedBy,children:renderContent()});return jsx(PopoverContext.Provider,{value:{close:handleClose,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy},children:jsx(Floating,{open:opened,strategy:"fixed",onOpenChange:handleOpenChange,placement:placementProp,onPlacementChange:handlePlacementChange,content:dialog,constrainSize:true,dismissEnabled:!!dismissEnabled,closeOnFocusOut:!!dismissEnabled,showArrow:showTail,portal:portal,rootBoundary:rootBoundary,shiftPadding:viewportPadding,initialFocusRef:initialFocusId?initialFocusRef:undefined,returnFocus:closedFocusId?returnFocusRef:true,testId:testId,children:jsx(PopoverAnchor,{id:`${uniqueId}-anchor`,"aria-controls":uniqueId,"aria-expanded":opened?"true":"false",onClick:handleAnchorClick,children:children})})})}
|
|
19
20
|
|
|
20
21
|
const CloseButton=props=>{const{"aria-label":ariaLabel="Close Popover",style,testId}=props;const{close}=React.useContext(PopoverContext);return jsx(IconButton,{icon:xIcon,"aria-label":ariaLabel,onClick:close,kind:"tertiary",actionType:"neutral",style:style,testId:testId})};
|
|
21
22
|
|
|
22
|
-
const PopoverContentCore=React.forwardRef(function PopoverContentCore({"aria-label":ariaLabel,children,closeButtonLight=false,closeButtonLabel,closeButtonVisible=false,style,testId},ref){return jsxs(View,{testId:testId,style:[styles$1.content,style],
|
|
23
|
+
const PopoverContentCore=React.forwardRef(function PopoverContentCore({"aria-label":ariaLabel,children,closeButtonLight=false,closeButtonLabel,closeButtonVisible=false,style,testId},ref){const popoverContext=React.useContext(PopoverContext);const labelProps=ariaLabel?{"aria-label":ariaLabel}:{"aria-label":popoverContext["aria-label"],"aria-labelledby":popoverContext["aria-labelledby"]};return jsx(ScrollableView,{...labelProps,style:styles$1.scrollableView,children:jsxs(View,{testId:testId,style:[styles$1.content,style],ref:ref,children:[closeButtonVisible&&jsx(CloseButton,{"aria-label":closeButtonLabel,style:[styles$1.closeButton,closeButtonLight&&actionStyles.inverse],testId:`${testId||"popover"}-close-btn`}),children]})})});PopoverContentCore.displayName="PopoverContentCore";const styles$1=StyleSheet.create({scrollableView:{borderRadius:`calc(${border.radius.radius_040} - ${border.width.thin})`},content:{margin:0,maxInlineSize:`calc(${sizing.size_160} * 18)`,padding:sizing.size_240,overflow:"hidden",justifyContent:"center",flexShrink:0},closeButton:{margin:0,position:"absolute",insetInlineEnd:sizing.size_040,insetBlockStart:sizing.size_040,zIndex:1}});
|
|
23
24
|
|
|
24
25
|
const StyledImg=addStyle("img");const PopoverContent=React.forwardRef(function PopoverContent(props,ref){const{actions,closeButtonLabel,closeButtonVisible=false,content,icon,iconAlt,image,style,title,titleHeadingTag,testId,uniqueId}=props;const{close,placement}=React.useContext(PopoverContext);React.useEffect(()=>{if(image&&icon){throw new Error("'image' and 'icon' cannot be used at the same time. You can fix this by either removing 'image' or 'icon' from your instance.")}},[image,icon]);const validateProps=React.useCallback(({placement})=>{if(image&&(placement==="left"||placement==="right")){throw new Error("'image' can only be vertically placed. You can fix this by either changing `placement` to `top` or `bottom` or removing the `image` prop inside `content`.")}},[image]);const maybeRenderImage=context=>{if(!image){return null}return jsx(View,{style:[styles.image,context.placement==="bottom"&&styles.imageToBottom],children:image})};const maybeRenderIcon=()=>{if(!icon){return null}return jsx(View,{style:styles.iconContainer,children:typeof icon!=="string"?icon:jsx(StyledImg,{src:icon,style:styles.icon,alt:iconAlt||""})})};const maybeRenderActions=close=>{if(!actions){return null}return jsx(View,{style:styles.actions,children:typeof actions==="function"?actions({close:close}):actions})};validateProps({close,placement});return jsxs(PopoverContentCore,{closeButtonLight:!!image&&placement==="top",closeButtonLabel:closeButtonLabel,closeButtonVisible:closeButtonVisible,style:style,testId:testId,ref:ref,children:[jsxs(View,{style:!!icon&&styles.withIcon,children:[maybeRenderImage({placement}),maybeRenderIcon(),jsxs(View,{style:styles.text,children:[jsx(Heading,{size:"medium",tag:titleHeadingTag,id:`${uniqueId}-title`,style:styles.title,children:title}),jsx(BodyText,{tag:"span",id:`${uniqueId}-content`,children:content})]})]}),maybeRenderActions(close)]})});PopoverContent.displayName="PopoverContent";const styles=StyleSheet.create({actions:{marginBlockStart:sizing.size_240,flexDirection:"row",alignItems:"center",justifyContent:"flex-end"},text:{justifyContent:"center"},title:{marginBlockEnd:sizing.size_080},iconContainer:{alignItems:"center",justifyContent:"center",blockSize:sizing.size_640,inlineSize:sizing.size_640,minInlineSize:sizing.size_640,marginInlineEnd:sizing.size_160,overflow:"hidden"},icon:{width:"100%"},withIcon:{flexDirection:"row"},image:{marginBlockEnd:sizing.size_240,marginBlockStart:`calc(-1 * ${sizing.size_240})`,marginInline:`calc(-1 * ${sizing.size_240})`,inlineSize:`calc(100% + ${sizing.size_480})`},imageToBottom:{marginBlockEnd:`calc(-1 * ${sizing.size_240})`,marginBlockStart:sizing.size_240,order:1}});
|
|
25
26
|
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
|
9
9
|
var aphrodite = require('aphrodite');
|
|
10
10
|
var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
|
|
11
11
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
12
|
+
var wonderBlocksLayout = require('@khanacademy/wonder-blocks-layout');
|
|
12
13
|
var wonderBlocksStyles = require('@khanacademy/wonder-blocks-styles');
|
|
13
14
|
var xIcon = require('@phosphor-icons/core/regular/x.svg');
|
|
14
15
|
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
@@ -43,11 +44,11 @@ const PopoverAnchor=React__namespace.forwardRef(function PopoverAnchor(props,ref
|
|
|
43
44
|
|
|
44
45
|
const PopoverDialog=React__namespace.forwardRef(function PopoverDialog(props,ref){const{children,id,placement,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,"aria-label":ariaLabel}=props;return jsxRuntime.jsx(wonderBlocksCore.View,{"aria-label":ariaLabel,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,id:id,role:"dialog",ref:ref,"data-placement":placement,children:children})});PopoverDialog.displayName="PopoverDialog";
|
|
45
46
|
|
|
46
|
-
function Popover(props){const{children,content,placement:placementProp="top",dismissEnabled,id,closedFocusId,initialFocusId,opened:openedProp,onClose,showTail=true,portal=true,rootBoundary="viewport",viewportPadding,testId,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy}=props;const isControlled=typeof openedProp==="boolean";const[internalOpened,setInternalOpened]=React__namespace.useState(!!openedProp);const opened=isControlled?openedProp:internalOpened;const[placement,setPlacement]=React__namespace.useState(placementProp);const initialFocusRef=React__namespace.useRef(null);const returnFocusRef=React__namespace.useRef(null);const closeFiredRef=React__namespace.useRef(false);const generatedUniqueId=React__namespace.useId();const uniqueId=id??generatedUniqueId;React__namespace.useEffect(()=>{if(opened&&closedFocusId){returnFocusRef.current=document.getElementById(closedFocusId);}},[opened,closedFocusId]);const handleOpenChange=React__namespace.useCallback(nextOpened=>{if(!isControlled){setInternalOpened(nextOpened);}if(nextOpened){closeFiredRef.current=false;}else if(!closeFiredRef.current){closeFiredRef.current=true;onClose?.();}},[isControlled,onClose]);const handleClose=React__namespace.useCallback(()=>{handleOpenChange(false);},[handleOpenChange]);const handleAnchorClick=React__namespace.useCallback(()=>{if(!opened){handleOpenChange(true);}else if(dismissEnabled){handleOpenChange(false);}},[opened,dismissEnabled,handleOpenChange]);const handlePlacementChange=React__namespace.useCallback(nextPlacement=>{setPlacement(nextPlacement.split("-")[0]);},[]);const handleDialogRef=React__namespace.useCallback(node=>{if(node&&initialFocusId){initialFocusRef.current=node.querySelector(`#${initialFocusId}`);}},[initialFocusId]);const renderContent=()=>{const popoverContents=typeof content==="function"?content({close:handleClose}):content;return React__namespace.cloneElement(popoverContents,{uniqueId})};const describedBy=ariaDescribedBy||`${uniqueId}-content`;const ariaLabelledBy=ariaLabel?undefined:`${uniqueId}-title`;const dialog=jsxRuntime.jsx(PopoverDialog,{ref:handleDialogRef,id:uniqueId,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-describedby":describedBy,children:renderContent()});return jsxRuntime.jsx(PopoverContext.Provider,{value:{close:handleClose,placement:placement},children:jsxRuntime.jsx(wonderBlocksFloating.Floating,{open:opened,strategy:"fixed",onOpenChange:handleOpenChange,placement:placementProp,onPlacementChange:handlePlacementChange,content:dialog,dismissEnabled:!!dismissEnabled,closeOnFocusOut:!!dismissEnabled,showArrow:showTail,portal:portal,rootBoundary:rootBoundary,shiftPadding:viewportPadding,initialFocusRef:initialFocusId?initialFocusRef:undefined,returnFocus:closedFocusId?returnFocusRef:true,testId:testId,children:jsxRuntime.jsx(PopoverAnchor,{id:`${uniqueId}-anchor`,"aria-controls":uniqueId,"aria-expanded":opened?"true":"false",onClick:handleAnchorClick,children:children})})})}
|
|
47
|
+
function Popover(props){const{children,content,placement:placementProp="top",dismissEnabled,id,closedFocusId,initialFocusId,opened:openedProp,onClose,showTail=true,portal=true,rootBoundary="viewport",viewportPadding,testId,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy}=props;const isControlled=typeof openedProp==="boolean";const[internalOpened,setInternalOpened]=React__namespace.useState(!!openedProp);const opened=isControlled?openedProp:internalOpened;const[placement,setPlacement]=React__namespace.useState(placementProp);const initialFocusRef=React__namespace.useRef(null);const returnFocusRef=React__namespace.useRef(null);const closeFiredRef=React__namespace.useRef(false);const generatedUniqueId=React__namespace.useId();const uniqueId=id??generatedUniqueId;React__namespace.useEffect(()=>{if(opened&&closedFocusId){returnFocusRef.current=document.getElementById(closedFocusId);}},[opened,closedFocusId]);const handleOpenChange=React__namespace.useCallback(nextOpened=>{if(!isControlled){setInternalOpened(nextOpened);}if(nextOpened){closeFiredRef.current=false;}else if(!closeFiredRef.current){closeFiredRef.current=true;onClose?.();}},[isControlled,onClose]);const handleClose=React__namespace.useCallback(()=>{handleOpenChange(false);},[handleOpenChange]);const handleAnchorClick=React__namespace.useCallback(()=>{if(!opened){handleOpenChange(true);}else if(dismissEnabled){handleOpenChange(false);}},[opened,dismissEnabled,handleOpenChange]);const handlePlacementChange=React__namespace.useCallback(nextPlacement=>{setPlacement(nextPlacement.split("-")[0]);},[]);const handleDialogRef=React__namespace.useCallback(node=>{if(node&&initialFocusId){initialFocusRef.current=node.querySelector(`#${initialFocusId}`);}},[initialFocusId]);const renderContent=()=>{const popoverContents=typeof content==="function"?content({close:handleClose}):content;return React__namespace.cloneElement(popoverContents,{uniqueId})};const describedBy=ariaDescribedBy||`${uniqueId}-content`;const ariaLabelledBy=ariaLabel?undefined:`${uniqueId}-title`;const dialog=jsxRuntime.jsx(PopoverDialog,{ref:handleDialogRef,id:uniqueId,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy,"aria-describedby":describedBy,children:renderContent()});return jsxRuntime.jsx(PopoverContext.Provider,{value:{close:handleClose,placement:placement,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledBy},children:jsxRuntime.jsx(wonderBlocksFloating.Floating,{open:opened,strategy:"fixed",onOpenChange:handleOpenChange,placement:placementProp,onPlacementChange:handlePlacementChange,content:dialog,constrainSize:true,dismissEnabled:!!dismissEnabled,closeOnFocusOut:!!dismissEnabled,showArrow:showTail,portal:portal,rootBoundary:rootBoundary,shiftPadding:viewportPadding,initialFocusRef:initialFocusId?initialFocusRef:undefined,returnFocus:closedFocusId?returnFocusRef:true,testId:testId,children:jsxRuntime.jsx(PopoverAnchor,{id:`${uniqueId}-anchor`,"aria-controls":uniqueId,"aria-expanded":opened?"true":"false",onClick:handleAnchorClick,children:children})})})}
|
|
47
48
|
|
|
48
49
|
const CloseButton=props=>{const{"aria-label":ariaLabel="Close Popover",style,testId}=props;const{close}=React__namespace.useContext(PopoverContext);return jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],"aria-label":ariaLabel,onClick:close,kind:"tertiary",actionType:"neutral",style:style,testId:testId})};
|
|
49
50
|
|
|
50
|
-
const PopoverContentCore=React__namespace.forwardRef(function PopoverContentCore({"aria-label":ariaLabel,children,closeButtonLight=false,closeButtonLabel,closeButtonVisible=false,style,testId},ref){return jsxRuntime.jsxs(wonderBlocksCore.View,{testId:testId,style:[styles$1.content,style],
|
|
51
|
+
const PopoverContentCore=React__namespace.forwardRef(function PopoverContentCore({"aria-label":ariaLabel,children,closeButtonLight=false,closeButtonLabel,closeButtonVisible=false,style,testId},ref){const popoverContext=React__namespace.useContext(PopoverContext);const labelProps=ariaLabel?{"aria-label":ariaLabel}:{"aria-label":popoverContext["aria-label"],"aria-labelledby":popoverContext["aria-labelledby"]};return jsxRuntime.jsx(wonderBlocksLayout.ScrollableView,{...labelProps,style:styles$1.scrollableView,children:jsxRuntime.jsxs(wonderBlocksCore.View,{testId:testId,style:[styles$1.content,style],ref:ref,children:[closeButtonVisible&&jsxRuntime.jsx(CloseButton,{"aria-label":closeButtonLabel,style:[styles$1.closeButton,closeButtonLight&&wonderBlocksStyles.actionStyles.inverse],testId:`${testId||"popover"}-close-btn`}),children]})})});PopoverContentCore.displayName="PopoverContentCore";const styles$1=aphrodite.StyleSheet.create({scrollableView:{borderRadius:`calc(${wonderBlocksTokens.border.radius.radius_040} - ${wonderBlocksTokens.border.width.thin})`},content:{margin:0,maxInlineSize:`calc(${wonderBlocksTokens.sizing.size_160} * 18)`,padding:wonderBlocksTokens.sizing.size_240,overflow:"hidden",justifyContent:"center",flexShrink:0},closeButton:{margin:0,position:"absolute",insetInlineEnd:wonderBlocksTokens.sizing.size_040,insetBlockStart:wonderBlocksTokens.sizing.size_040,zIndex:1}});
|
|
51
52
|
|
|
52
53
|
const StyledImg=wonderBlocksCore.addStyle("img");const PopoverContent=React__namespace.forwardRef(function PopoverContent(props,ref){const{actions,closeButtonLabel,closeButtonVisible=false,content,icon,iconAlt,image,style,title,titleHeadingTag,testId,uniqueId}=props;const{close,placement}=React__namespace.useContext(PopoverContext);React__namespace.useEffect(()=>{if(image&&icon){throw new Error("'image' and 'icon' cannot be used at the same time. You can fix this by either removing 'image' or 'icon' from your instance.")}},[image,icon]);const validateProps=React__namespace.useCallback(({placement})=>{if(image&&(placement==="left"||placement==="right")){throw new Error("'image' can only be vertically placed. You can fix this by either changing `placement` to `top` or `bottom` or removing the `image` prop inside `content`.")}},[image]);const maybeRenderImage=context=>{if(!image){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:[styles.image,context.placement==="bottom"&&styles.imageToBottom],children:image})};const maybeRenderIcon=()=>{if(!icon){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.iconContainer,children:typeof icon!=="string"?icon:jsxRuntime.jsx(StyledImg,{src:icon,style:styles.icon,alt:iconAlt||""})})};const maybeRenderActions=close=>{if(!actions){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.actions,children:typeof actions==="function"?actions({close:close}):actions})};validateProps({close,placement});return jsxRuntime.jsxs(PopoverContentCore,{closeButtonLight:!!image&&placement==="top",closeButtonLabel:closeButtonLabel,closeButtonVisible:closeButtonVisible,style:style,testId:testId,ref:ref,children:[jsxRuntime.jsxs(wonderBlocksCore.View,{style:!!icon&&styles.withIcon,children:[maybeRenderImage({placement}),maybeRenderIcon(),jsxRuntime.jsxs(wonderBlocksCore.View,{style:styles.text,children:[jsxRuntime.jsx(wonderBlocksTypography.Heading,{size:"medium",tag:titleHeadingTag,id:`${uniqueId}-title`,style:styles.title,children:title}),jsxRuntime.jsx(wonderBlocksTypography.BodyText,{tag:"span",id:`${uniqueId}-content`,children:content})]})]}),maybeRenderActions(close)]})});PopoverContent.displayName="PopoverContent";const styles=aphrodite.StyleSheet.create({actions:{marginBlockStart:wonderBlocksTokens.sizing.size_240,flexDirection:"row",alignItems:"center",justifyContent:"flex-end"},text:{justifyContent:"center"},title:{marginBlockEnd:wonderBlocksTokens.sizing.size_080},iconContainer:{alignItems:"center",justifyContent:"center",blockSize:wonderBlocksTokens.sizing.size_640,inlineSize:wonderBlocksTokens.sizing.size_640,minInlineSize:wonderBlocksTokens.sizing.size_640,marginInlineEnd:wonderBlocksTokens.sizing.size_160,overflow:"hidden"},icon:{width:"100%"},withIcon:{flexDirection:"row"},image:{marginBlockEnd:wonderBlocksTokens.sizing.size_240,marginBlockStart:`calc(-1 * ${wonderBlocksTokens.sizing.size_240})`,marginInline:`calc(-1 * ${wonderBlocksTokens.sizing.size_240})`,inlineSize:`calc(100% + ${wonderBlocksTokens.sizing.size_480})`},imageToBottom:{marginBlockEnd:`calc(-1 * ${wonderBlocksTokens.sizing.size_240})`,marginBlockStart:wonderBlocksTokens.sizing.size_240,order:1}});
|
|
53
54
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "7.0.
|
|
6
|
+
"version": "7.0.2",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@khanacademy/wonder-blocks-core": "12.5.0",
|
|
24
|
-
"@khanacademy/wonder-blocks-floating": "0.
|
|
25
|
-
"@khanacademy/wonder-blocks-
|
|
24
|
+
"@khanacademy/wonder-blocks-floating": "0.2.0",
|
|
25
|
+
"@khanacademy/wonder-blocks-layout": "3.2.0",
|
|
26
26
|
"@khanacademy/wonder-blocks-styles": "0.4.0",
|
|
27
|
+
"@khanacademy/wonder-blocks-icon-button": "12.0.1",
|
|
27
28
|
"@khanacademy/wonder-blocks-tokens": "18.0.0",
|
|
28
29
|
"@khanacademy/wonder-blocks-typography": "5.0.5"
|
|
29
30
|
},
|