@teammodlr/ui-kit 2.0.40 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/lib/components/avatar/Avatar.vue.d.ts +1 -1
  2. package/lib/components/avatargroup/AvatarGroup.vue.d.ts +1 -1
  3. package/lib/components/badge/Badge.vue.d.ts +1 -1
  4. package/lib/components/breadcrumb/Breadcrumb.vue.d.ts +1 -10
  5. package/lib/components/breadcrumb/BreadcrumbItem.vue.d.ts +1 -1
  6. package/lib/components/button/Button.vue.d.ts +2 -2
  7. package/lib/components/buttongroup/ButtonGroup.vue.d.ts +1 -1
  8. package/lib/components/checkbox/Checkbox.vue.d.ts +1 -1
  9. package/lib/components/colorpicker/ColorPicker.vue.d.ts +1 -1
  10. package/lib/components/dialog/Dialog.vue.d.ts +46 -0
  11. package/lib/components/dialog/DialogProvider.vue.d.ts +37 -0
  12. package/lib/components/dialog/props.d.ts +22 -0
  13. package/lib/components/dialog/providerProps.d.ts +8 -0
  14. package/lib/components/dialog/types.d.ts +27 -0
  15. package/lib/components/dialog/useDialog.d.ts +2 -0
  16. package/lib/components/dropdown/Dropdown.vue.d.ts +1 -1
  17. package/lib/components/dropdown/DropdownItem.vue.d.ts +1 -1
  18. package/lib/components/dropdown/DropdownList.vue.d.ts +1 -1
  19. package/lib/components/dropdown/DropdownSeperator.vue.d.ts +1 -1
  20. package/lib/components/dropdown/DropdownWrapper.vue.d.ts +1 -1
  21. package/lib/components/form/Form.vue.d.ts +1 -1
  22. package/lib/components/image/Image.vue.d.ts +1 -1
  23. package/lib/components/index.d.ts +3 -0
  24. package/lib/components/input/Input.vue.d.ts +2 -2
  25. package/lib/components/link/Link.vue.d.ts +1 -1
  26. package/lib/components/messageprovider/Message.vue.d.ts +2 -2
  27. package/lib/components/messageprovider/MessageProvider.vue.d.ts +3 -3
  28. package/lib/components/modal/Modal.vue.d.ts +12 -1
  29. package/lib/components/pagination/Pagination.vue.d.ts +1 -1
  30. package/lib/components/radio/Radio.vue.d.ts +13 -4
  31. package/lib/components/radiobutton/RadioButton.vue.d.ts +1 -1
  32. package/lib/components/radiobuttongroup/RadioButtonGroup.vue.d.ts +1 -1
  33. package/lib/components/renderer/examlpes/basic.vue.d.ts +2 -0
  34. package/lib/components/renderer/examlpes/index.d.ts +1 -0
  35. package/lib/components/renderer/props.d.ts +12 -0
  36. package/lib/components/renderer/renderer.d.ts +23 -0
  37. package/lib/components/select/Select.vue.d.ts +2 -2
  38. package/lib/components/select/style/Select.css.d.ts +2 -0
  39. package/lib/components/skeleton/Skeleton.vue.d.ts +1 -1
  40. package/lib/components/slider/Slider.vue.d.ts +1 -1
  41. package/lib/components/switch/Switch.vue.d.ts +1 -1
  42. package/lib/components/tab/Tab.vue.d.ts +1 -1
  43. package/lib/components/tab/TabGroup.vue.d.ts +1 -1
  44. package/lib/components/table/Table.vue.d.ts +1 -1
  45. package/lib/components/table/TableBody.vue.d.ts +1 -1
  46. package/lib/components/table/TableCell.vue.d.ts +1 -1
  47. package/lib/components/table/TableHead.vue.d.ts +1 -1
  48. package/lib/components/table/TableHeadRow.vue.d.ts +1 -1
  49. package/lib/components/table/TableRow.vue.d.ts +1 -1
  50. package/lib/components/tag/Tag.vue.d.ts +2 -2
  51. package/lib/components/textarea/Textarea.vue.d.ts +3 -3
  52. package/lib/components/tooltip/Tooltip.vue.d.ts +1 -1
  53. package/lib/components/transfer/Transfer.vue.d.ts +1 -1
  54. package/lib/components/virtualscroll/VirtualScroll.vue.d.ts +1 -1
  55. package/lib/composables/index.d.ts +1 -0
  56. package/lib/index.cjs.js +2 -8
  57. package/lib/index.es.js +2877 -3237
  58. package/lib/nuxt.plugin.js +1 -1
  59. package/lib/style.css +1 -1
  60. package/lib/styles/theme.css.d.ts +10 -10
  61. package/package.json +24 -27
  62. package/src/components/breadcrumb/Breadcrumb.vue +4 -8
  63. package/src/components/dialog/Dialog.vue +60 -0
  64. package/src/components/dialog/DialogProvider.vue +81 -0
  65. package/src/components/dialog/examples/basic.vue +48 -0
  66. package/src/components/dialog/examples/index.stories.ts +29 -0
  67. package/src/components/dialog/examples/index.ts +1 -0
  68. package/src/components/dialog/examples/wrapper.vue +9 -0
  69. package/src/components/dialog/props.ts +24 -0
  70. package/src/components/dialog/providerProps.ts +11 -0
  71. package/src/components/dialog/types.ts +34 -0
  72. package/src/components/dialog/useDialog.ts +12 -0
  73. package/src/components/index.ts +3 -0
  74. package/src/components/messageprovider/MessageProvider.vue +7 -7
  75. package/src/components/messageprovider/style/Message.css.ts +2 -1
  76. package/src/components/modal/Modal.vue +36 -11
  77. package/src/components/radio/Radio.vue +32 -33
  78. package/src/components/radio/examples/basic.vue +2 -3
  79. package/src/components/radio/examples/group.vue +15 -0
  80. package/src/components/radio/examples/index.stories.ts +2 -0
  81. package/src/components/radio/examples/index.ts +1 -0
  82. package/src/components/renderer/examlpes/basic.vue +23 -0
  83. package/src/components/renderer/examlpes/index.stories.ts +18 -0
  84. package/src/components/renderer/examlpes/index.ts +1 -0
  85. package/src/components/renderer/props.ts +15 -0
  86. package/src/components/renderer/renderer.ts +16 -0
  87. package/src/components/select/Select.vue +7 -1
  88. package/src/components/select/style/Select.css.ts +25 -1
  89. package/src/composables/index.ts +2 -1
  90. package/src/composables/useZIndex.ts +5 -3
  91. package/src/examples/modal/modal.stories.ts +9 -0
  92. package/src/examples/modal/modal.vue +52 -0
  93. package/src/exports/nuxt.plugin.js +1 -1
@@ -0,0 +1,34 @@
1
+ import type { Variant } from '../../types/props';
2
+ import type { VNodeChild } from 'vue';
3
+
4
+ export type DialogContentType = string;
5
+
6
+ export type DialogContentRender = (props: any) => VNodeChild;
7
+
8
+ export interface DialogOptions {
9
+ title?: string,
10
+ render?: DialogContentRender,
11
+ content: DialogContentType,
12
+ onClose?: () => void,
13
+ onOpen?: () => void,
14
+ onOk?: () => void,
15
+ onCancel?: () => void,
16
+ okVariant?: Variant,
17
+ okText?: DialogContentType,
18
+ cancelText?: DialogContentType,
19
+ }
20
+
21
+ export interface DialogResponse {
22
+ result: boolean,
23
+ data: any
24
+ }
25
+
26
+ export interface DialogApiInjection {
27
+ create: (options: DialogOptions) => Dialog
28
+ destroyAll: () => void
29
+ }
30
+
31
+
32
+ export interface Dialog extends DialogOptions {
33
+ destroy: () => void
34
+ }
@@ -0,0 +1,12 @@
1
+ import { inject } from 'vue';
2
+ import type { DialogApiInjection } from './types';
3
+
4
+ export function useDialog(): DialogApiInjection {
5
+ const api = inject('m-dialog', null);
6
+
7
+ if (api === null) {
8
+ throw new Error('m-dialog api is not provided, ensure the component is wrapped in <m-dialog-provider />.');
9
+ }
10
+
11
+ return api;
12
+ }
@@ -1,3 +1,4 @@
1
+ export { default as MRenderer } from './renderer/renderer';
1
2
  export { default as MAvatar } from './avatar/Avatar.vue';
2
3
  export { default as MAvatarGroup } from './avatargroup/AvatarGroup.vue';
3
4
  export { default as MBadge } from './badge/Badge.vue';
@@ -39,3 +40,5 @@ export { default as MTextarea } from './textarea/Textarea.vue';
39
40
  export { default as MTooltip } from './tooltip/Tooltip.vue';
40
41
  export { default as MTransfer } from './transfer/Transfer.vue';
41
42
  export { default as MVirtualScroll } from './virtualscroll/VirtualScroll.vue';
43
+ export { default as MDialog } from './dialog/Dialog.vue';
44
+ export { default as MDialogProvider } from './dialog/DialogProvider.vue';
@@ -1,13 +1,13 @@
1
1
  <template>
2
2
  <slot />
3
- <template v-if="messageList.length">
3
+ <template>
4
4
  <Teleport :to="teleportTo ?? 'body'">
5
5
  <transition
6
6
  type="animation"
7
- :enter-active-class="scale.enterActive"
8
- :leave-active-class="scale.leaveActive"
9
- :enter-from-class="scale.enterFrom"
10
- :leave-to-class="scale.leaveTo"
7
+ :enter-active-class="modalScale.enterActive"
8
+ :leave-active-class="modalScale.leaveActive"
9
+ :enter-from-class="modalScale.enterFrom"
10
+ :leave-to-class="modalScale.leaveTo"
11
11
  >
12
12
  <div :class="classes">
13
13
  <MMessage v-for="message in messageList"
@@ -39,7 +39,7 @@ import type { PropType } from 'vue';
39
39
  import MMessage from './Message.vue';
40
40
  import { useCachedUid } from '../../composables/useCachedUid';
41
41
  import * as style from './style';
42
- import { scale } from '../../styles/transitions.css';
42
+ import { modalScale } from '../../styles/transitions.css';
43
43
  export type MessageProviderInst = MessageApiInjection;
44
44
 
45
45
  interface PrivateMessageReactive extends MessageReactive {
@@ -144,7 +144,7 @@ export default defineComponent({
144
144
  messageList: messageListRef,
145
145
  onInternalAfterLeave,
146
146
  classes,
147
- scale
147
+ modalScale
148
148
  },
149
149
  api,
150
150
  )
@@ -35,7 +35,8 @@ export const base = style({
35
35
  fontSize: themeVars.fontSize.base,
36
36
  color: themeVars.color.font.text,
37
37
  alignItems: "center",
38
- transition: "top 0.3s ease-out 0.5s, bottom 0.3s ease-out 0.5s",
38
+ willChange: "top, bottom, width",
39
+ transition: "top 0.3s ease-out 0.5s, bottom 0.3s ease-out 0.5s, width 0.3s ease-out 0.5s",
39
40
  })
40
41
 
41
42
  export const placement = styleVariants({
@@ -7,7 +7,7 @@
7
7
  :enter-from-class="fade.enterFrom"
8
8
  :leave-to-class="fade.leaveTo"
9
9
  >
10
- <div v-show="isOpen" :class="style.background" :style="{zIndex: zIndex}" @click="closeOutside">
10
+ <div v-show="isOpen" :class="style.background" :style="{zIndex: zIndex}" @mousedown="closeOutside">
11
11
  <Transition
12
12
  type="animation"
13
13
  :enter-active-class="modalScale.enterActive"
@@ -46,11 +46,10 @@
46
46
  import type {PropType} from "vue";
47
47
  import type {Size} from "../../types/props";
48
48
  import {defineComponent, ref, computed, watch, nextTick} from 'vue';
49
- import {useFocusTrap} from '@vueuse/integrations/useFocusTrap'
50
49
  import * as style from './style';
51
50
  import { modalScale, fade } from "../../styles/transitions.css";
52
51
  import {useZIndex} from "../../composables/useZIndex";
53
- import { useMagicKeys, watchOnce } from "@vueuse/core";
52
+ import { useEventListener, useMagicKeys } from "@vueuse/core";
54
53
 
55
54
  export default defineComponent({
56
55
  name: "MModal",
@@ -67,6 +66,10 @@ export default defineComponent({
67
66
  type: Boolean,
68
67
  default: true
69
68
  },
69
+ onClose: {
70
+ type: Function as PropType<() => void>,
71
+ default: () => {}
72
+ },
70
73
  zIndex: {
71
74
  type: Number
72
75
  }
@@ -77,11 +80,13 @@ export default defineComponent({
77
80
  const isOpen = ref(false);
78
81
  const target = ref();
79
82
  const zIndex = ref(props.zIndex ?? nextZIndex());
80
- const {hasFocus, activate, deactivate} = useFocusTrap(target, {
81
- immediate: true,
82
- escapeDeactivates: false,
83
- allowOutsideClick: true
84
- });
83
+
84
+ const clickInside = ref(false);
85
+ // const {hasFocus, activate, deactivate} = useFocusTrap(target, {
86
+ // immediate: true,
87
+ // escapeDeactivates: false,
88
+ // allowOutsideClick: true
89
+ // });
85
90
 
86
91
  const { escape } = useMagicKeys()
87
92
 
@@ -98,13 +103,19 @@ export default defineComponent({
98
103
  ];
99
104
  });
100
105
 
106
+ useEventListener(target, 'mousedown', handleMouseDown);
107
+ useEventListener(document, 'mouseup', handleMouseUp);
108
+
101
109
  const closeOutside = () => {
102
- if (props.canClickOutside) {
110
+ if (props.canClickOutside && !clickInside.value) {
103
111
  close();
104
112
  }
105
113
  };
106
114
 
107
115
  const close = () => {
116
+ if (props.onClose) {
117
+ props.onClose();
118
+ }
108
119
  ownerScrollbarClose();
109
120
  isOpen.value = false;
110
121
  };
@@ -115,6 +126,18 @@ export default defineComponent({
115
126
  isOpen.value = true;
116
127
  };
117
128
 
129
+ function handleMouseUp(event: MouseEvent) {
130
+ nextTick(() => {
131
+ if (clickInside.value) {
132
+ clickInside.value = false;
133
+ }
134
+ });
135
+ }
136
+
137
+ function handleMouseDown(event: MouseEvent) {
138
+ clickInside.value = true;
139
+ }
140
+
118
141
  function ownerScrollbarOpen() {
119
142
  let ownerWindow = window;
120
143
  let documentElement = ownerWindow.document.documentElement;
@@ -144,16 +167,18 @@ export default defineComponent({
144
167
  zIndex.value = props.zIndex ? zIndex.value++ : nextZIndex();
145
168
  emit('open');
146
169
  nextTick(() => {
147
- activate()
170
+ // activate()
148
171
  })
149
172
  } else {
150
- deactivate()
173
+ // deactivate()
151
174
  }
152
175
  });
153
176
 
154
177
  return {
155
178
  close,
156
179
  closeOutside,
180
+ handleMouseUp,
181
+ handleMouseDown,
157
182
  open,
158
183
  target,
159
184
  style,
@@ -1,17 +1,18 @@
1
1
  <template>
2
- <label :class="style.base" @click.prevent="toggle">
2
+ <label :class="style.base">
3
3
  <input
4
- v-model="checked"
5
- type="radio"
6
- :aria-checked="checked ? 'true' : 'false'"
7
- :aria-disabled="(disabled || loading) ? 'true' : 'false'"
8
- :aria-labelledby="`${id}-label`"
9
- :disabled="disabled || loading"
10
- :name="name"
11
- :id="id"
12
- :class="style.input"
13
- v-bind="$attrs"
14
- v-on="inputListeners"
4
+ v-model="pick"
5
+ :value="value"
6
+ type="radio"
7
+ :aria-checked="checked ? 'true' : 'false'"
8
+ :aria-disabled="(disabled || loading) ? 'true' : 'false'"
9
+ :aria-labelledby="`${id}-label`"
10
+ :disabled="disabled || loading"
11
+ :name="name"
12
+ :id="id"
13
+ v-bind="$attrs"
14
+ v-on="inputListeners"
15
+ :class="style.input"
15
16
  />
16
17
  <span :class="classes"></span>
17
18
  <span :class="style.label" :id="`${id}-label`">
@@ -27,10 +28,11 @@
27
28
  </template>
28
29
 
29
30
  <script lang="ts">
30
- import {defineComponent, toRef, ref, type PropType, watch, computed, defineExpose } from 'vue';
31
- import {useInput} from '../../composables/useInput';
32
- import {useInteractive} from "../../composables/useInteractive";
33
- import type {Size} from '../../types/props';
31
+ import type { PropType } from 'vue';
32
+ import { computed, defineComponent, defineExpose, ref, toRef } from 'vue';
33
+ import { useInput } from '../../composables/useInput';
34
+ import { useInteractive } from "../../composables/useInteractive";
35
+ import type { Size } from '../../types/props';
34
36
  import * as style from './style';
35
37
 
36
38
  export default defineComponent({
@@ -53,6 +55,10 @@ export default defineComponent({
53
55
  loading: {
54
56
  type: Boolean,
55
57
  default: false
58
+ },
59
+ value: {
60
+ type: [String, Number, Boolean],
61
+ default: null
56
62
  }
57
63
  },
58
64
  setup(props, {slots, emit}) {
@@ -74,8 +80,16 @@ export default defineComponent({
74
80
 
75
81
  const disabled = computed(() => formDisabled || formLoading || props.disabled || props.loading);
76
82
  const name = toRef(props, 'name');
77
- const checked = ref(false);
83
+ const checked = computed(() => props.modelValue === props.value);
78
84
  const hasSlot = computed(() => !!(slots.default));
85
+ const pick = computed({
86
+ get() {
87
+ return props.modelValue;
88
+ },
89
+ set(value) {
90
+ emit('update:modelValue', value);
91
+ }
92
+ });
79
93
 
80
94
  const classes = computed(() => {
81
95
  return [
@@ -92,21 +106,6 @@ export default defineComponent({
92
106
  return formError.value || props.error;
93
107
  });
94
108
 
95
- watch(() => props.modelValue, (value) => {
96
- checked.value = !!value;
97
- }, {immediate: true});
98
-
99
- watch(() => checked.value, (value) => {
100
- emit('update:modelValue', value);
101
- });
102
-
103
- function toggle() {
104
- if (disabled.value) {
105
- return;
106
- }
107
- checked.value = !checked.value;
108
- }
109
-
110
109
  defineExpose({
111
110
  focus,
112
111
  blur,
@@ -122,9 +121,9 @@ export default defineComponent({
122
121
  disabled,
123
122
  name,
124
123
  checked,
124
+ pick,
125
125
  radioRef,
126
126
  inputError,
127
- toggle,
128
127
  style,
129
128
  classes,
130
129
  hasSlot,
@@ -1,9 +1,8 @@
1
1
  <template>
2
- <MRadio v-model="checked" label="Test" />
2
+ <MRadio label="Test" name="item" value="sms" v-model="selected" />
3
3
  </template>
4
4
 
5
5
  <script lang="ts" setup>
6
6
  import { ref } from 'vue'
7
-
8
- const checked = ref(false);
7
+ const selected = ref('');
9
8
  </script>
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div>
3
+ <MRadio label="SMS" name="item" value="sms" v-model="selected" /><br />
4
+ <MRadio label="Email" name="item" value="email" v-model="selected" />
5
+ <div>
6
+ Selected: {{ selected }}
7
+ </div>
8
+ </div>
9
+ </template>
10
+
11
+ <script lang="ts" setup>
12
+ import { ref } from 'vue'
13
+
14
+ const selected = ref('sms');
15
+ </script>
@@ -1,6 +1,7 @@
1
1
  import MRadio from "../Radio.vue";
2
2
  import {
3
3
  MRadioBasic,
4
+ MRadioGroup,
4
5
  } from "./index";
5
6
 
6
7
  import {
@@ -17,3 +18,4 @@ export default {
17
18
  }
18
19
 
19
20
  export const Basic = createStory(MRadioBasic);
21
+ export const Group = createStory(MRadioGroup);
@@ -1,2 +1,3 @@
1
1
  export { default as MRadioBasic } from './basic.vue';
2
+ export { default as MRadioGroup } from './group.vue';
2
3
 
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <MRenderer :h="renderMessage" :props="{ message: msg }">
3
+ </MRenderer>
4
+ </template>
5
+
6
+ <script setup lang="ts">
7
+ import { h, ref } from 'vue'
8
+ const msg = ref('some content')
9
+
10
+ function renderMessage({ message }: { message: string }) {
11
+ return h('p', [
12
+ 'Here are ',
13
+ h(
14
+ 'span',
15
+ {
16
+ style: 'color: red'
17
+ },
18
+ [message]
19
+ ),
20
+ ' that using render function',
21
+ ])
22
+ }
23
+ </script>
@@ -0,0 +1,18 @@
1
+ import MRenderer from "../renderer";
2
+ import {
3
+ MRendererBasic,
4
+ } from "./index";
5
+
6
+ import {
7
+ createStory, sizeArgType
8
+ } from "../../../__storybook__";
9
+
10
+ export default {
11
+ component: MRenderer,
12
+ title: 'Components/Renderer',
13
+ argTypes: {
14
+ ...sizeArgType()
15
+ }
16
+ }
17
+
18
+ export const Basic = createStory(MRendererBasic);
@@ -0,0 +1 @@
1
+ export { default as MRendererBasic } from './basic.vue';
@@ -0,0 +1,15 @@
1
+ import type { ExtractPropTypes, PropType } from 'vue';
2
+
3
+
4
+ export const rendererProps = {
5
+ h: {
6
+ type: Function,
7
+ default: null
8
+ },
9
+ props: {
10
+ type: Object as PropType<Record<string, any>>,
11
+ default: undefined
12
+ }
13
+ }
14
+
15
+ export type RendererProps = ExtractPropTypes<typeof rendererProps>
@@ -0,0 +1,16 @@
1
+ import { defineComponent, renderSlot } from 'vue';
2
+ import { rendererProps } from './props';
3
+
4
+ export default defineComponent({
5
+ name: "Renderer",
6
+ props: rendererProps,
7
+ setup(props, { slots }) {
8
+ return () => {
9
+ if (typeof props.h !== 'function') {
10
+ return renderSlot(slots, 'default', props.props);
11
+ }
12
+
13
+ return props.h(props.props);
14
+ }
15
+ }
16
+ })
@@ -41,7 +41,8 @@
41
41
  <div :class="style.menu" v-if="isOpen" ref="popper" :style="computedConsistentWidth"
42
42
  :aria-hidden="isOpen ? 'false' : 'true'">
43
43
  <div v-if="searchable" :class="style.search">
44
- <MInput v-model="search" placeholder="Search" size="sm" ref="searchRef"/>
44
+ <!-- <MInput v-model="search" placeholder="Search" size="sm" ref="searchRef"/> -->
45
+ <input type="text" ref="searchRef" v-model="search" placeholder="Search" :class="style.searchInput" />
45
46
  </div>
46
47
  <div :class="style.options">
47
48
  <div v-for="(option, index) in computedOptions" :key="index" ref="optionsRef"
@@ -54,6 +55,11 @@
54
55
  @hover="selectedIndex = index">
55
56
  {{ option.label }}
56
57
  </div>
58
+ <template v-if="computedOptions.length === 0">
59
+ <div :class="style.noResults">
60
+ No results
61
+ </div>
62
+ </template>
57
63
  </div>
58
64
  </div>
59
65
  </Transition>
@@ -63,6 +63,7 @@ export const base = style({
63
63
  lineHeight: vars.height,
64
64
  boxSizing: 'border-box',
65
65
  resize: 'none',
66
+ cursor: 'pointer',
66
67
  boxShadow: 'none',
67
68
  transition: `color .3s ${themeVars.transition.default},
68
69
  background-color .3s ${themeVars.transition.default},
@@ -194,13 +195,23 @@ export const placeholder = style({
194
195
  })
195
196
 
196
197
  export const search = style({
197
- padding: `${themeVars.space[1]} ${themeVars.space[1]} 0`,
198
+ // padding: `${themeVars.space[1]} ${themeVars.space[1]} 0`,
198
199
  backgroundColor: '#FFFFFF',
199
200
  position: 'sticky',
200
201
  top: 0,
201
202
  zIndex: 1,
202
203
  });
203
204
 
205
+ export const searchInput = style({
206
+ padding: `${themeVars.space[2.5]} ${themeVars.space[2.5]}`,
207
+ border: 'none',
208
+ outline: 'none',
209
+ width: '100%',
210
+ fontSize: themeVars.fontSize.base,
211
+ borderBottom: `1px solid ${themeVars.color.gray[200]}`,
212
+ color: themeVars.color.gray[800],
213
+ });
214
+
204
215
  export const options = style({
205
216
  padding: themeVars.space[1],
206
217
  display: 'flex',
@@ -259,3 +270,16 @@ export const optionSelected = style({
259
270
  },
260
271
  }
261
272
  });
273
+
274
+ export const noResults = style({
275
+ padding: `${themeVars.space[2]} 0`,
276
+ display: 'flex',
277
+ // flexDirection: 'column',
278
+ alignItems: 'center',
279
+ textAlign: 'center',
280
+ justifyContent: 'center',
281
+ gap: themeVars.space[0.5],
282
+ width: '100%',
283
+ color: themeVars.color.gray[500],
284
+ fontSize: themeVars.fontSize.small,
285
+ });
@@ -1,3 +1,4 @@
1
1
  export { useMessage } from '../components/messageprovider/useMessage';
2
+ export { useDialog } from '../components/dialog/useDialog';
2
3
  export { usePopper } from './usePopper';
3
- export { useZIndex } from './useZIndex';
4
+ export { useZIndex } from './useZIndex';
@@ -1,6 +1,5 @@
1
1
  import type {InjectionKey, Ref} from "vue";
2
2
  import {computed, inject, ref, unref} from "vue";
3
- import {isNumber} from "@vueuse/core";
4
3
 
5
4
  const zIndex = ref(0);
6
5
  export const initialZIndex = 1000;
@@ -11,7 +10,10 @@ export const useZIndex = (override?: Ref<number>) => {
11
10
 
12
11
  const initial = computed(() => {
13
12
  const fromInjection = unref(injection);
14
- return isNumber(fromInjection) ? fromInjection : initialZIndex;
13
+ if (fromInjection === undefined || isNaN(fromInjection)) {
14
+ return initialZIndex;
15
+ }
16
+ return fromInjection;
15
17
  });
16
18
 
17
19
  const current = computed(() => {
@@ -28,4 +30,4 @@ export const useZIndex = (override?: Ref<number>) => {
28
30
  current,
29
31
  nextZIndex
30
32
  }
31
- }
33
+ }
@@ -0,0 +1,9 @@
1
+ import Modal from "./modal.vue";
2
+ import {createStory} from "../../__storybook__";
3
+
4
+ export default {
5
+ component: Modal,
6
+ title: 'Examples/Modals'
7
+ }
8
+
9
+ export const Basic = createStory(Modal);
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <MModal ref="modal" title="I am a modal" size="md" :canClickOutside="true" :canBounceOnOpen="false" :canSlideIn="true">
3
+ <template #body>
4
+ <div>
5
+ <MSelect
6
+ v-model="value"
7
+ :options="options"
8
+ :option-value="'id'"
9
+ :option-label="'name'"
10
+ blank
11
+ searchable
12
+ />
13
+ </div>
14
+ </template>
15
+ <template #footer>
16
+ <div style="display: flex; flex-grow: 1; justify-content: end;">
17
+ <MButton variant="primary" @click="modal?.close()">
18
+ Okay
19
+ </MButton>
20
+ <MButton style="margin-left: 8px;" @click="modal?.close()">
21
+ Cancel
22
+ </MButton>
23
+ </div>
24
+ </template>
25
+ </MModal>
26
+
27
+ <div style="position: relative; width: 100%; height: 1000px;">
28
+ <button @click="open" style="position: absolute; width: 100px; height: 50px; top: 0; left: 0;">Top Left</button>
29
+ <button @click="open" style="position: absolute; width: 100px; height: 50px; top: 0; right: 0;">Top Right</button>
30
+ <button @click="open" style="position: absolute; width: 100px; height: 50px; bottom: 0; left: 0;">Bottom
31
+ Left</button>
32
+ <button @click="open" style="position: absolute; width: 100px; height: 50px; bottom: 0; right: 0;">Bottom
33
+ Right</button>
34
+ </div>
35
+ </template>
36
+
37
+ <script lang="ts" setup>
38
+ import { ref } from 'vue'
39
+
40
+ const modal = ref<any>(null);
41
+ // make list of options with 1000 items
42
+ const options = Array.from({ length: 50 }, (_, i) => ({
43
+ id: i,
44
+ name: `Option ${i+1}`
45
+ }));
46
+
47
+ const value = ref();
48
+ const open = (event: MouseEvent) => {
49
+ modal.value.open(event.target);
50
+ };
51
+
52
+ </script>
@@ -1,5 +1,5 @@
1
1
  import { defineNuxtPlugin } from '#app'
2
- import create from '../src/create'
2
+ import create from '../create'
3
3
 
4
4
  export default defineNuxtPlugin((nuxtApp) => {
5
5
  const UI = create(nuxtApp.$config.modlrUiOptions)