@mittwald/flow-react-components 1.5.41 → 1.5.43
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/assets/component-index.json +1 -1
- package/dist/assets/doc-properties.json +1 -1
- package/dist/js/packages/components/src/components/Link/Link.mjs.map +1 -1
- package/dist/js/packages/components/src/lib/controller/overlay/useCloseOverlayConfirmationController.mjs +1 -0
- package/dist/js/packages/components/src/lib/controller/overlay/useCloseOverlayConfirmationController.mjs.map +1 -1
- package/dist/js/packages/components-base/src/overlay/OverlayState.mjs +22 -4
- package/dist/js/packages/components-base/src/overlay/OverlayState.mjs.map +1 -1
- package/dist/types/_bundled/flow-components-base/overlay/OverlayState.d.ts +5 -1
- package/dist/types/components/Link/Link.d.ts +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.mjs","names":["styles","_Fragment","_jsx"],"sources":["../../../../../../../src/components/Link/Link.tsx"],"sourcesContent":["import type {\n ComponentProps,\n ComponentType,\n CSSProperties,\n MouseEvent,\n PropsWithChildren,\n} from \"react\";\nimport { useContext } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport { dynamic, type PropsContext } from \"@/lib/propsContext\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport styles from \"./Link.module.scss\";\nimport clsx from \"clsx\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport {\n type AlphaColor,\n isAlphaColor,\n type PropsWithClassName,\n} from \"@/lib/types/props\";\nimport { linkContext } from \"@/components/Link/context\";\nimport { LinkIcon } from \"@/components/Link/components/LinkIcon\";\nimport { handleLinkClick, useRouter } from \"@react-aria/utils\";\nimport { UiComponentTunnelExit } from \"@/components/UiComponentTunnel/UiComponentTunnelExit\";\nimport { SkeletonTextContent } from \"@/components/SkeletonMode/components/SkeletonTextContent\";\nimport { useSkeletonMode } from \"@/components/SkeletonMode/skeletonModeContext\";\nimport { hasContent } from \"@/components/SkeletonMode/lib/hasContent\";\nimport { containsTextChild } from \"@/lib/react/remote\";\n\nexport interface LinkProps\n extends\n PropsWithChildren
|
|
1
|
+
{"version":3,"file":"Link.mjs","names":["styles","_Fragment","_jsx"],"sources":["../../../../../../../src/components/Link/Link.tsx"],"sourcesContent":["import type {\n ComponentProps,\n ComponentType,\n CSSProperties,\n MouseEvent,\n PropsWithChildren,\n} from \"react\";\nimport { useContext } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport { dynamic, type PropsContext } from \"@/lib/propsContext\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport styles from \"./Link.module.scss\";\nimport clsx from \"clsx\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport {\n type AlphaColor,\n isAlphaColor,\n type PropsWithClassName,\n} from \"@/lib/types/props\";\nimport { linkContext } from \"@/components/Link/context\";\nimport { LinkIcon } from \"@/components/Link/components/LinkIcon\";\nimport { handleLinkClick, useRouter } from \"@react-aria/utils\";\nimport { UiComponentTunnelExit } from \"@/components/UiComponentTunnel/UiComponentTunnelExit\";\nimport { SkeletonTextContent } from \"@/components/SkeletonMode/components/SkeletonTextContent\";\nimport { useSkeletonMode } from \"@/components/SkeletonMode/skeletonModeContext\";\nimport { hasContent } from \"@/components/SkeletonMode/lib/hasContent\";\nimport { containsTextChild } from \"@/lib/react/remote\";\n\nexport interface LinkProps\n extends\n PropsWithChildren<\n Omit<Aria.LinkProps, \"children\" | \"slot\" | \"className\" | \"aria-current\">\n >,\n FlowComponentProps<HTMLAnchorElement>,\n PropsWithClassName {\n /** Whether the link should be styled for being displayed inside a text. */\n inline?: boolean;\n /** An alternative link component. */\n linkComponent?: ComponentType<Omit<ComponentProps<\"a\">, \"ref\">>;\n /** The color of the link. @default \"default\" */\n color?: \"default\" | AlphaColor;\n /** Marks the link as the currently active one, e.g. in a navigation. */\n \"aria-current\"?: string;\n /**\n * The name of the slot the link is placed in. In action groups: `primary` (at\n * the end), `secondary` (before the primary action) or `abort` (at the\n * start).\n */\n slot?: string;\n /** The whiteSpace css value of the element. */\n whiteSpace?: CSSProperties[\"whiteSpace\"];\n /** The size of the element. @default \"m\" */\n size?: \"s\" | \"m\";\n /** @internal */\n unstyled?: boolean;\n}\n\n/** @flr-generate all */\nexport const Link = flowComponent(\"Link\", (props) => {\n const {\n children,\n className,\n inline,\n linkComponent: linkComponentFromProps,\n color = \"default\",\n unstyled = false,\n \"aria-current\": ariaCurrent,\n ref,\n slot: ignoredSlotProp,\n style,\n whiteSpace,\n size = \"m\",\n onClickCapture: onClickCaptureFromProps,\n target,\n download,\n ...rest\n } = props;\n\n const { linkComponent: linkComponentFromContext } = useContext(linkContext);\n const isSkeleton = useSkeletonMode();\n const Link = linkComponentFromProps\n ? (linkComponentFromProps as typeof Aria.Link)\n : props.href && linkComponentFromContext\n ? (linkComponentFromContext as typeof Aria.Link)\n : Aria.Link;\n\n const router = useRouter();\n\n /**\n * An interactive child (e.g. a Button) stops click propagation via React\n * Aria's `usePress`, so the anchor's own `onClick` never runs and navigation\n * falls back to a full page load. Handling it in the capture phase (top-down,\n * before the child) keeps navigation client-side. Only needed for React\n * Aria's `<a>`; custom link components handle navigation themselves.\n */\n const handleClickCapture =\n Link === Aria.Link && props.href\n ? (event: MouseEvent<HTMLAnchorElement>) => {\n onClickCaptureFromProps?.(event);\n if (event.target !== event.currentTarget) {\n handleLinkClick(event, router, props.href, props.routerOptions);\n }\n }\n : onClickCaptureFromProps;\n\n const rootClassName = unstyled\n ? className\n : clsx(\n styles.link,\n inline && styles.inline,\n isAlphaColor(color) && styles[color],\n size === \"s\" && styles[\"size-s\"],\n className,\n );\n\n const propsContext: PropsContext = {\n Icon: {\n tunnel: {\n component: \"Link\",\n id: \"icon\",\n },\n className: styles.icon,\n size: \"s\",\n },\n AlertText: {\n className: styles.alertText,\n },\n AccentBox: { className: styles.accentBox },\n LayoutCard: { className: styles.layoutCard },\n Button: {\n elementType: \"span\",\n className: styles.button,\n size: props.size,\n color: props.color === \"default\" ? undefined : props.color,\n isDisabled: props.isDisabled,\n children: dynamic((buttonProps) => (\n <>\n {buttonProps.children}\n <LinkIcon download={download} target={target} unstyled={unstyled} />\n </>\n )),\n },\n };\n\n const unsupportedTypingsLinkProps = ariaCurrent\n ? ({\n \"aria-current\": true,\n } as Record<string, unknown>)\n : {};\n\n /* Without text of its own — a Link styled as a Button, a Link around a\n LayoutCard — the content follows its own skeleton rules instead of\n becoming a text bar. */\n const hasOnlyElements = hasContent(children) && !containsTextChild(children);\n\n const textBars = (\n <SkeletonTextContent defaultWidth=\"6em\">{children}</SkeletonTextContent>\n );\n\n const content = (\n <PropsContextProvider props={propsContext}>\n {hasOnlyElements ? children : textBars}\n <LinkIcon\n withZeroWidthJoiner\n unstyled={unstyled}\n target={target}\n download={download}\n >\n <UiComponentTunnelExit id={\"icon\"} component={\"Link\"} />\n </LinkIcon>\n </PropsContextProvider>\n );\n\n /* react-aria's Link drops `inert`, and a skeleton needs no anchor. */\n if (isSkeleton) {\n return (\n <span className={rootClassName} style={{ ...style, whiteSpace }} inert>\n {content}\n </span>\n );\n }\n\n return (\n <Link\n {...unsupportedTypingsLinkProps}\n {...rest}\n target={target}\n download={download}\n onClickCapture={handleClickCapture}\n className={rootClassName}\n ref={ref}\n style={{ ...style, whiteSpace }}\n >\n {content}\n </Link>\n );\n});\n\nexport default Link;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,OAAO,cAAc,SAAS,UAAU;CACnD,MAAM,EACJ,UACA,WACA,QACA,eAAe,wBACf,QAAQ,WACR,WAAW,OACX,gBAAgB,aAChB,KACA,MAAM,iBACN,OACA,YACA,OAAO,KACP,gBAAgB,yBAChB,QACA,UACA,GAAG,SACD;CAEJ,MAAM,EAAE,eAAe,6BAA6B,WAAW,WAAW;CAC1E,MAAM,aAAa,gBAAgB;CACnC,MAAM,OAAO,yBACR,yBACD,MAAM,QAAQ,2BACX,2BACD,KAAK;CAEX,MAAM,SAAS,UAAU;;;;;;;;CASzB,MAAM,qBACJ,SAAS,KAAK,QAAQ,MAAM,QACvB,UAAyC;EACxC,0BAA0B,KAAK;EAC/B,IAAI,MAAM,WAAW,MAAM,eACzB,gBAAgB,OAAO,QAAQ,MAAM,MAAM,MAAM,aAAa;CAElE,IACA;CAEN,MAAM,gBAAgB,WAClB,YACA,KACEA,oBAAO,MACP,UAAUA,oBAAO,QACjB,aAAa,KAAK,KAAKA,oBAAO,QAC9B,SAAS,OAAOA,oBAAO,WACvB,SACF;CAEJ,MAAM,eAA6B;EACjC,MAAM;GACJ,QAAQ;IACN,WAAW;IACX,IAAI;GACN;GACA,WAAWA,oBAAO;GAClB,MAAM;EACR;EACA,WAAW,EACT,WAAWA,oBAAO,UACpB;EACA,WAAW,EAAE,WAAWA,oBAAO,UAAU;EACzC,YAAY,EAAE,WAAWA,oBAAO,WAAW;EAC3C,QAAQ;GACN,aAAa;GACb,WAAWA,oBAAO;GAClB,MAAM,MAAM;GACZ,OAAO,MAAM,UAAU,YAAY,KAAA,IAAY,MAAM;GACrD,YAAY,MAAM;GAClB,UAAU,SAAS,gBACjB,qBAAAC,YAAA,EAAA,UAAA,CACG,YAAY,UACb,oBAAC,UAAD;IAAoB;IAAkB;IAAkB;GAAW,CAAA,CACnE,EAAA,CAAA,CACH;EACH;CACF;CAEA,MAAM,8BAA8B,cAC/B,EACC,gBAAgB,KAClB,IACA,CAAC;CAKL,MAAM,kBAAkB,WAAW,QAAQ,KAAK,CAAC,kBAAkB,QAAQ;CAM3E,MAAM,UACJ,qBAAC,sBAAD;EAAsB,OAAO;EAA7B,UAAA,CACG,kBAAkB,WALrBC,oBAAC,qBAAD;GAAqB,cAAa;GAAO;EAA8B,CAKvC,GAC9B,oBAAC,UAAD;GACE,qBAAA;GACU;GACF;GACE;GAEV,UAAA,oBAAC,uBAAD;IAAuB,IAAI;IAAQ,WAAW;GAAS,CAAA;EAC/C,CAAA,CACU;;CAIxB,IAAI,YACF,OACE,oBAAC,QAAD;EAAM,WAAW;EAAe,OAAO;GAAE,GAAG;GAAO;EAAW;EAAG,OAAA;EAC9D,UAAA;CACG,CAAA;CAIV,OACE,oBAAC,MAAD;EACE,GAAI;EACJ,GAAI;EACI;EACE;EACV,gBAAgB;EAChB,WAAW;EACN;EACL,OAAO;GAAE,GAAG;GAAO;EAAW;EAE7B,UAAA;CACG,CAAA;AAEV,CAAC"}
|
|
@@ -13,6 +13,7 @@ var useCloseOverlayConfirmationController = (parentController) => {
|
|
|
13
13
|
});
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
if (showConfirmationModal) confirmationModalController.open();
|
|
16
|
+
else confirmationModalController.close();
|
|
16
17
|
}, [confirmationModalController, showConfirmationModal]);
|
|
17
18
|
if (parentController.confirmClose) return {
|
|
18
19
|
controller: confirmationModalController,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCloseOverlayConfirmationController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/useCloseOverlayConfirmationController.ts"],"sourcesContent":["import type { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport { useModalController } from \"@/lib/controller/overlay/useModalController\";\nimport { useEffect } from \"react\";\n\nexport const useCloseOverlayConfirmationController = (\n parentController: OverlayController,\n) => {\n const showConfirmationModal = parentController.useShowConfirmationModal();\n\n const confirmationModalController = useModalController({\n reuseControllerFromContext: false,\n onClose: () => {\n if (showConfirmationModal) {\n parentController.cancelConfirmation();\n }\n },\n });\n\n useEffect(() => {\n if (showConfirmationModal) {\n confirmationModalController.open();\n }\n }, [confirmationModalController, showConfirmationModal]);\n\n if (parentController.confirmClose) {\n return {\n controller: confirmationModalController,\n cancel: () => parentController.cancelConfirmation(),\n confirm: () => {\n parentController.confirmClose();\n parentController.close();\n },\n } as const;\n }\n};\n"],"mappings":";;;;;AAIA,IAAa,yCACX,qBACG;CACH,MAAM,wBAAwB,iBAAiB,yBAAyB;CAExE,MAAM,8BAA8B,mBAAmB;EACrD,4BAA4B;EAC5B,eAAe;GACb,IAAI,uBACF,iBAAiB,mBAAmB;EAExC;CACF,CAAC;CAED,gBAAgB;EACd,IAAI,uBACF,4BAA4B,KAAK;
|
|
1
|
+
{"version":3,"file":"useCloseOverlayConfirmationController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/useCloseOverlayConfirmationController.ts"],"sourcesContent":["import type { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport { useModalController } from \"@/lib/controller/overlay/useModalController\";\nimport { useEffect } from \"react\";\n\nexport const useCloseOverlayConfirmationController = (\n parentController: OverlayController,\n) => {\n const showConfirmationModal = parentController.useShowConfirmationModal();\n\n const confirmationModalController = useModalController({\n reuseControllerFromContext: false,\n onClose: () => {\n if (showConfirmationModal) {\n parentController.cancelConfirmation();\n }\n },\n });\n\n useEffect(() => {\n if (showConfirmationModal) {\n confirmationModalController.open();\n } else {\n confirmationModalController.close();\n }\n }, [confirmationModalController, showConfirmationModal]);\n\n if (parentController.confirmClose) {\n return {\n controller: confirmationModalController,\n cancel: () => parentController.cancelConfirmation(),\n confirm: () => {\n parentController.confirmClose();\n parentController.close();\n },\n } as const;\n }\n};\n"],"mappings":";;;;;AAIA,IAAa,yCACX,qBACG;CACH,MAAM,wBAAwB,iBAAiB,yBAAyB;CAExE,MAAM,8BAA8B,mBAAmB;EACrD,4BAA4B;EAC5B,eAAe;GACb,IAAI,uBACF,iBAAiB,mBAAmB;EAExC;CACF,CAAC;CAED,gBAAgB;EACd,IAAI,uBACF,4BAA4B,KAAK;OAEjC,4BAA4B,MAAM;CAEtC,GAAG,CAAC,6BAA6B,qBAAqB,CAAC;CAEvD,IAAI,iBAAiB,cACnB,OAAO;EACL,YAAY;EACZ,cAAc,iBAAiB,mBAAmB;EAClD,eAAe;GACb,iBAAiB,aAAa;GAC9B,iBAAiB,MAAM;EACzB;CACF;AAEJ"}
|
|
@@ -71,11 +71,20 @@ var OverlayState = class {
|
|
|
71
71
|
* @internal Bindings call it from their lifecycle.
|
|
72
72
|
*/
|
|
73
73
|
setConfirmOnCloseSource(source, confirmOnClose) {
|
|
74
|
-
runInAction(() =>
|
|
74
|
+
runInAction(() => {
|
|
75
|
+
this.confirmOnCloseSources.set(source, confirmOnClose);
|
|
76
|
+
this.withdrawUnneededConfirmation();
|
|
77
|
+
});
|
|
75
78
|
}
|
|
76
79
|
/** @internal Bindings call it from their lifecycle. */
|
|
77
80
|
removeConfirmOnCloseSource(source) {
|
|
78
|
-
runInAction(() =>
|
|
81
|
+
runInAction(() => {
|
|
82
|
+
this.confirmOnCloseSources.delete(source);
|
|
83
|
+
this.withdrawUnneededConfirmation();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
withdrawUnneededConfirmation() {
|
|
87
|
+
if (!this.confirmOnCloseEnabled) this.showConfirmationModal = false;
|
|
79
88
|
}
|
|
80
89
|
addOpenStateHandler(handler, handlersSet) {
|
|
81
90
|
handlersSet.add(handler);
|
|
@@ -125,10 +134,19 @@ var OverlayState = class {
|
|
|
125
134
|
/**
|
|
126
135
|
* Sets the open state without running any handler. Use it to mirror a
|
|
127
136
|
* controlled `isOpen` prop, whose change comes from the consumer – notifying
|
|
128
|
-
* them of their own state would echo it back.
|
|
137
|
+
* them of their own state would echo it back. Closing this way drops a
|
|
138
|
+
* pending close confirmation as well.
|
|
129
139
|
*/
|
|
130
140
|
syncOpen(toOpen) {
|
|
141
|
+
this.assignOpenState(toOpen);
|
|
142
|
+
}
|
|
143
|
+
/** A closed overlay has no close left to confirm. */
|
|
144
|
+
assignOpenState(toOpen) {
|
|
131
145
|
this.isOpen = toOpen;
|
|
146
|
+
if (!toOpen) {
|
|
147
|
+
this.showConfirmationModal = false;
|
|
148
|
+
this.closeIsConfirmed = false;
|
|
149
|
+
}
|
|
132
150
|
}
|
|
133
151
|
applyOpenState(toOpen, options) {
|
|
134
152
|
const { bypassConfirmation = false } = options ?? {};
|
|
@@ -144,7 +162,7 @@ var OverlayState = class {
|
|
|
144
162
|
if (toOpen) aborted = this.executeOnOpen();
|
|
145
163
|
else aborted = this.executeOnClose();
|
|
146
164
|
if (!aborted) aborted = this.executeOnOpenChange(toOpen);
|
|
147
|
-
if (!aborted) this.
|
|
165
|
+
if (!aborted) this.assignOpenState(toOpen);
|
|
148
166
|
}
|
|
149
167
|
setIsContentSuspended(to) {
|
|
150
168
|
this.isContentSuspended = to;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OverlayState.mjs","names":[],"sources":["../../../../../../../components-base/src/overlay/OverlayState.ts"],"sourcesContent":["import {\n action,\n computed,\n makeObservable,\n observable,\n runInAction,\n} from \"mobx\";\n\nexport type OverlayOpenHandler = () => unknown;\nexport type OverlayCloseHandler = () => unknown;\nexport type OverlayOpenStateHandler = (isOpen: boolean) => unknown;\nexport type AnyOverlayOpenStateHandler =\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler;\n\nexport type DisposerFn = () => void;\n\nexport interface OverlayCloseOptions {\n /** Close without asking, even when the overlay requires confirmation. */\n bypassConfirmation?: boolean;\n}\n\nexport interface OverlayStateOptions {\n isDefaultOpen?: boolean;\n /**\n * Whether closing the overlay must be confirmed while no source has an\n * opinion (`setConfirmOnCloseSource`).\n */\n confirmOnClose?: boolean;\n}\n\n/**\n * Whether an overlay is open, and whether closing it has to be confirmed first.\n * Each binding adds its subscription and its lifecycle: React's\n * `OverlayController` subclasses it, Vue's adapter wraps it in refs.\n *\n * `TCloseOptions` lets a binding pass more on a close than the state reads —\n * React's `overlay`, resolved by `Action` before the close arrives here.\n */\nexport class OverlayState<\n TCloseOptions extends OverlayCloseOptions = OverlayCloseOptions,\n> {\n public isOpen = false;\n public isContentSuspended = false;\n private onOpenHandlers = new Set<OverlayOpenHandler>();\n private onCloseHandlers = new Set<OverlayCloseHandler>();\n private onOpenChangeHandlers = new Set<OverlayOpenStateHandler>();\n\n public showConfirmationModal = false;\n public closeIsConfirmed = false;\n private readonly confirmOnCloseFromOptions: boolean;\n /**\n * Every mounted component that has an opinion on close confirmation\n * contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop\n * and a `Form` tracking its dirty state. Combining them instead of assigning\n * a single flag keeps them from overwriting each other.\n */\n private confirmOnCloseSources = observable.map<object, boolean>();\n /**\n * Active grants that allow closing without a confirmation. Each entry is\n * scoped to an ongoing operation that legitimately closes the overlay – e.g.\n * a `Form` submit – and is dropped again when that operation has finished, so\n * an operation that does _not_ close the overlay leaves the confirmation\n * armed.\n */\n private closeWithoutConfirmationGrants = new Set<object>();\n /**\n * The open state a `setOpen` call is currently applying. Handlers run before\n * `isOpen` is assigned, so a handler that calls `setOpen` again would not be\n * caught by the equality check at the top and would recurse.\n */\n private openStateInFlight: boolean | undefined;\n\n public constructor(options: OverlayStateOptions = {}) {\n makeObservable(this, {\n isOpen: observable,\n isContentSuspended: observable,\n showConfirmationModal: observable,\n confirmOnCloseEnabled: computed,\n open: action.bound,\n close: action.bound,\n toggle: action.bound,\n setOpen: action.bound,\n syncOpen: action.bound,\n setIsContentSuspended: action.bound,\n confirmClose: action.bound,\n cancelConfirmation: action.bound,\n });\n const { isDefaultOpen = false, confirmOnClose = false } = options;\n this.isOpen = isDefaultOpen;\n this.confirmOnCloseFromOptions = confirmOnClose;\n }\n\n /** Whether closing this overlay currently requires a confirmation. */\n public get confirmOnCloseEnabled(): boolean {\n if (this.confirmOnCloseSources.size === 0) {\n return this.confirmOnCloseFromOptions;\n }\n return Array.from(this.confirmOnCloseSources.values()).some(Boolean);\n }\n\n /**\n * Sets the opinion of one source – any object the caller keeps – on close\n * confirmation. Remove the source again when its owner goes away.\n *\n * @internal Bindings call it from their lifecycle.\n */\n public setConfirmOnCloseSource(source: object, confirmOnClose: boolean) {\n runInAction(() => this.confirmOnCloseSources.set(source, confirmOnClose));\n }\n\n /** @internal Bindings call it from their lifecycle. */\n public removeConfirmOnCloseSource(source: object) {\n runInAction(() => this.confirmOnCloseSources.delete(source));\n }\n\n private addOpenStateHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T,\n handlersSet: Set<T>,\n ): DisposerFn {\n handlersSet.add(handler);\n return () => {\n handlersSet.delete(handler);\n };\n }\n\n private executeHandlers(\n isOpen: boolean,\n handlers: Set<\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler\n >,\n ): boolean {\n const handlerResult = Array.from(handlers).map((handler) =>\n handler(isOpen),\n );\n return handlerResult.some((result) => result === false);\n }\n\n private executeOnClose(): boolean {\n return this.executeHandlers(false, this.onCloseHandlers);\n }\n\n private executeOnOpen(): boolean {\n return this.executeHandlers(true, this.onOpenHandlers);\n }\n\n private executeOnOpenChange(isOpen: boolean): boolean {\n return this.executeHandlers(isOpen, this.onOpenChangeHandlers);\n }\n\n public addOnClose(handler: OverlayCloseHandler) {\n return this.addOpenStateHandler(handler, this.onCloseHandlers);\n }\n\n public addOnOpen(handler: OverlayOpenHandler) {\n return this.addOpenStateHandler(handler, this.onOpenHandlers);\n }\n\n public addOnOpenChange(handler: OverlayOpenStateHandler) {\n return this.addOpenStateHandler(handler, this.onOpenChangeHandlers);\n }\n\n public open(): void {\n this.setOpen(true);\n }\n\n public close(options?: TCloseOptions): void {\n this.setOpen(false, options);\n }\n\n public toggle(): void {\n this.setOpen(!this.isOpen);\n }\n\n public setOpen(toOpen: boolean, options?: TCloseOptions): void {\n if (this.isOpen === toOpen || this.openStateInFlight === toOpen) {\n return;\n }\n\n this.openStateInFlight = toOpen;\n try {\n this.applyOpenState(toOpen, options);\n } finally {\n this.openStateInFlight = undefined;\n }\n }\n\n /**\n * Sets the open state without running any handler. Use it to mirror a\n * controlled `isOpen` prop, whose change comes from the consumer – notifying\n * them of their own state would echo it back.\n */\n public syncOpen(toOpen: boolean): void {\n this.isOpen = toOpen;\n }\n\n private applyOpenState(toOpen: boolean, options?: TCloseOptions): void {\n const { bypassConfirmation = false } = options ?? {};\n\n if (toOpen === false) {\n // The confirmation is a one-shot permission for exactly this close\n // attempt – consume it here instead of only when a close succeeds, so it\n // cannot survive an aborted close and disarm later attempts.\n const closeIsConfirmed = this.closeIsConfirmed;\n this.closeIsConfirmed = false;\n\n if (\n this.confirmOnCloseEnabled &&\n !closeIsConfirmed &&\n this.closeWithoutConfirmationGrants.size === 0 &&\n !bypassConfirmation\n ) {\n this.showConfirmationModal = true;\n return;\n }\n }\n\n let aborted: boolean;\n if (toOpen) {\n aborted = this.executeOnOpen();\n } else {\n aborted = this.executeOnClose();\n }\n if (!aborted) {\n aborted = this.executeOnOpenChange(toOpen);\n }\n\n if (!aborted) {\n this.isOpen = toOpen;\n }\n }\n\n public setIsContentSuspended(to: boolean): void {\n this.isContentSuspended = to;\n }\n\n /**\n * Allows closing this overlay without a confirmation until the returned\n * disposer is called. Use it around an operation that may legitimately close\n * the overlay – e.g. a `Form` submit, where a \"discard unsaved changes?\"\n * prompt would be nonsense – and dispose it as soon as that operation has\n * finished. An operation that ends without closing the overlay therefore\n * leaves the confirmation armed (#2775).\n */\n public grantCloseWithoutConfirmation(): DisposerFn {\n const grant = {};\n this.closeWithoutConfirmationGrants.add(grant);\n return () => {\n this.closeWithoutConfirmationGrants.delete(grant);\n };\n }\n\n public confirmClose(): void {\n this.closeIsConfirmed = true;\n this.showConfirmationModal = false;\n }\n\n public cancelConfirmation(): void {\n this.showConfirmationModal = false;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OverlayState.mjs","names":[],"sources":["../../../../../../../components-base/src/overlay/OverlayState.ts"],"sourcesContent":["import {\n action,\n computed,\n makeObservable,\n observable,\n runInAction,\n} from \"mobx\";\n\nexport type OverlayOpenHandler = () => unknown;\nexport type OverlayCloseHandler = () => unknown;\nexport type OverlayOpenStateHandler = (isOpen: boolean) => unknown;\nexport type AnyOverlayOpenStateHandler =\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler;\n\nexport type DisposerFn = () => void;\n\nexport interface OverlayCloseOptions {\n /** Close without asking, even when the overlay requires confirmation. */\n bypassConfirmation?: boolean;\n}\n\nexport interface OverlayStateOptions {\n isDefaultOpen?: boolean;\n /**\n * Whether closing the overlay must be confirmed while no source has an\n * opinion (`setConfirmOnCloseSource`).\n */\n confirmOnClose?: boolean;\n}\n\n/**\n * Whether an overlay is open, and whether closing it has to be confirmed first.\n * Each binding adds its subscription and its lifecycle: React's\n * `OverlayController` subclasses it, Vue's adapter wraps it in refs.\n *\n * `TCloseOptions` lets a binding pass more on a close than the state reads —\n * React's `overlay`, resolved by `Action` before the close arrives here.\n */\nexport class OverlayState<\n TCloseOptions extends OverlayCloseOptions = OverlayCloseOptions,\n> {\n public isOpen = false;\n public isContentSuspended = false;\n private onOpenHandlers = new Set<OverlayOpenHandler>();\n private onCloseHandlers = new Set<OverlayCloseHandler>();\n private onOpenChangeHandlers = new Set<OverlayOpenStateHandler>();\n\n public showConfirmationModal = false;\n public closeIsConfirmed = false;\n private readonly confirmOnCloseFromOptions: boolean;\n /**\n * Every mounted component that has an opinion on close confirmation\n * contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop\n * and a `Form` tracking its dirty state. Combining them instead of assigning\n * a single flag keeps them from overwriting each other.\n */\n private confirmOnCloseSources = observable.map<object, boolean>();\n /**\n * Active grants that allow closing without a confirmation. Each entry is\n * scoped to an ongoing operation that legitimately closes the overlay – e.g.\n * a `Form` submit – and is dropped again when that operation has finished, so\n * an operation that does _not_ close the overlay leaves the confirmation\n * armed.\n */\n private closeWithoutConfirmationGrants = new Set<object>();\n /**\n * The open state a `setOpen` call is currently applying. Handlers run before\n * `isOpen` is assigned, so a handler that calls `setOpen` again would not be\n * caught by the equality check at the top and would recurse.\n */\n private openStateInFlight: boolean | undefined;\n\n public constructor(options: OverlayStateOptions = {}) {\n makeObservable(this, {\n isOpen: observable,\n isContentSuspended: observable,\n showConfirmationModal: observable,\n confirmOnCloseEnabled: computed,\n open: action.bound,\n close: action.bound,\n toggle: action.bound,\n setOpen: action.bound,\n syncOpen: action.bound,\n setIsContentSuspended: action.bound,\n confirmClose: action.bound,\n cancelConfirmation: action.bound,\n });\n const { isDefaultOpen = false, confirmOnClose = false } = options;\n this.isOpen = isDefaultOpen;\n this.confirmOnCloseFromOptions = confirmOnClose;\n }\n\n /** Whether closing this overlay currently requires a confirmation. */\n public get confirmOnCloseEnabled(): boolean {\n if (this.confirmOnCloseSources.size === 0) {\n return this.confirmOnCloseFromOptions;\n }\n return Array.from(this.confirmOnCloseSources.values()).some(Boolean);\n }\n\n /**\n * Sets the opinion of one source – any object the caller keeps – on close\n * confirmation. Remove the source again when its owner goes away.\n *\n * @internal Bindings call it from their lifecycle.\n */\n public setConfirmOnCloseSource(source: object, confirmOnClose: boolean) {\n runInAction(() => {\n this.confirmOnCloseSources.set(source, confirmOnClose);\n this.withdrawUnneededConfirmation();\n });\n }\n\n /** @internal Bindings call it from their lifecycle. */\n public removeConfirmOnCloseSource(source: object) {\n runInAction(() => {\n this.confirmOnCloseSources.delete(source);\n this.withdrawUnneededConfirmation();\n });\n }\n\n private withdrawUnneededConfirmation() {\n if (!this.confirmOnCloseEnabled) {\n this.showConfirmationModal = false;\n }\n }\n\n private addOpenStateHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T,\n handlersSet: Set<T>,\n ): DisposerFn {\n handlersSet.add(handler);\n return () => {\n handlersSet.delete(handler);\n };\n }\n\n private executeHandlers(\n isOpen: boolean,\n handlers: Set<\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler\n >,\n ): boolean {\n const handlerResult = Array.from(handlers).map((handler) =>\n handler(isOpen),\n );\n return handlerResult.some((result) => result === false);\n }\n\n private executeOnClose(): boolean {\n return this.executeHandlers(false, this.onCloseHandlers);\n }\n\n private executeOnOpen(): boolean {\n return this.executeHandlers(true, this.onOpenHandlers);\n }\n\n private executeOnOpenChange(isOpen: boolean): boolean {\n return this.executeHandlers(isOpen, this.onOpenChangeHandlers);\n }\n\n public addOnClose(handler: OverlayCloseHandler) {\n return this.addOpenStateHandler(handler, this.onCloseHandlers);\n }\n\n public addOnOpen(handler: OverlayOpenHandler) {\n return this.addOpenStateHandler(handler, this.onOpenHandlers);\n }\n\n public addOnOpenChange(handler: OverlayOpenStateHandler) {\n return this.addOpenStateHandler(handler, this.onOpenChangeHandlers);\n }\n\n public open(): void {\n this.setOpen(true);\n }\n\n public close(options?: TCloseOptions): void {\n this.setOpen(false, options);\n }\n\n public toggle(): void {\n this.setOpen(!this.isOpen);\n }\n\n public setOpen(toOpen: boolean, options?: TCloseOptions): void {\n if (this.isOpen === toOpen || this.openStateInFlight === toOpen) {\n return;\n }\n\n this.openStateInFlight = toOpen;\n try {\n this.applyOpenState(toOpen, options);\n } finally {\n this.openStateInFlight = undefined;\n }\n }\n\n /**\n * Sets the open state without running any handler. Use it to mirror a\n * controlled `isOpen` prop, whose change comes from the consumer – notifying\n * them of their own state would echo it back. Closing this way drops a\n * pending close confirmation as well.\n */\n public syncOpen(toOpen: boolean): void {\n this.assignOpenState(toOpen);\n }\n\n /** A closed overlay has no close left to confirm. */\n private assignOpenState(toOpen: boolean): void {\n this.isOpen = toOpen;\n if (!toOpen) {\n this.showConfirmationModal = false;\n this.closeIsConfirmed = false;\n }\n }\n\n private applyOpenState(toOpen: boolean, options?: TCloseOptions): void {\n const { bypassConfirmation = false } = options ?? {};\n\n if (toOpen === false) {\n // The confirmation is a one-shot permission for exactly this close\n // attempt – consume it here instead of only when a close succeeds, so it\n // cannot survive an aborted close and disarm later attempts.\n const closeIsConfirmed = this.closeIsConfirmed;\n this.closeIsConfirmed = false;\n\n if (\n this.confirmOnCloseEnabled &&\n !closeIsConfirmed &&\n this.closeWithoutConfirmationGrants.size === 0 &&\n !bypassConfirmation\n ) {\n this.showConfirmationModal = true;\n return;\n }\n }\n\n let aborted: boolean;\n if (toOpen) {\n aborted = this.executeOnOpen();\n } else {\n aborted = this.executeOnClose();\n }\n if (!aborted) {\n aborted = this.executeOnOpenChange(toOpen);\n }\n\n if (!aborted) {\n this.assignOpenState(toOpen);\n }\n }\n\n public setIsContentSuspended(to: boolean): void {\n this.isContentSuspended = to;\n }\n\n /**\n * Allows closing this overlay without a confirmation until the returned\n * disposer is called. Use it around an operation that may legitimately close\n * the overlay – e.g. a `Form` submit, where a \"discard unsaved changes?\"\n * prompt would be nonsense – and dispose it as soon as that operation has\n * finished. An operation that ends without closing the overlay therefore\n * leaves the confirmation armed (#2775).\n */\n public grantCloseWithoutConfirmation(): DisposerFn {\n const grant = {};\n this.closeWithoutConfirmationGrants.add(grant);\n return () => {\n this.closeWithoutConfirmationGrants.delete(grant);\n };\n }\n\n public confirmClose(): void {\n this.closeIsConfirmed = true;\n this.showConfirmationModal = false;\n }\n\n public cancelConfirmation(): void {\n this.showConfirmationModal = false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -56,6 +56,7 @@ export declare class OverlayState<TCloseOptions extends OverlayCloseOptions = Ov
|
|
|
56
56
|
constructor(options?: OverlayStateOptions);
|
|
57
57
|
/** Whether closing this overlay currently requires a confirmation. */
|
|
58
58
|
get confirmOnCloseEnabled(): boolean;
|
|
59
|
+
private withdrawUnneededConfirmation;
|
|
59
60
|
private addOpenStateHandler;
|
|
60
61
|
private executeHandlers;
|
|
61
62
|
private executeOnClose;
|
|
@@ -71,9 +72,12 @@ export declare class OverlayState<TCloseOptions extends OverlayCloseOptions = Ov
|
|
|
71
72
|
/**
|
|
72
73
|
* Sets the open state without running any handler. Use it to mirror a
|
|
73
74
|
* controlled `isOpen` prop, whose change comes from the consumer – notifying
|
|
74
|
-
* them of their own state would echo it back.
|
|
75
|
+
* them of their own state would echo it back. Closing this way drops a
|
|
76
|
+
* pending close confirmation as well.
|
|
75
77
|
*/
|
|
76
78
|
syncOpen(toOpen: boolean): void;
|
|
79
|
+
/** A closed overlay has no close left to confirm. */
|
|
80
|
+
private assignOpenState;
|
|
77
81
|
private applyOpenState;
|
|
78
82
|
setIsContentSuspended(to: boolean): void;
|
|
79
83
|
/**
|
|
@@ -2,7 +2,7 @@ import { ComponentProps, ComponentType, CSSProperties, PropsWithChildren } from
|
|
|
2
2
|
import { FlowComponentProps } from '../../lib/componentFactory/flowComponent';
|
|
3
3
|
import { AlphaColor, PropsWithClassName } from '../../lib/types/props';
|
|
4
4
|
import * as Aria from "react-aria-components";
|
|
5
|
-
export interface LinkProps extends PropsWithChildren<Omit<Aria.LinkProps, "children" | "slot" | "className">>, FlowComponentProps<HTMLAnchorElement>, PropsWithClassName {
|
|
5
|
+
export interface LinkProps extends PropsWithChildren<Omit<Aria.LinkProps, "children" | "slot" | "className" | "aria-current">>, FlowComponentProps<HTMLAnchorElement>, PropsWithClassName {
|
|
6
6
|
/** Whether the link should be styled for being displayed inside a text. */
|
|
7
7
|
inline?: boolean;
|
|
8
8
|
/** An alternative link component. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mittwald/flow-react-components",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A React implementation of Flow, mittwald’s design system",
|
|
6
6
|
"homepage": "https://flow.mittwald.de",
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"@internationalized/string-compiler": "^3.4.1",
|
|
85
85
|
"@lezer/common": "^1.5.2",
|
|
86
86
|
"@lezer/highlight": "^1.2.3",
|
|
87
|
-
"@mittwald/flow-icons": "^1.5.
|
|
87
|
+
"@mittwald/flow-icons": "^1.5.43",
|
|
88
88
|
"@mittwald/password-tools-js": "^3.0.0",
|
|
89
|
-
"@mittwald/react-tunnel": "^1.5.
|
|
89
|
+
"@mittwald/react-tunnel": "^1.5.43",
|
|
90
90
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
91
91
|
"@react-aria/form": "^3.2.1",
|
|
92
92
|
"@react-aria/i18n": "^3.13.1",
|
|
@@ -139,13 +139,13 @@
|
|
|
139
139
|
"@internationalized/date": "^3.12.3",
|
|
140
140
|
"@lezer/generator": "^1.8.0",
|
|
141
141
|
"@lezer/lr": "^1.4.10",
|
|
142
|
-
"@mittwald/flow-components-base": "1.5.
|
|
143
|
-
"@mittwald/flow-core": "1.5.
|
|
144
|
-
"@mittwald/flow-design-tokens": "1.5.
|
|
145
|
-
"@mittwald/flow-icons-base": "1.5.
|
|
142
|
+
"@mittwald/flow-components-base": "1.5.43",
|
|
143
|
+
"@mittwald/flow-core": "1.5.43",
|
|
144
|
+
"@mittwald/flow-design-tokens": "1.5.43",
|
|
145
|
+
"@mittwald/flow-icons-base": "1.5.43",
|
|
146
146
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
147
147
|
"@mittwald/remote-dom-react": "1.2.2-mittwald.10",
|
|
148
|
-
"@mittwald/typescript-config": "1.5.
|
|
148
|
+
"@mittwald/typescript-config": "1.5.43",
|
|
149
149
|
"@nx/storybook": "^22.7.6",
|
|
150
150
|
"@storybook/addon-a11y": "^10.5.10",
|
|
151
151
|
"@storybook/addon-actions": "^9.0.8",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
},
|
|
200
200
|
"peerDependencies": {
|
|
201
201
|
"@internationalized/date": "^3.12.2",
|
|
202
|
-
"@mittwald/flow-icons-pro": "1.5.
|
|
202
|
+
"@mittwald/flow-icons-pro": "1.5.43",
|
|
203
203
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
204
204
|
"next": "^16.2.3",
|
|
205
205
|
"react": "^19.2.0",
|
|
@@ -223,5 +223,5 @@
|
|
|
223
223
|
"browserslist": [
|
|
224
224
|
"baseline widely available"
|
|
225
225
|
],
|
|
226
|
-
"gitHead": "
|
|
226
|
+
"gitHead": "1674f81f415a6800a14dd2e535a76c1442c1347b"
|
|
227
227
|
}
|