@floegence/floe-webapp-core 0.51.0 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/Dialog.d.ts +7 -0
- package/dist/components/ui/Dialog.js +160 -114
- package/dist/components/ui/Dropdown.js +192 -172
- package/dist/floe.css +31 -0
- package/dist/hooks/useOverlayMask.js +95 -83
- package/dist/styles.css +1 -1
- package/dist/surface.css +2 -2
- package/package.json +1 -1
|
@@ -15,6 +15,13 @@ export interface DialogProps {
|
|
|
15
15
|
children: JSX.Element;
|
|
16
16
|
footer?: JSX.Element;
|
|
17
17
|
class?: string;
|
|
18
|
+
/** Bottom drawers retain the same modal and surface-placement contract. */
|
|
19
|
+
presentation?: 'dialog' | 'bottom-drawer';
|
|
20
|
+
/** Undefined uses the default header; null leaves only accessible title/description. */
|
|
21
|
+
header?: JSX.Element;
|
|
22
|
+
contentClass?: string;
|
|
23
|
+
/** Includes the exit animation, so hosts can retain background input isolation. */
|
|
24
|
+
onPresenceChange?: (present: boolean) => void;
|
|
18
25
|
/** Optional stacking layer for global dialogs. Overrides the placement provider default. */
|
|
19
26
|
globalZIndex?: number;
|
|
20
27
|
}
|
|
@@ -1,105 +1,112 @@
|
|
|
1
|
-
import { createComponent as
|
|
2
|
-
import { createUniqueId as
|
|
3
|
-
import { cn as
|
|
4
|
-
import { Button as
|
|
5
|
-
import { X as
|
|
6
|
-
import { useResolvedFloeConfig as
|
|
7
|
-
import { useOverlayMask as
|
|
8
|
-
import { resolveSurfacePortalHost as
|
|
9
|
-
import { LOCAL_INTERACTION_SURFACE_ATTR as
|
|
10
|
-
import { createFloatingPresence as
|
|
11
|
-
import { useDialogPlacement as
|
|
12
|
-
var
|
|
13
|
-
const
|
|
1
|
+
import { createComponent as r, use as L, setAttribute as s, style as ee, Portal as te, spread as B, mergeProps as F, memo as C, insert as i, effect as A, className as N, template as c } from "solid-js/web";
|
|
2
|
+
import { createUniqueId as ne, createSignal as I, createEffect as G, onCleanup as j, createMemo as q, Show as f, untrack as re } from "solid-js";
|
|
3
|
+
import { cn as v } from "../../utils/cn.js";
|
|
4
|
+
import { Button as E } from "./Button.js";
|
|
5
|
+
import { X as oe } from "../icons/index.js";
|
|
6
|
+
import { useResolvedFloeConfig as ie } from "../../context/FloeConfigContext.js";
|
|
7
|
+
import { useOverlayMask as le } from "../../hooks/useOverlayMask.js";
|
|
8
|
+
import { resolveSurfacePortalHost as ae, DIALOG_SURFACE_BOUNDARY_ATTR as O, SURFACE_PORTAL_LAYER_ATTR as de, DIALOG_SURFACE_HOST_ATTR as ce, isSurfacePortalMode as K, projectSurfacePortalRect as ue, resolveSurfacePortalBoundaryRect as se, resolveSurfacePortalMount as fe } from "./dialogSurfaceScope.js";
|
|
9
|
+
import { LOCAL_INTERACTION_SURFACE_ATTR as ge } from "./localInteractionSurface.js";
|
|
10
|
+
import { createFloatingPresence as me } from "./floatingPresence.js";
|
|
11
|
+
import { useDialogPlacement as he } from "./DialogPlacementContext.js";
|
|
12
|
+
var be = /* @__PURE__ */ c("<span aria-hidden=true>"), ve = /* @__PURE__ */ c('<h2 class="text-sm font-semibold">'), we = /* @__PURE__ */ c('<p class="mt-0.5 text-xs text-muted-foreground">'), ye = /* @__PURE__ */ c('<div class="flex items-start justify-between p-3 border-b border-border"><div>'), xe = /* @__PURE__ */ c('<div class="flex items-center justify-end gap-2 p-3 border-t border-border">'), $e = /* @__PURE__ */ c("<div><div></div><div><div data-floe-surface=floating><div>"), _e = /* @__PURE__ */ c("<h2 class=sr-only>"), Ce = /* @__PURE__ */ c("<p class=sr-only>"), Ae = /* @__PURE__ */ c("<div>");
|
|
13
|
+
const Oe = {
|
|
14
14
|
display: "none"
|
|
15
15
|
};
|
|
16
|
-
function
|
|
16
|
+
function Re(e) {
|
|
17
17
|
if (typeof queueMicrotask == "function") {
|
|
18
18
|
queueMicrotask(e);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
Promise.resolve().then(e);
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function U(e) {
|
|
24
24
|
return `${e.left}|${e.top}|${e.right}|${e.bottom}|${e.width}|${e.height}`;
|
|
25
25
|
}
|
|
26
|
-
function
|
|
26
|
+
function ke(e) {
|
|
27
27
|
return typeof window < "u" && typeof window.requestAnimationFrame == "function" ? window.requestAnimationFrame(e) : window.setTimeout(() => e(Date.now()), 16);
|
|
28
28
|
}
|
|
29
|
-
function
|
|
29
|
+
function Pe(e) {
|
|
30
30
|
if (typeof window < "u" && typeof window.cancelAnimationFrame == "function") {
|
|
31
31
|
window.cancelAnimationFrame(e);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
window.clearTimeout(e);
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
const
|
|
38
|
-
let
|
|
39
|
-
const [
|
|
40
|
-
open: () => e.open && !!
|
|
41
|
-
exitDurationMs
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
function pe(e) {
|
|
37
|
+
const w = he(), g = ne(), p = () => `dialog-${g}-title`, S = () => `dialog-${g}-description`;
|
|
38
|
+
let T;
|
|
39
|
+
const [R, z] = I(null), [M, Z] = I(0), [V, W] = I(0), m = () => e.presentation === "bottom-drawer", u = me({
|
|
40
|
+
open: () => e.open && !!R() && M() > 0,
|
|
41
|
+
get exitDurationMs() {
|
|
42
|
+
return m() ? 180 : 120;
|
|
43
|
+
}
|
|
44
|
+
}), y = () => u.mounted() && !!R() && M() > 0;
|
|
45
|
+
G(() => e.onPresenceChange?.(y())), j(() => e.onPresenceChange?.(!1));
|
|
46
|
+
const Y = (n) => {
|
|
47
|
+
z(n), Re(() => {
|
|
48
|
+
re(R) === n && Z((d) => d + 1);
|
|
45
49
|
});
|
|
46
|
-
},
|
|
47
|
-
owner:
|
|
50
|
+
}, k = q(() => y() ? ae({
|
|
51
|
+
owner: R()
|
|
48
52
|
}) : {
|
|
49
53
|
host: null,
|
|
50
54
|
boundaryHost: null,
|
|
51
55
|
mountHost: null,
|
|
52
56
|
mode: "global"
|
|
53
|
-
}),
|
|
54
|
-
return
|
|
55
|
-
const
|
|
56
|
-
if (!
|
|
57
|
+
}), x = () => `dialog-boundary-${g}`, o = () => w.mode() === "auto" && K(k()), X = () => o() ? fe(k()) : void 0, H = () => e.globalZIndex ?? w.globalZIndex(), D = (n) => ue(se(n), n), J = () => D(k()), P = q(() => (V(), J())), Q = (n) => typeof Element < "u" && n instanceof Element ? !!n.closest(`[${O}="${x()}"]`) : typeof Node < "u" && n instanceof Node ? !!n.parentElement?.closest(`[${O}="${x()}"]`) : !1;
|
|
58
|
+
return G(() => {
|
|
59
|
+
const n = k();
|
|
60
|
+
if (!y() || !o() || typeof window > "u")
|
|
57
61
|
return;
|
|
58
|
-
let
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
62
|
+
let d = !1, b = null, l = U(D(n));
|
|
63
|
+
const $ = () => {
|
|
64
|
+
if (d || !K(n))
|
|
61
65
|
return;
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
const t = U(D(n));
|
|
67
|
+
t !== l && (l = t, W((h) => h + 1));
|
|
68
|
+
}, _ = () => {
|
|
69
|
+
d || (b = ke(() => {
|
|
70
|
+
$(), _();
|
|
67
71
|
}));
|
|
68
72
|
};
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
_(), j(() => {
|
|
74
|
+
d = !0, b !== null && Pe(b);
|
|
71
75
|
});
|
|
72
|
-
}),
|
|
73
|
-
open:
|
|
74
|
-
root: () =>
|
|
75
|
-
containsTarget:
|
|
76
|
+
}), le({
|
|
77
|
+
open: y,
|
|
78
|
+
root: () => T,
|
|
79
|
+
containsTarget: Q,
|
|
76
80
|
onClose: () => e.onOpenChange(!1),
|
|
77
|
-
lockBodyScroll: () => !
|
|
81
|
+
lockBodyScroll: () => !o(),
|
|
78
82
|
trapFocus: !0,
|
|
79
|
-
closeOnEscape: () =>
|
|
83
|
+
closeOnEscape: () => o() ? "inside" : !0,
|
|
80
84
|
escapeKeyPhase: () => e.escapeKeyPhase ?? "capture",
|
|
81
85
|
blockHotkeys: !0,
|
|
82
86
|
// Block scroll bleed outside the dialog while keeping the dialog content scrollable.
|
|
83
|
-
blockWheel: () =>
|
|
84
|
-
blockTouchMove: () =>
|
|
87
|
+
blockWheel: () => o() ? "none" : "outside",
|
|
88
|
+
blockTouchMove: () => o() ? "none" : "outside",
|
|
85
89
|
restoreFocus: !0
|
|
86
90
|
}), [(() => {
|
|
87
|
-
var
|
|
88
|
-
return
|
|
89
|
-
})(),
|
|
91
|
+
var n = be();
|
|
92
|
+
return L(Y, n), s(n, "data-floe-dialog-owner-anchor", g), ee(n, Oe), n;
|
|
93
|
+
})(), r(f, {
|
|
90
94
|
get when() {
|
|
91
|
-
return
|
|
95
|
+
return y();
|
|
92
96
|
},
|
|
93
97
|
get children() {
|
|
94
|
-
return
|
|
98
|
+
return r(te, {
|
|
95
99
|
get mount() {
|
|
96
|
-
return
|
|
100
|
+
return X();
|
|
97
101
|
},
|
|
98
102
|
get children() {
|
|
99
|
-
var
|
|
100
|
-
|
|
103
|
+
var n = $e(), d = n.firstChild, b = d.nextSibling, l = b.firstChild, $ = l.firstChild;
|
|
104
|
+
s(n, "data-floe-dialog-overlay-root", g), B(n, F({
|
|
101
105
|
get "data-floe-dialog-mode"() {
|
|
102
|
-
return
|
|
106
|
+
return o() ? "surface" : "global";
|
|
107
|
+
},
|
|
108
|
+
get "data-floe-dialog-presentation"() {
|
|
109
|
+
return e.presentation ?? "dialog";
|
|
103
110
|
},
|
|
104
111
|
get "data-floating-presence"() {
|
|
105
112
|
return u.state();
|
|
@@ -108,110 +115,149 @@ function Ce(e) {
|
|
|
108
115
|
return u.exiting() ? "true" : void 0;
|
|
109
116
|
}
|
|
110
117
|
}, () => ({
|
|
111
|
-
[
|
|
118
|
+
[ge]: o() ? "true" : void 0
|
|
119
|
+
}), () => ({
|
|
120
|
+
[de]: "true",
|
|
121
|
+
[O]: x()
|
|
112
122
|
}), {
|
|
113
123
|
get class() {
|
|
114
|
-
return
|
|
124
|
+
return v(o() ? "absolute z-20 box-border p-3" : v("fixed inset-0 box-border p-4", H() === void 0 && "z-50"), m() && "floe-bottom-drawer-overlay", u.exiting() && !m() && "pointer-events-none");
|
|
115
125
|
},
|
|
116
126
|
get style() {
|
|
117
|
-
return
|
|
118
|
-
left: `${
|
|
119
|
-
top: `${
|
|
120
|
-
width: `${
|
|
121
|
-
height: `${
|
|
127
|
+
return C(() => !!o())() ? {
|
|
128
|
+
left: `${P().left}px`,
|
|
129
|
+
top: `${P().top}px`,
|
|
130
|
+
width: `${P().width}px`,
|
|
131
|
+
height: `${P().height}px`
|
|
122
132
|
} : {
|
|
123
|
-
"z-index":
|
|
133
|
+
"z-index": H()
|
|
124
134
|
};
|
|
125
135
|
}
|
|
126
|
-
}), !1, !0),
|
|
127
|
-
[
|
|
136
|
+
}), !1, !0), s(d, "data-floe-dialog-backdrop", g), B(d, F(() => ({
|
|
137
|
+
[O]: x()
|
|
128
138
|
}), {
|
|
129
139
|
get "data-floating-presence"() {
|
|
130
140
|
return u.state();
|
|
131
141
|
},
|
|
132
142
|
get class() {
|
|
133
|
-
return
|
|
143
|
+
return v("absolute inset-0 floe-floating-presence floe-floating-backdrop", e.closeOnBackdropClick === !1 ? "cursor-default" : "cursor-pointer", m() ? "floe-bottom-drawer-backdrop" : o() ? "bg-background/72 backdrop-blur-[2px]" : "bg-background/80 backdrop-blur-sm");
|
|
134
144
|
},
|
|
135
145
|
onClick: () => {
|
|
136
|
-
e.closeOnBackdropClick !== !1 && e.onOpenChange(!1);
|
|
146
|
+
!u.exiting() && e.closeOnBackdropClick !== !1 && e.onOpenChange(!1);
|
|
137
147
|
}
|
|
138
148
|
}), !1, !1);
|
|
139
|
-
var
|
|
140
|
-
return typeof
|
|
141
|
-
[
|
|
149
|
+
var _ = T;
|
|
150
|
+
return typeof _ == "function" ? L(_, l) : T = l, s(l, "data-floe-dialog-panel", g), B(l, F(() => ({
|
|
151
|
+
[O]: x(),
|
|
152
|
+
[ce]: "true"
|
|
142
153
|
}), {
|
|
143
154
|
get class() {
|
|
144
|
-
return
|
|
155
|
+
return v(o() ? "flex max-h-[calc(100%-1rem)] w-[min(32rem,calc(100%-1rem))] max-w-[calc(100%-1rem)] flex-col" : "w-full max-w-md max-h-[85vh]", "bg-card text-card-foreground rounded-md shadow-lg", "border border-border", "floe-floating-presence", m() ? "floe-bottom-drawer-panel" : "floe-floating-dialog-panel", "pointer-events-auto flex flex-col", e.class);
|
|
145
156
|
},
|
|
146
157
|
get "data-floating-presence"() {
|
|
147
158
|
return u.state();
|
|
148
159
|
},
|
|
160
|
+
get inert() {
|
|
161
|
+
return C(() => !!m())() && u.exiting();
|
|
162
|
+
},
|
|
149
163
|
role: "dialog",
|
|
150
164
|
get "aria-modal"() {
|
|
151
|
-
return
|
|
165
|
+
return o() ? void 0 : "true";
|
|
152
166
|
},
|
|
153
167
|
get "aria-labelledby"() {
|
|
154
|
-
return
|
|
168
|
+
return C(() => !!e.title)() ? p() : void 0;
|
|
155
169
|
},
|
|
156
170
|
get "aria-describedby"() {
|
|
157
|
-
return
|
|
171
|
+
return C(() => !!e.description)() ? S() : void 0;
|
|
158
172
|
},
|
|
159
|
-
onKeyDown: (
|
|
173
|
+
onKeyDown: (t) => e.onKeyDown?.(t),
|
|
160
174
|
tabIndex: -1
|
|
161
|
-
}), !1, !0),
|
|
175
|
+
}), !1, !0), i(l, r(f, {
|
|
162
176
|
get when() {
|
|
163
|
-
return e.
|
|
177
|
+
return e.header === void 0;
|
|
164
178
|
},
|
|
165
|
-
get
|
|
166
|
-
|
|
167
|
-
return a(_, o(b, {
|
|
179
|
+
get fallback() {
|
|
180
|
+
return [r(f, {
|
|
168
181
|
get when() {
|
|
169
182
|
return e.title;
|
|
170
183
|
},
|
|
171
184
|
get children() {
|
|
172
|
-
var
|
|
173
|
-
return
|
|
185
|
+
var t = _e();
|
|
186
|
+
return i(t, () => e.title), A(() => s(t, "id", p())), t;
|
|
174
187
|
}
|
|
175
|
-
}),
|
|
188
|
+
}), r(f, {
|
|
176
189
|
get when() {
|
|
177
190
|
return e.description;
|
|
178
191
|
},
|
|
179
192
|
get children() {
|
|
180
|
-
var
|
|
181
|
-
return
|
|
193
|
+
var t = Ce();
|
|
194
|
+
return i(t, () => e.description), A(() => s(t, "id", S())), t;
|
|
182
195
|
}
|
|
183
|
-
}),
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return e.closeLabel ?? "Close";
|
|
196
|
+
}), C(() => e.header)];
|
|
197
|
+
},
|
|
198
|
+
get children() {
|
|
199
|
+
return r(f, {
|
|
200
|
+
get when() {
|
|
201
|
+
return e.title || e.description;
|
|
190
202
|
},
|
|
191
203
|
get children() {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
var t = ye(), h = t.firstChild;
|
|
205
|
+
return i(h, r(f, {
|
|
206
|
+
get when() {
|
|
207
|
+
return e.title;
|
|
208
|
+
},
|
|
209
|
+
get children() {
|
|
210
|
+
var a = ve();
|
|
211
|
+
return i(a, () => e.title), A(() => s(a, "id", p())), a;
|
|
212
|
+
}
|
|
213
|
+
}), null), i(h, r(f, {
|
|
214
|
+
get when() {
|
|
215
|
+
return e.description;
|
|
216
|
+
},
|
|
217
|
+
get children() {
|
|
218
|
+
var a = we();
|
|
219
|
+
return i(a, () => e.description), A(() => s(a, "id", S())), a;
|
|
220
|
+
}
|
|
221
|
+
}), null), i(t, r(E, {
|
|
222
|
+
variant: "ghost-destructive",
|
|
223
|
+
size: "icon",
|
|
224
|
+
class: "-my-2 -mr-2 h-[46px] w-[46px] shrink-0 sm:my-0 sm:-mr-1 sm:h-6 sm:w-6",
|
|
225
|
+
onClick: () => e.onOpenChange(!1),
|
|
226
|
+
get "aria-label"() {
|
|
227
|
+
return e.closeLabel ?? "Close";
|
|
228
|
+
},
|
|
229
|
+
get children() {
|
|
230
|
+
return r(oe, {
|
|
231
|
+
class: "w-3.5 h-3.5"
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}), null), t;
|
|
195
235
|
}
|
|
196
|
-
})
|
|
236
|
+
});
|
|
197
237
|
}
|
|
198
|
-
}),
|
|
238
|
+
}), $), i($, () => e.children), i(l, r(f, {
|
|
199
239
|
get when() {
|
|
200
240
|
return e.footer;
|
|
201
241
|
},
|
|
202
242
|
get children() {
|
|
203
|
-
var
|
|
204
|
-
return
|
|
243
|
+
var t = xe();
|
|
244
|
+
return i(t, () => e.footer), t;
|
|
205
245
|
}
|
|
206
|
-
}), null), t
|
|
246
|
+
}), null), A((t) => {
|
|
247
|
+
var h = v("pointer-events-none relative z-[1] flex h-full w-full justify-center", m() ? "items-end" : "items-center"), a = v("min-h-0 flex-1 overflow-auto overscroll-contain p-3", e.contentClass);
|
|
248
|
+
return h !== t.e && N(b, t.e = h), a !== t.t && N($, t.t = a), t;
|
|
249
|
+
}, {
|
|
250
|
+
e: void 0,
|
|
251
|
+
t: void 0
|
|
252
|
+
}), n;
|
|
207
253
|
}
|
|
208
254
|
});
|
|
209
255
|
}
|
|
210
256
|
})];
|
|
211
257
|
}
|
|
212
|
-
function
|
|
213
|
-
const
|
|
214
|
-
return
|
|
258
|
+
function je(e) {
|
|
259
|
+
const w = ie();
|
|
260
|
+
return r(pe, {
|
|
215
261
|
get open() {
|
|
216
262
|
return e.open;
|
|
217
263
|
},
|
|
@@ -228,16 +274,16 @@ function Te(e) {
|
|
|
228
274
|
return e.globalZIndex;
|
|
229
275
|
},
|
|
230
276
|
get footer() {
|
|
231
|
-
return [
|
|
277
|
+
return [r(E, {
|
|
232
278
|
variant: "ghost",
|
|
233
279
|
onClick: () => e.onOpenChange(!1),
|
|
234
280
|
get disabled() {
|
|
235
281
|
return e.loading;
|
|
236
282
|
},
|
|
237
283
|
get children() {
|
|
238
|
-
return e.cancelText ??
|
|
284
|
+
return e.cancelText ?? w.config.strings.confirmDialog.cancel;
|
|
239
285
|
}
|
|
240
|
-
}),
|
|
286
|
+
}), r(E, {
|
|
241
287
|
get variant() {
|
|
242
288
|
return e.variant === "destructive" ? "destructive" : "primary";
|
|
243
289
|
},
|
|
@@ -248,16 +294,16 @@ function Te(e) {
|
|
|
248
294
|
return e.loading;
|
|
249
295
|
},
|
|
250
296
|
get children() {
|
|
251
|
-
return e.confirmText ??
|
|
297
|
+
return e.confirmText ?? w.config.strings.confirmDialog.confirm;
|
|
252
298
|
}
|
|
253
299
|
})];
|
|
254
300
|
},
|
|
255
301
|
get children() {
|
|
256
|
-
return e.children ??
|
|
302
|
+
return e.children ?? Ae();
|
|
257
303
|
}
|
|
258
304
|
});
|
|
259
305
|
}
|
|
260
306
|
export {
|
|
261
|
-
|
|
262
|
-
|
|
307
|
+
je as ConfirmDialog,
|
|
308
|
+
pe as Dialog
|
|
263
309
|
};
|