@varlet/ui 3.0.6 → 3.1.0-alpha.1709284240068

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.
Files changed (67) hide show
  1. package/es/action-sheet/ActionItem.mjs +79 -0
  2. package/es/action-sheet/ActionItemSfc.css +0 -0
  3. package/es/action-sheet/ActionSheet.mjs +29 -56
  4. package/es/action-sheet/actionSheet.css +1 -1
  5. package/es/action-sheet/props.mjs +4 -1
  6. package/es/action-sheet/style/index.mjs +1 -0
  7. package/es/button/Button.mjs +6 -6
  8. package/es/checkbox/Checkbox.mjs +77 -49
  9. package/es/checkbox/checkbox.css +1 -1
  10. package/es/context/stack.mjs +46 -0
  11. package/es/dialog/Dialog.mjs +12 -2
  12. package/es/dialog/props.mjs +4 -1
  13. package/es/field-decorator/FieldDecorator.mjs +10 -7
  14. package/es/field-decorator/props.mjs +1 -1
  15. package/es/hover-overlay/HoverOverlay.mjs +4 -2
  16. package/es/image-preview/ImagePreview.mjs +12 -16
  17. package/es/image-preview/props.mjs +4 -1
  18. package/es/index.bundle.mjs +1 -1
  19. package/es/index.mjs +1 -1
  20. package/es/input/Input.mjs +8 -8
  21. package/es/link/Link.mjs +10 -4
  22. package/es/link/link.css +1 -1
  23. package/es/menu/menu.css +1 -1
  24. package/es/menu/props.mjs +6 -1
  25. package/es/menu/usePopover.mjs +12 -2
  26. package/es/menu-option/MenuOption.mjs +72 -43
  27. package/es/menu-option/menuOption.css +1 -1
  28. package/es/menu-select/MenuSelect.mjs +28 -3
  29. package/es/option/Option.mjs +77 -48
  30. package/es/option/option.css +1 -1
  31. package/es/overlay/Overlay.mjs +19 -2
  32. package/es/overlay/props.mjs +7 -1
  33. package/es/paper/paper.css +1 -1
  34. package/es/picker/Picker.mjs +2 -0
  35. package/es/picker/props.mjs +4 -1
  36. package/es/popup/Popup.mjs +18 -2
  37. package/es/popup/props.mjs +7 -1
  38. package/es/select/Select.mjs +279 -213
  39. package/es/select/select.css +1 -1
  40. package/es/snackbar/style/index.mjs +1 -1
  41. package/es/style.css +1 -1
  42. package/es/switch/Switch.mjs +82 -52
  43. package/es/switch/switch.css +1 -1
  44. package/es/tab/tab.css +1 -1
  45. package/es/themes/dark/link.mjs +2 -1
  46. package/es/themes/dark/paper.mjs +2 -1
  47. package/es/themes/dark/tab.mjs +3 -1
  48. package/es/themes/md3-dark/link.mjs +2 -1
  49. package/es/themes/md3-dark/paper.mjs +2 -1
  50. package/es/themes/md3-dark/tab.mjs +3 -1
  51. package/es/themes/md3-light/link.mjs +2 -1
  52. package/es/themes/md3-light/paper.mjs +2 -1
  53. package/es/themes/md3-light/tab.mjs +3 -1
  54. package/es/tooltip/props.mjs +6 -1
  55. package/es/uploader/Uploader.mjs +70 -44
  56. package/es/uploader/uploader.css +1 -1
  57. package/es/utils/elements.mjs +32 -0
  58. package/es/varlet.esm.js +7721 -7457
  59. package/highlight/web-types.en-US.json +2 -2
  60. package/highlight/web-types.zh-CN.json +3 -3
  61. package/lib/style.css +1 -1
  62. package/lib/varlet.cjs.js +1527 -1084
  63. package/package.json +7 -7
  64. package/types/input.d.ts +1 -1
  65. package/types/select.d.ts +1 -0
  66. package/types/styleVars.d.ts +100 -92
  67. package/umd/varlet.js +6 -6
@@ -8,7 +8,7 @@ const props = {
8
8
  type: String,
9
9
  default: ""
10
10
  },
11
- isFocus: Boolean,
11
+ isFocusing: Boolean,
12
12
  size: {
13
13
  type: String,
14
14
  default: "normal"
@@ -1,13 +1,14 @@
1
1
  import { defineComponent } from "vue";
2
2
  import { props } from "./props.mjs";
3
3
  import { createNamespace } from "../utils/components.mjs";
4
+ import { inMobile } from "@varlet/shared";
4
5
  const { name, n, classes } = createNamespace("hover-overlay");
5
6
  import { normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue";
6
7
  function __render__(_ctx, _cache) {
7
8
  return _openBlock(), _createElementBlock(
8
9
  "div",
9
10
  {
10
- class: _normalizeClass(_ctx.classes(_ctx.n(), [_ctx.hovering, _ctx.n("--hovering")], [_ctx.focusing, _ctx.n("--focusing")]))
11
+ class: _normalizeClass(_ctx.classes(_ctx.n(), [_ctx.hovering, _ctx.n("--hovering")], [_ctx.focusing && !_ctx.inMobile(), _ctx.n("--focusing")]))
11
12
  },
12
13
  null,
13
14
  2
@@ -19,7 +20,8 @@ const __sfc__ = defineComponent({
19
20
  props,
20
21
  setup: () => ({
21
22
  n,
22
- classes
23
+ classes,
24
+ inMobile
23
25
  })
24
26
  });
25
27
  __sfc__.render = __render__;
@@ -2,9 +2,9 @@ import VarSwipe from "../swipe/index.mjs";
2
2
  import VarSwipeItem from "../swipe-item/index.mjs";
3
3
  import VarIcon from "../icon/index.mjs";
4
4
  import VarPopup from "../popup/index.mjs";
5
- import { defineComponent, ref, computed, watch } from "vue";
5
+ import { defineComponent, ref, computed } from "vue";
6
6
  import { toNumber, clamp, preventDefault, call } from "@varlet/shared";
7
- import { useEventListener, useTouch } from "@varlet/use";
7
+ import { useEventListener, useTouch, useVModel } from "@varlet/use";
8
8
  import { props } from "./props.mjs";
9
9
  import { createNamespace } from "../utils/components.mjs";
10
10
  const { name, n, classes } = createNamespace("image-preview");
@@ -24,18 +24,21 @@ function __render__(_ctx, _cache) {
24
24
  const _component_var_icon = _resolveComponent("var-icon");
25
25
  const _component_var_popup = _resolveComponent("var-popup");
26
26
  return _openBlock(), _createBlock(_component_var_popup, {
27
- class: _normalizeClass(_ctx.n("popup")),
28
27
  "var-image-preview-cover": "",
28
+ class: _normalizeClass(_ctx.n("popup")),
29
29
  transition: _ctx.n("$-fade"),
30
- show: _ctx.popupShow,
31
30
  overlay: false,
32
31
  "close-on-click-overlay": false,
32
+ "close-on-key-escape": _ctx.closeOnKeyEscape,
33
33
  "lock-scroll": _ctx.lockScroll,
34
34
  teleport: _ctx.teleport,
35
+ show: _ctx.show,
36
+ "onUpdate:show": _cache[3] || (_cache[3] = ($event) => _ctx.show = $event),
35
37
  onOpen: _ctx.onOpen,
36
38
  onClose: _ctx.onClose,
37
39
  onClosed: _ctx.onClosed,
38
40
  onOpened: _ctx.onOpened,
41
+ onKeyEscape: _ctx.onKeyEscape,
39
42
  onRouteChange: _ctx.onRouteChange
40
43
  }, {
41
44
  default: _withCtx(() => [
@@ -132,7 +135,7 @@ function __render__(_ctx, _cache) {
132
135
  ]),
133
136
  _: 3
134
137
  /* FORWARDED */
135
- }, 8, ["class", "transition", "show", "lock-scroll", "teleport", "onOpen", "onClose", "onClosed", "onOpened", "onRouteChange"]);
138
+ }, 8, ["class", "transition", "close-on-key-escape", "lock-scroll", "teleport", "show", "onOpen", "onClose", "onClosed", "onOpened", "onKeyEscape", "onRouteChange"]);
136
139
  }
137
140
  const __sfc__ = defineComponent({
138
141
  name,
@@ -145,7 +148,7 @@ const __sfc__ = defineComponent({
145
148
  inheritAttrs: false,
146
149
  props,
147
150
  setup(props2) {
148
- const popupShow = ref(false);
151
+ const show = useVModel(props2, "show");
149
152
  const scale = ref(1);
150
153
  const translateX = ref(0);
151
154
  const translateY = ref(0);
@@ -155,8 +158,8 @@ const __sfc__ = defineComponent({
155
158
  const swipeRef = ref(null);
156
159
  const { moveX, moveY, distance, startTime, startTouch, moveTouch, endTouch } = useTouch();
157
160
  const isPreventDefault = computed(() => {
158
- const { imagePreventDefault, show } = props2;
159
- return show && imagePreventDefault;
161
+ const { imagePreventDefault, show: show2 } = props2;
162
+ return show2 && imagePreventDefault;
160
163
  });
161
164
  let closeRunner = null;
162
165
  let longPressRunner = null;
@@ -166,13 +169,6 @@ const __sfc__ = defineComponent({
166
169
  prev: null
167
170
  };
168
171
  useEventListener(() => document, "contextmenu", preventImageDefault);
169
- watch(
170
- () => props2.show,
171
- (newShow) => {
172
- popupShow.value = newShow;
173
- },
174
- { immediate: true }
175
- );
176
172
  function zoomIn(ratio) {
177
173
  scale.value = toNumber(ratio);
178
174
  canSwipe.value = false;
@@ -313,7 +309,7 @@ const __sfc__ = defineComponent({
313
309
  return {
314
310
  swipeRef,
315
311
  isPreventDefault,
316
- popupShow,
312
+ show,
317
313
  scale,
318
314
  translateX,
319
315
  translateY,
@@ -43,7 +43,10 @@ const props = __spreadValues(__spreadValues({
43
43
  "onOpened",
44
44
  "onClosed",
45
45
  // internal for function call closes the dialog
46
- "onRouteChange"
46
+ "onRouteChange",
47
+ // internal for esc
48
+ "closeOnKeyEscape",
49
+ "onKeyEscape"
47
50
  ]));
48
51
  export {
49
52
  props
@@ -262,7 +262,7 @@ import './tooltip/style/index.mjs'
262
262
  import './uploader/style/index.mjs'
263
263
  import './watermark/style/index.mjs'
264
264
 
265
- const version = '3.0.6'
265
+ const version = '3.1.0-alpha.1709284240068'
266
266
 
267
267
  function install(app) {
268
268
  ActionSheet.install && app.use(ActionSheet)
package/es/index.mjs CHANGED
@@ -174,7 +174,7 @@ export * from './tooltip/index.mjs'
174
174
  export * from './uploader/index.mjs'
175
175
  export * from './watermark/index.mjs'
176
176
 
177
- const version = '3.0.6'
177
+ const version = '3.1.0-alpha.1709284240068'
178
178
 
179
179
  function install(app) {
180
180
  ActionSheet.install && app.use(ActionSheet)
@@ -35,7 +35,7 @@ function __render__(_ctx, _cache) {
35
35
  textColor: _ctx.textColor,
36
36
  focusColor: _ctx.focusColor,
37
37
  blurColor: _ctx.blurColor,
38
- isFocus: _ctx.isFocus,
38
+ isFocusing: _ctx.isFocusing,
39
39
  errorMessage: _ctx.errorMessage,
40
40
  formDisabled: _ctx.formDisabled,
41
41
  disabled: _ctx.disabled,
@@ -47,8 +47,8 @@ function __render__(_ctx, _cache) {
47
47
  onClear: _ctx.handleClear
48
48
  })),
49
49
  _createSlots({
50
- "clear-icon": _withCtx(() => [
51
- _renderSlot(_ctx.$slots, "clear-icon")
50
+ "clear-icon": _withCtx(({ clear }) => [
51
+ _renderSlot(_ctx.$slots, "clear-icon", { clear })
52
52
  ]),
53
53
  "append-icon": _withCtx(() => [
54
54
  _renderSlot(_ctx.$slots, "append-icon")
@@ -179,7 +179,7 @@ const __sfc__ = defineComponent({
179
179
  setup(props2) {
180
180
  const id = useId();
181
181
  const el = ref(null);
182
- const isFocus = ref(false);
182
+ const isFocusing = ref(false);
183
183
  const isComposing = ref(false);
184
184
  const { bindForm, form } = useForm();
185
185
  const {
@@ -214,7 +214,7 @@ const __sfc__ = defineComponent({
214
214
  if (errorMessage.value) {
215
215
  return "var(--field-decorator-error-color)";
216
216
  }
217
- if (isFocus.value) {
217
+ if (isFocusing.value) {
218
218
  return focusColor || "var(--field-decorator-focus-color)";
219
219
  }
220
220
  return blurColor || "var(--field-decorator-placeholder-color, var(--field-decorator-blur-color))";
@@ -237,12 +237,12 @@ const __sfc__ = defineComponent({
237
237
  });
238
238
  }
239
239
  function handleFocus(e) {
240
- isFocus.value = true;
240
+ isFocusing.value = true;
241
241
  call(props2.onFocus, e);
242
242
  validateWithTrigger("onFocus");
243
243
  }
244
244
  function handleBlur(e) {
245
- isFocus.value = false;
245
+ isFocusing.value = false;
246
246
  call(props2.onBlur, e);
247
247
  validateWithTrigger("onBlur");
248
248
  }
@@ -343,7 +343,7 @@ const __sfc__ = defineComponent({
343
343
  return {
344
344
  el,
345
345
  id,
346
- isFocus,
346
+ isFocusing,
347
347
  isComposing,
348
348
  errorMessage,
349
349
  placeholderColor,
package/es/link/Link.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { computed, defineComponent } from "vue";
1
+ import { computed, defineComponent, ref } from "vue";
2
2
  import { props } from "./props.mjs";
3
3
  import { createNamespace } from "../utils/components.mjs";
4
4
  import { toSizeUnit } from "../utils/elements.mjs";
5
- import { call } from "@varlet/shared";
5
+ import { call, inMobile } from "@varlet/shared";
6
6
  const { name, n, classes } = createNamespace("link");
7
7
  import { renderSlot as _renderSlot, resolveDynamicComponent as _resolveDynamicComponent, mergeProps as _mergeProps, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from "vue";
8
8
  function __render__(_ctx, _cache) {
@@ -13,13 +13,16 @@ function __render__(_ctx, _cache) {
13
13
  _ctx.n("$--inline-flex"),
14
14
  _ctx.n(`--${_ctx.type}`),
15
15
  [_ctx.underline !== "none", _ctx.n(`--underline-${_ctx.underline}`)],
16
- [_ctx.disabled, _ctx.n("--disabled")]
16
+ [_ctx.disabled, _ctx.n("--disabled")],
17
+ [_ctx.isFocusing && !_ctx.inMobile(), _ctx.n("--focusing")]
17
18
  ),
18
19
  style: {
19
20
  color: _ctx.textColor,
20
21
  fontSize: _ctx.toSizeUnit(_ctx.textSize)
21
22
  },
22
- onClick: _ctx.handleClick
23
+ onClick: _ctx.handleClick,
24
+ onFocus: _cache[0] || (_cache[0] = ($event) => _ctx.isFocusing = true),
25
+ onBlur: _cache[1] || (_cache[1] = ($event) => _ctx.isFocusing = false)
23
26
  }), {
24
27
  default: _withCtx(() => [
25
28
  _renderSlot(_ctx.$slots, "default")
@@ -32,6 +35,7 @@ const __sfc__ = defineComponent({
32
35
  name,
33
36
  props,
34
37
  setup(props2) {
38
+ const isFocusing = ref(false);
35
39
  const tag = computed(() => {
36
40
  const { disabled, href, to } = props2;
37
41
  if (disabled) {
@@ -67,6 +71,8 @@ const __sfc__ = defineComponent({
67
71
  return {
68
72
  tag,
69
73
  linkProps,
74
+ isFocusing,
75
+ inMobile,
70
76
  n,
71
77
  classes,
72
78
  handleClick,
package/es/link/link.css CHANGED
@@ -1 +1 @@
1
- :root { --link-default-color: #555; --link-primary-color: var(--color-primary); --link-danger-color: var(--color-danger); --link-success-color: var(--color-success); --link-warning-color: var(--color-warning); --link-info-color: var(--color-info); --link-disabled-color: var(--color-text-disabled); --link-font-size: var(--font-size-md);}.var-link { position: relative; justify-content: center; align-items: center; outline: none; cursor: pointer; font-family: inherit; white-space: nowrap; text-decoration: none; font-size: var(--link-font-size);}.var-link--underline-always { text-decoration: underline;}.var-link--underline-hover:hover { text-decoration: underline;}.var-link--default { color: var(--link-default-color);}.var-link--primary { color: var(--link-primary-color);}.var-link--info { color: var(--link-info-color);}.var-link--success { color: var(--link-success-color);}.var-link--warning { color: var(--link-warning-color);}.var-link--danger { color: var(--link-danger-color);}.var-link--disabled { color: var(--link-disabled-color); cursor: not-allowed;}
1
+ :root { --link-default-color: #555; --link-primary-color: var(--color-primary); --link-danger-color: var(--color-danger); --link-success-color: var(--color-success); --link-warning-color: var(--color-warning); --link-info-color: var(--color-info); --link-disabled-color: var(--color-text-disabled); --link-font-size: var(--font-size-md); --link-focus-opacity: 0.8;}.var-link { position: relative; justify-content: center; align-items: center; outline: none; cursor: pointer; font-family: inherit; white-space: nowrap; text-decoration: none; font-size: var(--link-font-size); transition: opacity 0.15s;}.var-link--underline-always { text-decoration: underline;}.var-link--underline-hover:hover { text-decoration: underline;}.var-link--default { color: var(--link-default-color);}.var-link--primary { color: var(--link-primary-color);}.var-link--info { color: var(--link-info-color);}.var-link--success { color: var(--link-success-color);}.var-link--warning { color: var(--link-warning-color);}.var-link--danger { color: var(--link-danger-color);}.var-link--disabled { color: var(--link-disabled-color); cursor: not-allowed;}.var-link--focusing { opacity: var(--link-focus-opacity);}
package/es/menu/menu.css CHANGED
@@ -1 +1 @@
1
- :root { --menu-background-color: var(--color-surface-container-high); --menu-border-radius: 2px;}.var-menu { display: inline-block;}.var-menu__menu { border-radius: var(--menu-border-radius);}.var-menu-enter-from,.var-menu-leave-to { opacity: 0; transform: scale(0.8);}.var-menu-enter-active,.var-menu-leave-active { transition-property: opacity, transform; transition-duration: 0.2s;}.var-menu--menu-background-color { background: var(--menu-background-color);}
1
+ :root { --menu-background-color: var(--color-surface-container-high); --menu-border-radius: 2px;}.var-menu { display: inline-block; outline: none;}.var-menu__menu { border-radius: var(--menu-border-radius);}.var-menu-enter-from,.var-menu-leave-to { opacity: 0; transform: scale(0.8);}.var-menu-enter-active,.var-menu-leave-active { transition-property: opacity, transform; transition-duration: 0.2s;}.var-menu--menu-background-color { background: var(--menu-background-color);}
package/es/menu/props.mjs CHANGED
@@ -43,7 +43,12 @@ const props = {
43
43
  onClose: defineListenerProp(),
44
44
  onClosed: defineListenerProp(),
45
45
  onClickOutside: defineListenerProp(),
46
- "onUpdate:show": defineListenerProp()
46
+ "onUpdate:show": defineListenerProp(),
47
+ // internal for esc
48
+ closeOnKeyEscape: {
49
+ type: Boolean,
50
+ default: true
51
+ }
47
52
  };
48
53
  export {
49
54
  props
@@ -40,12 +40,13 @@ var __async = (__this, __arguments, generator) => {
40
40
  import flip from "@popperjs/core/lib/modifiers/flip.js";
41
41
  import offset from "@popperjs/core/lib/modifiers/offset.js";
42
42
  import computeStyles from "@popperjs/core/lib/modifiers/computeStyles.js";
43
- import { onWindowResize, useClickOutside, useVModel } from "@varlet/use";
44
- import { doubleRaf, getStyle, call } from "@varlet/shared";
43
+ import { onWindowResize, useClickOutside, useEventListener, useVModel } from "@varlet/use";
44
+ import { doubleRaf, getStyle, call, preventDefault } from "@varlet/shared";
45
45
  import { toPxNum } from "../utils/elements.mjs";
46
46
  import { onMounted, onUnmounted, ref, watch } from "vue";
47
47
  import { createPopper } from "@popperjs/core/lib/popper-lite.js";
48
48
  import { useZIndex } from "../context/zIndex.mjs";
49
+ import { useStack } from "../context/stack.mjs";
49
50
  function usePopover(options) {
50
51
  const host = ref(null);
51
52
  const popover = ref(null);
@@ -63,6 +64,7 @@ function usePopover(options) {
63
64
  }
64
65
  });
65
66
  const { zIndex } = useZIndex(() => show.value, 1);
67
+ useStack(() => show.value, zIndex);
66
68
  let popoverInstance = null;
67
69
  let enterPopover = false;
68
70
  let enterHost = false;
@@ -288,6 +290,13 @@ function usePopover(options) {
288
290
  };
289
291
  };
290
292
  const getReference = () => options.reference ? host.value.querySelector(options.reference) : host.value;
293
+ const handleKeydown = (event) => {
294
+ const { closeOnKeyEscape = false } = options;
295
+ if (event.key === "Escape" && closeOnKeyEscape && show.value) {
296
+ preventDefault(event);
297
+ close();
298
+ }
299
+ };
291
300
  const resize = () => {
292
301
  popoverInstance.setOptions(getPopperOptions());
293
302
  };
@@ -303,6 +312,7 @@ function usePopover(options) {
303
312
  show.value = false;
304
313
  call(options["onUpdate:show"], false);
305
314
  };
315
+ useEventListener(window, "keydown", handleKeydown);
306
316
  useClickOutside(getReference, "click", handleClickOutside);
307
317
  onWindowResize(resize);
308
318
  watch(() => [options.offsetX, options.offsetY, options.placement, options.strategy], resize);
@@ -6,59 +6,62 @@ import { defineComponent, computed, ref, watch } from "vue";
6
6
  import { useMenuSelect } from "./provide.mjs";
7
7
  import { createNamespace } from "../utils/components.mjs";
8
8
  import { props } from "./props.mjs";
9
+ import { preventDefault } from "@varlet/shared";
10
+ import { useEventListener } from "@varlet/use";
9
11
  const { name, n, classes } = createNamespace("menu-option");
10
- import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withModifiers as _withModifiers, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, renderSlot as _renderSlot, toDisplayString as _toDisplayString, createVNode as _createVNode, resolveDirective as _resolveDirective, createElementBlock as _createElementBlock, withDirectives as _withDirectives } from "vue";
12
+ import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withModifiers as _withModifiers, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, renderSlot as _renderSlot, toDisplayString as _toDisplayString, createVNode as _createVNode, resolveDirective as _resolveDirective, createElementBlock as _createElementBlock, withDirectives as _withDirectives, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from "vue";
13
+ const _withScopeId = (n2) => (_pushScopeId(""), n2 = n2(), _popScopeId(), n2);
14
+ const _hoisted_1 = ["tabindex"];
11
15
  function __render__(_ctx, _cache) {
12
16
  const _component_var_checkbox = _resolveComponent("var-checkbox");
13
17
  const _component_var_hover_overlay = _resolveComponent("var-hover-overlay");
14
18
  const _directive_ripple = _resolveDirective("ripple");
15
19
  const _directive_hover = _resolveDirective("hover");
16
- return _withDirectives((_openBlock(), _createElementBlock(
17
- "div",
18
- {
19
- class: _normalizeClass(
20
- _ctx.classes(_ctx.n(), _ctx.n("$--box"), _ctx.n(`--${_ctx.size}`), [_ctx.optionSelected, _ctx.n("--selected-color")], [_ctx.disabled, _ctx.n("--disabled")])
21
- ),
22
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.handleClick && _ctx.handleClick(...args))
23
- },
24
- [
20
+ return _withDirectives((_openBlock(), _createElementBlock("div", {
21
+ ref: "root",
22
+ class: _normalizeClass(
23
+ _ctx.classes(_ctx.n(), _ctx.n("$--box"), _ctx.n(`--${_ctx.size}`), [_ctx.optionSelected, _ctx.n("--selected-color")], [_ctx.disabled, _ctx.n("--disabled")])
24
+ ),
25
+ tabindex: _ctx.disabled ? void 0 : "-1",
26
+ onClick: _cache[2] || (_cache[2] = (...args) => _ctx.handleClick && _ctx.handleClick(...args)),
27
+ onFocus: _cache[3] || (_cache[3] = ($event) => _ctx.isFocusing = true),
28
+ onBlur: _cache[4] || (_cache[4] = ($event) => _ctx.isFocusing = false)
29
+ }, [
30
+ _createElementVNode(
31
+ "div",
32
+ {
33
+ class: _normalizeClass(_ctx.classes(_ctx.n("cover"), [_ctx.optionSelected, _ctx.n("--selected-background")]))
34
+ },
35
+ null,
36
+ 2
37
+ /* CLASS */
38
+ ),
39
+ _ctx.multiple ? (_openBlock(), _createBlock(_component_var_checkbox, {
40
+ key: 0,
41
+ ref: "checkbox",
42
+ modelValue: _ctx.optionSelected,
43
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.optionSelected = $event),
44
+ disabled: _ctx.disabled,
45
+ onClick: _cache[1] || (_cache[1] = _withModifiers(() => {
46
+ }, ["stop"])),
47
+ onChange: _ctx.handleSelect
48
+ }, null, 8, ["modelValue", "disabled", "onChange"])) : _createCommentVNode("v-if", true),
49
+ _renderSlot(_ctx.$slots, "default", {}, () => [
25
50
  _createElementVNode(
26
51
  "div",
27
52
  {
28
- class: _normalizeClass(_ctx.classes(_ctx.n("cover"), [_ctx.optionSelected, _ctx.n("--selected-background")]))
53
+ class: _normalizeClass(_ctx.classes(_ctx.n("text"), _ctx.n("$--ellipsis")))
29
54
  },
30
- null,
31
- 2
32
- /* CLASS */
33
- ),
34
- _ctx.multiple ? (_openBlock(), _createBlock(_component_var_checkbox, {
35
- key: 0,
36
- ref: "checkbox",
37
- modelValue: _ctx.optionSelected,
38
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.optionSelected = $event),
39
- disabled: _ctx.disabled,
40
- onClick: _cache[1] || (_cache[1] = _withModifiers(() => {
41
- }, ["stop"])),
42
- onChange: _ctx.handleSelect
43
- }, null, 8, ["modelValue", "disabled", "onChange"])) : _createCommentVNode("v-if", true),
44
- _renderSlot(_ctx.$slots, "default", {}, () => [
45
- _createElementVNode(
46
- "div",
47
- {
48
- class: _normalizeClass(_ctx.classes(_ctx.n("text"), _ctx.n("$--ellipsis")))
49
- },
50
- _toDisplayString(_ctx.label),
51
- 3
52
- /* TEXT, CLASS */
53
- )
54
- ]),
55
- _createVNode(_component_var_hover_overlay, {
56
- hovering: _ctx.hovering && !_ctx.disabled
57
- }, null, 8, ["hovering"])
58
- ],
59
- 2
60
- /* CLASS */
61
- )), [
55
+ _toDisplayString(_ctx.label),
56
+ 3
57
+ /* TEXT, CLASS */
58
+ )
59
+ ]),
60
+ _createVNode(_component_var_hover_overlay, {
61
+ hovering: _ctx.hovering && !_ctx.disabled,
62
+ focusing: _ctx.isFocusing && !_ctx.disabled
63
+ }, null, 8, ["hovering", "focusing"])
64
+ ], 42, _hoisted_1)), [
62
65
  [_directive_ripple, { disabled: _ctx.disabled }],
63
66
  [_directive_hover, _ctx.handleHovering, "desktop"]
64
67
  ]);
@@ -72,6 +75,8 @@ const __sfc__ = defineComponent({
72
75
  },
73
76
  props,
74
77
  setup(props2) {
78
+ const root = ref();
79
+ const isFocusing = ref(false);
75
80
  const optionSelected = ref(false);
76
81
  const selected = computed(() => optionSelected.value);
77
82
  const label = computed(() => props2.label);
@@ -87,12 +92,34 @@ const __sfc__ = defineComponent({
87
92
  };
88
93
  watch([() => props2.label, () => props2.value], computeLabel);
89
94
  bindMenuSelect(menuOptionProvider);
95
+ useEventListener(() => window, "keydown", handleKeydown);
96
+ useEventListener(() => window, "keyup", handleKeyup);
90
97
  function handleClick() {
91
98
  if (props2.disabled) {
92
99
  return;
93
100
  }
94
101
  handleSelect();
95
102
  }
103
+ function handleKeydown(event) {
104
+ if (!isFocusing.value) {
105
+ return;
106
+ }
107
+ if (event.key === " " || event.key === "Enter") {
108
+ preventDefault(event);
109
+ }
110
+ if (event.key === "Enter") {
111
+ root.value.click();
112
+ }
113
+ }
114
+ function handleKeyup(event) {
115
+ if (!isFocusing.value) {
116
+ return;
117
+ }
118
+ if (event.key === " ") {
119
+ preventDefault(event);
120
+ root.value.click();
121
+ }
122
+ }
96
123
  function handleSelect() {
97
124
  if (multiple.value) {
98
125
  optionSelected.value = !optionSelected.value;
@@ -103,10 +130,12 @@ const __sfc__ = defineComponent({
103
130
  optionSelected.value = checked;
104
131
  }
105
132
  return {
133
+ root,
106
134
  optionSelected,
107
135
  size,
108
136
  multiple,
109
137
  hovering,
138
+ isFocusing,
110
139
  n,
111
140
  classes,
112
141
  handleHovering,
@@ -1 +1 @@
1
- :root { --menu-option-normal-height: 38px; --menu-option-small-height: 30px; --menu-option-mini-height: 24px; --menu-option-large-height: 46px; --menu-option-padding: 0 12px; --menu-option-normal-font-size: var(--font-size-md); --menu-option-small-font-size: var(--font-size-sm); --menu-option-mini-font-size: var(--font-size-xs); --menu-option-large-font-size: var(--font-size-lg); --menu-option-selected-background: var(--color-primary); --menu-option-text-color: #555; --menu-option-disabled-color: var(--color-text-disabled);}.var-menu-option { position: relative; display: flex; align-items: center; padding: var(--menu-option-padding); cursor: pointer; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); color: var(--menu-option-text-color);}.var-menu-option__cover { position: absolute; top: 0; left: 0; right: 0; bottom: 0; opacity: 0.2; background: transparent;}.var-menu-option__text { display: flex; align-items: center;}.var-menu-option--normal { height: var(--menu-option-normal-height); font-size: var(--menu-option-normal-font-size);}.var-menu-option--large { height: var(--menu-option-large-height); font-size: var(--menu-option-large-font-size);}.var-menu-option--small { height: var(--menu-option-small-height); font-size: var(--menu-option-small-font-size);}.var-menu-option--mini { height: var(--menu-option-mini-height); font-size: var(--menu-option-mini-font-size);}.var-menu-option--selected-background { background: var(--menu-option-selected-background);}.var-menu-option--selected-color { color: var(--menu-option-selected-background);}.var-menu-option--disabled { color: var(--menu-option-disabled-color); cursor: not-allowed;}
1
+ :root { --menu-option-normal-height: 38px; --menu-option-small-height: 30px; --menu-option-mini-height: 24px; --menu-option-large-height: 46px; --menu-option-padding: 0 12px; --menu-option-normal-font-size: var(--font-size-md); --menu-option-small-font-size: var(--font-size-sm); --menu-option-mini-font-size: var(--font-size-xs); --menu-option-large-font-size: var(--font-size-lg); --menu-option-selected-background: var(--color-primary); --menu-option-text-color: #555; --menu-option-disabled-color: var(--color-text-disabled);}.var-menu-option { position: relative; display: flex; align-items: center; padding: var(--menu-option-padding); cursor: pointer; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); color: var(--menu-option-text-color); outline: none;}.var-menu-option__cover { position: absolute; top: 0; left: 0; right: 0; bottom: 0; opacity: 0.2; background: transparent;}.var-menu-option__text { display: flex; align-items: center;}.var-menu-option--normal { height: var(--menu-option-normal-height); font-size: var(--menu-option-normal-font-size);}.var-menu-option--large { height: var(--menu-option-large-height); font-size: var(--menu-option-large-font-size);}.var-menu-option--small { height: var(--menu-option-small-height); font-size: var(--menu-option-small-font-size);}.var-menu-option--mini { height: var(--menu-option-mini-height); font-size: var(--menu-option-mini-font-size);}.var-menu-option--selected-background { background: var(--menu-option-selected-background);}.var-menu-option--selected-color { color: var(--menu-option-selected-background);}.var-menu-option--disabled { color: var(--menu-option-disabled-color); cursor: not-allowed;}
@@ -4,14 +4,16 @@ import { props } from "./props.mjs";
4
4
  import { createNamespace, formatElevation } from "../utils/components.mjs";
5
5
  import { useMenuOptions } from "./provide.mjs";
6
6
  import { useSelectController } from "../select/useSelectController.mjs";
7
- import { call } from "@varlet/shared";
8
- import { useVModel } from "@varlet/use";
7
+ import { call, preventDefault } from "@varlet/shared";
8
+ import { useEventListener, useVModel } from "@varlet/use";
9
+ import { focusChildElementByKey } from "../utils/elements.mjs";
9
10
  const { name, n, classes } = createNamespace("menu-select");
10
11
  import { renderSlot as _renderSlot, normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from "vue";
11
12
  function __render__(_ctx, _cache) {
12
13
  const _component_var_menu = _resolveComponent("var-menu");
13
14
  return _openBlock(), _createBlock(_component_var_menu, {
14
15
  ref: "menu",
16
+ tabindex: "-1",
15
17
  class: _normalizeClass(_ctx.n()),
16
18
  disabled: _ctx.disabled,
17
19
  trigger: _ctx.trigger,
@@ -26,6 +28,7 @@ function __render__(_ctx, _cache) {
26
28
  "default-style": false,
27
29
  "popover-class": _ctx.popoverClass,
28
30
  "close-on-click-reference": _ctx.closeOnClickReference,
31
+ "close-on-key-escape": false,
29
32
  show: _ctx.show,
30
33
  "onUpdate:show": _cache[0] || (_cache[0] = ($event) => _ctx.show = $event),
31
34
  onOpen: _ctx.onOpen,
@@ -38,6 +41,7 @@ function __render__(_ctx, _cache) {
38
41
  _createElementVNode(
39
42
  "div",
40
43
  {
44
+ ref: "menuOptionsRef",
41
45
  class: _normalizeClass(_ctx.classes(_ctx.n("menu"), _ctx.formatElevation(_ctx.elevation, 3), [_ctx.scrollable, _ctx.n("--scrollable")]))
42
46
  },
43
47
  [
@@ -60,6 +64,7 @@ const __sfc__ = defineComponent({
60
64
  props,
61
65
  setup(props2) {
62
66
  const menu = ref(null);
67
+ const menuOptionsRef = ref(null);
63
68
  const show = useVModel(props2, "show");
64
69
  const { menuOptions, length, bindMenuOptions } = useMenuOptions();
65
70
  const { computeLabel, getSelectedValue } = useSelectController({
@@ -75,11 +80,30 @@ const __sfc__ = defineComponent({
75
80
  onSelect
76
81
  };
77
82
  bindMenuOptions(menuSelectProvider);
83
+ useEventListener(() => window, "keydown", handleKeydown);
78
84
  function onSelect(option) {
79
85
  const { multiple, closeOnSelect } = props2;
80
86
  call(props2["onUpdate:modelValue"], getSelectedValue(option));
81
87
  if (!multiple && closeOnSelect) {
82
- show.value = false;
88
+ menu.value.$el.focus();
89
+ close();
90
+ }
91
+ }
92
+ function handleKeydown(event) {
93
+ if (props2.disabled || !show.value) {
94
+ return;
95
+ }
96
+ const { key } = event;
97
+ if (["Escape", "ArrowDown", "ArrowUp"].includes(key)) {
98
+ preventDefault(event);
99
+ }
100
+ if (key === "Escape") {
101
+ menu.value.$el.focus();
102
+ close();
103
+ return;
104
+ }
105
+ if (key === "ArrowDown" || key === "ArrowUp") {
106
+ focusChildElementByKey(menu.value.$el, menuOptionsRef.value, key);
83
107
  }
84
108
  }
85
109
  function open() {
@@ -97,6 +121,7 @@ const __sfc__ = defineComponent({
97
121
  return {
98
122
  show,
99
123
  menu,
124
+ menuOptionsRef,
100
125
  n,
101
126
  classes,
102
127
  formatElevation,