@neo4j-ndl/react 4.23.5 → 4.24.1

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 (94) hide show
  1. package/lib/cjs/announcement-banner/AnnouncementBanner.js +198 -0
  2. package/lib/cjs/announcement-banner/AnnouncementBanner.js.map +1 -0
  3. package/lib/cjs/announcement-banner/index.js +38 -0
  4. package/lib/cjs/announcement-banner/index.js.map +1 -0
  5. package/lib/cjs/announcement-banner/stories/announcement-banner-closeable.story.js +30 -0
  6. package/lib/cjs/announcement-banner/stories/announcement-banner-closeable.story.js.map +1 -0
  7. package/lib/cjs/announcement-banner/stories/announcement-banner-custom-icons.story.js +31 -0
  8. package/lib/cjs/announcement-banner/stories/announcement-banner-custom-icons.story.js.map +1 -0
  9. package/lib/cjs/announcement-banner/stories/announcement-banner-default.story.js +30 -0
  10. package/lib/cjs/announcement-banner/stories/announcement-banner-default.story.js.map +1 -0
  11. package/lib/cjs/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js +32 -0
  12. package/lib/cjs/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js.map +1 -0
  13. package/lib/cjs/announcement-banner/stories/announcement-banner-injected-urgent.story.js +32 -0
  14. package/lib/cjs/announcement-banner/stories/announcement-banner-injected-urgent.story.js.map +1 -0
  15. package/lib/cjs/announcement-banner/stories/announcement-banner-present-at-page-render.story.js +30 -0
  16. package/lib/cjs/announcement-banner/stories/announcement-banner-present-at-page-render.story.js.map +1 -0
  17. package/lib/cjs/announcement-banner/stories/announcement-banner-variants.story.js +30 -0
  18. package/lib/cjs/announcement-banner/stories/announcement-banner-variants.story.js.map +1 -0
  19. package/lib/cjs/announcement-banner/stories/announcement-banner-with-actions.story.js +30 -0
  20. package/lib/cjs/announcement-banner/stories/announcement-banner-with-actions.story.js.map +1 -0
  21. package/lib/cjs/announcement-banner/stories/announcement-banner-with-page-content.story.js +32 -0
  22. package/lib/cjs/announcement-banner/stories/announcement-banner-with-page-content.story.js.map +1 -0
  23. package/lib/cjs/announcement-banner/stories/index.js +64 -0
  24. package/lib/cjs/announcement-banner/stories/index.js.map +1 -0
  25. package/lib/cjs/index.js +4 -2
  26. package/lib/cjs/index.js.map +1 -1
  27. package/lib/cjs/popover/Popover.js +3 -2
  28. package/lib/cjs/popover/Popover.js.map +1 -1
  29. package/lib/cjs/popover/use-popover.js +3 -1
  30. package/lib/cjs/popover/use-popover.js.map +1 -1
  31. package/lib/esm/announcement-banner/AnnouncementBanner.js +159 -0
  32. package/lib/esm/announcement-banner/AnnouncementBanner.js.map +1 -0
  33. package/lib/esm/announcement-banner/index.js +22 -0
  34. package/lib/esm/announcement-banner/index.js.map +1 -0
  35. package/lib/esm/announcement-banner/stories/announcement-banner-closeable.story.js +28 -0
  36. package/lib/esm/announcement-banner/stories/announcement-banner-closeable.story.js.map +1 -0
  37. package/lib/esm/announcement-banner/stories/announcement-banner-custom-icons.story.js +29 -0
  38. package/lib/esm/announcement-banner/stories/announcement-banner-custom-icons.story.js.map +1 -0
  39. package/lib/esm/announcement-banner/stories/announcement-banner-default.story.js +28 -0
  40. package/lib/esm/announcement-banner/stories/announcement-banner-default.story.js.map +1 -0
  41. package/lib/esm/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js +30 -0
  42. package/lib/esm/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js.map +1 -0
  43. package/lib/esm/announcement-banner/stories/announcement-banner-injected-urgent.story.js +30 -0
  44. package/lib/esm/announcement-banner/stories/announcement-banner-injected-urgent.story.js.map +1 -0
  45. package/lib/esm/announcement-banner/stories/announcement-banner-present-at-page-render.story.js +28 -0
  46. package/lib/esm/announcement-banner/stories/announcement-banner-present-at-page-render.story.js.map +1 -0
  47. package/lib/esm/announcement-banner/stories/announcement-banner-variants.story.js +28 -0
  48. package/lib/esm/announcement-banner/stories/announcement-banner-variants.story.js.map +1 -0
  49. package/lib/esm/announcement-banner/stories/announcement-banner-with-actions.story.js +28 -0
  50. package/lib/esm/announcement-banner/stories/announcement-banner-with-actions.story.js.map +1 -0
  51. package/lib/esm/announcement-banner/stories/announcement-banner-with-page-content.story.js +30 -0
  52. package/lib/esm/announcement-banner/stories/announcement-banner-with-page-content.story.js.map +1 -0
  53. package/lib/esm/announcement-banner/stories/index.js +49 -0
  54. package/lib/esm/announcement-banner/stories/index.js.map +1 -0
  55. package/lib/esm/index.js +1 -0
  56. package/lib/esm/index.js.map +1 -1
  57. package/lib/esm/popover/Popover.js +3 -2
  58. package/lib/esm/popover/Popover.js.map +1 -1
  59. package/lib/esm/popover/use-popover.js +3 -1
  60. package/lib/esm/popover/use-popover.js.map +1 -1
  61. package/lib/types/announcement-banner/AnnouncementBanner.d.ts +75 -0
  62. package/lib/types/announcement-banner/AnnouncementBanner.d.ts.map +1 -0
  63. package/lib/types/announcement-banner/index.d.ts +22 -0
  64. package/lib/types/announcement-banner/index.d.ts.map +1 -0
  65. package/lib/types/announcement-banner/stories/announcement-banner-closeable.story.d.ts +24 -0
  66. package/lib/types/announcement-banner/stories/announcement-banner-closeable.story.d.ts.map +1 -0
  67. package/lib/types/announcement-banner/stories/announcement-banner-custom-icons.story.d.ts +24 -0
  68. package/lib/types/announcement-banner/stories/announcement-banner-custom-icons.story.d.ts.map +1 -0
  69. package/lib/types/announcement-banner/stories/announcement-banner-default.story.d.ts +24 -0
  70. package/lib/types/announcement-banner/stories/announcement-banner-default.story.d.ts.map +1 -0
  71. package/lib/types/announcement-banner/stories/announcement-banner-injected-non-urgent.story.d.ts +24 -0
  72. package/lib/types/announcement-banner/stories/announcement-banner-injected-non-urgent.story.d.ts.map +1 -0
  73. package/lib/types/announcement-banner/stories/announcement-banner-injected-urgent.story.d.ts +24 -0
  74. package/lib/types/announcement-banner/stories/announcement-banner-injected-urgent.story.d.ts.map +1 -0
  75. package/lib/types/announcement-banner/stories/announcement-banner-present-at-page-render.story.d.ts +24 -0
  76. package/lib/types/announcement-banner/stories/announcement-banner-present-at-page-render.story.d.ts.map +1 -0
  77. package/lib/types/announcement-banner/stories/announcement-banner-variants.story.d.ts +24 -0
  78. package/lib/types/announcement-banner/stories/announcement-banner-variants.story.d.ts.map +1 -0
  79. package/lib/types/announcement-banner/stories/announcement-banner-with-actions.story.d.ts +24 -0
  80. package/lib/types/announcement-banner/stories/announcement-banner-with-actions.story.d.ts.map +1 -0
  81. package/lib/types/announcement-banner/stories/announcement-banner-with-page-content.story.d.ts +24 -0
  82. package/lib/types/announcement-banner/stories/announcement-banner-with-page-content.story.d.ts.map +1 -0
  83. package/lib/types/announcement-banner/stories/index.d.ts +39 -0
  84. package/lib/types/announcement-banner/stories/index.d.ts.map +1 -0
  85. package/lib/types/index.d.ts +1 -0
  86. package/lib/types/index.d.ts.map +1 -1
  87. package/lib/types/popover/Popover.d.ts +7 -1
  88. package/lib/types/popover/Popover.d.ts.map +1 -1
  89. package/lib/types/popover/use-popover.d.ts +3 -1
  90. package/lib/types/popover/use-popover.d.ts.map +1 -1
  91. package/package.json +7 -2
  92. package/skills/ndl-react/SKILL.md +3 -2
  93. package/skills/ndl-react/components/announcement-banner.md +468 -0
  94. package/skills/ndl-react/components/popover.md +3 -0
@@ -56,6 +56,12 @@ type PopoverProps = {
56
56
  role?: 'tooltip' | 'dialog' | 'alertdialog' | 'menu' | 'listbox' | 'grid' | 'tree';
57
57
  /** If the popover should close when the user clicks outside of it */
58
58
  closeOnClickOutside?: boolean;
59
+ /**
60
+ * If the popover should close when focus moves outside of it, for example when tabbing away or focusing another element.
61
+ * Defaults to the value of `closeOnClickOutside`.
62
+ * Has no effect when `shouldCaptureFocus` is true, since focus cannot leave the popover.
63
+ */
64
+ shouldCloseOnFocusOut?: boolean;
59
65
  /** The strategy of the popover. Fixed should be used when the popover is inside a Dialog. */
60
66
  strategy?: 'fixed' | 'absolute';
61
67
  /** Whether the content is rendered in a portal */
@@ -81,7 +87,7 @@ type PopoverContentProps = {
81
87
  className?: string;
82
88
  style?: React.CSSProperties;
83
89
  };
84
- declare const Popover: (({ children, anchorElement, placement, isOpen, offset, anchorPosition, hasAnchorPortal: hasAnchorPortalProp, shouldCaptureFocus, initialFocus, onOpenChange, role, closeOnClickOutside, isPortaled: isPortaledProp, strategy: strategyProp, shouldConstrainSize, }: PopoverProps) => import("react/jsx-runtime").JSX.Element) & {
90
+ declare const Popover: (({ children, anchorElement, placement, isOpen, offset, anchorPosition, hasAnchorPortal: hasAnchorPortalProp, shouldCaptureFocus, initialFocus, onOpenChange, role, closeOnClickOutside, shouldCloseOnFocusOut, isPortaled: isPortaledProp, strategy: strategyProp, shouldConstrainSize, }: PopoverProps) => import("react/jsx-runtime").JSX.Element) & {
85
91
  Anchor: ({ children, ref, ...props }: CommonProps<"div", PopoverAnchorProps>) => import("react/jsx-runtime").JSX.Element;
86
92
  Content: <T extends React.ElementType = "div">({ as, className, style, children, htmlAttributes, ref, ...restProps }: PolymorphicCommonProps<T, PopoverContentProps>) => import("react/jsx-runtime").JSX.Element | null;
87
93
  Trigger: ({ children, hasButtonWrapper, ref, ...props }: CommonProps<"button", PopoverTriggerProps>) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/popover/Popover.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAO1B,KAAK,gBAAgB,GACjB,oBAAoB,GACpB,wBAAwB,GACxB,0BAA0B,GAC1B,oBAAoB,GACpB,wBAAwB,GACxB,0BAA0B,GAC1B,yBAAyB,GACzB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,mBAAmB,GACnB,yBAAyB,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAapE,CAAC;AACF,KAAK,YAAY,GAAG;IAClB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,0EAA0E;IAC1E,cAAc,CAAC,EAAE;QAGf,CAAC,EAAE,MAAM,CAAC;QAGV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,gTAAgT;IAChT,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,yHAAyH;IACzH,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,sKAAsK;IACtK,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACxD,yHAAyH;IACzH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE5D;;OAEG;IACH,IAAI,CAAC,EACD,SAAS,GACT,QAAQ,GACR,aAAa,GACb,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,CAAC;IACX,qEAAqE;IAGrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChC,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;SAGK;IACL,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,iBAAiB,gDAQ7B,CAAC;AAiDF,KAAK,mBAAmB,GAAG;IACzB,iCAAiC;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iGAAiG;IACjG,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AA0CF,KAAK,kBAAkB,GAAG;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAmCF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAqEF,QAAA,MAAM,OAAO,uQA5LV,YAAY;0CAyFZ,WAAW,CAAC,KAAK,EAAE,kBAAkB,CAAC;cAgCjB,CAAC,SAAS,KAAK,CAAC,WAAW,iFAQhD,sBAAsB,CAAC,CAAC,EAAE,mBAAmB,CAAC;6DAtF9C,WAAW,CAAC,QAAQ,EAAE,mBAAmB,CAAC;CAqJ3C,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/popover/Popover.tsx"],"names":[],"mappings":"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"}
@@ -36,6 +36,7 @@ export interface PopoverOptions {
36
36
  role?: 'tooltip' | 'dialog' | 'alertdialog' | 'menu' | 'listbox' | 'grid' | 'tree';
37
37
  closeOnClickOutside?: boolean;
38
38
  closeOnReferencePress?: boolean;
39
+ shouldCloseOnFocusOut?: boolean;
39
40
  returnFocus?: FloatingFocusManagerProps['returnFocus'];
40
41
  strategy?: 'fixed' | 'absolute';
41
42
  isPortaled?: boolean;
@@ -50,9 +51,10 @@ export interface UsePopoverReturn extends UseInteractionsReturn, ReturnType<type
50
51
  setDescriptionId: (descriptionId: string | undefined) => void;
51
52
  anchorElementAsPortalAnchor: boolean | undefined;
52
53
  shouldCaptureFocus: boolean | undefined;
54
+ shouldCloseOnFocusOut: boolean | undefined;
53
55
  initialFocus: number | React.RefObject<HTMLElement | null> | undefined;
54
56
  isPortaled: boolean;
55
57
  returnFocus: FloatingFocusManagerProps['returnFocus'];
56
58
  }
57
- export declare function usePopover({ isInitialOpen, placement, isOpen: controlledOpen, onOpenChange: setControlledOpen, offsetOption, anchorElement, anchorPosition, anchorElementAsPortalAnchor, shouldCaptureFocus, initialFocus, role: roleProp, closeOnClickOutside, closeOnReferencePress, returnFocus, strategy, isPortaled, shouldConstrainSize, }?: PopoverOptions): UsePopoverReturn;
59
+ export declare function usePopover({ isInitialOpen, placement, isOpen: controlledOpen, onOpenChange: setControlledOpen, offsetOption, anchorElement, anchorPosition, anchorElementAsPortalAnchor, shouldCaptureFocus, initialFocus, role: roleProp, closeOnClickOutside, closeOnReferencePress, shouldCloseOnFocusOut, returnFocus, strategy, isPortaled, shouldConstrainSize, }?: PopoverOptions): UsePopoverReturn;
58
60
  //# sourceMappingURL=use-popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-popover.d.ts","sourceRoot":"","sources":["../../../src/popover/use-popover.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGL,KAAK,yBAAyB,EAE9B,KAAK,aAAa,EAClB,KAAK,SAAS,EAMd,WAAW,EAEX,KAAK,qBAAqB,EAG3B,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE;QAGf,CAAC,EAAE,MAAM,CAAC;QAGV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IAGF,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,EACD,SAAS,GACT,QAAQ,GACR,aAAa,GACb,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,CAAC;IAGX,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAG9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,gBACf,SAAQ,qBAAqB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC;IACtC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAG9D,2BAA2B,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,kBAAkB,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IACvE,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;CACvD;AAED,wBAAgB,UAAU,CAAC,EACzB,aAAqB,EACrB,SAAoB,EACpB,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,iBAAiB,EAC/B,YAAiB,EACjB,aAAa,EACb,cAAc,EACd,2BAA2B,EAC3B,kBAAkB,EAClB,YAAY,EACZ,IAAI,EAAE,QAAQ,EACd,mBAAmB,EACnB,qBAAqB,EACrB,WAAW,EACX,QAAqB,EACrB,UAAiB,EACjB,mBAA2B,GAC5B,GAAE,cAAmB,GAAG,gBAAgB,CA4GxC"}
1
+ {"version":3,"file":"use-popover.d.ts","sourceRoot":"","sources":["../../../src/popover/use-popover.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGL,KAAK,yBAAyB,EAE9B,KAAK,aAAa,EAClB,KAAK,SAAS,EAMd,WAAW,EAEX,KAAK,qBAAqB,EAG3B,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE;QAGf,CAAC,EAAE,MAAM,CAAC;QAGV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IAGF,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,EACD,SAAS,GACT,QAAQ,GACR,aAAa,GACb,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,CAAC;IAGX,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAG9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,gBACf,SAAQ,qBAAqB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC;IACtC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAG9D,2BAA2B,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,kBAAkB,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,qBAAqB,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IACvE,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;CACvD;AAED,wBAAgB,UAAU,CAAC,EACzB,aAAqB,EACrB,SAAoB,EACpB,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,iBAAiB,EAC/B,YAAiB,EACjB,aAAa,EACb,cAAc,EACd,2BAA2B,EAC3B,kBAAkB,EAClB,YAAY,EACZ,IAAI,EAAE,QAAQ,EACd,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,QAAqB,EACrB,UAAiB,EACjB,mBAA2B,GAC5B,GAAE,cAAmB,GAAG,gBAAgB,CA8GxC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo4j-ndl/react",
3
- "version": "4.23.5",
3
+ "version": "4.24.1",
4
4
  "sideEffects": false,
5
5
  "description": "React implementation of Neo4j Design System",
6
6
  "keywords": [
@@ -32,6 +32,11 @@
32
32
  "require": "./lib/cjs/ai/index.js",
33
33
  "import": "./lib/esm/ai/index.js"
34
34
  },
35
+ "./announcement-banner": {
36
+ "types": "./lib/types/announcement-banner/index.d.ts",
37
+ "require": "./lib/cjs/announcement-banner/index.js",
38
+ "import": "./lib/esm/announcement-banner/index.js"
39
+ },
35
40
  "./avatar": {
36
41
  "types": "./lib/types/avatar/index.d.ts",
37
42
  "require": "./lib/cjs/avatar/index.js",
@@ -404,7 +409,7 @@
404
409
  "@tanstack/react-table": "8.21.3",
405
410
  "react": ">=19.0.0",
406
411
  "react-dom": ">=19.0.0",
407
- "@neo4j-ndl/base": "^4.22.4"
412
+ "@neo4j-ndl/base": "^4.23.0"
408
413
  },
409
414
  "dependencies": {
410
415
  "@dnd-kit/core": "6.3.1",
@@ -2,7 +2,7 @@
2
2
  name: ndl-react
3
3
  metadata:
4
4
  package: '@neo4j-ndl/react'
5
- version: '4.23.5'
5
+ version: '4.24.1'
6
6
  description: >-
7
7
  Build and edit UI with the Neo4j Needle React design system
8
8
  (@neo4j-ndl/react). Use when adding, composing, or modifying Needle components
@@ -15,7 +15,7 @@ description: >-
15
15
 
16
16
  # Neo4j Needle (@neo4j-ndl/react)
17
17
 
18
- > 📌 Shipped with `@neo4j-ndl/react` v4.23.5. Once installed into your repo (e.g. via
18
+ > 📌 Shipped with `@neo4j-ndl/react` v4.24.1. Once installed into your repo (e.g. via
19
19
  > `npx skills add`) this folder is detached from the package — the installed
20
20
  > package (TypeScript types in `node_modules/@neo4j-ndl/react`) is the source of
21
21
  > truth.
@@ -134,6 +134,7 @@ Import from `@neo4j-ndl/react`.
134
134
  | Component | Docs | Accessibility | Examples |
135
135
  |-----------|------|---------------|----------|
136
136
  | `Accordion` | [components/accordion.md](components/accordion.md) | ✅ | 6 |
137
+ | `AnnouncementBanner` | [components/announcement-banner.md](components/announcement-banner.md) | ✅ | 9 |
137
138
  | `Avatar` | [components/avatar.md](components/avatar.md) | ✅ | 7 |
138
139
  | `Banner` | [components/banner.md](components/banner.md) | ✅ | 6 |
139
140
  | `Box` | [components/box.md](components/box.md) | | 1 |
@@ -0,0 +1,468 @@
1
+ [//]: # (This file is auto-generated by the docs:generate-skills script, do not edit it manually)
2
+
3
+ # AnnouncementBanner
4
+
5
+ Import: `import { AnnouncementBanner } from '@neo4j-ndl/react'`
6
+
7
+ ## Props
8
+
9
+ ### AnnouncementBanner
10
+
11
+ | Prop | Type | Required | Default | Description |
12
+ |------|------|----------|---------|-------------|
13
+ | `as` | `ElementType<any, keyof IntrinsicElements>` | | | An override of the default HTML tag of the root of the component. Can also be another React component. |
14
+ | `children` | `ReactNode` | | | Content to be shown in the announcement banner. |
15
+ | `hasIcon` | `boolean` | | `false` | Shows a status icon. The icon is based on the value of the `variant` prop |
16
+ | `icon` | `ReactNode` | | | Decorative icon shown when `hasIcon` is true. Only used for `discovery` and `neutral`; those variants fall back to Sparkles and Bolt. `info`, `warning`, and `danger` always use their status icons. |
17
+ | `isCloseable` | `boolean` | | `false` | If the banner is closeable. Renders an icon button on the right |
18
+ | `liveRegion` | `'alert' \| 'status'` | | | Announces the header when the banner appears or its header changes. `status` announces politely, while `alert` interrupts the user. Leave this unset for banners that are present during the page's initial render. This is independent of the visual `variant`. |
19
+ | `onClose` | `((error?: MouseEvent<HTMLElement, MouseEvent> \| KeyboardEvent<HTMLElement>) => void)` | | | Event handler for when the close icon is clicked |
20
+ | `ref` | `any` | | | A ref to apply to the root element. |
21
+ | `variant` | `'danger' \| 'discovery' \| 'info' \| 'neutral' \| 'warning'` | | `info` | The variant of the announcement banner |
22
+
23
+ ### AnnouncementBanner.Actions
24
+
25
+ | Prop | Type | Required | Default | Description |
26
+ |------|------|----------|---------|-------------|
27
+ | `children` | `ReactNode` | ✅ | | |
28
+ | `ref` | `Ref<HTMLDivElement>` | | | A ref to apply to the root element. |
29
+
30
+ ### AnnouncementBanner.Header
31
+
32
+ | Prop | Type | Required | Default | Description |
33
+ |------|------|----------|---------|-------------|
34
+ | `children` | `ReactNode` | ✅ | | |
35
+ | `ref` | `Ref<HTMLSpanElement>` | | | A ref to apply to the root element. |
36
+
37
+ ## Accessibility
38
+
39
+ ## Implementation guidelines
40
+
41
+ Place `AnnouncementBanner` as the first child of its parent so content below is shifted down by the banner’s height. The banner stays in normal document flow (not sticky or fixed), so it does not overlay content underneath and does not obscure focused content (WCAG 2.2 SC 2.4.11 Focus Not Obscured).
42
+
43
+ ### Content and meaning
44
+
45
+ - Put the announcement meaning in text. Status icons are decorative (`aria-hidden` on the icon wrapper) and reinforce the `variant` visually; do not rely on color or the icon alone to convey severity (WCAG 2.2 SC 1.4.1 Use of Color). Prefer wording such as “Warning: …” or “Error: …”.
46
+ - `info`, `warning`, and `danger` always use the built-in status icons. For `discovery` and `neutral`, pass `icon` to replace Sparkles or Bolt; custom icons stay decorative through the same wrapper.
47
+
48
+ ### Live region semantics
49
+
50
+ The time at which a banner appears and its urgency are separate concerns:
51
+
52
+ - `variant` communicates visual meaning and never enables a live region.
53
+ - `liveRegion` controls whether a new or updated header is announced (WCAG 2.2 SC 4.1.3 Status Messages).
54
+
55
+ Use `liveRegion` only when a banner appears or changes after the page is ready and the user may already be interacting with it. Omit it for banners that are part of the initial page or shell render, including important `warning` and `danger` banners. Data that resolves as part of normal initial page loading does not necessarily make a banner a live update.
56
+
57
+ | `liveRegion` | Behavior | Use when |
58
+ | --- | --- | --- |
59
+ | `"status"` | Uses `role="status"` (`aria-live="polite"`) | New information is useful but can wait until the screen reader reaches a natural pause. |
60
+ | `"alert"` | Uses `role="alert"` (`aria-live="assertive"`) | New information is sufficiently urgent that interrupting the user is justified. |
61
+ | omitted | No live region | The banner is present during initial rendering, regardless of its visual severity. |
62
+
63
+ | Scenario | Recommended semantics |
64
+ | --- | --- |
65
+ | A deprecation, license, payment, or service warning is present during initial rendering | Omit `liveRegion`; choose an appropriate `variant` |
66
+ | A campaign or informational message appears later from polling or an event | `liveRegion="status"` |
67
+ | A connection loss, session expiry, or other urgent message appears later | `liveRegion="alert"` |
68
+
69
+ For reliable announcements across screen readers, the component mounts an empty, visually hidden live region before adding the message after a short delay. Only the text in `AnnouncementBanner.Header` is copied into that region; action and close controls remain available through normal keyboard and screen reader navigation without being duplicated in the announcement. `aria-atomic="true"` is set explicitly for interoperability. Do not add a redundant `aria-live` attribute, because combining it with `role="alert"` can cause duplicate announcements in VoiceOver on iOS.
70
+
71
+ ### Interactive controls
72
+
73
+ - When `isCloseable` is `true`, the close control is a keyboard-operable button labeled “Close”.
74
+ - Action buttons passed into `AnnouncementBanner.Actions` must have accessible names (visible text or `aria-label`).
75
+
76
+ ### Reflow and target size
77
+
78
+ - Narrow widths are supported without horizontal scrolling (WCAG 2.2 SC 1.4.10 Reflow): below `512px` of banner width the message and actions stack, and long or unbreakable strings (such as URLs) wrap, so the banner reflows down to a 320px viewport / 400% zoom without a horizontal scrollbar.
79
+ - Close and action controls meet the 24×24 CSS pixel minimum target size (WCAG 2.2 SC 2.5.8 Target Size Minimum).
80
+
81
+ ## Examples
82
+
83
+ ### Default
84
+
85
+ ```tsx
86
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
87
+
88
+ import { AnnouncementBanner } from '@neo4j-ndl/react';
89
+
90
+ const Component = () => {
91
+ return (
92
+ <AnnouncementBanner variant="info" hasIcon={true}>
93
+ <AnnouncementBanner.Header>
94
+ Scheduled maintenance starts tonight at 22:00 UTC.
95
+ </AnnouncementBanner.Header>
96
+ </AnnouncementBanner>
97
+ );
98
+ };
99
+
100
+ export default Component;
101
+ ```
102
+
103
+ ### Closeable
104
+
105
+ ```tsx
106
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
107
+
108
+ import { AnnouncementBanner } from '@neo4j-ndl/react';
109
+
110
+ const Component = () => {
111
+ return (
112
+ <AnnouncementBanner
113
+ isCloseable={true}
114
+ onClose={() => alert('Announcement banner closed')}
115
+ >
116
+ <AnnouncementBanner.Header>
117
+ This announcement can be dismissed.
118
+ </AnnouncementBanner.Header>
119
+ </AnnouncementBanner>
120
+ );
121
+ };
122
+
123
+ export default Component;
124
+ ```
125
+
126
+ ### Custom Icons
127
+
128
+ ```tsx
129
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
130
+
131
+ import { AnnouncementBanner } from '@neo4j-ndl/react';
132
+ import { GiftIconSolid, RocketLaunchIconSolid } from '@neo4j-ndl/react/icons';
133
+
134
+ const Component = () => {
135
+ return (
136
+ <div className="n-flex n-flex-col n-gap-token-8 n-w-full">
137
+ <AnnouncementBanner variant="discovery" hasIcon={true}>
138
+ <AnnouncementBanner.Header>
139
+ Discovery with the default Sparkles icon
140
+ </AnnouncementBanner.Header>
141
+ </AnnouncementBanner>
142
+ <AnnouncementBanner
143
+ variant="discovery"
144
+ hasIcon={true}
145
+ icon={<GiftIconSolid />}
146
+ >
147
+ <AnnouncementBanner.Header>
148
+ Discovery with a custom gift icon
149
+ </AnnouncementBanner.Header>
150
+ </AnnouncementBanner>
151
+ <AnnouncementBanner variant="neutral" hasIcon={true}>
152
+ <AnnouncementBanner.Header>
153
+ Neutral with the default Bolt icon
154
+ </AnnouncementBanner.Header>
155
+ </AnnouncementBanner>
156
+ <AnnouncementBanner
157
+ variant="neutral"
158
+ hasIcon={true}
159
+ icon={<RocketLaunchIconSolid />}
160
+ >
161
+ <AnnouncementBanner.Header>
162
+ Neutral with a custom rocket icon
163
+ </AnnouncementBanner.Header>
164
+ </AnnouncementBanner>
165
+ </div>
166
+ );
167
+ };
168
+
169
+ export default Component;
170
+ ```
171
+
172
+ ### Injected Non Urgent
173
+
174
+ ```tsx
175
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
176
+
177
+ import {
178
+ AnnouncementBanner,
179
+ OutlinedButton,
180
+ Typography,
181
+ } from '@neo4j-ndl/react';
182
+ import { useState } from 'react';
183
+
184
+ const Component = () => {
185
+ const [isVisible, setIsVisible] = useState(false);
186
+
187
+ return (
188
+ <div className="n-flex n-flex-col n-w-full">
189
+ {isVisible && (
190
+ <AnnouncementBanner
191
+ variant="discovery"
192
+ hasIcon={true}
193
+ liveRegion="status"
194
+ isCloseable={true}
195
+ onClose={() => setIsVisible(false)}
196
+ >
197
+ <AnnouncementBanner.Header>
198
+ New Aura features are available for your organization.
199
+ </AnnouncementBanner.Header>
200
+ </AnnouncementBanner>
201
+ )}
202
+ <div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default">
203
+ <OutlinedButton onClick={() => setIsVisible((visible) => !visible)}>
204
+ {isVisible ? 'Hide announcement' : 'Show announcement'}
205
+ </OutlinedButton>
206
+ <Typography variant="body-medium">
207
+ The page is already loaded. Toggle the announcement in to simulate a
208
+ later campaign or poll. <code>liveRegion=&quot;status&quot;</code>{' '}
209
+ announces politely without interrupting.
210
+ </Typography>
211
+ </div>
212
+ </div>
213
+ );
214
+ };
215
+
216
+ export default Component;
217
+ ```
218
+
219
+ ### Injected Urgent
220
+
221
+ ```tsx
222
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
223
+
224
+ import {
225
+ AnnouncementBanner,
226
+ OutlinedButton,
227
+ Typography,
228
+ } from '@neo4j-ndl/react';
229
+ import { useState } from 'react';
230
+
231
+ const Component = () => {
232
+ const [isVisible, setIsVisible] = useState(false);
233
+
234
+ return (
235
+ <div className="n-flex n-flex-col n-w-full">
236
+ {isVisible && (
237
+ <AnnouncementBanner variant="danger" hasIcon={true} liveRegion="alert">
238
+ <AnnouncementBanner.Header>
239
+ Error: connection to the database was lost. Reconnecting…
240
+ </AnnouncementBanner.Header>
241
+ </AnnouncementBanner>
242
+ )}
243
+ <div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default">
244
+ <OutlinedButton onClick={() => setIsVisible((visible) => !visible)}>
245
+ {isVisible ? 'Hide announcement' : 'Show announcement'}
246
+ </OutlinedButton>
247
+ <Typography variant="body-medium">
248
+ The page is already loaded. Toggle the announcement in to simulate a
249
+ connection loss or session expiry.{' '}
250
+ <code>liveRegion=&quot;alert&quot;</code> interrupts the screen reader
251
+ because the message is time-sensitive.
252
+ </Typography>
253
+ </div>
254
+ </div>
255
+ );
256
+ };
257
+
258
+ export default Component;
259
+ ```
260
+
261
+ ### Present At Page Render
262
+
263
+ ```tsx
264
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
265
+
266
+ import { AnnouncementBanner, Typography } from '@neo4j-ndl/react';
267
+
268
+ const Component = () => {
269
+ return (
270
+ <div className="n-flex n-flex-col n-w-full">
271
+ <AnnouncementBanner variant="danger" hasIcon={true}>
272
+ <AnnouncementBanner.Header>
273
+ Warning: your marketplace subscription will be deprecated on September
274
+ 19, 2026.
275
+ </AnnouncementBanner.Header>
276
+ </AnnouncementBanner>
277
+ <div className="n-p-token-24 n-bg-neutral-bg-default">
278
+ <Typography variant="body-medium">
279
+ This banner is part of the initial page render, so `liveRegion` is
280
+ omitted. Screen reader users hear it when they reach it in the page,
281
+ not as an interruption.
282
+ </Typography>
283
+ </div>
284
+ </div>
285
+ );
286
+ };
287
+
288
+ export default Component;
289
+ ```
290
+
291
+ ### Variants
292
+
293
+ ```tsx
294
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
295
+
296
+ import { AnnouncementBanner } from '@neo4j-ndl/react';
297
+
298
+ const Component = () => {
299
+ return (
300
+ <div className="n-flex n-flex-col n-gap-token-8 n-w-full">
301
+ <AnnouncementBanner variant="info" hasIcon={true}>
302
+ <AnnouncementBanner.Header>Info announcement</AnnouncementBanner.Header>
303
+ </AnnouncementBanner>
304
+ <AnnouncementBanner variant="warning" hasIcon={true}>
305
+ <AnnouncementBanner.Header>
306
+ Warning announcement
307
+ </AnnouncementBanner.Header>
308
+ </AnnouncementBanner>
309
+ <AnnouncementBanner variant="danger" hasIcon={true}>
310
+ <AnnouncementBanner.Header>
311
+ Danger announcement
312
+ </AnnouncementBanner.Header>
313
+ </AnnouncementBanner>
314
+ <AnnouncementBanner variant="discovery" hasIcon={true}>
315
+ <AnnouncementBanner.Header>
316
+ Discovery announcement
317
+ </AnnouncementBanner.Header>
318
+ </AnnouncementBanner>
319
+ <AnnouncementBanner variant="neutral" hasIcon={true}>
320
+ <AnnouncementBanner.Header>
321
+ Neutral announcement
322
+ </AnnouncementBanner.Header>
323
+ </AnnouncementBanner>
324
+ </div>
325
+ );
326
+ };
327
+
328
+ export default Component;
329
+ ```
330
+
331
+ ### With Actions
332
+
333
+ ```tsx
334
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
335
+
336
+ import {
337
+ AnnouncementBanner,
338
+ OutlinedButton,
339
+ TextButton,
340
+ } from '@neo4j-ndl/react';
341
+
342
+ const Component = () => {
343
+ return (
344
+ <AnnouncementBanner hasIcon={true} variant="warning">
345
+ <AnnouncementBanner.Header>
346
+ Your trial ends in 3 days.
347
+ </AnnouncementBanner.Header>
348
+ <AnnouncementBanner.Actions>
349
+ <OutlinedButton>Upgrade</OutlinedButton>
350
+ <TextButton>Learn more</TextButton>
351
+ </AnnouncementBanner.Actions>
352
+ </AnnouncementBanner>
353
+ );
354
+ };
355
+
356
+ export default Component;
357
+ ```
358
+
359
+ ### With Page Content
360
+
361
+ ```tsx
362
+ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
363
+
364
+ import {
365
+ AnnouncementBanner,
366
+ OutlinedButton,
367
+ TextButton,
368
+ Typography,
369
+ } from '@neo4j-ndl/react';
370
+ import { useState } from 'react';
371
+
372
+ const Component = () => {
373
+ const [isVisible, setIsVisible] = useState(true);
374
+
375
+ return (
376
+ <div className="n-flex n-flex-col n-max-w-[768px] n-h-52">
377
+ {isVisible && (
378
+ <AnnouncementBanner
379
+ variant="warning"
380
+ hasIcon={true}
381
+ isCloseable={true}
382
+ onClose={() => setIsVisible(false)}
383
+ >
384
+ <AnnouncementBanner.Header>
385
+ Scheduled maintenance starts tonight at 22:00 UTC.
386
+ </AnnouncementBanner.Header>
387
+ <AnnouncementBanner.Actions>
388
+ <OutlinedButton>Learn more</OutlinedButton>
389
+ </AnnouncementBanner.Actions>
390
+ </AnnouncementBanner>
391
+ )}
392
+ <div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default n-flex-1 n-min-h-0 n-overflow-y-auto">
393
+ {!isVisible && (
394
+ <div>
395
+ <TextButton onClick={() => setIsVisible(true)}>
396
+ Show announcement again
397
+ </TextButton>
398
+ </div>
399
+ )}
400
+ <Typography variant="title-2">Page title</Typography>
401
+ <OutlinedButton>Can focus</OutlinedButton>
402
+ <Typography variant="body-medium">
403
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
404
+ tempus, quam non molestie faucibus, orci nibh bibendum urna, ut
405
+ lacinia orci dui a augue. Nullam at risus quam. Fusce pulvinar, metus
406
+ vitae finibus dapibus, nisi ipsum venenatis sapien, at facilisis eros
407
+ massa ac nunc. Aliquam sed odio orci. Vivamus condimentum sit amet
408
+ ipsum bibendum sollicitudin. Etiam eget vehicula urna, et ullamcorper
409
+ libero. Interdum et malesuada fames ac ante ipsum primis in faucibus.
410
+ Proin sodales euismod sem, posuere maximus libero interdum semper.
411
+ Nunc mollis posuere arcu non elementum. Vivamus sed laoreet mauris.
412
+ Etiam fringilla arcu convallis erat vehicula iaculis. Pellentesque
413
+ dictum aliquam cursus.
414
+ </Typography>
415
+ <Typography variant="body-medium">
416
+ Integer vehicula turpis quis risus aliquet congue. Vivamus
417
+ pellentesque nibh ac blandit varius. Fusce placerat lacus ut mauris
418
+ porta, nec facilisis risus pulvinar. Nullam elementum nulla ut laoreet
419
+ imperdiet. Maecenas eget erat erat. Phasellus in turpis placerat,
420
+ imperdiet ante nec, tincidunt nisl. Donec a lacus neque. Nullam
421
+ iaculis ante molestie ultrices semper. Sed non lorem ullamcorper
422
+ ligula elementum convallis. Aenean egestas risus quis tortor cursus
423
+ dapibus. Nulla hendrerit at orci ut scelerisque. Nullam vel bibendum
424
+ tellus. Praesent efficitur ultrices lectus at posuere. Maecenas
425
+ facilisis lacus ac turpis malesuada, sit amet imperdiet ipsum
426
+ condimentum. Donec et nibh eget justo luctus ornare. Maecenas suscipit
427
+ nulla at ullamcorper congue.
428
+ </Typography>
429
+ <Typography variant="body-medium">
430
+ Vestibulum vehicula nibh mi, ultrices condimentum massa venenatis sit
431
+ amet. Pellentesque accumsan mollis ex, id lobortis lacus venenatis id.
432
+ Proin sem dui, mollis id gravida ac, vulputate et lacus. In pharetra
433
+ nunc odio, in fermentum elit dignissim at. Nunc ut justo elit. Proin
434
+ ligula orci, faucibus vitae vehicula nec, faucibus sit amet erat.
435
+ Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque
436
+ pharetra venenatis rutrum. Sed pharetra turpis id arcu maximus,
437
+ interdum rhoncus eros mollis. Donec vitae sapien et odio interdum
438
+ bibendum. Quisque eleifend, sem ut ornare mollis, orci nunc dapibus
439
+ odio, aliquam fringilla augue nulla id magna. Phasellus consectetur,
440
+ velit egestas sodales ultricies, odio nunc facilisis libero, vel
441
+ vehicula nisi quam quis nisl. Proin vel massa libero.
442
+ </Typography>
443
+ <Typography variant="body-medium">
444
+ Sed mollis lacinia tincidunt. Curabitur blandit pellentesque
445
+ consequat. Maecenas mollis pharetra dolor in ornare. Cras vel nibh eu
446
+ nisi venenatis convallis id vel nisl. Curabitur et viverra nisl.
447
+ Phasellus et finibus turpis. Praesent scelerisque vel lectus at
448
+ imperdiet. Curabitur porta egestas magna ullamcorper hendrerit.
449
+ </Typography>
450
+ <Typography variant="body-medium">
451
+ Curabitur hendrerit egestas mi, ut venenatis turpis sagittis nec.
452
+ Proin consectetur, nisi et vehicula placerat, tellus augue luctus
453
+ odio, in commodo mauris urna nec libero. Maecenas eu placerat sapien,
454
+ in aliquam tellus. Sed pharetra nunc id urna iaculis tincidunt. In hac
455
+ habitasse platea dictumst. Donec tincidunt risus vitae congue congue.
456
+ Fusce consequat ut justo ut tristique. Nunc ut urna quis neque
457
+ consequat venenatis. Praesent nec feugiat orci. Vestibulum rutrum dui
458
+ lacus, sit amet vulputate dolor finibus ut. Donec placerat urna eu
459
+ fringilla convallis. Praesent sollicitudin felis at lacus semper, vel
460
+ convallis magna scelerisque.
461
+ </Typography>
462
+ </div>
463
+ </div>
464
+ );
465
+ };
466
+
467
+ export default Component;
468
+ ```
@@ -23,6 +23,7 @@ Import: `import { Popover } from '@neo4j-ndl/react'`
23
23
  | `placement` | `'bottom-end-bottom-start' \| 'bottom-end-top-end' \| 'bottom-middle-top-middle' \| 'bottom-start-bottom-end' \| 'bottom-start-top-start' \| 'middle-end-middle-start' \| 'middle-start-middle-end' \| 'top-end-bottom-end' \| 'top-end-top-start' \| 'top-middle-bottom-middle' \| 'top-start-bottom-start' \| 'top-start-top-end'` | | | The placement of the floating element is determined by two sets of words. The first set of words specifies the point on the anchor element where the floating element will be attached. The second set of coordinates specifies the point on the floating element that will attach to the anchor element. |
24
24
  | `role` | `'alertdialog' \| 'dialog' \| 'grid' \| 'listbox' \| 'menu' \| 'tooltip' \| 'tree'` | | | The role of the popover. @deprecated - This prop will be removed in v5. |
25
25
  | `shouldCaptureFocus` | `boolean` | | `false` | If the popover should constrain the focus inside the popover while open |
26
+ | `shouldCloseOnFocusOut` | `boolean` | | | If the popover should close when focus moves outside of it, for example when tabbing away or focusing another element. Defaults to the value of `closeOnClickOutside`. Has no effect when `shouldCaptureFocus` is true, since focus cannot leave the popover. |
26
27
  | `shouldConstrainSize` | `boolean` | | | When true, limits the popover's max-height and max-width to the available viewport space. The consumer is responsible for adding overflow handling (e.g. overflow-y: auto) to the content. |
27
28
  | `strategy` | `'absolute' \| 'fixed'` | | | The strategy of the popover. Fixed should be used when the popover is inside a Dialog. |
28
29
 
@@ -55,6 +56,8 @@ Import: `import { Popover } from '@neo4j-ndl/react'`
55
56
 
56
57
  When used with a toggle button, the button should have aria-expanded (true when open, false when closed), aria-haspopup set to the role of the popover, and aria-controls set to the id of the popover.
57
58
 
59
+ By default, a popover that doesn't capture focus closes when focus moves outside of it. Setting `closeOnClickOutside` or `shouldCloseOnFocusOut` to false keeps it open while keyboard users tab through the rest of the page. Make sure it doesn't hide the focused element (WCAG 2.4.11), and give users a way to close it, for example with the Escape key or a close button.
60
+
58
61
  ## Examples
59
62
 
60
63
  ### Default