@v-c/dialog 0.0.3 → 1.0.0

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.
@@ -8,34 +8,20 @@ let vue = require("vue");
8
8
  let _v_c_util = require("@v-c/util");
9
9
  let _v_c_util_dist_pickAttrs = require("@v-c/util/dist/pickAttrs");
10
10
  _v_c_util_dist_pickAttrs = require_rolldown_runtime.__toESM(_v_c_util_dist_pickAttrs);
11
+ let _v_c_util_dist_Dom_focus = require("@v-c/util/dist/Dom/focus");
11
12
  let _v_c_util_dist_props_util = require("@v-c/util/dist/props-util");
12
- var sentinelStyle = {
13
- width: 0,
14
- height: 0,
15
- overflow: "hidden",
16
- outline: "none"
17
- };
18
- var entityStyle = { outline: "none" };
19
13
  var Panel = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots }) => {
20
14
  const { setPanel } = require_context.useGetRefContext();
21
- const mergedRef = (0, vue.shallowRef)();
15
+ const internalRef = (0, vue.shallowRef)();
22
16
  const mergeRefFun = (el) => {
23
- mergedRef.value = el;
24
- setPanel(el);
17
+ internalRef.value = el;
18
+ setPanel?.(el);
25
19
  props?.holderRef?.(el);
26
20
  };
27
- const sentinelStartRef = (0, vue.shallowRef)();
28
- const sentinelEndRef = (0, vue.shallowRef)();
29
- expose({
30
- focus: () => {
31
- sentinelStartRef.value?.focus?.({ preventScroll: true });
32
- },
33
- changeActive: (next) => {
34
- const { activeElement } = document;
35
- if (next && activeElement === sentinelEndRef.value) sentinelStartRef.value?.focus?.({ preventScroll: true });
36
- else if (!next && activeElement === sentinelStartRef.value) sentinelEndRef.value?.focus?.({ preventScroll: true });
37
- }
38
- });
21
+ (0, _v_c_util_dist_Dom_focus.useLockFocus)((0, vue.computed)(() => !!props.visible && !!props.isFixedPos && props.focusTrap !== false), () => internalRef.value);
22
+ expose({ focus: () => {
23
+ internalRef.value?.focus?.({ preventScroll: true });
24
+ } });
39
25
  return () => {
40
26
  const { width, height, footer, prefixCls, classNames: modalClassNames, styles: modalStyles, title, closable, closeIcon, bodyProps, bodyStyle, ariaId, style, className, forceRender, onClose, onMouseDown, onMouseUp, modalRender, animationVisible } = props;
41
27
  const contentStyle = {};
@@ -100,16 +86,9 @@ var Panel = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
100
86
  },
101
87
  "class": [prefixCls, className],
102
88
  "onMousedown": onMouseDown,
103
- "onMouseup": onMouseUp
104
- }), [(0, vue.createVNode)("div", {
105
- "ref": sentinelStartRef,
106
- "tabindex": 0,
107
- "style": entityStyle
108
- }, [renderContent()]), (0, vue.createVNode)("div", {
109
- "tabindex": 0,
110
- "ref": sentinelEndRef,
111
- "style": sentinelStyle
112
- }, null)]);
89
+ "onMouseup": onMouseUp,
90
+ "tabindex": -1
91
+ }), [renderContent()]);
113
92
  };
114
93
  }, {
115
94
  props: {
@@ -138,6 +117,11 @@ var Panel = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
138
117
  required: false,
139
118
  default: void 0
140
119
  },
120
+ isFixedPos: {
121
+ type: Boolean,
122
+ required: false,
123
+ default: void 0
124
+ },
141
125
  className: {
142
126
  type: String,
143
127
  required: false,
@@ -360,6 +344,11 @@ var Panel = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
360
344
  required: false,
361
345
  default: void 0
362
346
  },
347
+ focusTrap: {
348
+ type: Boolean,
349
+ required: false,
350
+ default: void 0
351
+ },
363
352
  panelRef: {
364
353
  required: false,
365
354
  default: void 0
@@ -6,10 +6,11 @@ export interface PanelProps extends Omit<IDialogPropTypes, 'getOpenCount'> {
6
6
  onMouseDown?: (e: MouseEvent) => void;
7
7
  onMouseUp?: MouseEventHandler;
8
8
  holderRef?: (el: HTMLDivElement) => void;
9
+ /** Used for focus lock. When true and open, focus will lock into the panel */
10
+ isFixedPos?: boolean;
9
11
  }
10
12
  export interface ContentRef {
11
13
  focus: () => void;
12
- changeActive: (next: boolean) => void;
13
14
  }
14
15
  declare const Panel: import('vue').DefineSetupFnComponent<PanelProps & {
15
16
  animationVisible: boolean;
@@ -1,35 +1,21 @@
1
1
  import { useGetRefContext } from "../../context.js";
2
- import { createVNode, defineComponent, mergeProps, shallowRef } from "vue";
2
+ import { computed, createVNode, defineComponent, mergeProps, shallowRef } from "vue";
3
3
  import { classNames, clsx } from "@v-c/util";
4
4
  import pickAttrs from "@v-c/util/dist/pickAttrs";
5
+ import { useLockFocus } from "@v-c/util/dist/Dom/focus";
5
6
  import { getStylePxValue } from "@v-c/util/dist/props-util";
6
- var sentinelStyle = {
7
- width: 0,
8
- height: 0,
9
- overflow: "hidden",
10
- outline: "none"
11
- };
12
- var entityStyle = { outline: "none" };
13
7
  var Panel_default = /* @__PURE__ */ defineComponent((props, { expose, slots }) => {
14
8
  const { setPanel } = useGetRefContext();
15
- const mergedRef = shallowRef();
9
+ const internalRef = shallowRef();
16
10
  const mergeRefFun = (el) => {
17
- mergedRef.value = el;
18
- setPanel(el);
11
+ internalRef.value = el;
12
+ setPanel?.(el);
19
13
  props?.holderRef?.(el);
20
14
  };
21
- const sentinelStartRef = shallowRef();
22
- const sentinelEndRef = shallowRef();
23
- expose({
24
- focus: () => {
25
- sentinelStartRef.value?.focus?.({ preventScroll: true });
26
- },
27
- changeActive: (next) => {
28
- const { activeElement } = document;
29
- if (next && activeElement === sentinelEndRef.value) sentinelStartRef.value?.focus?.({ preventScroll: true });
30
- else if (!next && activeElement === sentinelStartRef.value) sentinelEndRef.value?.focus?.({ preventScroll: true });
31
- }
32
- });
15
+ useLockFocus(computed(() => !!props.visible && !!props.isFixedPos && props.focusTrap !== false), () => internalRef.value);
16
+ expose({ focus: () => {
17
+ internalRef.value?.focus?.({ preventScroll: true });
18
+ } });
33
19
  return () => {
34
20
  const { width, height, footer, prefixCls, classNames: modalClassNames, styles: modalStyles, title, closable, closeIcon, bodyProps, bodyStyle, ariaId, style, className, forceRender, onClose, onMouseDown, onMouseUp, modalRender, animationVisible } = props;
35
21
  const contentStyle = {};
@@ -94,16 +80,9 @@ var Panel_default = /* @__PURE__ */ defineComponent((props, { expose, slots }) =
94
80
  },
95
81
  "class": [prefixCls, className],
96
82
  "onMousedown": onMouseDown,
97
- "onMouseup": onMouseUp
98
- }), [createVNode("div", {
99
- "ref": sentinelStartRef,
100
- "tabindex": 0,
101
- "style": entityStyle
102
- }, [renderContent()]), createVNode("div", {
103
- "tabindex": 0,
104
- "ref": sentinelEndRef,
105
- "style": sentinelStyle
106
- }, null)]);
83
+ "onMouseup": onMouseUp,
84
+ "tabindex": -1
85
+ }), [renderContent()]);
107
86
  };
108
87
  }, {
109
88
  props: {
@@ -132,6 +111,11 @@ var Panel_default = /* @__PURE__ */ defineComponent((props, { expose, slots }) =
132
111
  required: false,
133
112
  default: void 0
134
113
  },
114
+ isFixedPos: {
115
+ type: Boolean,
116
+ required: false,
117
+ default: void 0
118
+ },
135
119
  className: {
136
120
  type: String,
137
121
  required: false,
@@ -354,6 +338,11 @@ var Panel_default = /* @__PURE__ */ defineComponent((props, { expose, slots }) =
354
338
  required: false,
355
339
  default: void 0
356
340
  },
341
+ focusTrap: {
342
+ type: Boolean,
343
+ required: false,
344
+ default: void 0
345
+ },
357
346
  panelRef: {
358
347
  required: false,
359
348
  default: void 0
@@ -86,6 +86,11 @@ var Content = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) => {
86
86
  required: false,
87
87
  default: void 0
88
88
  },
89
+ isFixedPos: {
90
+ type: Boolean,
91
+ required: false,
92
+ default: void 0
93
+ },
89
94
  className: {
90
95
  type: String,
91
96
  required: false,
@@ -308,6 +313,11 @@ var Content = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) => {
308
313
  required: false,
309
314
  default: void 0
310
315
  },
316
+ focusTrap: {
317
+ type: Boolean,
318
+ required: false,
319
+ default: void 0
320
+ },
311
321
  panelRef: {
312
322
  required: false,
313
323
  default: void 0
@@ -81,6 +81,11 @@ var Content_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
81
81
  required: false,
82
82
  default: void 0
83
83
  },
84
+ isFixedPos: {
85
+ type: Boolean,
86
+ required: false,
87
+ default: void 0
88
+ },
84
89
  className: {
85
90
  type: String,
86
91
  required: false,
@@ -303,6 +308,11 @@ var Content_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
303
308
  required: false,
304
309
  default: void 0
305
310
  },
311
+ focusTrap: {
312
+ type: Boolean,
313
+ required: false,
314
+ default: void 0
315
+ },
306
316
  panelRef: {
307
317
  required: false,
308
318
  default: void 0
@@ -10,8 +10,6 @@ let vue = require("vue");
10
10
  let _v_c_util = require("@v-c/util");
11
11
  let _v_c_util_dist_Dom_contains = require("@v-c/util/dist/Dom/contains");
12
12
  _v_c_util_dist_Dom_contains = require_rolldown_runtime.__toESM(_v_c_util_dist_Dom_contains);
13
- let _v_c_util_dist_KeyCode = require("@v-c/util/dist/KeyCode");
14
- _v_c_util_dist_KeyCode = require_rolldown_runtime.__toESM(_v_c_util_dist_KeyCode);
15
13
  let _v_c_util_dist_pickAttrs = require("@v-c/util/dist/pickAttrs");
16
14
  _v_c_util_dist_pickAttrs = require_rolldown_runtime.__toESM(_v_c_util_dist_pickAttrs);
17
15
  var Dialog = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots }) => {
@@ -72,13 +70,6 @@ var Dialog = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
72
70
  else if (wrapperRef.value === e.target) onInternalClose(e);
73
71
  };
74
72
  }, { immediate: true });
75
- function onWrapperKeyDown(e) {
76
- if (props.keyboard && e === _v_c_util_dist_KeyCode.default.ESC) {
77
- e.stopPropagation();
78
- onInternalClose(e);
79
- }
80
- if (props.visible && e.keyCode === _v_c_util_dist_KeyCode.default.TAB) contentRef.value?.changeActive?.(!e.shiftKey);
81
- }
82
73
  (0, vue.watch)(() => props.visible, () => {
83
74
  if (props.visible) {
84
75
  animatedVisible.value = true;
@@ -109,8 +100,6 @@ var Dialog = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
109
100
  "maskProps": maskProps,
110
101
  "className": modalClassNames?.mask
111
102
  }, null), (0, vue.createVNode)("div", (0, vue.mergeProps)({
112
- "tabindex": -1,
113
- "onKeydown": onWrapperKeyDown,
114
103
  "class": [
115
104
  `${prefixCls}-wrap`,
116
105
  wrapClassName,
@@ -363,14 +352,18 @@ var Dialog = /* @__PURE__ */ (0, vue.defineComponent)((props, { expose, slots })
363
352
  required: false,
364
353
  default: void 0
365
354
  },
355
+ focusTrap: {
356
+ type: Boolean,
357
+ required: false,
358
+ default: void 0
359
+ },
366
360
  panelRef: {
367
361
  required: false,
368
362
  default: void 0
369
363
  }
370
364
  }, {
371
365
  prefixCls: "vc-dialog",
372
- visible: true,
373
- keyboard: true,
366
+ visible: false,
374
367
  focusTriggerAfterClose: true,
375
368
  closable: true,
376
369
  mask: true,
@@ -4,7 +4,6 @@ import Mask_default from "./Mask.js";
4
4
  import { createVNode, defineComponent, mergeDefaults, mergeProps, onUnmounted, shallowRef, useId, watch } from "vue";
5
5
  import { warning } from "@v-c/util";
6
6
  import contains from "@v-c/util/dist/Dom/contains";
7
- import KeyCode from "@v-c/util/dist/KeyCode";
8
7
  import pickAttrs from "@v-c/util/dist/pickAttrs";
9
8
  var Dialog_default = /* @__PURE__ */ defineComponent((props, { expose, slots }) => {
10
9
  if (process.env.NODE_ENV !== "production") {
@@ -64,13 +63,6 @@ var Dialog_default = /* @__PURE__ */ defineComponent((props, { expose, slots })
64
63
  else if (wrapperRef.value === e.target) onInternalClose(e);
65
64
  };
66
65
  }, { immediate: true });
67
- function onWrapperKeyDown(e) {
68
- if (props.keyboard && e === KeyCode.ESC) {
69
- e.stopPropagation();
70
- onInternalClose(e);
71
- }
72
- if (props.visible && e.keyCode === KeyCode.TAB) contentRef.value?.changeActive?.(!e.shiftKey);
73
- }
74
66
  watch(() => props.visible, () => {
75
67
  if (props.visible) {
76
68
  animatedVisible.value = true;
@@ -101,8 +93,6 @@ var Dialog_default = /* @__PURE__ */ defineComponent((props, { expose, slots })
101
93
  "maskProps": maskProps,
102
94
  "className": modalClassNames?.mask
103
95
  }, null), createVNode("div", mergeProps({
104
- "tabindex": -1,
105
- "onKeydown": onWrapperKeyDown,
106
96
  "class": [
107
97
  `${prefixCls}-wrap`,
108
98
  wrapClassName,
@@ -355,14 +345,18 @@ var Dialog_default = /* @__PURE__ */ defineComponent((props, { expose, slots })
355
345
  required: false,
356
346
  default: void 0
357
347
  },
348
+ focusTrap: {
349
+ type: Boolean,
350
+ required: false,
351
+ default: void 0
352
+ },
358
353
  panelRef: {
359
354
  required: false,
360
355
  default: void 0
361
356
  }
362
357
  }, {
363
358
  prefixCls: "vc-dialog",
364
- visible: true,
365
- keyboard: true,
359
+ visible: false,
366
360
  focusTriggerAfterClose: true,
367
361
  closable: true,
368
362
  mask: true,
@@ -11,6 +11,13 @@ _v_c_portal = require_rolldown_runtime.__toESM(_v_c_portal);
11
11
  var DialogWrap = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) => {
12
12
  const animatedVisible = (0, vue.shallowRef)(false);
13
13
  require_context.useRefProvide(props);
14
+ const onEsc = ({ top, event }) => {
15
+ const { keyboard = true } = props;
16
+ if (top && keyboard) {
17
+ event.stopPropagation();
18
+ props?.onClose?.(event);
19
+ }
20
+ };
14
21
  (0, vue.watch)(() => props.visible, () => {
15
22
  if (props.visible) animatedVisible.value = true;
16
23
  }, { immediate: true });
@@ -20,6 +27,7 @@ var DialogWrap = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) =>
20
27
  return (0, vue.createVNode)(_v_c_portal.default, {
21
28
  "open": visible || forceRender || animatedVisible.value,
22
29
  "autoDestroy": false,
30
+ "onEsc": onEsc,
23
31
  "getContainer": getContainer,
24
32
  "autoLock": visible || animatedVisible.value
25
33
  }, { default: () => [(0, vue.createVNode)(require_index.default, (0, vue.mergeProps)(props, {
@@ -259,6 +267,11 @@ var DialogWrap = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) =>
259
267
  required: false,
260
268
  default: void 0
261
269
  },
270
+ focusTrap: {
271
+ type: Boolean,
272
+ required: false,
273
+ default: void 0
274
+ },
262
275
  panelRef: {
263
276
  required: false,
264
277
  default: void 0
@@ -267,12 +280,12 @@ var DialogWrap = /* @__PURE__ */ (0, vue.defineComponent)((props, { slots }) =>
267
280
  getContainer: void 0,
268
281
  closeIcon: void 0,
269
282
  prefixCls: "vc-dialog",
270
- visible: true,
271
283
  keyboard: true,
272
284
  focusTriggerAfterClose: true,
273
285
  closable: true,
274
286
  mask: true,
275
287
  maskClosable: true,
288
+ destroyOnHidden: false,
276
289
  forceRender: false
277
290
  }),
278
291
  name: "Dialog"
@@ -5,6 +5,13 @@ import Portal from "@v-c/portal";
5
5
  var DialogWrap_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
6
6
  const animatedVisible = shallowRef(false);
7
7
  useRefProvide(props);
8
+ const onEsc = ({ top, event }) => {
9
+ const { keyboard = true } = props;
10
+ if (top && keyboard) {
11
+ event.stopPropagation();
12
+ props?.onClose?.(event);
13
+ }
14
+ };
8
15
  watch(() => props.visible, () => {
9
16
  if (props.visible) animatedVisible.value = true;
10
17
  }, { immediate: true });
@@ -14,6 +21,7 @@ var DialogWrap_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
14
21
  return createVNode(Portal, {
15
22
  "open": visible || forceRender || animatedVisible.value,
16
23
  "autoDestroy": false,
24
+ "onEsc": onEsc,
17
25
  "getContainer": getContainer,
18
26
  "autoLock": visible || animatedVisible.value
19
27
  }, { default: () => [createVNode(Dialog_default, mergeProps(props, {
@@ -253,6 +261,11 @@ var DialogWrap_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
253
261
  required: false,
254
262
  default: void 0
255
263
  },
264
+ focusTrap: {
265
+ type: Boolean,
266
+ required: false,
267
+ default: void 0
268
+ },
256
269
  panelRef: {
257
270
  required: false,
258
271
  default: void 0
@@ -261,12 +274,12 @@ var DialogWrap_default = /* @__PURE__ */ defineComponent((props, { slots }) => {
261
274
  getContainer: void 0,
262
275
  closeIcon: void 0,
263
276
  prefixCls: "vc-dialog",
264
- visible: true,
265
277
  keyboard: true,
266
278
  focusTriggerAfterClose: true,
267
279
  closable: true,
268
280
  mask: true,
269
281
  maskClosable: true,
282
+ destroyOnHidden: false,
270
283
  forceRender: false
271
284
  }),
272
285
  name: "Dialog"
@@ -50,5 +50,6 @@ export interface IDialogPropTypes {
50
50
  modalRender?: (node: VueNode) => VueNode;
51
51
  forceRender?: boolean;
52
52
  focusTriggerAfterClose?: boolean;
53
+ focusTrap?: boolean;
53
54
  panelRef?: any;
54
55
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@v-c/dialog",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "1.0.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -25,8 +25,8 @@
25
25
  "vue": "^3.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@v-c/portal": "^1.0.1",
29
- "@v-c/util": "^1.0.7"
28
+ "@v-c/portal": "^1.0.6",
29
+ "@v-c/util": "^1.0.9"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "vite build",