@mittwald/flow-react-components 1.6.0-next.37 → 1.6.0-next.39
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/Action/models/ActionState.mjs +2 -2
- package/dist/js/packages/components/src/components/Calendar/components/RangeCalendar/helpers/useCalendarDateRangePresets.mjs +1 -1
- package/dist/js/packages/components/src/components/Link/Link.mjs.map +1 -1
- package/dist/js/packages/components/src/components/List/model/ListViewMode.mjs +2 -2
- package/dist/js/packages/components/src/components/List/model/ReactTable.mjs +2 -2
- package/dist/js/packages/components/src/components/List/model/loading/IncrementalLoaderState.mjs +2 -2
- package/dist/js/packages/components/src/components/Table/components/TableCell/TableCell.mjs +5 -12
- package/dist/js/packages/components/src/components/Table/components/TableCell/TableCell.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs +4 -2
- package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Table/components/TableHeader/TableHeader.mjs +7 -1
- package/dist/js/packages/components/src/components/Table/components/TableHeader/TableHeader.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Table/components/TableHeader/context.mjs +14 -0
- package/dist/js/packages/components/src/components/Table/components/TableHeader/context.mjs.map +1 -0
- package/dist/js/packages/components/src/lib/controller/overlay/OverlayController.mjs +10 -158
- package/dist/js/packages/components/src/lib/controller/overlay/OverlayController.mjs.map +1 -1
- package/dist/js/packages/components-base/src/index.mjs +2 -1
- package/dist/js/packages/components-base/src/overlay/OverlayState.mjs +178 -0
- package/dist/js/packages/components-base/src/overlay/OverlayState.mjs.map +1 -0
- package/dist/types/_bundled/flow-components-base/index.d.ts +1 -0
- package/dist/types/_bundled/flow-components-base/overlay/OverlayState.d.ts +90 -0
- package/dist/types/components/Link/Link.d.ts +1 -1
- package/dist/types/components/Table/components/TableCell/TableCell.d.ts +4 -1
- package/dist/types/components/Table/components/TableHeader/context.d.ts +6 -0
- package/dist/types/lib/controller/overlay/OverlayController.d.ts +8 -74
- package/package.json +10 -10
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
/* */
|
|
3
|
+
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
|
4
|
+
//#region ../components-base/src/overlay/OverlayState.ts
|
|
5
|
+
/**
|
|
6
|
+
* Whether an overlay is open, and whether closing it has to be confirmed first.
|
|
7
|
+
* Each binding adds its subscription and its lifecycle: React's
|
|
8
|
+
* `OverlayController` subclasses it, Vue's adapter wraps it in refs.
|
|
9
|
+
*
|
|
10
|
+
* `TCloseOptions` lets a binding pass more on a close than the state reads —
|
|
11
|
+
* React's `overlay`, resolved by `Action` before the close arrives here.
|
|
12
|
+
*/
|
|
13
|
+
var OverlayState = class {
|
|
14
|
+
isOpen = false;
|
|
15
|
+
isContentSuspended = false;
|
|
16
|
+
onOpenHandlers = /* @__PURE__ */ new Set();
|
|
17
|
+
onCloseHandlers = /* @__PURE__ */ new Set();
|
|
18
|
+
onOpenChangeHandlers = /* @__PURE__ */ new Set();
|
|
19
|
+
showConfirmationModal = false;
|
|
20
|
+
closeIsConfirmed = false;
|
|
21
|
+
confirmOnCloseFromOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Every mounted component that has an opinion on close confirmation
|
|
24
|
+
* contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop
|
|
25
|
+
* and a `Form` tracking its dirty state. Combining them instead of assigning
|
|
26
|
+
* a single flag keeps them from overwriting each other.
|
|
27
|
+
*/
|
|
28
|
+
confirmOnCloseSources = observable.map();
|
|
29
|
+
/**
|
|
30
|
+
* Active grants that allow closing without a confirmation. Each entry is
|
|
31
|
+
* scoped to an ongoing operation that legitimately closes the overlay – e.g.
|
|
32
|
+
* a `Form` submit – and is dropped again when that operation has finished, so
|
|
33
|
+
* an operation that does _not_ close the overlay leaves the confirmation
|
|
34
|
+
* armed.
|
|
35
|
+
*/
|
|
36
|
+
closeWithoutConfirmationGrants = /* @__PURE__ */ new Set();
|
|
37
|
+
/**
|
|
38
|
+
* The open state a `setOpen` call is currently applying. Handlers run before
|
|
39
|
+
* `isOpen` is assigned, so a handler that calls `setOpen` again would not be
|
|
40
|
+
* caught by the equality check at the top and would recurse.
|
|
41
|
+
*/
|
|
42
|
+
openStateInFlight;
|
|
43
|
+
constructor(options = {}) {
|
|
44
|
+
makeObservable(this, {
|
|
45
|
+
isOpen: observable,
|
|
46
|
+
isContentSuspended: observable,
|
|
47
|
+
showConfirmationModal: observable,
|
|
48
|
+
confirmOnCloseEnabled: computed,
|
|
49
|
+
open: action.bound,
|
|
50
|
+
close: action.bound,
|
|
51
|
+
toggle: action.bound,
|
|
52
|
+
setOpen: action.bound,
|
|
53
|
+
syncOpen: action.bound,
|
|
54
|
+
setIsContentSuspended: action.bound,
|
|
55
|
+
confirmClose: action.bound,
|
|
56
|
+
cancelConfirmation: action.bound
|
|
57
|
+
});
|
|
58
|
+
const { isDefaultOpen = false, confirmOnClose = false } = options;
|
|
59
|
+
this.isOpen = isDefaultOpen;
|
|
60
|
+
this.confirmOnCloseFromOptions = confirmOnClose;
|
|
61
|
+
}
|
|
62
|
+
/** Whether closing this overlay currently requires a confirmation. */
|
|
63
|
+
get confirmOnCloseEnabled() {
|
|
64
|
+
if (this.confirmOnCloseSources.size === 0) return this.confirmOnCloseFromOptions;
|
|
65
|
+
return Array.from(this.confirmOnCloseSources.values()).some(Boolean);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets the opinion of one source – any object the caller keeps – on close
|
|
69
|
+
* confirmation. Remove the source again when its owner goes away.
|
|
70
|
+
*
|
|
71
|
+
* @internal Bindings call it from their lifecycle.
|
|
72
|
+
*/
|
|
73
|
+
setConfirmOnCloseSource(source, confirmOnClose) {
|
|
74
|
+
runInAction(() => this.confirmOnCloseSources.set(source, confirmOnClose));
|
|
75
|
+
}
|
|
76
|
+
/** @internal Bindings call it from their lifecycle. */
|
|
77
|
+
removeConfirmOnCloseSource(source) {
|
|
78
|
+
runInAction(() => this.confirmOnCloseSources.delete(source));
|
|
79
|
+
}
|
|
80
|
+
addOpenStateHandler(handler, handlersSet) {
|
|
81
|
+
handlersSet.add(handler);
|
|
82
|
+
return () => {
|
|
83
|
+
handlersSet.delete(handler);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
executeHandlers(isOpen, handlers) {
|
|
87
|
+
return Array.from(handlers).map((handler) => handler(isOpen)).some((result) => result === false);
|
|
88
|
+
}
|
|
89
|
+
executeOnClose() {
|
|
90
|
+
return this.executeHandlers(false, this.onCloseHandlers);
|
|
91
|
+
}
|
|
92
|
+
executeOnOpen() {
|
|
93
|
+
return this.executeHandlers(true, this.onOpenHandlers);
|
|
94
|
+
}
|
|
95
|
+
executeOnOpenChange(isOpen) {
|
|
96
|
+
return this.executeHandlers(isOpen, this.onOpenChangeHandlers);
|
|
97
|
+
}
|
|
98
|
+
addOnClose(handler) {
|
|
99
|
+
return this.addOpenStateHandler(handler, this.onCloseHandlers);
|
|
100
|
+
}
|
|
101
|
+
addOnOpen(handler) {
|
|
102
|
+
return this.addOpenStateHandler(handler, this.onOpenHandlers);
|
|
103
|
+
}
|
|
104
|
+
addOnOpenChange(handler) {
|
|
105
|
+
return this.addOpenStateHandler(handler, this.onOpenChangeHandlers);
|
|
106
|
+
}
|
|
107
|
+
open() {
|
|
108
|
+
this.setOpen(true);
|
|
109
|
+
}
|
|
110
|
+
close(options) {
|
|
111
|
+
this.setOpen(false, options);
|
|
112
|
+
}
|
|
113
|
+
toggle() {
|
|
114
|
+
this.setOpen(!this.isOpen);
|
|
115
|
+
}
|
|
116
|
+
setOpen(toOpen, options) {
|
|
117
|
+
if (this.isOpen === toOpen || this.openStateInFlight === toOpen) return;
|
|
118
|
+
this.openStateInFlight = toOpen;
|
|
119
|
+
try {
|
|
120
|
+
this.applyOpenState(toOpen, options);
|
|
121
|
+
} finally {
|
|
122
|
+
this.openStateInFlight = void 0;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Sets the open state without running any handler. Use it to mirror a
|
|
127
|
+
* controlled `isOpen` prop, whose change comes from the consumer – notifying
|
|
128
|
+
* them of their own state would echo it back.
|
|
129
|
+
*/
|
|
130
|
+
syncOpen(toOpen) {
|
|
131
|
+
this.isOpen = toOpen;
|
|
132
|
+
}
|
|
133
|
+
applyOpenState(toOpen, options) {
|
|
134
|
+
const { bypassConfirmation = false } = options ?? {};
|
|
135
|
+
if (toOpen === false) {
|
|
136
|
+
const closeIsConfirmed = this.closeIsConfirmed;
|
|
137
|
+
this.closeIsConfirmed = false;
|
|
138
|
+
if (this.confirmOnCloseEnabled && !closeIsConfirmed && this.closeWithoutConfirmationGrants.size === 0 && !bypassConfirmation) {
|
|
139
|
+
this.showConfirmationModal = true;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
let aborted;
|
|
144
|
+
if (toOpen) aborted = this.executeOnOpen();
|
|
145
|
+
else aborted = this.executeOnClose();
|
|
146
|
+
if (!aborted) aborted = this.executeOnOpenChange(toOpen);
|
|
147
|
+
if (!aborted) this.isOpen = toOpen;
|
|
148
|
+
}
|
|
149
|
+
setIsContentSuspended(to) {
|
|
150
|
+
this.isContentSuspended = to;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Allows closing this overlay without a confirmation until the returned
|
|
154
|
+
* disposer is called. Use it around an operation that may legitimately close
|
|
155
|
+
* the overlay – e.g. a `Form` submit, where a "discard unsaved changes?"
|
|
156
|
+
* prompt would be nonsense – and dispose it as soon as that operation has
|
|
157
|
+
* finished. An operation that ends without closing the overlay therefore
|
|
158
|
+
* leaves the confirmation armed (#2775).
|
|
159
|
+
*/
|
|
160
|
+
grantCloseWithoutConfirmation() {
|
|
161
|
+
const grant = {};
|
|
162
|
+
this.closeWithoutConfirmationGrants.add(grant);
|
|
163
|
+
return () => {
|
|
164
|
+
this.closeWithoutConfirmationGrants.delete(grant);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
confirmClose() {
|
|
168
|
+
this.closeIsConfirmed = true;
|
|
169
|
+
this.showConfirmationModal = false;
|
|
170
|
+
}
|
|
171
|
+
cancelConfirmation() {
|
|
172
|
+
this.showConfirmationModal = false;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
176
|
+
export { OverlayState };
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=OverlayState.mjs.map
|
|
@@ -0,0 +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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"}
|
|
@@ -23,3 +23,4 @@ export type { ListSortingShape, SortingDefaultMode, SortingFn, } from "./list/so
|
|
|
23
23
|
export { ListViewMode } from "./list/viewMode/ListViewMode";
|
|
24
24
|
export type { ListViewModeOptions, ListViewModeValue, } from "./list/viewMode/types";
|
|
25
25
|
export { customPropertyPrefix, type CustomPropertyName, type PropertyName, type PropertyValue, type PropertyValueRenderMethod, } from "./list/types";
|
|
26
|
+
export { OverlayState, type AnyOverlayOpenStateHandler, type DisposerFn, type OverlayCloseHandler, type OverlayCloseOptions, type OverlayOpenHandler, type OverlayOpenStateHandler, type OverlayStateOptions, } from "./overlay/OverlayState";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export type OverlayOpenHandler = () => unknown;
|
|
2
|
+
export type OverlayCloseHandler = () => unknown;
|
|
3
|
+
export type OverlayOpenStateHandler = (isOpen: boolean) => unknown;
|
|
4
|
+
export type AnyOverlayOpenStateHandler = OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler;
|
|
5
|
+
export type DisposerFn = () => void;
|
|
6
|
+
export interface OverlayCloseOptions {
|
|
7
|
+
/** Close without asking, even when the overlay requires confirmation. */
|
|
8
|
+
bypassConfirmation?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface OverlayStateOptions {
|
|
11
|
+
isDefaultOpen?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether closing the overlay must be confirmed while no source has an
|
|
14
|
+
* opinion (`setConfirmOnCloseSource`).
|
|
15
|
+
*/
|
|
16
|
+
confirmOnClose?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Whether an overlay is open, and whether closing it has to be confirmed first.
|
|
20
|
+
* Each binding adds its subscription and its lifecycle: React's
|
|
21
|
+
* `OverlayController` subclasses it, Vue's adapter wraps it in refs.
|
|
22
|
+
*
|
|
23
|
+
* `TCloseOptions` lets a binding pass more on a close than the state reads —
|
|
24
|
+
* React's `overlay`, resolved by `Action` before the close arrives here.
|
|
25
|
+
*/
|
|
26
|
+
export declare class OverlayState<TCloseOptions extends OverlayCloseOptions = OverlayCloseOptions> {
|
|
27
|
+
isOpen: boolean;
|
|
28
|
+
isContentSuspended: boolean;
|
|
29
|
+
private onOpenHandlers;
|
|
30
|
+
private onCloseHandlers;
|
|
31
|
+
private onOpenChangeHandlers;
|
|
32
|
+
showConfirmationModal: boolean;
|
|
33
|
+
closeIsConfirmed: boolean;
|
|
34
|
+
private readonly confirmOnCloseFromOptions;
|
|
35
|
+
/**
|
|
36
|
+
* Every mounted component that has an opinion on close confirmation
|
|
37
|
+
* contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop
|
|
38
|
+
* and a `Form` tracking its dirty state. Combining them instead of assigning
|
|
39
|
+
* a single flag keeps them from overwriting each other.
|
|
40
|
+
*/
|
|
41
|
+
private confirmOnCloseSources;
|
|
42
|
+
/**
|
|
43
|
+
* Active grants that allow closing without a confirmation. Each entry is
|
|
44
|
+
* scoped to an ongoing operation that legitimately closes the overlay – e.g.
|
|
45
|
+
* a `Form` submit – and is dropped again when that operation has finished, so
|
|
46
|
+
* an operation that does _not_ close the overlay leaves the confirmation
|
|
47
|
+
* armed.
|
|
48
|
+
*/
|
|
49
|
+
private closeWithoutConfirmationGrants;
|
|
50
|
+
/**
|
|
51
|
+
* The open state a `setOpen` call is currently applying. Handlers run before
|
|
52
|
+
* `isOpen` is assigned, so a handler that calls `setOpen` again would not be
|
|
53
|
+
* caught by the equality check at the top and would recurse.
|
|
54
|
+
*/
|
|
55
|
+
private openStateInFlight;
|
|
56
|
+
constructor(options?: OverlayStateOptions);
|
|
57
|
+
/** Whether closing this overlay currently requires a confirmation. */
|
|
58
|
+
get confirmOnCloseEnabled(): boolean;
|
|
59
|
+
private addOpenStateHandler;
|
|
60
|
+
private executeHandlers;
|
|
61
|
+
private executeOnClose;
|
|
62
|
+
private executeOnOpen;
|
|
63
|
+
private executeOnOpenChange;
|
|
64
|
+
addOnClose(handler: OverlayCloseHandler): DisposerFn;
|
|
65
|
+
addOnOpen(handler: OverlayOpenHandler): DisposerFn;
|
|
66
|
+
addOnOpenChange(handler: OverlayOpenStateHandler): DisposerFn;
|
|
67
|
+
open(): void;
|
|
68
|
+
close(options?: TCloseOptions): void;
|
|
69
|
+
toggle(): void;
|
|
70
|
+
setOpen(toOpen: boolean, options?: TCloseOptions): void;
|
|
71
|
+
/**
|
|
72
|
+
* Sets the open state without running any handler. Use it to mirror a
|
|
73
|
+
* controlled `isOpen` prop, whose change comes from the consumer – notifying
|
|
74
|
+
* them of their own state would echo it back.
|
|
75
|
+
*/
|
|
76
|
+
syncOpen(toOpen: boolean): void;
|
|
77
|
+
private applyOpenState;
|
|
78
|
+
setIsContentSuspended(to: boolean): void;
|
|
79
|
+
/**
|
|
80
|
+
* Allows closing this overlay without a confirmation until the returned
|
|
81
|
+
* disposer is called. Use it around an operation that may legitimately close
|
|
82
|
+
* the overlay – e.g. a `Form` submit, where a "discard unsaved changes?"
|
|
83
|
+
* prompt would be nonsense – and dispose it as soon as that operation has
|
|
84
|
+
* finished. An operation that ends without closing the overlay therefore
|
|
85
|
+
* leaves the confirmation armed (#2775).
|
|
86
|
+
*/
|
|
87
|
+
grantCloseWithoutConfirmation(): DisposerFn;
|
|
88
|
+
confirmClose(): void;
|
|
89
|
+
cancelConfirmation(): void;
|
|
90
|
+
}
|
|
@@ -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. */
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { FC, PropsWithChildren } from 'react';
|
|
2
2
|
import * as Aria from "react-aria-components";
|
|
3
3
|
export interface TableCellProps extends Omit<Aria.CellProps, "children" | "style" | "render">, PropsWithChildren {
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Styles the cell as a row header. Its semantics come from the column: the
|
|
6
|
+
* first column, or the one with `isRowHeader`.
|
|
7
|
+
*/
|
|
5
8
|
rowHeader?: boolean;
|
|
6
9
|
/** Horizontal alignment of the cell content @default "start" */
|
|
7
10
|
horizontalAlign?: "start" | "center" | "end";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a column is the first of its `TableHeader`. Undefined outside a
|
|
3
|
+
* header that can tell, e.g. with dynamic `columns`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const IsFirstColumnContext: import('react').Context<boolean | undefined>;
|
|
6
|
+
export declare const useIsFirstColumn: () => boolean | undefined;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
+
import { OverlayState, OverlayCloseHandler, OverlayCloseOptions, OverlayOpenHandler, OverlayOpenStateHandler } from '../../../_bundled/flow-components-base/index';
|
|
1
2
|
import { DependencyList } from 'react';
|
|
2
3
|
import { FlowComponentName } from '../../../components/propTypes';
|
|
3
|
-
export type OverlayOpenHandler
|
|
4
|
-
export
|
|
5
|
-
export type OverlayOpenStateHandler = (isOpen: boolean) => unknown;
|
|
6
|
-
type DisposerFn = () => void;
|
|
7
|
-
export interface CloseOverlayOptions {
|
|
4
|
+
export type { OverlayCloseHandler, OverlayOpenHandler, OverlayOpenStateHandler, } from '../../../_bundled/flow-components-base/index';
|
|
5
|
+
export interface CloseOverlayOptions extends OverlayCloseOptions {
|
|
8
6
|
/**
|
|
9
7
|
* The overlay to close. Omitted, the nearest enclosing overlay is closed –
|
|
10
8
|
* the same thing `closeOverlay={true}` means.
|
|
11
9
|
*/
|
|
12
10
|
overlay?: FlowComponentName | OverlayController;
|
|
13
|
-
bypassConfirmation?: boolean;
|
|
14
11
|
}
|
|
15
12
|
export interface OnOverlayClosedOptions {
|
|
16
13
|
dependencies?: DependencyList;
|
|
@@ -35,48 +32,17 @@ export interface OverlayControllerOptions {
|
|
|
35
32
|
*/
|
|
36
33
|
confirmOnClose?: boolean;
|
|
37
34
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
private onCloseHandlers;
|
|
44
|
-
private onOpenChangeHandlers;
|
|
45
|
-
showConfirmationModal: boolean;
|
|
46
|
-
closeIsConfirmed: boolean;
|
|
47
|
-
private readonly confirmOnCloseFromOptions;
|
|
48
|
-
/**
|
|
49
|
-
* Every mounted component that has an opinion on close confirmation
|
|
50
|
-
* contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop
|
|
51
|
-
* and a `Form` tracking its dirty state. Combining them instead of assigning
|
|
52
|
-
* a single flag keeps them from overwriting each other.
|
|
53
|
-
*/
|
|
54
|
-
private confirmOnCloseSources;
|
|
55
|
-
/**
|
|
56
|
-
* Active grants that allow closing without a confirmation. Each entry is
|
|
57
|
-
* scoped to an ongoing operation that legitimately closes the overlay – e.g.
|
|
58
|
-
* a `Form` submit – and is dropped again when that operation has finished, so
|
|
59
|
-
* an operation that does _not_ close the overlay leaves the confirmation
|
|
60
|
-
* armed.
|
|
61
|
-
*/
|
|
62
|
-
private closeWithoutConfirmationGrants;
|
|
63
|
-
/**
|
|
64
|
-
* The open state a `setOpen` call is currently applying. Handlers run before
|
|
65
|
-
* `isOpen` is assigned, so a handler that calls `setOpen` again would not be
|
|
66
|
-
* caught by the equality check at the top and would recurse.
|
|
67
|
-
*/
|
|
68
|
-
private openStateInFlight;
|
|
69
|
-
constructor(options?: ConstructorOptions);
|
|
70
|
-
/** Whether closing this overlay currently requires a confirmation. */
|
|
71
|
-
get confirmOnCloseEnabled(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The state is `OverlayState` from `@mittwald/flow-components-base`, shared
|
|
37
|
+
* with every remote binding; this adds the hooks.
|
|
38
|
+
*/
|
|
39
|
+
export declare class OverlayController extends OverlayState<CloseOptions> {
|
|
72
40
|
useUpdateOptions(options?: OverlayControllerOptions): void;
|
|
73
41
|
/**
|
|
74
42
|
* Registers the calling component as a close confirmation source for as long
|
|
75
43
|
* as it is mounted. `undefined` contributes nothing at all.
|
|
76
44
|
*/
|
|
77
45
|
private useConfirmOnCloseSource;
|
|
78
|
-
private setConfirmOnCloseSource;
|
|
79
|
-
private removeConfirmOnCloseSource;
|
|
80
46
|
/**
|
|
81
47
|
* Can be used to execute a callback when the Overlay has unmounted – means
|
|
82
48
|
* after any closing animation.
|
|
@@ -85,27 +51,7 @@ export declare class OverlayController {
|
|
|
85
51
|
*/
|
|
86
52
|
useOnClosed(callback: () => unknown, options?: OnOverlayClosedOptions): void;
|
|
87
53
|
static useNew(options?: OverlayControllerOptions): OverlayController;
|
|
88
|
-
private addOpenStateHandler;
|
|
89
54
|
private useOnHandler;
|
|
90
|
-
private executeHandlers;
|
|
91
|
-
private executeOnClose;
|
|
92
|
-
private executeOnOpen;
|
|
93
|
-
private executeOnOpenChange;
|
|
94
|
-
addOnClose(handler: OverlayCloseHandler): DisposerFn;
|
|
95
|
-
addOnOpen(handler: OverlayOpenHandler): DisposerFn;
|
|
96
|
-
addOnOpenChange(handler: OverlayOpenStateHandler): DisposerFn;
|
|
97
|
-
open(): void;
|
|
98
|
-
close(options?: CloseOptions): void;
|
|
99
|
-
toggle(): void;
|
|
100
|
-
setOpen(toOpen: boolean, options?: CloseOptions): void;
|
|
101
|
-
/**
|
|
102
|
-
* Sets the open state without running any handler. Use it to mirror a
|
|
103
|
-
* controlled `isOpen` prop, whose change comes from the consumer – notifying
|
|
104
|
-
* them of their own state would echo it back.
|
|
105
|
-
*/
|
|
106
|
-
syncOpen(toOpen: boolean): void;
|
|
107
|
-
private applyOpenState;
|
|
108
|
-
setIsContentSuspended(to: boolean): void;
|
|
109
55
|
useIsOpen(): boolean;
|
|
110
56
|
useIsContentSuspended(): boolean;
|
|
111
57
|
useShowConfirmationModal(): boolean;
|
|
@@ -115,16 +61,4 @@ export declare class OverlayController {
|
|
|
115
61
|
readonly cancel: () => void;
|
|
116
62
|
readonly confirm: () => void;
|
|
117
63
|
} | undefined;
|
|
118
|
-
/**
|
|
119
|
-
* Allows closing this overlay without a confirmation until the returned
|
|
120
|
-
* disposer is called. Use it around an operation that may legitimately close
|
|
121
|
-
* the overlay – e.g. a `Form` submit, where a "discard unsaved changes?"
|
|
122
|
-
* prompt would be nonsense – and dispose it as soon as that operation has
|
|
123
|
-
* finished. An operation that ends without closing the overlay therefore
|
|
124
|
-
* leaves the confirmation armed (#2775).
|
|
125
|
-
*/
|
|
126
|
-
grantCloseWithoutConfirmation(): DisposerFn;
|
|
127
|
-
confirmClose(): void;
|
|
128
|
-
cancelConfirmation(): void;
|
|
129
64
|
}
|
|
130
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mittwald/flow-react-components",
|
|
3
|
-
"version": "1.6.0-next.
|
|
3
|
+
"version": "1.6.0-next.39",
|
|
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.6.0-next.
|
|
87
|
+
"@mittwald/flow-icons": "^1.6.0-next.39",
|
|
88
88
|
"@mittwald/password-tools-js": "^3.0.0",
|
|
89
|
-
"@mittwald/react-tunnel": "^1.6.0-next.
|
|
89
|
+
"@mittwald/react-tunnel": "^1.6.0-next.39",
|
|
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.6.0-next.
|
|
143
|
-
"@mittwald/flow-core": "1.6.0-next.
|
|
144
|
-
"@mittwald/flow-design-tokens": "1.6.0-next.
|
|
145
|
-
"@mittwald/flow-icons-base": "1.6.0-next.
|
|
142
|
+
"@mittwald/flow-components-base": "1.6.0-next.39",
|
|
143
|
+
"@mittwald/flow-core": "1.6.0-next.39",
|
|
144
|
+
"@mittwald/flow-design-tokens": "1.6.0-next.39",
|
|
145
|
+
"@mittwald/flow-icons-base": "1.6.0-next.39",
|
|
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.6.0-next.
|
|
148
|
+
"@mittwald/typescript-config": "1.6.0-next.39",
|
|
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.6.0-next.
|
|
202
|
+
"@mittwald/flow-icons-pro": "1.6.0-next.39",
|
|
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": "ff0590a0a5c672cef5cf8e08817b5c17da235d7e"
|
|
227
227
|
}
|