@fluixi-ui/bottom-sheet 0.2.0-alpha.2 → 0.2.0-alpha.20

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.
@@ -1,337 +1,399 @@
1
- import { delegateEvents, createComponent, splitProps, createNativeElement, spread, mergeProps, insert, handleRef } from "@fluixi/dom";
2
- import { createSignal, createEffect, createMemo, createRenderEffect, onCleanup } from "@fluixi/reactive/signal";
3
- import { useRef, Show } from "@fluixi/core";
4
- import { createSafeContext, createControllableBooleanSignal, createId, composeId, composeEventHandlers, mergeRefs, dataAttr } from "@fluixi-ui/kit";
5
- import { createScrollLock, Portal, createLayerIndex, createDismissableLayer, createFocusScope } from "@fluixi-ui/primitives";
1
+ import { createComponent, createNativeElement, delegateEvents, handleRef, insert, mergeProps, splitProps, spread } from "@fluixi/dom";
2
+ import { createEffect, createMemo, createRenderEffect, createSignal, onCleanup } from "@fluixi/reactive/signal";
3
+ import { fxProps } from "@fluixi-ui/fx";
4
+ import { Show, useRef } from "@fluixi/core";
5
+ import { composeEventHandlers, composeId, createControllableBooleanSignal, createId, createSafeContext, dataAttr, mergeRefs } from "@fluixi-ui/kit";
6
+ import { Portal, createDismissableLayer, createFocusScope, createLayerIndex, createScrollLock } from "@fluixi-ui/primitives";
7
+ //#region src/bottom-sheet.tsx
6
8
  delegateEvents(["click"]);
7
- const [BottomSheetProvider, useBottomSheetContext] = createSafeContext("BottomSheet");
8
- const viewportHeight = () => typeof window !== "undefined" ? window.innerHeight : 800;
9
+ var [BottomSheetProvider, useBottomSheetContext] = createSafeContext("BottomSheet");
10
+ var viewportHeight = () => typeof window !== "undefined" ? window.innerHeight : 800;
11
+ /**
12
+ * Root of a bottom sheet — a panel anchored to the bottom edge that a user can
13
+ * drag to resize freely (it stays where released), or drag down to dismiss (via
14
+ * {@link BottomSheetHandle}). Built on the same overlay primitives as
15
+ * `Dialog`/`Drawer`; owns open state and, when `modal` (the default), locks
16
+ * scroll and traps focus.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import {
21
+ * BottomSheet, BottomSheetTrigger, BottomSheetPortal, BottomSheetOverlay,
22
+ * BottomSheetContent, BottomSheetHandle, BottomSheetHeader, BottomSheetTitle,
23
+ * BottomSheetBody, BottomSheetClose,
24
+ * } from '@fluixi-ui/bottom-sheet';
25
+ *
26
+ * <BottomSheet defaultHeight={0.5}>
27
+ * <BottomSheetTrigger>Open</BottomSheetTrigger>
28
+ * <BottomSheetPortal>
29
+ * <BottomSheetOverlay />
30
+ * <BottomSheetContent>
31
+ * <BottomSheetHandle />
32
+ * <BottomSheetHeader><BottomSheetTitle>Share</BottomSheetTitle></BottomSheetHeader>
33
+ * <BottomSheetBody>…</BottomSheetBody>
34
+ * </BottomSheetContent>
35
+ * </BottomSheetPortal>
36
+ * </BottomSheet>
37
+ * ```
38
+ */
9
39
  function BottomSheet(props) {
10
- const [isOpen, setInternalOpen] = createControllableBooleanSignal({
11
- value: () => props.open,
12
- defaultValue: () => props.defaultOpen ?? false,
13
- onChange: (open) => props.onOpenChange?.(open)
14
- });
15
- const baseId = createId("bottom-sheet");
16
- const modal = props.modal ?? true;
17
- const [triggerRef, setTriggerRef] = createSignal(void 0);
18
- const [descriptionCount, setDescriptionCount] = createSignal(0);
19
- const [height, setHeight] = createSignal(null);
20
- const [isDragging, setIsDragging] = createSignal(false);
21
- const defaultPx = () => Math.round((props.defaultHeight ?? 0.5) * viewportHeight());
22
- const maxPx = () => Math.round((props.maxHeight ?? 0.95) * viewportHeight());
23
- const closePx = () => (props.closeThreshold ?? 0.25) * viewportHeight();
24
- if (modal) {
25
- createScrollLock(() => isOpen());
26
- }
27
- const setOpen = (open) => setInternalOpen(open);
28
- createEffect(() => {
29
- if (isOpen()) {
30
- if (height() == null) setHeight(defaultPx());
31
- } else {
32
- setHeight(null);
33
- }
34
- });
35
- const beginDrag = (event) => {
36
- if (event.button !== 0) return;
37
- event.preventDefault();
38
- const handleEl = event.currentTarget;
39
- try {
40
- handleEl?.setPointerCapture(event.pointerId);
41
- } catch {
42
- }
43
- const max = maxPx();
44
- const close = closePx();
45
- const startY = event.clientY;
46
- const startHeight = height() ?? defaultPx();
47
- setIsDragging(true);
48
- const onMove = (e) => {
49
- const delta = startY - e.clientY;
50
- setHeight(Math.max(0, Math.min(max, startHeight + delta)));
51
- };
52
- const onUp = (e) => {
53
- document.removeEventListener("pointermove", onMove);
54
- document.removeEventListener("pointerup", onUp);
55
- try {
56
- handleEl?.releasePointerCapture(e.pointerId);
57
- } catch {
58
- }
59
- setIsDragging(false);
60
- if ((height() ?? defaultPx()) < close) setOpen(false);
61
- };
62
- document.addEventListener("pointermove", onMove);
63
- document.addEventListener("pointerup", onUp);
64
- };
65
- const context = {
66
- isOpen,
67
- setOpen,
68
- modal,
69
- ids: {
70
- trigger: composeId(baseId, "trigger"),
71
- content: composeId(baseId, "content"),
72
- title: composeId(baseId, "title"),
73
- description: composeId(baseId, "description")
74
- },
75
- triggerRef,
76
- setTriggerRef,
77
- hasDescription: () => descriptionCount() > 0,
78
- registerDescription: () => {
79
- setDescriptionCount((count) => count + 1);
80
- return () => setDescriptionCount((count) => count - 1);
81
- },
82
- height,
83
- isDragging,
84
- beginDrag
85
- };
86
- return createMemo(() => createComponent(BottomSheetProvider, {
87
- get value() {
88
- return context;
89
- },
90
- get children() {
91
- return props.children;
92
- }
93
- }));
40
+ const [isOpen, setInternalOpen] = createControllableBooleanSignal({
41
+ value: () => props.open,
42
+ defaultValue: () => props.defaultOpen ?? false,
43
+ onChange: (open) => props.onOpenChange?.(open)
44
+ });
45
+ const baseId = createId("bottom-sheet");
46
+ const modal = props.modal ?? true;
47
+ const [triggerRef, setTriggerRef] = createSignal(void 0);
48
+ const [descriptionCount, setDescriptionCount] = createSignal(0);
49
+ const [height, setHeight] = createSignal(null);
50
+ const [isDragging, setIsDragging] = createSignal(false);
51
+ const defaultPx = () => Math.round((props.defaultHeight ?? .5) * viewportHeight());
52
+ const maxPx = () => Math.round((props.maxHeight ?? .95) * viewportHeight());
53
+ const closePx = () => (props.closeThreshold ?? .25) * viewportHeight();
54
+ if (modal) createScrollLock(() => isOpen());
55
+ const setOpen = (open) => setInternalOpen(open);
56
+ createEffect(() => {
57
+ if (isOpen()) {
58
+ if (height() == null) setHeight(defaultPx());
59
+ } else setHeight(null);
60
+ });
61
+ const beginDrag = (event) => {
62
+ if (event.button !== 0) return;
63
+ event.preventDefault();
64
+ const handleEl = event.currentTarget;
65
+ try {
66
+ handleEl?.setPointerCapture(event.pointerId);
67
+ } catch {}
68
+ const max = maxPx();
69
+ const close = closePx();
70
+ const startY = event.clientY;
71
+ const startHeight = height() ?? defaultPx();
72
+ setIsDragging(true);
73
+ const onMove = (e) => {
74
+ const delta = startY - e.clientY;
75
+ setHeight(Math.max(0, Math.min(max, startHeight + delta)));
76
+ };
77
+ const onUp = (e) => {
78
+ document.removeEventListener("pointermove", onMove);
79
+ document.removeEventListener("pointerup", onUp);
80
+ try {
81
+ handleEl?.releasePointerCapture(e.pointerId);
82
+ } catch {}
83
+ setIsDragging(false);
84
+ if ((height() ?? defaultPx()) < close) setOpen(false);
85
+ };
86
+ document.addEventListener("pointermove", onMove);
87
+ document.addEventListener("pointerup", onUp);
88
+ };
89
+ const context = {
90
+ isOpen,
91
+ setOpen,
92
+ modal,
93
+ ids: {
94
+ trigger: composeId(baseId, "trigger"),
95
+ content: composeId(baseId, "content"),
96
+ title: composeId(baseId, "title"),
97
+ description: composeId(baseId, "description")
98
+ },
99
+ triggerRef,
100
+ setTriggerRef,
101
+ hasDescription: () => descriptionCount() > 0,
102
+ registerDescription: () => {
103
+ setDescriptionCount((count) => count + 1);
104
+ return () => setDescriptionCount((count) => count - 1);
105
+ },
106
+ height,
107
+ isDragging,
108
+ beginDrag
109
+ };
110
+ return createMemo(() => createComponent(BottomSheetProvider, {
111
+ get value() {
112
+ return context;
113
+ },
114
+ get children() {
115
+ return props.children;
116
+ }
117
+ }));
94
118
  }
119
+ /** The button that opens its {@link BottomSheet}. */
95
120
  function BottomSheetTrigger(props) {
96
- const sheet = useBottomSheetContext();
97
- const [local, others] = splitProps(props, ["onClick", "ref", "children"]);
98
- return (() => {
99
- const _el$ = createNativeElement("button");
100
- spread({
101
- element: _el$,
102
- props: mergeProps(others, {
103
- ref: mergeRefs(sheet.setTriggerRef, local.ref),
104
- type: "button",
105
- id: () => sheet.ids.trigger,
106
- "aria-haspopup": "dialog",
107
- "aria-expanded": () => sheet.isOpen() ? "true" : "false",
108
- "aria-controls": () => sheet.ids.content,
109
- "data-state": () => sheet.isOpen() ? "open" : "closed",
110
- onClick: composeEventHandlers([local.onClick, () => sheet.setOpen(true)])
111
- })
112
- });
113
- insert(_el$, local.children);
114
- return _el$;
115
- })();
121
+ const sheet = useBottomSheetContext();
122
+ const [local, others] = splitProps(props, [
123
+ "onClick",
124
+ "ref",
125
+ "children",
126
+ "fx",
127
+ "style"
128
+ ]);
129
+ return (() => {
130
+ const _el$ = createNativeElement("button");
131
+ spread({
132
+ element: _el$,
133
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
134
+ ref: mergeRefs(sheet.setTriggerRef, local.ref),
135
+ type: "button",
136
+ id: () => sheet.ids.trigger,
137
+ "aria-haspopup": "dialog",
138
+ "aria-expanded": () => sheet.isOpen() ? "true" : "false",
139
+ "aria-controls": () => sheet.ids.content,
140
+ "data-state": () => sheet.isOpen() ? "open" : "closed",
141
+ onClick: composeEventHandlers([local.onClick, () => sheet.setOpen(true)])
142
+ })
143
+ });
144
+ insert(_el$, local.children, null);
145
+ return _el$;
146
+ })();
116
147
  }
148
+ /** Portals the sheet overlay and content to the document body while open. */
117
149
  function BottomSheetPortal(props) {
118
- const sheet = useBottomSheetContext();
119
- const ref = useRef(null);
120
- createEffect(() => {
121
- if (!sheet.isOpen() && ref.current) {
122
- ref.current.remove();
123
- }
124
- });
125
- return createMemo(() => createComponent(Show, {
126
- get when() {
127
- return sheet.isOpen();
128
- },
129
- get children() {
130
- return createMemo(() => createComponent(Portal, {
131
- get ref() {
132
- return ref;
133
- },
134
- get children() {
135
- return props.children;
136
- }
137
- }));
138
- }
139
- }));
150
+ const sheet = useBottomSheetContext();
151
+ const ref = useRef(null);
152
+ createEffect(() => {
153
+ if (!sheet.isOpen() && ref.current) ref.current.remove();
154
+ });
155
+ return createMemo(() => createComponent(Show, {
156
+ get when() {
157
+ return sheet.isOpen();
158
+ },
159
+ get children() {
160
+ return createMemo(() => createComponent(Portal, {
161
+ get ref() {
162
+ return ref;
163
+ },
164
+ get children() {
165
+ return props.children;
166
+ }
167
+ }));
168
+ }
169
+ }));
140
170
  }
171
+ /** The backdrop rendered behind the sheet. */
141
172
  function BottomSheetOverlay(props) {
142
- const sheet = useBottomSheetContext();
143
- const [local, others] = splitProps(props, ["children"]);
144
- const [element, setElement] = createSignal(void 0);
145
- createLayerIndex(element);
146
- return (() => {
147
- const _el$ = createNativeElement("div");
148
- spread({
149
- element: _el$,
150
- props: mergeProps(others, {
151
- ref: setElement,
152
- "data-bottom-sheet-overlay": "",
153
- "data-state": () => sheet.isOpen() ? "open" : "closed"
154
- })
155
- });
156
- insert(_el$, local.children);
157
- return _el$;
158
- })();
173
+ const sheet = useBottomSheetContext();
174
+ const [local, others] = splitProps(props, [
175
+ "children",
176
+ "fx",
177
+ "style"
178
+ ]);
179
+ const [element, setElement] = createSignal(void 0);
180
+ createLayerIndex(element);
181
+ return (() => {
182
+ const _el$ = createNativeElement("div");
183
+ spread({
184
+ element: _el$,
185
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
186
+ ref: setElement,
187
+ "data-bottom-sheet-overlay": "",
188
+ "data-state": () => sheet.isOpen() ? "open" : "closed"
189
+ })
190
+ });
191
+ insert(_el$, local.children, null);
192
+ return _el$;
193
+ })();
159
194
  }
195
+ /** The focus-trapped sheet panel; its height tracks the drag / snap point. */
160
196
  function BottomSheetContent(props) {
161
- const sheet = useBottomSheetContext();
162
- const [local, others] = splitProps(props, ["ref", "children", "onEscapeKeyDown", "onPointerDownOutside"]);
163
- const [element, setElement] = createSignal(void 0);
164
- createDismissableLayer(element, {
165
- disableOutsidePointerEvents: sheet.modal,
166
- shouldExcludeTarget: (target) => {
167
- const trigger = sheet.triggerRef();
168
- return !!trigger && (trigger === target || trigger.contains(target));
169
- },
170
- onEscapeKeyDown: local.onEscapeKeyDown,
171
- onPointerDownOutside: local.onPointerDownOutside,
172
- onDismiss: () => sheet.setOpen(false)
173
- });
174
- createFocusScope(element, {
175
- trap: () => sheet.modal,
176
- autoFocus: true,
177
- restoreFocus: true
178
- });
179
- const setRef = (node) => {
180
- setElement(node);
181
- handleRef(local.ref, node);
182
- };
183
- createRenderEffect(() => {
184
- const el = element();
185
- if (!el) return;
186
- const h = sheet.height();
187
- if (h != null) el.style.setProperty("--flx-ui-bottom-sheet-h", `${h}px`);
188
- else el.style.removeProperty("--flx-ui-bottom-sheet-h");
189
- });
190
- return (() => {
191
- const _el$ = createNativeElement("div");
192
- spread({
193
- element: _el$,
194
- props: mergeProps(others, {
195
- ref: setRef,
196
- role: "dialog",
197
- id: () => sheet.ids.content,
198
- "aria-modal": () => sheet.modal ? "true" : void 0,
199
- "aria-labelledby": () => sheet.ids.title,
200
- "aria-describedby": () => sheet.hasDescription() ? sheet.ids.description : void 0,
201
- "data-bottom-sheet-content": "",
202
- "data-dragging": () => dataAttr(sheet.isDragging()),
203
- "data-state": () => sheet.isOpen() ? "open" : "closed",
204
- tabindex: () => -1
205
- })
206
- });
207
- insert(_el$, local.children);
208
- return _el$;
209
- })();
197
+ const sheet = useBottomSheetContext();
198
+ const [local, others] = splitProps(props, [
199
+ "ref",
200
+ "children",
201
+ "onEscapeKeyDown",
202
+ "onPointerDownOutside",
203
+ "fx",
204
+ "style"
205
+ ]);
206
+ const [element, setElement] = createSignal(void 0);
207
+ createDismissableLayer(element, {
208
+ disableOutsidePointerEvents: sheet.modal,
209
+ shouldExcludeTarget: (target) => {
210
+ const trigger = sheet.triggerRef();
211
+ return !!trigger && (trigger === target || trigger.contains(target));
212
+ },
213
+ onEscapeKeyDown: local.onEscapeKeyDown,
214
+ onPointerDownOutside: local.onPointerDownOutside,
215
+ onDismiss: () => sheet.setOpen(false)
216
+ });
217
+ createFocusScope(element, {
218
+ trap: () => sheet.modal,
219
+ autoFocus: true,
220
+ restoreFocus: true
221
+ });
222
+ const setRef = (node) => {
223
+ setElement(node);
224
+ handleRef(local.ref, node);
225
+ };
226
+ createRenderEffect(() => {
227
+ const el = element();
228
+ if (!el) return;
229
+ const h = sheet.height();
230
+ if (h != null) el.style.setProperty("--flx-ui-bottom-sheet-h", `${h}px`);
231
+ else el.style.removeProperty("--flx-ui-bottom-sheet-h");
232
+ });
233
+ return (() => {
234
+ const _el$ = createNativeElement("div");
235
+ spread({
236
+ element: _el$,
237
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
238
+ ref: setRef,
239
+ role: "dialog",
240
+ id: () => sheet.ids.content,
241
+ "aria-modal": () => sheet.modal ? "true" : void 0,
242
+ "aria-labelledby": () => sheet.ids.title,
243
+ "aria-describedby": () => sheet.hasDescription() ? sheet.ids.description : void 0,
244
+ "data-bottom-sheet-content": "",
245
+ "data-dragging": () => dataAttr(sheet.isDragging()),
246
+ "data-state": () => sheet.isOpen() ? "open" : "closed",
247
+ tabindex: -1
248
+ })
249
+ });
250
+ insert(_el$, local.children, null);
251
+ return _el$;
252
+ })();
210
253
  }
254
+ /** The drag affordance (grabber). Drag it up to grow the sheet, down to shrink or dismiss it. */
211
255
  function BottomSheetHandle(props) {
212
- const sheet = useBottomSheetContext();
213
- const [local, others] = splitProps(props, ["ref", "children"]);
214
- const setRef = (node) => {
215
- node.addEventListener("pointerdown", sheet.beginDrag);
216
- onCleanup(() => node.removeEventListener("pointerdown", sheet.beginDrag));
217
- handleRef(local.ref, node);
218
- };
219
- return (() => {
220
- const _el$ = createNativeElement("div");
221
- spread({
222
- element: _el$,
223
- props: mergeProps(others, {
224
- ref: setRef,
225
- "data-bottom-sheet-handle": "",
226
- "aria-hidden": "true"
227
- })
228
- });
229
- insert(_el$, local.children);
230
- return _el$;
231
- })();
256
+ const sheet = useBottomSheetContext();
257
+ const [local, others] = splitProps(props, [
258
+ "ref",
259
+ "children",
260
+ "fx",
261
+ "style"
262
+ ]);
263
+ const setRef = (node) => {
264
+ node.addEventListener("pointerdown", sheet.beginDrag);
265
+ onCleanup(() => node.removeEventListener("pointerdown", sheet.beginDrag));
266
+ handleRef(local.ref, node);
267
+ };
268
+ return (() => {
269
+ const _el$ = createNativeElement("div");
270
+ spread({
271
+ element: _el$,
272
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
273
+ ref: setRef,
274
+ "data-bottom-sheet-handle": "",
275
+ "aria-hidden": "true"
276
+ })
277
+ });
278
+ insert(_el$, local.children, null);
279
+ return _el$;
280
+ })();
232
281
  }
282
+ /** The sheet's header region. */
233
283
  function BottomSheetHeader(props) {
234
- const [local, others] = splitProps(props, ["children"]);
235
- return (() => {
236
- const _el$ = createNativeElement("div");
237
- spread({
238
- element: _el$,
239
- props: mergeProps(others, {
240
- "data-bottom-sheet-header": ""
241
- })
242
- });
243
- insert(_el$, local.children);
244
- return _el$;
245
- })();
284
+ const [local, others] = splitProps(props, [
285
+ "children",
286
+ "fx",
287
+ "style"
288
+ ]);
289
+ return (() => {
290
+ const _el$ = createNativeElement("div");
291
+ spread({
292
+ element: _el$,
293
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, { "data-bottom-sheet-header": "" })
294
+ });
295
+ insert(_el$, local.children, null);
296
+ return _el$;
297
+ })();
246
298
  }
299
+ /** The accessible title; labels the sheet via `aria-labelledby`. */
247
300
  function BottomSheetTitle(props) {
248
- const sheet = useBottomSheetContext();
249
- const [local, others] = splitProps(props, ["children"]);
250
- return (() => {
251
- const _el$ = createNativeElement("h2");
252
- spread({
253
- element: _el$,
254
- props: mergeProps(others, {
255
- id: () => sheet.ids.title,
256
- "data-bottom-sheet-title": ""
257
- })
258
- });
259
- insert(_el$, local.children);
260
- return _el$;
261
- })();
301
+ const sheet = useBottomSheetContext();
302
+ const [local, others] = splitProps(props, [
303
+ "children",
304
+ "fx",
305
+ "style"
306
+ ]);
307
+ return (() => {
308
+ const _el$ = createNativeElement("h2");
309
+ spread({
310
+ element: _el$,
311
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
312
+ id: () => sheet.ids.title,
313
+ "data-bottom-sheet-title": ""
314
+ })
315
+ });
316
+ insert(_el$, local.children, null);
317
+ return _el$;
318
+ })();
262
319
  }
320
+ /** Optional supporting text; describes the sheet via `aria-describedby`. */
263
321
  function BottomSheetDescription(props) {
264
- const sheet = useBottomSheetContext();
265
- const [local, others] = splitProps(props, ["children"]);
266
- onCleanup(sheet.registerDescription());
267
- return (() => {
268
- const _el$ = createNativeElement("p");
269
- spread({
270
- element: _el$,
271
- props: mergeProps(others, {
272
- id: () => sheet.ids.description,
273
- "data-bottom-sheet-description": ""
274
- })
275
- });
276
- insert(_el$, local.children);
277
- return _el$;
278
- })();
322
+ const sheet = useBottomSheetContext();
323
+ const [local, others] = splitProps(props, [
324
+ "children",
325
+ "fx",
326
+ "style"
327
+ ]);
328
+ onCleanup(sheet.registerDescription());
329
+ return (() => {
330
+ const _el$ = createNativeElement("p");
331
+ spread({
332
+ element: _el$,
333
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
334
+ id: () => sheet.ids.description,
335
+ "data-bottom-sheet-description": ""
336
+ })
337
+ });
338
+ insert(_el$, local.children, null);
339
+ return _el$;
340
+ })();
279
341
  }
342
+ /** The scrollable main content region of the sheet. */
280
343
  function BottomSheetBody(props) {
281
- const [local, others] = splitProps(props, ["children"]);
282
- return (() => {
283
- const _el$ = createNativeElement("div");
284
- spread({
285
- element: _el$,
286
- props: mergeProps(others, {
287
- "data-bottom-sheet-body": ""
288
- })
289
- });
290
- insert(_el$, local.children);
291
- return _el$;
292
- })();
344
+ const [local, others] = splitProps(props, [
345
+ "children",
346
+ "fx",
347
+ "style"
348
+ ]);
349
+ return (() => {
350
+ const _el$ = createNativeElement("div");
351
+ spread({
352
+ element: _el$,
353
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, { "data-bottom-sheet-body": "" })
354
+ });
355
+ insert(_el$, local.children, null);
356
+ return _el$;
357
+ })();
293
358
  }
359
+ /** The sheet's footer — typically actions. */
294
360
  function BottomSheetFooter(props) {
295
- const [local, others] = splitProps(props, ["children"]);
296
- return (() => {
297
- const _el$ = createNativeElement("div");
298
- spread({
299
- element: _el$,
300
- props: mergeProps(others, {
301
- "data-bottom-sheet-footer": ""
302
- })
303
- });
304
- insert(_el$, local.children);
305
- return _el$;
306
- })();
361
+ const [local, others] = splitProps(props, [
362
+ "children",
363
+ "fx",
364
+ "style"
365
+ ]);
366
+ return (() => {
367
+ const _el$ = createNativeElement("div");
368
+ spread({
369
+ element: _el$,
370
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, { "data-bottom-sheet-footer": "" })
371
+ });
372
+ insert(_el$, local.children, null);
373
+ return _el$;
374
+ })();
307
375
  }
376
+ /** A button that closes its {@link BottomSheet}. */
308
377
  function BottomSheetClose(props) {
309
- const sheet = useBottomSheetContext();
310
- const [local, others] = splitProps(props, ["onClick", "children"]);
311
- return (() => {
312
- const _el$ = createNativeElement("button");
313
- spread({
314
- element: _el$,
315
- props: mergeProps(others, {
316
- type: "button",
317
- onClick: composeEventHandlers([local.onClick, () => sheet.setOpen(false)])
318
- })
319
- });
320
- insert(_el$, local.children);
321
- return _el$;
322
- })();
378
+ const sheet = useBottomSheetContext();
379
+ const [local, others] = splitProps(props, [
380
+ "onClick",
381
+ "children",
382
+ "fx",
383
+ "style"
384
+ ]);
385
+ return (() => {
386
+ const _el$ = createNativeElement("button");
387
+ spread({
388
+ element: _el$,
389
+ props: mergeProps(fxProps(() => local.fx, () => local.style), others, {
390
+ type: "button",
391
+ onClick: composeEventHandlers([local.onClick, () => sheet.setOpen(false)])
392
+ })
393
+ });
394
+ insert(_el$, local.children, null);
395
+ return _el$;
396
+ })();
323
397
  }
324
- export {
325
- BottomSheet,
326
- BottomSheetBody,
327
- BottomSheetClose,
328
- BottomSheetContent,
329
- BottomSheetDescription,
330
- BottomSheetFooter,
331
- BottomSheetHandle,
332
- BottomSheetHeader,
333
- BottomSheetOverlay,
334
- BottomSheetPortal,
335
- BottomSheetTitle,
336
- BottomSheetTrigger
337
- };
398
+ //#endregion
399
+ export { BottomSheet, BottomSheetBody, BottomSheetClose, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHandle, BottomSheetHeader, BottomSheetOverlay, BottomSheetPortal, BottomSheetTitle, BottomSheetTrigger };