@dsn-starter-kit/components-react 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Drawer/Drawer.d.mts +5 -2
- package/dist/Drawer/Drawer.d.mts.map +1 -1
- package/dist/Drawer/Drawer2.mjs +18 -3
- package/dist/Drawer/Drawer2.mjs.map +1 -1
- package/dist/ModalDialog/ModalDialog.d.mts +13 -3
- package/dist/ModalDialog/ModalDialog.d.mts.map +1 -1
- package/dist/ModalDialog/ModalDialog2.mjs +10 -3
- package/dist/ModalDialog/ModalDialog2.mjs.map +1 -1
- package/dist/Popover/Popover.d.mts +16 -23
- package/dist/Popover/Popover.d.mts.map +1 -1
- package/dist/Popover/Popover2.mjs +33 -119
- package/dist/Popover/Popover2.mjs.map +1 -1
- package/dist/PopoverMenu/PopoverMenu.d.mts +62 -0
- package/dist/PopoverMenu/PopoverMenu.d.mts.map +1 -0
- package/dist/PopoverMenu/PopoverMenu2.mjs +66 -0
- package/dist/PopoverMenu/PopoverMenu2.mjs.map +1 -0
- package/dist/PopoverMenu/index.d.mts +2 -0
- package/dist/index.cjs +169 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +5147 -4522
- package/dist/index.d.cts +104 -17
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +2 -1
- package/dist/utils/popover.d.mts +27 -0
- package/dist/utils/popover.d.mts.map +1 -0
- package/dist/utils/popover.mjs +142 -0
- package/dist/utils/popover.mjs.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover2.mjs","names":["toggleEvent"],"sources":["../../src/Popover/Popover.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { Button } from '../Button';\nimport { Icon } from '../Icon';\nimport './Popover.css';\n\n/*\n * React 18 ondersteunt het `popover`-attribuut en `onToggle` niet natively in de\n * JSX-types. Module-uitbreiding voegt de ontbrekende types toe.\n */\ndeclare module 'react' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface HTMLAttributes<T> {\n popover?: 'auto' | 'manual' | '' | undefined;\n popoverTarget?: string | undefined;\n popoverTargetAction?: 'hide' | 'show' | 'toggle' | undefined;\n }\n}\n\n/*\n * HTMLElement.showPopover / hidePopover zijn nog niet in alle TypeScript DOM-libs.\n * Declaratie toegevoegd voor veilig gebruik.\n */\ndeclare global {\n interface HTMLElement {\n showPopover(): void;\n hidePopover(): void;\n }\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype Placement = 'top' | 'bottom' | 'start' | 'end';\n\n// =============================================================================\n// Positioneringshelper\n// =============================================================================\n\nconst GAP = 4; // px afstand tussen trigger en popover\n\nfunction positionPopover(\n popover: HTMLElement,\n trigger: HTMLElement,\n placement: Placement\n): void {\n const triggerRect = trigger.getBoundingClientRect();\n // offsetWidth/offsetHeight — onaangepast door CSS transforms (zoals @starting-style scale).\n // getBoundingClientRect geeft de getransformeerde afmetingen, wat leidt tot onjuiste clamping.\n const popoverWidth = popover.offsetWidth;\n const popoverHeight = popover.offsetHeight;\n const popoverRect = { width: popoverWidth, height: popoverHeight };\n const isRTL =\n document.documentElement.dir === 'rtl' ||\n getComputedStyle(trigger).direction === 'rtl';\n\n let top: number;\n let left: number;\n\n switch (placement) {\n case 'bottom':\n top = triggerRect.bottom + GAP;\n left = isRTL ? triggerRect.right - popoverRect.width : triggerRect.left;\n break;\n case 'top':\n top = triggerRect.top - popoverRect.height - GAP;\n left = isRTL ? triggerRect.right - popoverRect.width : triggerRect.left;\n break;\n case 'end':\n top = triggerRect.top;\n left = isRTL\n ? triggerRect.left - popoverRect.width - GAP\n : triggerRect.right + GAP;\n break;\n case 'start':\n top = triggerRect.top;\n left = isRTL\n ? triggerRect.right + GAP\n : triggerRect.left - popoverRect.width - GAP;\n break;\n default:\n top = triggerRect.bottom + GAP;\n left = triggerRect.left;\n }\n\n // Klamp binnen het viewport (8px marge)\n const margin = 8;\n left = Math.max(\n margin,\n Math.min(left, window.innerWidth - popoverRect.width - margin)\n );\n top = Math.max(\n margin,\n Math.min(top, window.innerHeight - popoverRect.height - margin)\n );\n\n popover.style.top = `${top}px`;\n popover.style.left = `${left}px`;\n popover.style.right = 'auto';\n popover.style.bottom = 'auto';\n}\n\n// Zet focus op het eerste interactieve element in de popover\nfunction focusFirstInteractive(container: HTMLElement): void {\n const selector = [\n 'button:not(:disabled)',\n 'a[href]',\n 'input:not(:disabled)',\n 'select:not(:disabled)',\n 'textarea:not(:disabled)',\n '[tabindex]:not([tabindex=\"-1\"])',\n ].join(', ');\n const first = container.querySelector<HTMLElement>(selector);\n if (first) {\n first.focus();\n } else {\n container.focus();\n }\n}\n\n// =============================================================================\n// Context\n// =============================================================================\n\ninterface PopoverContextValue {\n headingId: string;\n onClose?: () => void;\n}\n\nconst PopoverContext = React.createContext<PopoverContextValue>({\n headingId: '',\n});\n\n// =============================================================================\n// Popover (root)\n// =============================================================================\n\nexport interface PopoverProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /**\n * Bepaalt of de popover getoond wordt.\n */\n isOpen: boolean;\n\n /**\n * Callback bij sluiten (Escape, klik buiten, sluitknop in header).\n */\n onClose?: () => void;\n\n /**\n * Referentie naar het triggerelement voor positionering en focus-herstel.\n */\n triggerRef: React.RefObject<HTMLElement>;\n\n /**\n * Gewenste plaatsing relatief aan het triggerelement.\n * @default 'bottom'\n */\n placement?: Placement;\n\n /**\n * Toegankelijke naam voor popovers zonder `PopoverHeader`/`PopoverHeading`.\n * Gebruik `aria-labelledby` via context wanneer er wél een heading is.\n */\n label?: string;\n\n /**\n * Subcomponenten: `PopoverHeader`, `PopoverBody`, `PopoverFooter`\n */\n children?: React.ReactNode;\n}\n\n/**\n * Popover component\n * Lichtgewicht, contextgebonden overlay verankerd aan een triggerelement.\n *\n * Gebaseerd op de HTML Popover API (`popover=\"auto\"`) voor ingebakken\n * light-dismiss en top-layer gedrag. Positionering via JavaScript.\n *\n * @example\n * ```tsx\n * const triggerRef = useRef<HTMLButtonElement>(null);\n * const [isOpen, setIsOpen] = useState(false);\n *\n * <Button ref={triggerRef} onClick={() => setIsOpen(true)}>Opties</Button>\n * <Popover isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef} label=\"Opties\">\n * <PopoverBody>\n * <Menu>...</Menu>\n * </PopoverBody>\n * </Popover>\n * ```\n */\nexport const Popover = React.forwardRef<HTMLDivElement, PopoverProps>(\n (\n {\n className,\n isOpen,\n onClose,\n triggerRef,\n placement = 'bottom',\n label,\n children,\n ...props\n },\n ref\n ) => {\n const internalRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = (ref as React.RefObject<HTMLDivElement>) ?? internalRef;\n const headingId = React.useId();\n\n // Toon/verberg popover via de Popover API\n React.useEffect(() => {\n const el = popoverRef.current;\n if (!el) return;\n\n if (isOpen) {\n el.showPopover();\n const trigger = triggerRef.current;\n if (trigger) {\n positionPopover(el, trigger, placement);\n }\n focusFirstInteractive(el);\n } else {\n // hidePopover gooit een fout als de popover al gesloten is\n try {\n el.hidePopover();\n } catch {\n // popover was al gesloten — geen actie nodig\n }\n }\n }, [isOpen, placement, triggerRef, popoverRef]);\n\n // Synchroniseer aria-expanded op het triggerelement\n React.useEffect(() => {\n const trigger = triggerRef.current;\n if (!trigger) return;\n trigger.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n return () => {\n trigger.setAttribute('aria-expanded', 'false');\n };\n }, [isOpen, triggerRef]);\n\n // Verwerk het toggle-event van de Popover API (Escape / klik buiten binnen hetzelfde document)\n // onToggle is niet beschikbaar als JSX-prop op div in React 18 — gebruik addEventListener.\n // Gebruik een ref voor onClose zodat de listener stabiel blijft en nooit stale is.\n const onCloseRef = React.useRef(onClose);\n onCloseRef.current = onClose;\n\n React.useEffect(() => {\n const el = popoverRef.current;\n if (!el) return;\n\n const handleToggle = (event: Event) => {\n const toggleEvent = event as Event & { newState?: string };\n if (toggleEvent.newState === 'closed') {\n onCloseRef.current?.();\n triggerRef.current?.focus();\n }\n };\n\n el.addEventListener('toggle', handleToggle);\n return () => {\n el.removeEventListener('toggle', handleToggle);\n };\n }, [triggerRef, popoverRef]);\n\n // Fallback light-dismiss via pointerdown — vangt klikken buiten het popover op\n // in contexten waar de Popover API's native light-dismiss niet bereikbaar is\n // (bijv. iframe-grenzen, of oudere browsers zonder Popover API).\n React.useEffect(() => {\n if (!isOpen) return;\n const el = popoverRef.current;\n if (!el) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n // Sluit niet als er op de popover zelf of het triggerelement geklikt wordt\n if (el.contains(target) || triggerRef.current?.contains(target)) return;\n onCloseRef.current?.();\n triggerRef.current?.focus();\n };\n\n document.addEventListener('pointerdown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n };\n }, [isOpen, triggerRef, popoverRef]);\n\n const classes = classNames(\n 'dsn-popover',\n `dsn-popover--placement-${placement}`,\n className\n );\n\n const ariaProps = label\n ? { 'aria-label': label }\n : { 'aria-labelledby': headingId };\n\n return (\n <PopoverContext.Provider value={{ headingId, onClose }}>\n <div\n ref={popoverRef}\n popover=\"auto\"\n className={classes}\n role=\"dialog\"\n aria-modal=\"false\"\n tabIndex={-1}\n {...ariaProps}\n {...props}\n >\n {children}\n </div>\n </PopoverContext.Provider>\n );\n }\n);\n\nPopover.displayName = 'Popover';\n\n// =============================================================================\n// PopoverHeader\n// =============================================================================\n\nexport interface PopoverHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Inhoud van de header — doorgaans een `PopoverHeading`.\n * De sluitknop wordt automatisch geïnjecteerd.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverHeader\n * De headerstrook van de popover met heading en sluitknop.\n */\nexport const PopoverHeader = React.forwardRef<\n HTMLDivElement,\n PopoverHeaderProps\n>(({ className, children, ...props }, ref) => {\n const { onClose } = React.useContext(PopoverContext);\n\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__header', className)}\n {...props}\n >\n {children}\n <Button\n variant=\"subtle\"\n size=\"small\"\n iconOnly\n onClick={onClose}\n iconStart={<Icon name=\"x\" aria-hidden />}\n >\n Sluiten\n </Button>\n </div>\n );\n});\n\nPopoverHeader.displayName = 'PopoverHeader';\n\n// =============================================================================\n// PopoverHeading\n// =============================================================================\n\nexport interface PopoverHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /**\n * Semantisch heading-niveau. Kies op basis van documenthiërarchie.\n * @default 2\n */\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n\n /**\n * De zichtbare heading-tekst.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverHeading\n * De heading van de popover. ID wordt automatisch gegenereerd voor aria-labelledby.\n */\nexport const PopoverHeading = React.forwardRef<\n HTMLHeadingElement,\n PopoverHeadingProps\n>(({ className, level = 2, children, ...props }, ref) => {\n const { headingId } = React.useContext(PopoverContext);\n const Tag = `h${level}` as React.ElementType;\n\n return (\n <Tag\n ref={ref}\n id={headingId}\n className={classNames('dsn-popover-heading', className)}\n {...props}\n >\n {children}\n </Tag>\n );\n});\n\nPopoverHeading.displayName = 'PopoverHeading';\n\n// =============================================================================\n// PopoverBody\n// =============================================================================\n\nexport interface PopoverBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * De hoofdinhoud van de popover — willekeurige slot-content.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverBody\n * De inhoudssectie van de popover.\n */\nexport const PopoverBody = React.forwardRef<HTMLDivElement, PopoverBodyProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__body', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nPopoverBody.displayName = 'PopoverBody';\n\n// =============================================================================\n// PopoverFooter\n// =============================================================================\n\nexport interface PopoverFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Actieknoppen of slotzin van de popover.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverFooter\n * De voettekst van de popover met actieknoppen.\n */\nexport const PopoverFooter = React.forwardRef<\n HTMLDivElement,\n PopoverFooterProps\n>(({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__footer', className)}\n {...props}\n >\n {children}\n </div>\n );\n});\n\nPopoverFooter.displayName = 'PopoverFooter';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover2.mjs","names":[],"sources":["../../src/Popover/Popover.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { Button } from '../Button';\nimport { Icon } from '../Icon';\nimport { usePopover, type PopoverPlacement } from '../utils/popover';\nimport './Popover.css';\n\n// =============================================================================\n// Context\n// =============================================================================\n\ninterface PopoverContextValue {\n headingId: string;\n headingRef: React.MutableRefObject<HTMLHeadingElement | null>;\n onClose?: () => void;\n}\n\nconst PopoverContext = React.createContext<PopoverContextValue>({\n headingId: '',\n headingRef: { current: null },\n});\n\n// =============================================================================\n// Popover (root)\n// =============================================================================\n\nexport interface PopoverProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /**\n * Bepaalt of de popover getoond wordt.\n */\n isOpen: boolean;\n\n /**\n * Callback bij sluiten (Escape, klik buiten, sluitknop in header).\n */\n onClose?: () => void;\n\n /**\n * Referentie naar het triggerelement voor positionering en focus-herstel.\n */\n triggerRef: React.RefObject<HTMLElement>;\n\n /**\n * Gewenste plaatsing relatief aan het triggerelement.\n * @default 'bottom'\n */\n placement?: PopoverPlacement;\n\n /**\n * Toegankelijke naam voor een popover zonder `PopoverHeader`/`PopoverHeading`.\n * Een zichtbare heading heeft de voorkeur; die koppelt via `aria-labelledby`.\n */\n label?: string;\n\n /**\n * Subcomponenten: `PopoverHeader`, `PopoverBody`, `PopoverFooter`\n */\n children?: React.ReactNode;\n}\n\n/**\n * Popover component\n * Niet-modaal dialoogvenster verankerd aan een triggerelement\n * (`role=\"dialog\"`, `aria-modal=\"false\"`).\n *\n * Gebaseerd op de HTML Popover API (`popover=\"auto\"`) voor ingebakken\n * light-dismiss en top-layer gedrag. Positionering via JavaScript.\n *\n * Voor een lijst met acties of links: gebruik `PopoverMenu`. Een lijst is\n * geen dialoogvenster.\n *\n * @example\n * ```tsx\n * const triggerRef = useRef<HTMLButtonElement>(null);\n * const [isOpen, setIsOpen] = useState(false);\n *\n * <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Filters</Button>\n * <Popover isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>\n * <PopoverHeader>\n * <PopoverHeading>Filters</PopoverHeading>\n * </PopoverHeader>\n * <PopoverBody>...</PopoverBody>\n * </Popover>\n * ```\n */\nexport const Popover = React.forwardRef<HTMLDivElement, PopoverProps>(\n (\n {\n className,\n isOpen,\n onClose,\n triggerRef,\n placement = 'bottom',\n label,\n children,\n ...props\n },\n ref\n ) => {\n const internalRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = (ref as React.RefObject<HTMLDivElement>) ?? internalRef;\n const headingId = React.useId();\n const headingRef = React.useRef<HTMLHeadingElement | null>(null);\n\n /*\n * Bij openen krijgt de heading de focus, niet de sluitknop: zo wordt de\n * titel als eerste voorgelezen, net als bij ModalDialog en Drawer. Zonder\n * heading krijgt de popover zelf de focus (die heeft `tabindex=\"-1\"`).\n * Zie docs/decisions/DR-2026-12-dialogs-focus-bij-openen-op-de-heading.md.\n */\n usePopover({\n popoverRef,\n triggerRef,\n isOpen,\n onClose,\n placement,\n initialFocusRef: headingRef,\n });\n\n const classes = classNames(\n 'dsn-popover',\n `dsn-popover--placement-${placement}`,\n className\n );\n\n const ariaProps = label\n ? { 'aria-label': label }\n : { 'aria-labelledby': headingId };\n\n return (\n <PopoverContext.Provider value={{ headingId, headingRef, onClose }}>\n <div\n ref={popoverRef}\n popover=\"auto\"\n className={classes}\n role=\"dialog\"\n aria-modal=\"false\"\n tabIndex={-1}\n {...ariaProps}\n {...props}\n >\n {children}\n </div>\n </PopoverContext.Provider>\n );\n }\n);\n\nPopover.displayName = 'Popover';\n\n// =============================================================================\n// PopoverHeader\n// =============================================================================\n\nexport interface PopoverHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Inhoud van de header — doorgaans een `PopoverHeading`.\n * De sluitknop wordt automatisch geïnjecteerd.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverHeader\n * De headerstrook van de popover met heading en sluitknop.\n */\nexport const PopoverHeader = React.forwardRef<\n HTMLDivElement,\n PopoverHeaderProps\n>(({ className, children, ...props }, ref) => {\n const { onClose } = React.useContext(PopoverContext);\n\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__header', className)}\n {...props}\n >\n {children}\n <Button\n variant=\"subtle\"\n size=\"small\"\n iconOnly\n onClick={onClose}\n iconStart={<Icon name=\"x\" aria-hidden />}\n >\n Sluiten\n </Button>\n </div>\n );\n});\n\nPopoverHeader.displayName = 'PopoverHeader';\n\n// =============================================================================\n// PopoverHeading\n// =============================================================================\n\nexport interface PopoverHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /**\n * Semantisch heading-niveau. Kies op basis van documenthiërarchie.\n * @default 2\n */\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n\n /**\n * De zichtbare heading-tekst.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverHeading\n * De heading van de popover. ID wordt automatisch gegenereerd voor aria-labelledby.\n * Krijgt `tabindex=\"-1\"` zodat de Popover er bij openen de focus op kan zetten.\n */\nexport const PopoverHeading = React.forwardRef<\n HTMLHeadingElement,\n PopoverHeadingProps\n>(({ className, level = 2, children, ...props }, ref) => {\n const { headingId, headingRef } = React.useContext(PopoverContext);\n const Tag = `h${level}` as React.ElementType;\n\n // De Popover heeft de heading nodig om er bij openen de focus op te zetten;\n // een eventuele meegegeven ref blijft daarnaast gewoon werken.\n const setRef = React.useCallback(\n (node: HTMLHeadingElement | null) => {\n headingRef.current = node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLHeadingElement | null>).current =\n node;\n }\n },\n [headingRef, ref]\n );\n\n return (\n <Tag\n ref={setRef}\n id={headingId}\n className={classNames('dsn-popover-heading', className)}\n tabIndex={-1}\n {...props}\n >\n {children}\n </Tag>\n );\n});\n\nPopoverHeading.displayName = 'PopoverHeading';\n\n// =============================================================================\n// PopoverBody\n// =============================================================================\n\nexport interface PopoverBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * De hoofdinhoud van de popover — willekeurige slot-content.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverBody\n * De inhoudssectie van de popover.\n */\nexport const PopoverBody = React.forwardRef<HTMLDivElement, PopoverBodyProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__body', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nPopoverBody.displayName = 'PopoverBody';\n\n// =============================================================================\n// PopoverFooter\n// =============================================================================\n\nexport interface PopoverFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Actieknoppen of slotzin van de popover.\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverFooter\n * De voettekst van de popover met actieknoppen.\n */\nexport const PopoverFooter = React.forwardRef<\n HTMLDivElement,\n PopoverFooterProps\n>(({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-popover__footer', className)}\n {...props}\n >\n {children}\n </div>\n );\n});\n\nPopoverFooter.displayName = 'PopoverFooter';\n"],"mappings":";;;;;;;;AAiBA,MAAM,iBAAiB,MAAM,cAAmC;CAC9D,WAAW;CACX,YAAY,EAAE,SAAS,KAAK;AAC9B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAoED,MAAa,UAAU,MAAM,YAEzB,EACE,WACA,QACA,SACA,YACA,YAAY,UACZ,OACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,cAAc,MAAM,OAAuB,IAAI;CACrD,MAAM,aAAc,OAA2C;CAC/D,MAAM,YAAY,MAAM,MAAM;CAC9B,MAAM,aAAa,MAAM,OAAkC,IAAI;CAQ/D,WAAW;EACT;EACA;EACA;EACA;EACA;EACA,iBAAiB;CACnB,CAAC;CAED,MAAM,UAAU,WACd,eACA,0BAA0B,aAC1B,SACF;CAEA,MAAM,YAAY,QACd,EAAE,cAAc,MAAM,IACtB,EAAE,mBAAmB,UAAU;CAEnC,OACE,oBAAC,eAAe,UAAhB;EAAyB,OAAO;GAAE;GAAW;GAAY;EAAQ;EAC/D,UAAA,oBAAC,OAAD;GACE,KAAK;GACL,SAAQ;GACR,WAAW;GACX,MAAK;GACL,cAAW;GACX,UAAU;GACV,GAAI;GACJ,GAAI;GAEH;EACE,CAAA;CACkB,CAAA;AAE7B,CACF;AAEA,QAAQ,cAAc;;;;;AAkBtB,MAAa,gBAAgB,MAAM,YAGhC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,EAAE,YAAY,MAAM,WAAW,cAAc;CAEnD,OACE,qBAAC,OAAD;EACO;EACL,WAAW,WAAW,uBAAuB,SAAS;EACtD,GAAI;EAHN,UAAA,CAKG,UACD,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,UAAA;GACA,SAAS;GACT,WAAW,oBAAC,MAAD;IAAM,MAAK;IAAI,eAAA;GAAa,CAAA;GACxC,UAAA;EAEO,CAAA,CACL;;AAET,CAAC;AAED,cAAc,cAAc;;;;;;AAwB5B,MAAa,iBAAiB,MAAM,YAGjC,EAAE,WAAW,QAAQ,GAAG,UAAU,GAAG,SAAS,QAAQ;CACvD,MAAM,EAAE,WAAW,eAAe,MAAM,WAAW,cAAc;CACjE,MAAM,MAAM,IAAI;CAIhB,MAAM,SAAS,MAAM,aAClB,SAAoC;EACnC,WAAW,UAAU;EACrB,IAAI,OAAO,QAAQ,YACjB,IAAI,IAAI;OACH,IAAI,KACT,IAA2D,UACzD;CAEN,GACA,CAAC,YAAY,GAAG,CAClB;CAEA,OACE,oBAAC,KAAD;EACE,KAAK;EACL,IAAI;EACJ,WAAW,WAAW,uBAAuB,SAAS;EACtD,UAAU;EACV,GAAI;EAEH;CACE,CAAA;AAET,CAAC;AAED,eAAe,cAAc;;;;;AAiB7B,MAAa,cAAc,MAAM,YAC9B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,qBAAqB,SAAS;EACpD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,YAAY,cAAc;;;;;AAiB1B,MAAa,gBAAgB,MAAM,YAGhC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,uBAAuB,SAAS;EACtD,GAAI;EAEH;CACE,CAAA;AAET,CAAC;AAED,cAAc,cAAc"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { PopoverPlacement } from "../utils/popover.mjs";
|
|
2
|
+
import React from "react";
|
|
3
|
+
//#region src/PopoverMenu/PopoverMenu.d.ts
|
|
4
|
+
interface PopoverMenuProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
5
|
+
/**
|
|
6
|
+
* Bepaalt of het menu getoond wordt.
|
|
7
|
+
*/
|
|
8
|
+
isOpen: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Callback bij sluiten: Escape, klik buiten het menu, of het activeren van
|
|
11
|
+
* een `MenuButton` of `MenuLink`.
|
|
12
|
+
*/
|
|
13
|
+
onClose?: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Referentie naar het triggerelement voor positionering, `aria-expanded`
|
|
16
|
+
* en focusherstel.
|
|
17
|
+
*/
|
|
18
|
+
triggerRef: React.RefObject<HTMLElement>;
|
|
19
|
+
/**
|
|
20
|
+
* Gewenste plaatsing relatief aan het triggerelement.
|
|
21
|
+
* @default 'bottom'
|
|
22
|
+
*/
|
|
23
|
+
placement?: PopoverPlacement;
|
|
24
|
+
/**
|
|
25
|
+
* Doorgegeven aan `Menu`: geeft aan dat de items een `iconStart` hebben.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
iconStart?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* `MenuButton`- en/of `MenuLink`-items
|
|
31
|
+
*/
|
|
32
|
+
children?: React.ReactNode;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* PopoverMenu component
|
|
36
|
+
* Lijst met acties of links in een zwevend paneel, geopend vanuit een
|
|
37
|
+
* triggerknop.
|
|
38
|
+
*
|
|
39
|
+
* Anders dan `Popover` is dit géén dialoogvenster: het paneel heeft geen rol,
|
|
40
|
+
* de inhoud is een gewone lijst (`<ul role="list">`). Ook bewust geen
|
|
41
|
+
* `role="menu"`: die rol belooft pijltjesnavigatie en zet screenreaders in
|
|
42
|
+
* een applicatiemodus. De context komt uit het label van de trigger.
|
|
43
|
+
*
|
|
44
|
+
* Het menu sluit zichzelf zodra een item wordt geactiveerd, en zet de focus
|
|
45
|
+
* dan terug op de trigger.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* const triggerRef = useRef<HTMLButtonElement>(null);
|
|
50
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
51
|
+
*
|
|
52
|
+
* <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Acties</Button>
|
|
53
|
+
* <PopoverMenu isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>
|
|
54
|
+
* <MenuButton onClick={edit}>Bewerken</MenuButton>
|
|
55
|
+
* <MenuButton onClick={duplicate}>Dupliceren</MenuButton>
|
|
56
|
+
* </PopoverMenu>
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
declare const PopoverMenu: React.ForwardRefExoticComponent<PopoverMenuProps & React.RefAttributes<HTMLDivElement>>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { PopoverMenu, PopoverMenuProps };
|
|
62
|
+
//# sourceMappingURL=PopoverMenu.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopoverMenu.d.mts","names":[],"sources":["../../src/PopoverMenu/PopoverMenu.tsx"],"mappings":";;;UAaiB,yBAAyB,KACxC,MAAM,eAAe;;;;EAMrB;;;;;EAMA;;;;;EAMA,YAAY,MAAM,UAAU;;;;;EAM5B,YAAY;;;;;EAMZ;;;;EAKA,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BN,aAAW,MAAA,0BAAA,mBAAA,MAAA,cAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Menu } from "../Menu/Menu2.mjs";
|
|
2
|
+
import { usePopover } from "../utils/popover.mjs";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { classNames } from "@dsn-starter-kit/core";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/PopoverMenu/PopoverMenu.tsx
|
|
8
|
+
const ITEM_SELECTOR = ".dsn-menu-button__button, .dsn-menu-link__link";
|
|
9
|
+
/**
|
|
10
|
+
* PopoverMenu component
|
|
11
|
+
* Lijst met acties of links in een zwevend paneel, geopend vanuit een
|
|
12
|
+
* triggerknop.
|
|
13
|
+
*
|
|
14
|
+
* Anders dan `Popover` is dit géén dialoogvenster: het paneel heeft geen rol,
|
|
15
|
+
* de inhoud is een gewone lijst (`<ul role="list">`). Ook bewust geen
|
|
16
|
+
* `role="menu"`: die rol belooft pijltjesnavigatie en zet screenreaders in
|
|
17
|
+
* een applicatiemodus. De context komt uit het label van de trigger.
|
|
18
|
+
*
|
|
19
|
+
* Het menu sluit zichzelf zodra een item wordt geactiveerd, en zet de focus
|
|
20
|
+
* dan terug op de trigger.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const triggerRef = useRef<HTMLButtonElement>(null);
|
|
25
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
26
|
+
*
|
|
27
|
+
* <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Acties</Button>
|
|
28
|
+
* <PopoverMenu isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>
|
|
29
|
+
* <MenuButton onClick={edit}>Bewerken</MenuButton>
|
|
30
|
+
* <MenuButton onClick={duplicate}>Dupliceren</MenuButton>
|
|
31
|
+
* </PopoverMenu>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
const PopoverMenu = React.forwardRef(({ className, isOpen, onClose, triggerRef, placement = "bottom", iconStart = false, onClick, children, ...props }, ref) => {
|
|
35
|
+
const internalRef = React.useRef(null);
|
|
36
|
+
const popoverRef = ref ?? internalRef;
|
|
37
|
+
usePopover({
|
|
38
|
+
popoverRef,
|
|
39
|
+
triggerRef,
|
|
40
|
+
isOpen,
|
|
41
|
+
onClose,
|
|
42
|
+
placement
|
|
43
|
+
});
|
|
44
|
+
const handleClick = (event) => {
|
|
45
|
+
onClick?.(event);
|
|
46
|
+
if (event.target.closest(ITEM_SELECTOR)) onClose?.();
|
|
47
|
+
};
|
|
48
|
+
const classes = classNames("dsn-popover-menu", `dsn-popover-menu--placement-${placement}`, className);
|
|
49
|
+
return /* @__PURE__ */ jsx("div", {
|
|
50
|
+
ref: popoverRef,
|
|
51
|
+
popover: "auto",
|
|
52
|
+
className: classes,
|
|
53
|
+
onClick: handleClick,
|
|
54
|
+
...props,
|
|
55
|
+
children: /* @__PURE__ */ jsx(Menu, {
|
|
56
|
+
role: "list",
|
|
57
|
+
iconStart,
|
|
58
|
+
children
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
PopoverMenu.displayName = "PopoverMenu";
|
|
63
|
+
//#endregion
|
|
64
|
+
export { PopoverMenu };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=PopoverMenu2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopoverMenu2.mjs","names":[],"sources":["../../src/PopoverMenu/PopoverMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { Menu } from '../Menu';\nimport { usePopover, type PopoverPlacement } from '../utils/popover';\nimport './PopoverMenu.css';\n\n/*\n * Klikken op deze elementen activeert een item en sluit het menu. De\n * uitklapknop van een MenuLink met sub-items staat er bewust niet bij: die\n * toont meer items en is dus geen keuze.\n */\nconst ITEM_SELECTOR = '.dsn-menu-button__button, .dsn-menu-link__link';\n\nexport interface PopoverMenuProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /**\n * Bepaalt of het menu getoond wordt.\n */\n isOpen: boolean;\n\n /**\n * Callback bij sluiten: Escape, klik buiten het menu, of het activeren van\n * een `MenuButton` of `MenuLink`.\n */\n onClose?: () => void;\n\n /**\n * Referentie naar het triggerelement voor positionering, `aria-expanded`\n * en focusherstel.\n */\n triggerRef: React.RefObject<HTMLElement>;\n\n /**\n * Gewenste plaatsing relatief aan het triggerelement.\n * @default 'bottom'\n */\n placement?: PopoverPlacement;\n\n /**\n * Doorgegeven aan `Menu`: geeft aan dat de items een `iconStart` hebben.\n * @default false\n */\n iconStart?: boolean;\n\n /**\n * `MenuButton`- en/of `MenuLink`-items\n */\n children?: React.ReactNode;\n}\n\n/**\n * PopoverMenu component\n * Lijst met acties of links in een zwevend paneel, geopend vanuit een\n * triggerknop.\n *\n * Anders dan `Popover` is dit géén dialoogvenster: het paneel heeft geen rol,\n * de inhoud is een gewone lijst (`<ul role=\"list\">`). Ook bewust geen\n * `role=\"menu\"`: die rol belooft pijltjesnavigatie en zet screenreaders in\n * een applicatiemodus. De context komt uit het label van de trigger.\n *\n * Het menu sluit zichzelf zodra een item wordt geactiveerd, en zet de focus\n * dan terug op de trigger.\n *\n * @example\n * ```tsx\n * const triggerRef = useRef<HTMLButtonElement>(null);\n * const [isOpen, setIsOpen] = useState(false);\n *\n * <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Acties</Button>\n * <PopoverMenu isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>\n * <MenuButton onClick={edit}>Bewerken</MenuButton>\n * <MenuButton onClick={duplicate}>Dupliceren</MenuButton>\n * </PopoverMenu>\n * ```\n */\nexport const PopoverMenu = React.forwardRef<HTMLDivElement, PopoverMenuProps>(\n (\n {\n className,\n isOpen,\n onClose,\n triggerRef,\n placement = 'bottom',\n iconStart = false,\n onClick,\n children,\n ...props\n },\n ref\n ) => {\n const internalRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = (ref as React.RefObject<HTMLDivElement>) ?? internalRef;\n\n usePopover({ popoverRef, triggerRef, isOpen, onClose, placement });\n\n // Sluit na het activeren van een item. Het eigen onClick van het item is\n // dan al uitgevoerd, want dit event bubbelt vanaf het item omhoog.\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n const target = event.target as Element;\n if (target.closest(ITEM_SELECTOR)) {\n onClose?.();\n }\n };\n\n const classes = classNames(\n 'dsn-popover-menu',\n `dsn-popover-menu--placement-${placement}`,\n className\n );\n\n return (\n <div\n ref={popoverRef}\n popover=\"auto\"\n className={classes}\n onClick={handleClick}\n {...props}\n >\n <Menu role=\"list\" iconStart={iconStart}>\n {children}\n </Menu>\n </div>\n );\n }\n);\n\nPopoverMenu.displayName = 'PopoverMenu';\n"],"mappings":";;;;;;;AAWA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEtB,MAAa,cAAc,MAAM,YAE7B,EACE,WACA,QACA,SACA,YACA,YAAY,UACZ,YAAY,OACZ,SACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,cAAc,MAAM,OAAuB,IAAI;CACrD,MAAM,aAAc,OAA2C;CAE/D,WAAW;EAAE;EAAY;EAAY;EAAQ;EAAS;CAAU,CAAC;CAIjE,MAAM,eAAe,UAA4C;EAC/D,UAAU,KAAK;EAEf,IADe,MAAM,OACV,QAAQ,aAAa,GAC9B,UAAU;CAEd;CAEA,MAAM,UAAU,WACd,oBACA,+BAA+B,aAC/B,SACF;CAEA,OACE,oBAAC,OAAD;EACE,KAAK;EACL,SAAQ;EACR,WAAW;EACX,SAAS;EACT,GAAI;EAEJ,UAAA,oBAAC,MAAD;GAAM,MAAK;GAAkB;GAC1B;EACG,CAAA;CACH,CAAA;AAET,CACF;AAEA,YAAY,cAAc"}
|
package/dist/index.cjs
CHANGED
|
@@ -3562,14 +3562,28 @@ const Drawer = react.default.forwardRef(({ className, isOpen, onClose, modal = t
|
|
|
3562
3562
|
const dialogRef = ref ?? internalRef;
|
|
3563
3563
|
const headingId = react.default.useId();
|
|
3564
3564
|
const headingRef = react.default.useRef(null);
|
|
3565
|
+
const popoverShownRef = react.default.useRef(false);
|
|
3566
|
+
const previousFocusRef = react.default.useRef(null);
|
|
3565
3567
|
react.default.useEffect(() => {
|
|
3566
3568
|
const dialog = dialogRef.current;
|
|
3567
3569
|
if (!dialog) return;
|
|
3568
|
-
|
|
3570
|
+
const isShown = dialog.open || popoverShownRef.current;
|
|
3571
|
+
if (isOpen && !isShown) {
|
|
3569
3572
|
if (modal) dialog.showModal();
|
|
3570
|
-
else
|
|
3573
|
+
else {
|
|
3574
|
+
previousFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
3575
|
+
dialog.showPopover();
|
|
3576
|
+
popoverShownRef.current = true;
|
|
3577
|
+
}
|
|
3571
3578
|
(headingRef.current ?? dialog).focus();
|
|
3572
|
-
} else if (!isOpen &&
|
|
3579
|
+
} else if (!isOpen && isShown) {
|
|
3580
|
+
if (popoverShownRef.current) {
|
|
3581
|
+
const focusWasInside = dialog.contains(document.activeElement);
|
|
3582
|
+
dialog.hidePopover();
|
|
3583
|
+
popoverShownRef.current = false;
|
|
3584
|
+
if (focusWasInside) previousFocusRef.current?.focus();
|
|
3585
|
+
} else dialog.close();
|
|
3586
|
+
}
|
|
3573
3587
|
}, [
|
|
3574
3588
|
isOpen,
|
|
3575
3589
|
modal,
|
|
@@ -3616,6 +3630,7 @@ const Drawer = react.default.forwardRef(({ className, isOpen, onClose, modal = t
|
|
|
3616
3630
|
"aria-labelledby": headingId,
|
|
3617
3631
|
onCancel: handleCancel,
|
|
3618
3632
|
tabIndex: -1,
|
|
3633
|
+
popover: modal ? void 0 : "manual",
|
|
3619
3634
|
...props,
|
|
3620
3635
|
children
|
|
3621
3636
|
})
|
|
@@ -4711,6 +4726,7 @@ CardGroup.displayName = "CardGroup";
|
|
|
4711
4726
|
//#region src/ModalDialog/ModalDialog.tsx
|
|
4712
4727
|
const ModalDialogContext = react.default.createContext({
|
|
4713
4728
|
headingId: "",
|
|
4729
|
+
bodyId: "",
|
|
4714
4730
|
headingRef: { current: null }
|
|
4715
4731
|
});
|
|
4716
4732
|
/**
|
|
@@ -4724,7 +4740,7 @@ const ModalDialogContext = react.default.createContext({
|
|
|
4724
4740
|
*
|
|
4725
4741
|
* @example
|
|
4726
4742
|
* ```tsx
|
|
4727
|
-
* <ModalDialog isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
4743
|
+
* <ModalDialog alert isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
4728
4744
|
* <ModalDialogHeader>
|
|
4729
4745
|
* <ModalDialogHeading>Bevestig verwijderen</ModalDialogHeading>
|
|
4730
4746
|
* </ModalDialogHeader>
|
|
@@ -4733,17 +4749,18 @@ const ModalDialogContext = react.default.createContext({
|
|
|
4733
4749
|
* </ModalDialogBody>
|
|
4734
4750
|
* <ModalDialogFooter>
|
|
4735
4751
|
* <ActionGroup>
|
|
4736
|
-
* <Button variant="negative" onClick={() => setIsOpen(false)}>Verwijderen</Button>
|
|
4752
|
+
* <Button variant="strong-negative" onClick={() => setIsOpen(false)}>Verwijderen</Button>
|
|
4737
4753
|
* <Button variant="default" onClick={() => setIsOpen(false)}>Annuleren</Button>
|
|
4738
4754
|
* </ActionGroup>
|
|
4739
4755
|
* </ModalDialogFooter>
|
|
4740
4756
|
* </ModalDialog>
|
|
4741
4757
|
* ```
|
|
4742
4758
|
*/
|
|
4743
|
-
const ModalDialog = react.default.forwardRef(({ className, isOpen, onClose, triggerRef, children, ...props }, ref) => {
|
|
4759
|
+
const ModalDialog = react.default.forwardRef(({ className, isOpen, onClose, triggerRef, alert = false, children, ...props }, ref) => {
|
|
4744
4760
|
const internalRef = react.default.useRef(null);
|
|
4745
4761
|
const dialogRef = ref ?? internalRef;
|
|
4746
4762
|
const headingId = react.default.useId();
|
|
4763
|
+
const bodyId = react.default.useId();
|
|
4747
4764
|
const headingRef = react.default.useRef(null);
|
|
4748
4765
|
react.default.useEffect(() => {
|
|
4749
4766
|
const dialog = dialogRef.current;
|
|
@@ -4770,13 +4787,16 @@ const ModalDialog = react.default.forwardRef(({ className, isOpen, onClose, trig
|
|
|
4770
4787
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModalDialogContext.Provider, {
|
|
4771
4788
|
value: {
|
|
4772
4789
|
headingId,
|
|
4790
|
+
bodyId,
|
|
4773
4791
|
headingRef,
|
|
4774
4792
|
onClose
|
|
4775
4793
|
},
|
|
4776
4794
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dialog", {
|
|
4777
4795
|
ref: dialogRef,
|
|
4778
4796
|
className: classes,
|
|
4797
|
+
role: alert ? "alertdialog" : void 0,
|
|
4779
4798
|
"aria-labelledby": headingId,
|
|
4799
|
+
"aria-describedby": alert ? bodyId : void 0,
|
|
4780
4800
|
onCancel: handleCancel,
|
|
4781
4801
|
tabIndex: -1,
|
|
4782
4802
|
...props,
|
|
@@ -4837,8 +4857,10 @@ ModalDialogHeading.displayName = "ModalDialogHeading";
|
|
|
4837
4857
|
* De scrollbare inhoudssectie van het dialoogvenster met scroll-affordance schaduw.
|
|
4838
4858
|
*/
|
|
4839
4859
|
const ModalDialogBody = react.default.forwardRef(({ className, children, ...props }, ref) => {
|
|
4860
|
+
const { bodyId } = react.default.useContext(ModalDialogContext);
|
|
4840
4861
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4841
4862
|
ref,
|
|
4863
|
+
id: bodyId,
|
|
4842
4864
|
className: (0, _dsn_starter_kit_core.classNames)("dsn-modal-dialog__body", className),
|
|
4843
4865
|
...props,
|
|
4844
4866
|
children
|
|
@@ -4859,7 +4881,7 @@ const ModalDialogFooter = react.default.forwardRef(({ className, children, ...pr
|
|
|
4859
4881
|
});
|
|
4860
4882
|
ModalDialogFooter.displayName = "ModalDialogFooter";
|
|
4861
4883
|
//#endregion
|
|
4862
|
-
//#region src/
|
|
4884
|
+
//#region src/utils/popover.ts
|
|
4863
4885
|
const GAP = 4;
|
|
4864
4886
|
function positionPopover(popover, trigger, placement) {
|
|
4865
4887
|
const triggerRect = trigger.getBoundingClientRect();
|
|
@@ -4912,39 +4934,32 @@ function focusFirstInteractive(container) {
|
|
|
4912
4934
|
if (first) first.focus();
|
|
4913
4935
|
else container.focus();
|
|
4914
4936
|
}
|
|
4915
|
-
const PopoverContext = react.default.createContext({ headingId: "" });
|
|
4916
4937
|
/**
|
|
4917
|
-
*
|
|
4918
|
-
*
|
|
4919
|
-
*
|
|
4920
|
-
*
|
|
4921
|
-
*
|
|
4922
|
-
*
|
|
4923
|
-
*
|
|
4924
|
-
*
|
|
4925
|
-
*
|
|
4926
|
-
* const [isOpen, setIsOpen] = useState(false);
|
|
4927
|
-
*
|
|
4928
|
-
* <Button ref={triggerRef} onClick={() => setIsOpen(true)}>Opties</Button>
|
|
4929
|
-
* <Popover isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef} label="Opties">
|
|
4930
|
-
* <PopoverBody>
|
|
4931
|
-
* <Menu>...</Menu>
|
|
4932
|
-
* </PopoverBody>
|
|
4933
|
-
* </Popover>
|
|
4934
|
-
* ```
|
|
4938
|
+
* Opent en sluit een element met `popover="auto"` synchroon met `isOpen`,
|
|
4939
|
+
* positioneert het bij de trigger en houdt `aria-expanded` op de trigger bij.
|
|
4940
|
+
*
|
|
4941
|
+
* Bij openen gaat de focus naar `initialFocusRef` (of de popover zelf als die
|
|
4942
|
+
* ref leeg is), en anders naar het eerste interactieve element. Bij sluiten
|
|
4943
|
+
* gaat de focus alleen terug naar de trigger wanneer dat zinvol is: als de
|
|
4944
|
+
* focus op dat moment nog in de popover stond (Escape, een sluitknop, een
|
|
4945
|
+
* actie in de popover). Klikt de gebruiker ergens anders, dan blijft de focus
|
|
4946
|
+
* daar; terugspringen naar de trigger zou die klik tenietdoen.
|
|
4935
4947
|
*/
|
|
4936
|
-
|
|
4937
|
-
const
|
|
4938
|
-
const
|
|
4939
|
-
const
|
|
4948
|
+
function usePopover({ popoverRef, triggerRef, isOpen, onClose, placement, initialFocusRef }) {
|
|
4949
|
+
const restoreFocusRef = react.default.useRef(false);
|
|
4950
|
+
const dismissedByPointerRef = react.default.useRef(false);
|
|
4951
|
+
const onCloseRef = react.default.useRef(onClose);
|
|
4952
|
+
onCloseRef.current = onClose;
|
|
4940
4953
|
react.default.useEffect(() => {
|
|
4941
4954
|
const el = popoverRef.current;
|
|
4942
4955
|
if (!el) return;
|
|
4943
4956
|
if (isOpen) {
|
|
4957
|
+
dismissedByPointerRef.current = false;
|
|
4944
4958
|
el.showPopover();
|
|
4945
4959
|
const trigger = triggerRef.current;
|
|
4946
4960
|
if (trigger) positionPopover(el, trigger, placement);
|
|
4947
|
-
|
|
4961
|
+
if (initialFocusRef) (initialFocusRef.current ?? el).focus();
|
|
4962
|
+
else focusFirstInteractive(el);
|
|
4948
4963
|
} else try {
|
|
4949
4964
|
el.hidePopover();
|
|
4950
4965
|
} catch {}
|
|
@@ -4952,7 +4967,8 @@ const Popover = react.default.forwardRef(({ className, isOpen, onClose, triggerR
|
|
|
4952
4967
|
isOpen,
|
|
4953
4968
|
placement,
|
|
4954
4969
|
triggerRef,
|
|
4955
|
-
popoverRef
|
|
4970
|
+
popoverRef,
|
|
4971
|
+
initialFocusRef
|
|
4956
4972
|
]);
|
|
4957
4973
|
react.default.useEffect(() => {
|
|
4958
4974
|
const trigger = triggerRef.current;
|
|
@@ -4962,19 +4978,23 @@ const Popover = react.default.forwardRef(({ className, isOpen, onClose, triggerR
|
|
|
4962
4978
|
trigger.setAttribute("aria-expanded", "false");
|
|
4963
4979
|
};
|
|
4964
4980
|
}, [isOpen, triggerRef]);
|
|
4965
|
-
const onCloseRef = react.default.useRef(onClose);
|
|
4966
|
-
onCloseRef.current = onClose;
|
|
4967
4981
|
react.default.useEffect(() => {
|
|
4968
4982
|
const el = popoverRef.current;
|
|
4969
4983
|
if (!el) return;
|
|
4984
|
+
const handleBeforeToggle = (event) => {
|
|
4985
|
+
if (event.newState === "closed") restoreFocusRef.current = !dismissedByPointerRef.current && el.contains(document.activeElement);
|
|
4986
|
+
};
|
|
4970
4987
|
const handleToggle = (event) => {
|
|
4971
4988
|
if (event.newState === "closed") {
|
|
4972
4989
|
onCloseRef.current?.();
|
|
4973
|
-
triggerRef.current?.focus();
|
|
4990
|
+
if (restoreFocusRef.current) triggerRef.current?.focus();
|
|
4991
|
+
restoreFocusRef.current = false;
|
|
4974
4992
|
}
|
|
4975
4993
|
};
|
|
4994
|
+
el.addEventListener("beforetoggle", handleBeforeToggle);
|
|
4976
4995
|
el.addEventListener("toggle", handleToggle);
|
|
4977
4996
|
return () => {
|
|
4997
|
+
el.removeEventListener("beforetoggle", handleBeforeToggle);
|
|
4978
4998
|
el.removeEventListener("toggle", handleToggle);
|
|
4979
4999
|
};
|
|
4980
5000
|
}, [triggerRef, popoverRef]);
|
|
@@ -4985,8 +5005,8 @@ const Popover = react.default.forwardRef(({ className, isOpen, onClose, triggerR
|
|
|
4985
5005
|
const handlePointerDown = (event) => {
|
|
4986
5006
|
const target = event.target;
|
|
4987
5007
|
if (el.contains(target) || triggerRef.current?.contains(target)) return;
|
|
5008
|
+
dismissedByPointerRef.current = true;
|
|
4988
5009
|
onCloseRef.current?.();
|
|
4989
|
-
triggerRef.current?.focus();
|
|
4990
5010
|
};
|
|
4991
5011
|
document.addEventListener("pointerdown", handlePointerDown);
|
|
4992
5012
|
return () => {
|
|
@@ -4997,11 +5017,57 @@ const Popover = react.default.forwardRef(({ className, isOpen, onClose, triggerR
|
|
|
4997
5017
|
triggerRef,
|
|
4998
5018
|
popoverRef
|
|
4999
5019
|
]);
|
|
5020
|
+
}
|
|
5021
|
+
//#endregion
|
|
5022
|
+
//#region src/Popover/Popover.tsx
|
|
5023
|
+
const PopoverContext = react.default.createContext({
|
|
5024
|
+
headingId: "",
|
|
5025
|
+
headingRef: { current: null }
|
|
5026
|
+
});
|
|
5027
|
+
/**
|
|
5028
|
+
* Popover component
|
|
5029
|
+
* Niet-modaal dialoogvenster verankerd aan een triggerelement
|
|
5030
|
+
* (`role="dialog"`, `aria-modal="false"`).
|
|
5031
|
+
*
|
|
5032
|
+
* Gebaseerd op de HTML Popover API (`popover="auto"`) voor ingebakken
|
|
5033
|
+
* light-dismiss en top-layer gedrag. Positionering via JavaScript.
|
|
5034
|
+
*
|
|
5035
|
+
* Voor een lijst met acties of links: gebruik `PopoverMenu`. Een lijst is
|
|
5036
|
+
* geen dialoogvenster.
|
|
5037
|
+
*
|
|
5038
|
+
* @example
|
|
5039
|
+
* ```tsx
|
|
5040
|
+
* const triggerRef = useRef<HTMLButtonElement>(null);
|
|
5041
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
5042
|
+
*
|
|
5043
|
+
* <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Filters</Button>
|
|
5044
|
+
* <Popover isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>
|
|
5045
|
+
* <PopoverHeader>
|
|
5046
|
+
* <PopoverHeading>Filters</PopoverHeading>
|
|
5047
|
+
* </PopoverHeader>
|
|
5048
|
+
* <PopoverBody>...</PopoverBody>
|
|
5049
|
+
* </Popover>
|
|
5050
|
+
* ```
|
|
5051
|
+
*/
|
|
5052
|
+
const Popover = react.default.forwardRef(({ className, isOpen, onClose, triggerRef, placement = "bottom", label, children, ...props }, ref) => {
|
|
5053
|
+
const internalRef = react.default.useRef(null);
|
|
5054
|
+
const popoverRef = ref ?? internalRef;
|
|
5055
|
+
const headingId = react.default.useId();
|
|
5056
|
+
const headingRef = react.default.useRef(null);
|
|
5057
|
+
usePopover({
|
|
5058
|
+
popoverRef,
|
|
5059
|
+
triggerRef,
|
|
5060
|
+
isOpen,
|
|
5061
|
+
onClose,
|
|
5062
|
+
placement,
|
|
5063
|
+
initialFocusRef: headingRef
|
|
5064
|
+
});
|
|
5000
5065
|
const classes = (0, _dsn_starter_kit_core.classNames)("dsn-popover", `dsn-popover--placement-${placement}`, className);
|
|
5001
5066
|
const ariaProps = label ? { "aria-label": label } : { "aria-labelledby": headingId };
|
|
5002
5067
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PopoverContext.Provider, {
|
|
5003
5068
|
value: {
|
|
5004
5069
|
headingId,
|
|
5070
|
+
headingRef,
|
|
5005
5071
|
onClose
|
|
5006
5072
|
},
|
|
5007
5073
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -5045,14 +5111,21 @@ PopoverHeader.displayName = "PopoverHeader";
|
|
|
5045
5111
|
/**
|
|
5046
5112
|
* PopoverHeading
|
|
5047
5113
|
* De heading van de popover. ID wordt automatisch gegenereerd voor aria-labelledby.
|
|
5114
|
+
* Krijgt `tabindex="-1"` zodat de Popover er bij openen de focus op kan zetten.
|
|
5048
5115
|
*/
|
|
5049
5116
|
const PopoverHeading = react.default.forwardRef(({ className, level = 2, children, ...props }, ref) => {
|
|
5050
|
-
const { headingId } = react.default.useContext(PopoverContext);
|
|
5117
|
+
const { headingId, headingRef } = react.default.useContext(PopoverContext);
|
|
5051
5118
|
const Tag = `h${level}`;
|
|
5119
|
+
const setRef = react.default.useCallback((node) => {
|
|
5120
|
+
headingRef.current = node;
|
|
5121
|
+
if (typeof ref === "function") ref(node);
|
|
5122
|
+
else if (ref) ref.current = node;
|
|
5123
|
+
}, [headingRef, ref]);
|
|
5052
5124
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, {
|
|
5053
|
-
ref,
|
|
5125
|
+
ref: setRef,
|
|
5054
5126
|
id: headingId,
|
|
5055
5127
|
className: (0, _dsn_starter_kit_core.classNames)("dsn-popover-heading", className),
|
|
5128
|
+
tabIndex: -1,
|
|
5056
5129
|
...props,
|
|
5057
5130
|
children
|
|
5058
5131
|
});
|
|
@@ -5085,6 +5158,63 @@ const PopoverFooter = react.default.forwardRef(({ className, children, ...props
|
|
|
5085
5158
|
});
|
|
5086
5159
|
PopoverFooter.displayName = "PopoverFooter";
|
|
5087
5160
|
//#endregion
|
|
5161
|
+
//#region src/PopoverMenu/PopoverMenu.tsx
|
|
5162
|
+
const ITEM_SELECTOR = ".dsn-menu-button__button, .dsn-menu-link__link";
|
|
5163
|
+
/**
|
|
5164
|
+
* PopoverMenu component
|
|
5165
|
+
* Lijst met acties of links in een zwevend paneel, geopend vanuit een
|
|
5166
|
+
* triggerknop.
|
|
5167
|
+
*
|
|
5168
|
+
* Anders dan `Popover` is dit géén dialoogvenster: het paneel heeft geen rol,
|
|
5169
|
+
* de inhoud is een gewone lijst (`<ul role="list">`). Ook bewust geen
|
|
5170
|
+
* `role="menu"`: die rol belooft pijltjesnavigatie en zet screenreaders in
|
|
5171
|
+
* een applicatiemodus. De context komt uit het label van de trigger.
|
|
5172
|
+
*
|
|
5173
|
+
* Het menu sluit zichzelf zodra een item wordt geactiveerd, en zet de focus
|
|
5174
|
+
* dan terug op de trigger.
|
|
5175
|
+
*
|
|
5176
|
+
* @example
|
|
5177
|
+
* ```tsx
|
|
5178
|
+
* const triggerRef = useRef<HTMLButtonElement>(null);
|
|
5179
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
5180
|
+
*
|
|
5181
|
+
* <Button ref={triggerRef} onClick={() => setIsOpen((v) => !v)}>Acties</Button>
|
|
5182
|
+
* <PopoverMenu isOpen={isOpen} onClose={() => setIsOpen(false)} triggerRef={triggerRef}>
|
|
5183
|
+
* <MenuButton onClick={edit}>Bewerken</MenuButton>
|
|
5184
|
+
* <MenuButton onClick={duplicate}>Dupliceren</MenuButton>
|
|
5185
|
+
* </PopoverMenu>
|
|
5186
|
+
* ```
|
|
5187
|
+
*/
|
|
5188
|
+
const PopoverMenu = react.default.forwardRef(({ className, isOpen, onClose, triggerRef, placement = "bottom", iconStart = false, onClick, children, ...props }, ref) => {
|
|
5189
|
+
const internalRef = react.default.useRef(null);
|
|
5190
|
+
const popoverRef = ref ?? internalRef;
|
|
5191
|
+
usePopover({
|
|
5192
|
+
popoverRef,
|
|
5193
|
+
triggerRef,
|
|
5194
|
+
isOpen,
|
|
5195
|
+
onClose,
|
|
5196
|
+
placement
|
|
5197
|
+
});
|
|
5198
|
+
const handleClick = (event) => {
|
|
5199
|
+
onClick?.(event);
|
|
5200
|
+
if (event.target.closest(ITEM_SELECTOR)) onClose?.();
|
|
5201
|
+
};
|
|
5202
|
+
const classes = (0, _dsn_starter_kit_core.classNames)("dsn-popover-menu", `dsn-popover-menu--placement-${placement}`, className);
|
|
5203
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5204
|
+
ref: popoverRef,
|
|
5205
|
+
popover: "auto",
|
|
5206
|
+
className: classes,
|
|
5207
|
+
onClick: handleClick,
|
|
5208
|
+
...props,
|
|
5209
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Menu, {
|
|
5210
|
+
role: "list",
|
|
5211
|
+
iconStart,
|
|
5212
|
+
children
|
|
5213
|
+
})
|
|
5214
|
+
});
|
|
5215
|
+
});
|
|
5216
|
+
PopoverMenu.displayName = "PopoverMenu";
|
|
5217
|
+
//#endregion
|
|
5088
5218
|
//#region src/File/File.tsx
|
|
5089
5219
|
/**
|
|
5090
5220
|
* File component
|
|
@@ -5351,6 +5481,7 @@ exports.PopoverBody = PopoverBody;
|
|
|
5351
5481
|
exports.PopoverFooter = PopoverFooter;
|
|
5352
5482
|
exports.PopoverHeader = PopoverHeader;
|
|
5353
5483
|
exports.PopoverHeading = PopoverHeading;
|
|
5484
|
+
exports.PopoverMenu = PopoverMenu;
|
|
5354
5485
|
exports.PreHeading = PreHeading;
|
|
5355
5486
|
exports.ProgressBar = ProgressBar;
|
|
5356
5487
|
exports.Radio = Radio;
|