@destyler/dialog 0.0.2 → 0.0.4

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.
@@ -0,0 +1,540 @@
1
+ 'use strict';
2
+
3
+ const vue = require('vue');
4
+ const primitive = require('@destyler/primitive');
5
+ const composition = require('@destyler/composition');
6
+ const shared = require('@destyler/shared');
7
+ const presence = require('@destyler/presence');
8
+ const focusScope = require('@destyler/focus-scope');
9
+ const dismissableLayer = require('@destyler/dismissable-layer');
10
+ const component = require('@destyler/dismissable-layer/component');
11
+ const directives = require('@destyler/directives');
12
+ const teleport = require('@destyler/teleport');
13
+
14
+ const dialogRootProps = {
15
+ /**
16
+ * The controlled open state of the dialog. Can be binded as `v-model:open`.
17
+ *
18
+ * @default undefined
19
+ */
20
+ open: {
21
+ type: Boolean,
22
+ required: false,
23
+ default: void 0
24
+ },
25
+ /**
26
+ * The open state of the dialog when it is initially rendered.
27
+ * Use when you do not need to control its open state.
28
+ *
29
+ * @default false
30
+ */
31
+ defaultOpen: {
32
+ type: Boolean,
33
+ required: false,
34
+ default: false
35
+ },
36
+ /**
37
+ * The modality of the dialog When set to true,
38
+ * interaction with outside elements will be
39
+ * disabled and only dialog content will
40
+ * be visible to screen readers.
41
+ *
42
+ * @default true
43
+ */
44
+ modal: {
45
+ type: Boolean,
46
+ required: false,
47
+ default: true
48
+ }
49
+ };
50
+ const [injectDialogRootContext, provideDialogRootContext] = shared.createContext("DestylerDialogRoot");
51
+ const dialogRootEmits = {
52
+ /**
53
+ * Event handler called when the open state of the dialog changes.
54
+ */
55
+ "update:open": (_value) => true
56
+ };
57
+ const DialogRoot = vue.defineComponent({
58
+ name: "DestylerDialogRoot",
59
+ props: dialogRootProps,
60
+ emits: dialogRootEmits,
61
+ setup(props, { emit }) {
62
+ const open = composition.useVModel(props, "open", emit, {
63
+ defaultValue: props.defaultOpen,
64
+ passive: props.open === void 0
65
+ });
66
+ const triggerElement = vue.ref();
67
+ const contentElement = vue.ref();
68
+ const { modal } = vue.toRefs(props);
69
+ provideDialogRootContext({
70
+ open,
71
+ modal,
72
+ openModal: () => {
73
+ open.value = true;
74
+ },
75
+ onOpenChange: (value) => {
76
+ open.value = value;
77
+ },
78
+ onOpenToggle: () => {
79
+ open.value = !open.value;
80
+ },
81
+ contentId: "",
82
+ titleId: "",
83
+ descriptionId: "",
84
+ triggerElement,
85
+ contentElement
86
+ });
87
+ },
88
+ render() {
89
+ return this.$slots.default?.();
90
+ }
91
+ });
92
+
93
+ const dialogCloseProps = {
94
+ ...primitive.primitiveProps,
95
+ /**
96
+ * @default button
97
+ */
98
+ as: {
99
+ ...primitive.primitiveProps.as,
100
+ default: "button"
101
+ }
102
+ };
103
+ const DialogClose = vue.defineComponent({
104
+ name: "DestylerDialogClose",
105
+ props: dialogCloseProps,
106
+ setup() {
107
+ const rootContext = injectDialogRootContext();
108
+ composition.useForwardExpose();
109
+ return {
110
+ rootContext
111
+ };
112
+ },
113
+ render() {
114
+ return vue.h(primitive.Primitive, vue.mergeProps(this.$props, {
115
+ type: this.$props.as === "button" ? "button" : void 0,
116
+ onClick: () => {
117
+ this.rootContext.onOpenChange(false);
118
+ }
119
+ }), () => this.$slots.default?.());
120
+ }
121
+ });
122
+
123
+ const dialogContentImplProps = {
124
+ ...component.dismissableLayerProps,
125
+ /**
126
+ * Used to force mounting when more control is needed.
127
+ * Useful when controlling animation with Vue animation libraries.
128
+ *
129
+ * @default false
130
+ */
131
+ forceMount: {
132
+ type: Boolean,
133
+ required: false
134
+ },
135
+ /**
136
+ * When `true`, focus cannot escape the Content via keyboard,
137
+ * pointer, or a programmatic focus.
138
+ *
139
+ * @default false
140
+ */
141
+ trapFocus: {
142
+ type: Boolean,
143
+ required: false,
144
+ default: false
145
+ }
146
+ };
147
+ const dialogContentImplEmtis = {
148
+ ...component.dismissableLayerEmits,
149
+ /**
150
+ * Event handler called when auto-focusing on open. Can be prevented.
151
+ */
152
+ openAutoFocus: (_event) => true,
153
+ /**
154
+ * Event handler called when the a `pointerdown` event happens
155
+ * outside of the `DismissableLayer`. Can be prevented.
156
+ */
157
+ closeAutoFocus: (_event) => true
158
+ };
159
+ const DialogContentImpl = vue.defineComponent({
160
+ name: "DestylerDialogContentImpl",
161
+ props: dialogContentImplProps,
162
+ emits: dialogContentImplEmtis,
163
+ setup() {
164
+ const rootContext = injectDialogRootContext();
165
+ const { forwardRef, currentElement: contentElement } = composition.useForwardExpose();
166
+ rootContext.titleId || (rootContext.titleId = composition.useId(void 0, "destyler-dialog-title"));
167
+ rootContext.descriptionId || (rootContext.descriptionId = composition.useId(void 0, "destyler-dialog-description"));
168
+ vue.onMounted(() => {
169
+ rootContext.contentElement = contentElement;
170
+ });
171
+ return {
172
+ rootContext,
173
+ forwardRef
174
+ };
175
+ },
176
+ render() {
177
+ return vue.h(focusScope.FocusScope, {
178
+ asChild: true,
179
+ loop: true,
180
+ trapped: this.$props.trapFocus,
181
+ onMountAutoFocus: (event) => {
182
+ this.$emit("openAutoFocus", event);
183
+ },
184
+ onUnmountAutoFocus: (event) => {
185
+ this.$emit("closeAutoFocus", event);
186
+ }
187
+ }, () => vue.withDirectives(vue.h(dismissableLayer.DismissableLayer, vue.mergeProps(this.$attrs, {
188
+ "ref": (el) => this.forwardRef(el),
189
+ "as": this.$props.as,
190
+ "asChild": this.$props.asChild,
191
+ "disableOutsidePointerEvents": this.$props.disableOutsidePointerEvents,
192
+ "role": "dialog",
193
+ "aria-describedby": this.rootContext.descriptionId,
194
+ "aria-labelledby": this.rootContext.titleId,
195
+ "data-state": shared.getOpenState(this.rootContext.open.value),
196
+ "isDismissable": true,
197
+ "onDismiss": () => {
198
+ this.rootContext.onOpenChange(false);
199
+ },
200
+ "onEscapeKeyDown": (event) => {
201
+ this.$emit("escapeKeyDown", event);
202
+ },
203
+ "onFocusOutside": (event) => {
204
+ this.$emit("focusOutside", event);
205
+ },
206
+ "onInteractOutside": (event) => {
207
+ this.$emit("interactOutside", event);
208
+ },
209
+ "onPointerDownOutside": (event) => {
210
+ this.$emit("pointerDownOutside", event);
211
+ }
212
+ }), () => this.$slots.default?.()), [
213
+ [directives.BindOnceDirective, { id: this.rootContext.contentId }]
214
+ ]));
215
+ }
216
+ });
217
+
218
+ const DialogContentModal = vue.defineComponent({
219
+ name: "DestylerDialogContentModal",
220
+ props: dialogContentImplProps,
221
+ emits: dialogContentImplEmtis,
222
+ setup(_, { emit }) {
223
+ const rootContext = injectDialogRootContext();
224
+ const emitsAsProps = composition.useEmitAsProps(emit);
225
+ const { forwardRef, currentElement } = composition.useForwardExpose();
226
+ composition.useHideOthers(currentElement);
227
+ return {
228
+ rootContext,
229
+ emitsAsProps,
230
+ forwardRef
231
+ };
232
+ },
233
+ render() {
234
+ return vue.h(DialogContentImpl, vue.mergeProps(this.$props, this.emitsAsProps, {
235
+ "ref": (el) => this.forwardRef(el),
236
+ "trap-focus": this.rootContext.open.value,
237
+ "disableOutsidePointerEvents": true,
238
+ "onCloseAutoFocus": (event) => {
239
+ this.$emit("closeAutoFocus", event);
240
+ if (!event.defaultPrevented) {
241
+ event.preventDefault();
242
+ this.rootContext.triggerElement.value?.focus();
243
+ }
244
+ },
245
+ "onPointerDownOutside": (event) => {
246
+ const originalEvent = event.detail.originalEvent;
247
+ const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
248
+ const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
249
+ if (isRightClick)
250
+ event.preventDefault();
251
+ },
252
+ "onFocusOutside": (event) => {
253
+ event.preventDefault();
254
+ },
255
+ "onOpenAutoFocus": (event) => {
256
+ this.$emit("openAutoFocus", event);
257
+ }
258
+ }), () => this.$slots.default?.());
259
+ }
260
+ });
261
+
262
+ const DialogContentNonModal = vue.defineComponent({
263
+ name: "DestylerDialogContentNonModal",
264
+ props: dialogContentImplProps,
265
+ emits: dialogContentImplEmtis,
266
+ setup(_, { emit }) {
267
+ const rootContext = injectDialogRootContext();
268
+ const hasInteractedOutsideRef = vue.ref(false);
269
+ const hasPointerDownOutsideRef = vue.ref(false);
270
+ const emitsAsProps = composition.useEmitAsProps(emit);
271
+ return {
272
+ rootContext,
273
+ hasInteractedOutsideRef,
274
+ hasPointerDownOutsideRef,
275
+ emitsAsProps
276
+ };
277
+ },
278
+ render() {
279
+ return vue.h(DialogContentImpl, vue.mergeProps(this.$props, this.emitsAsProps, {
280
+ "trap-focus": false,
281
+ "disableOutsidePointerEvents": false,
282
+ "onCloseAutoFocus": (event) => {
283
+ this.$emit("closeAutoFocus", event);
284
+ if (!event.defaultPrevented) {
285
+ if (!this.hasInteractedOutsideRef)
286
+ this.rootContext.triggerElement.value?.focus();
287
+ event.preventDefault();
288
+ }
289
+ this.hasInteractedOutsideRef = false;
290
+ this.hasPointerDownOutsideRef = false;
291
+ },
292
+ "onInteractOutside": (event) => {
293
+ if (!event.defaultPrevented) {
294
+ this.hasInteractedOutsideRef = true;
295
+ if (event.detail.originalEvent.type === "pointerdown")
296
+ this.hasPointerDownOutsideRef = true;
297
+ }
298
+ const target = event.target;
299
+ const targetIsTrigger = this.rootContext.triggerElement.value?.contains(target);
300
+ if (targetIsTrigger)
301
+ event.preventDefault();
302
+ if (event.detail.originalEvent.type === "focusin" && this.hasPointerDownOutsideRef)
303
+ event.preventDefault();
304
+ }
305
+ }), () => this.$slots.default?.());
306
+ }
307
+ });
308
+
309
+ const dialogContentProps = {
310
+ ...dialogContentImplProps
311
+ };
312
+ const dialogContentEmits = {
313
+ ...dialogContentImplEmtis
314
+ };
315
+ const DialogContent = vue.defineComponent({
316
+ name: "DestylerDialogContent",
317
+ props: dialogContentProps,
318
+ emits: dialogContentEmits,
319
+ setup(_, { emit }) {
320
+ const rootContext = injectDialogRootContext();
321
+ const emitsAsProps = composition.useEmitAsProps(emit);
322
+ const { forwardRef } = composition.useForwardExpose();
323
+ return {
324
+ rootContext,
325
+ emitsAsProps,
326
+ forwardRef
327
+ };
328
+ },
329
+ render() {
330
+ const useVShow = this.$props.forceMount || this.rootContext.modal.value;
331
+ return vue.h(presence.Presence, {
332
+ present: this.$props.forceMount || this.rootContext.open.value
333
+ }, () => [
334
+ useVShow ? vue.h(DialogContentModal, vue.mergeProps(this.$props, this.emitsAsProps, this.$attrs, {
335
+ ref: (el) => this.forwardRef(el),
336
+ onOpenAutoFocus: (event) => {
337
+ this.$emit("openAutoFocus", event);
338
+ }
339
+ }), () => this.$slots.default?.()) : vue.h(DialogContentNonModal, vue.mergeProps(this.$props, this.emitsAsProps, this.$attrs, {
340
+ ref: (el) => this.forwardRef(el)
341
+ }), () => this.$slots.default?.())
342
+ ]);
343
+ }
344
+ });
345
+
346
+ const dialogDescriptionProps = {
347
+ ...primitive.primitiveProps,
348
+ /**
349
+ * @default p
350
+ */
351
+ as: {
352
+ ...primitive.primitiveProps.as,
353
+ default: "p"
354
+ }
355
+ };
356
+ const DialogDescription = vue.defineComponent({
357
+ name: "DestylerDialogDescription",
358
+ props: dialogDescriptionProps,
359
+ setup() {
360
+ const rootContext = injectDialogRootContext();
361
+ composition.useForwardExpose();
362
+ return {
363
+ rootContext
364
+ };
365
+ },
366
+ render() {
367
+ return vue.withDirectives(vue.h(primitive.Primitive, {
368
+ as: this.$props.as,
369
+ asChild: this.$props.asChild
370
+ }, () => this.$slots.default?.()), [
371
+ [directives.BindOnceDirective, { id: this.rootContext.descriptionId }]
372
+ ]);
373
+ }
374
+ });
375
+
376
+ const dialogOverlayImplProps = {
377
+ ...primitive.primitiveProps
378
+ };
379
+ const DialogOverlayImpl = vue.defineComponent({
380
+ name: "DestylerDialogOverlayImpl",
381
+ props: dialogOverlayImplProps,
382
+ setup() {
383
+ const rootContext = injectDialogRootContext();
384
+ composition.useForwardExpose();
385
+ return {
386
+ rootContext
387
+ };
388
+ },
389
+ render() {
390
+ return vue.h(primitive.Primitive, {
391
+ "as": this.$props.as,
392
+ "asChild": this.$props.asChild,
393
+ "data-state": this.rootContext.open.value ? "open" : "closed",
394
+ "style": {
395
+ "pointer-events": "auto"
396
+ }
397
+ }, () => this.$slots.default?.());
398
+ }
399
+ });
400
+
401
+ const dialogOverlayProps = {
402
+ ...primitive.primitiveProps,
403
+ /**
404
+ * Used to force mounting when more control is needed.
405
+ * Useful when controlling animation with Vue animation libraries.
406
+ */
407
+ forceMount: {
408
+ type: Boolean,
409
+ required: false
410
+ }
411
+ };
412
+ const DialogOverlay = vue.defineComponent({
413
+ name: "DestylerDialogOverlay",
414
+ props: dialogOverlayProps,
415
+ setup() {
416
+ const rootContext = injectDialogRootContext();
417
+ const { forwardRef } = composition.useForwardExpose();
418
+ return {
419
+ rootContext,
420
+ forwardRef
421
+ };
422
+ },
423
+ render() {
424
+ const useVShow = this.rootContext?.modal.value;
425
+ return useVShow ? vue.h(presence.Presence, {
426
+ present: this.$props.forceMount || this.rootContext.open.value
427
+ }, () => vue.h(DialogOverlayImpl, vue.mergeProps(this.$attrs, {
428
+ ref: (el) => this.forwardRef(el),
429
+ as: this.$props.as,
430
+ asChild: this.$props.asChild
431
+ }), () => this.$slots.default?.())) : null;
432
+ }
433
+ });
434
+
435
+ const dialogPortalProps = {
436
+ ...teleport.teleportPrimitiveProps
437
+ };
438
+ const DialogPortal = vue.defineComponent({
439
+ name: "DestylerDialogPortal",
440
+ props: dialogPortalProps,
441
+ render() {
442
+ return vue.h(teleport.TeleportPrimitive, vue.mergeProps(this.$props), () => this.$slots.default?.());
443
+ }
444
+ });
445
+
446
+ const dialogTitleProps = {
447
+ ...primitive.primitiveProps,
448
+ /**
449
+ * @default h2
450
+ */
451
+ as: {
452
+ ...primitive.primitiveProps.as,
453
+ default: "h2"
454
+ }
455
+ };
456
+ const DialogTitle = vue.defineComponent({
457
+ name: "DestylerDialogTitle",
458
+ props: dialogTitleProps,
459
+ setup() {
460
+ composition.useForwardExpose();
461
+ const rootContext = injectDialogRootContext();
462
+ return {
463
+ rootContext
464
+ };
465
+ },
466
+ render() {
467
+ return vue.withDirectives(vue.h(primitive.Primitive, {
468
+ as: this.$props.as,
469
+ asChild: this.$props.asChild
470
+ }, () => this.$slots.default?.()), [
471
+ [directives.BindOnceDirective, { id: this.rootContext.titleId }]
472
+ ]);
473
+ }
474
+ });
475
+
476
+ const dialogTriggerProps = {
477
+ ...primitive.primitiveProps,
478
+ /**
479
+ * @default button
480
+ */
481
+ as: {
482
+ ...primitive.primitiveProps.as,
483
+ default: "button"
484
+ }
485
+ };
486
+ const DialogTrigger = vue.defineComponent({
487
+ name: "DestylerDialogTrigger",
488
+ props: dialogTriggerProps,
489
+ setup() {
490
+ const rootContext = injectDialogRootContext();
491
+ const { forwardRef, currentElement } = composition.useForwardExpose();
492
+ rootContext.contentId || (rootContext.contentId = composition.useId(void 0, "destyler-dialog-content"));
493
+ vue.onMounted(() => {
494
+ rootContext.triggerElement = currentElement;
495
+ });
496
+ return {
497
+ rootContext,
498
+ forwardRef
499
+ };
500
+ },
501
+ render() {
502
+ return vue.h(primitive.Primitive, vue.mergeProps(this.$attrs, this.$props, {
503
+ "ref": (el) => this.forwardRef(el),
504
+ "type": this.$props.as === "button" ? "button" : void 0,
505
+ "aria-haspopup": "dialog",
506
+ "aria-expanded": this.rootContext.open.value || false,
507
+ "aria-controls": this.rootContext.open.value ? this.rootContext.contentId : void 0,
508
+ "data-state": this.rootContext.open.value ? "open" : "closed",
509
+ "onClick": () => {
510
+ this.rootContext.onOpenToggle();
511
+ }
512
+ }), () => this.$slots.default?.());
513
+ }
514
+ });
515
+
516
+ exports.DialogClose = DialogClose;
517
+ exports.DialogContent = DialogContent;
518
+ exports.DialogContentImpl = DialogContentImpl;
519
+ exports.DialogContentModal = DialogContentModal;
520
+ exports.DialogContentNonModal = DialogContentNonModal;
521
+ exports.DialogDescription = DialogDescription;
522
+ exports.DialogOverlay = DialogOverlay;
523
+ exports.DialogOverlayImpl = DialogOverlayImpl;
524
+ exports.DialogPortal = DialogPortal;
525
+ exports.DialogRoot = DialogRoot;
526
+ exports.DialogTitle = DialogTitle;
527
+ exports.DialogTrigger = DialogTrigger;
528
+ exports.dialogCloseProps = dialogCloseProps;
529
+ exports.dialogContentEmits = dialogContentEmits;
530
+ exports.dialogContentImplEmtis = dialogContentImplEmtis;
531
+ exports.dialogContentImplProps = dialogContentImplProps;
532
+ exports.dialogContentProps = dialogContentProps;
533
+ exports.dialogDescriptionProps = dialogDescriptionProps;
534
+ exports.dialogOverlayImplProps = dialogOverlayImplProps;
535
+ exports.dialogOverlayProps = dialogOverlayProps;
536
+ exports.dialogPortalProps = dialogPortalProps;
537
+ exports.dialogRootEmits = dialogRootEmits;
538
+ exports.dialogRootProps = dialogRootProps;
539
+ exports.dialogTitleProps = dialogTitleProps;
540
+ exports.dialogTriggerProps = dialogTriggerProps;