@teammodlr/ui-kit 2.1.78 → 2.2.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.
Files changed (33) hide show
  1. package/lib/components/dialog/Dialog.vue.d.ts +1 -1
  2. package/lib/components/dropdown/Dropdown.vue.d.ts +14 -9
  3. package/lib/components/dropdown/DropdownTrigger.vue.d.ts +11 -0
  4. package/lib/components/messageprovider/Message.vue.d.ts +1 -1
  5. package/lib/components/modal/Modal.vue.d.ts +1 -1
  6. package/lib/components/primative/index.d.ts +2 -0
  7. package/lib/components/primative/primitive.d.ts +30 -0
  8. package/lib/components/primative/slot.d.ts +5 -0
  9. package/lib/components/tooltip/Tooltip.vue.d.ts +12 -6
  10. package/lib/components/tooltip/TooltipTrigger.vue.d.ts +11 -0
  11. package/lib/index.cjs.js +7 -7
  12. package/lib/index.es.js +2675 -2542
  13. package/lib/utils/renderSlotFragments.d.ts +2 -0
  14. package/lib/utils/useForwardExpose.d.ts +6 -0
  15. package/package.json +1 -1
  16. package/src/components/button/Button.vue +1 -2
  17. package/src/components/dialog/Dialog.vue +4 -2
  18. package/src/components/dialogprovider/examples/basic.vue +54 -54
  19. package/src/components/dialogprovider/examples/index.stories.ts +26 -26
  20. package/src/components/dropdown/Dropdown.vue +28 -7
  21. package/src/components/dropdown/DropdownTrigger.vue +20 -0
  22. package/src/components/primative/examples/as-child.vue +13 -0
  23. package/src/components/primative/examples/as.vue +13 -0
  24. package/src/components/primative/examples/index.stories.ts +12 -0
  25. package/src/components/primative/examples/index.ts +2 -0
  26. package/src/components/primative/index.ts +2 -0
  27. package/src/components/primative/primitive.ts +56 -0
  28. package/src/components/primative/slot.ts +45 -0
  29. package/src/components/tooltip/Tooltip.vue +26 -8
  30. package/src/components/tooltip/TooltipTrigger.vue +20 -0
  31. package/src/components/tooltip/examples/basic.vue +1 -1
  32. package/src/utils/renderSlotFragments.ts +15 -0
  33. package/src/utils/useForwardExpose.ts +65 -0
@@ -0,0 +1,2 @@
1
+ import { type VNode } from 'vue';
2
+ export declare function renderSlotFragments(children?: VNode[]): VNode[];
@@ -0,0 +1,6 @@
1
+ import { type ComponentPublicInstance } from 'vue';
2
+ export declare function useForwardExpose(): {
3
+ forwardRef: (ref: Element | ComponentPublicInstance | null) => void;
4
+ currentRef: import("vue").Ref<Element | ComponentPublicInstance | null | undefined>;
5
+ currentElement: import("vue").ComputedRef<HTMLElement>;
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teammodlr/ui-kit",
3
- "version": "2.1.78",
3
+ "version": "2.2.0",
4
4
  "description": "",
5
5
  "main": "lib/index.cjs.js",
6
6
  "module": "lib/index.es.js",
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <component :is="computedTag" :to="to" :href="href" :type="type" :class="computedClasses" :disabled="disabled"
3
3
  @click="handleClick" v-bind="$attrs">
4
- <!-- <div :class="computedWaveClasses" :key="waveTimerId"></div>-->
5
4
  <div :class="computedBorderClasses"></div>
6
5
  <div :class="computedBorderStateClasses"></div>
7
6
  <span v-if="hasIconLeft" :class="iconLeft">
@@ -201,4 +200,4 @@ export default defineComponent({
201
200
  }
202
201
  })
203
202
  </script>
204
-
203
+
@@ -108,7 +108,7 @@ export default defineComponent({
108
108
  const wrapper = ref<HTMLElement | null>(null);
109
109
  const dialog = ref<HTMLElement | null>(null);
110
110
  const handle = ref<HTMLElement | null>(null);
111
- const { nextZIndex } = useZIndex();
111
+ const { nextZIndex, current: maxZIndex } = useZIndex();
112
112
  const zIndex = ref(props.zIndex ?? nextZIndex());
113
113
 
114
114
  const isOpen = ref<boolean>(props.open);
@@ -174,7 +174,9 @@ export default defineComponent({
174
174
  }
175
175
 
176
176
  function onDragStart() {
177
- zIndex.value = nextZIndex();
177
+ if (zIndex.value < maxZIndex.value) {
178
+ zIndex.value = nextZIndex();
179
+ }
178
180
  isDragging.value = true;
179
181
  }
180
182
 
@@ -1,54 +1,54 @@
1
- <template>
2
- <div>
3
- <button @click="showDialog">Show Dialog</button>
4
- <button @click="showDialog2">Show Dialog 2</button>
5
- {{ testTitle }}
6
- </div>
7
- </template>
8
-
9
- <script lang="ts" setup>
10
- import {ref, h} from 'vue';
11
- import {useDialog} from '../useDialog';
12
-
13
- const dialog = useDialog();
14
- const testTitle = ref('This is a test');
15
-
16
- function renderMessage({message}: { message: string }) {
17
- return h('p', [
18
- 'Here are ',
19
- h('span', {style: 'color: red'}, [message]),
20
- ' that using render function',
21
- ]);
22
- }
23
-
24
- function showDialog() {
25
- dialog.create('hello', {
26
- title: testTitle,
27
- render: renderMessage,
28
- props: {message: testTitle},
29
- open: true,
30
- });
31
-
32
- setTimeout(() => {
33
- testTitle.value = 'changed';
34
- }, 4000);
35
- }
36
-
37
- function showDialog2() {
38
- dialog.create('hello-two', {
39
- title: "Hello Second Dialog",
40
- render: renderMessage,
41
- props: {message: testTitle},
42
- open: true,
43
- modal: false,
44
- draggable: false,
45
- onOpen: () => {
46
- console.log('hello world')
47
- }
48
- });
49
-
50
- setTimeout(() => {
51
- testTitle.value = 'changed again';
52
- }, 4000);
53
- }
54
- </script>
1
+ <template>
2
+ <div>
3
+ <button @click="showDialog">Show Dialog</button>
4
+ <button @click="showDialog2">Show Dialog 2</button>
5
+ {{ testTitle }}
6
+ </div>
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ import {ref, h} from 'vue';
11
+ import {useDialog} from '../useDialog';
12
+
13
+ const dialog = useDialog();
14
+ const testTitle = ref('This is a test');
15
+
16
+ function renderMessage({message}: { message: string }) {
17
+ return h('p', [
18
+ 'Here are ',
19
+ h('span', {style: 'color: red'}, [message]),
20
+ ' that using render function',
21
+ ]);
22
+ }
23
+
24
+ function showDialog() {
25
+ dialog.create('hello', {
26
+ title: testTitle,
27
+ render: renderMessage,
28
+ props: {message: testTitle},
29
+ open: true,
30
+ });
31
+
32
+ setTimeout(() => {
33
+ testTitle.value = 'changed';
34
+ }, 4000);
35
+ }
36
+
37
+ function showDialog2() {
38
+ dialog.create('hello-two', {
39
+ title: "Hello Second Dialog",
40
+ render: renderMessage,
41
+ props: {message: testTitle},
42
+ open: true,
43
+ modal: false,
44
+ draggable: false,
45
+ onOpen: () => {
46
+ console.log('hello world')
47
+ }
48
+ });
49
+
50
+ setTimeout(() => {
51
+ testTitle.value = 'changed again';
52
+ }, 4000);
53
+ }
54
+ </script>
@@ -1,26 +1,26 @@
1
- import MDialogProvider from '../DialogProvider.vue';
2
- import { MDialogProviderBasic } from './index';
3
-
4
- const Template = (args: any) => ({
5
- components: {
6
- MDialogProvider,
7
- MDialogProviderBasic
8
- },
9
- setup() {
10
- return {
11
- args
12
- }
13
- },
14
- template: `
15
- <m-dialog-provider v-bind="args">
16
- <MDialogProviderBasic />
17
- </m-dialog-provider>
18
- `
19
- });
20
-
21
- export default {
22
- component: MDialogProvider,
23
- title: 'Components/DialogProvider'
24
- };
25
-
26
- export const Primary = Template.bind({});
1
+ import MDialogProvider from '../DialogProvider.vue';
2
+ import { MDialogProviderBasic } from './index';
3
+
4
+ const Template = (args: any) => ({
5
+ components: {
6
+ MDialogProvider,
7
+ MDialogProviderBasic
8
+ },
9
+ setup() {
10
+ return {
11
+ args
12
+ }
13
+ },
14
+ template: `
15
+ <m-dialog-provider v-bind="args">
16
+ <MDialogProviderBasic />
17
+ </m-dialog-provider>
18
+ `
19
+ });
20
+
21
+ export default {
22
+ component: MDialogProvider,
23
+ title: 'Components/DialogProvider'
24
+ };
25
+
26
+ export const Primary = Template.bind({});
@@ -1,11 +1,14 @@
1
1
  <template>
2
- <span ref="wrapper" :class="computedWrapperClasses">
3
- <span
2
+ <Primitive
3
+ as-child
4
+ ref="wrapper">
5
+
6
+ <DropdownTrigger
4
7
  ref="referenceRef"
5
8
  :class="computedReferenceClasses"
6
9
  @click="toggleDropdown">
7
10
  <slot />
8
- </span>
11
+ </DropdownTrigger>
9
12
 
10
13
  <DropdownWrapper>
11
14
  <Teleport :disabled="isNested" to="body">
@@ -24,13 +27,14 @@
24
27
  </transition>
25
28
  </Teleport>
26
29
  </DropdownWrapper>
27
- </span>
30
+ </Primitive>
28
31
  </template>
29
32
 
30
33
  <script lang="ts">
31
34
  import { usePopper } from '../../composables/usePopper';
32
35
  import type { Placement, VirtualElement } from '@popperjs/core';
33
36
  import { scale } from '../../styles/transitions.css';
37
+ import {Primitive} from "../primative/primitive";
34
38
  import {
35
39
  defineComponent,
36
40
  inject,
@@ -43,7 +47,7 @@ import {
43
47
  computed,
44
48
  toRef,
45
49
  reactive,
46
- watchEffect
50
+ watchEffect, type Ref
47
51
  } from 'vue';
48
52
  import { onClickOutside, useEventListener } from '@vueuse/core';
49
53
  import DropdownWrapper from './DropdownWrapper.vue';
@@ -52,11 +56,23 @@ import { useZIndex } from '../../composables/useZIndex';
52
56
  import type { DropdownState } from './symbol';
53
57
  import { DROPDOWN_STATE } from './symbol';
54
58
  import * as style from './style';
59
+ import {createContext} from "../../utils/injection";
60
+ import DropdownTrigger from "./DropdownTrigger.vue";
61
+
62
+ interface DropdownContext {
63
+ reference: Ref<HTMLElement | undefined>
64
+ onReferenceChange: (element: HTMLElement | undefined) => void
65
+ }
66
+
67
+ export const [injectDropdownContext, provideDropdownContext] = createContext<DropdownContext>('Dropdown');
68
+
55
69
 
56
70
  export default defineComponent({
57
71
  name: 'Dropdown',
58
72
  components: {
59
- DropdownWrapper
73
+ DropdownTrigger,
74
+ DropdownWrapper,
75
+ Primitive
60
76
  },
61
77
  props: {
62
78
  open: {
@@ -113,7 +129,7 @@ export default defineComponent({
113
129
  const placement = ref(props.placement);
114
130
  const transfer = toRef(props, 'transfer');
115
131
  const wrapper = ref(null);
116
- const referenceRef = ref(null);
132
+ const referenceRef = ref<HTMLElement>();
117
133
  const zIndex = ref(props.zIndex ?? nextZIndex());
118
134
  const reference = computed(() => {
119
135
  if (props.virtual !== null) {
@@ -141,6 +157,11 @@ export default defineComponent({
141
157
  return referenceRef.value;
142
158
  });
143
159
 
160
+ provideDropdownContext({
161
+ reference: referenceRef,
162
+ onReferenceChange: element => referenceRef.value = element
163
+ });
164
+
144
165
  const { popper, transferTo, updatePopper } = usePopper({
145
166
  reference: reference,
146
167
  placement,
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ import {Primitive} from "../primative/primitive";
3
+ import { useForwardExpose } from "../../utils/useForwardExpose";
4
+ import {onMounted} from "vue";
5
+ import { injectDropdownContext } from "./Dropdown.vue";
6
+
7
+ const { forwardRef, currentElement } = useForwardExpose();
8
+
9
+ const dropdownContext = injectDropdownContext();
10
+
11
+ onMounted(() => {
12
+ dropdownContext.onReferenceChange(currentElement.value);
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <Primitive as-child :ref="forwardRef">
18
+ <slot />
19
+ </Primitive>
20
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { Primitive, type PrimitiveProps } from '../index'
3
+
4
+ const props = withDefaults(defineProps<PrimitiveProps>(), {
5
+ asChild: true
6
+ })
7
+ </script>
8
+
9
+ <template>
10
+ <Primitive v-bind="props">
11
+ <a href="https://google.com">Google</a>
12
+ </Primitive>
13
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { Primitive, type PrimitiveProps } from '../index'
3
+
4
+ const props = withDefaults(defineProps<PrimitiveProps>(), {
5
+ as: 'span'
6
+ })
7
+ </script>
8
+
9
+ <template>
10
+ <Primitive v-bind="props">
11
+ ...
12
+ </Primitive>
13
+ </template>
@@ -0,0 +1,12 @@
1
+ import { Primitive } from '../';
2
+ import { PrimitiveAs, PrimitiveAsChild } from './index';
3
+
4
+ import { createStory } from '../../../__storybook__';
5
+
6
+ export default {
7
+ component: Primitive,
8
+ title: 'Components/Primitive'
9
+ };
10
+
11
+ export const As = createStory(PrimitiveAs);
12
+ export const AsChild = createStory(PrimitiveAsChild);
@@ -0,0 +1,2 @@
1
+ export { default as PrimitiveAs } from './as.vue';
2
+ export { default as PrimitiveAsChild } from './as-child.vue';
@@ -0,0 +1,2 @@
1
+ export { Primitive, type PrimitiveProps, type AsTag } from './primitive';
2
+ export { Slot } from './slot';
@@ -0,0 +1,56 @@
1
+ import { type Component, type PropType, defineComponent, h } from "vue";
2
+ import { Slot } from './slot';
3
+
4
+ export type AsTag =
5
+ | 'a'
6
+ | 'button'
7
+ | 'div'
8
+ | 'form'
9
+ | 'h2'
10
+ | 'h3'
11
+ | 'img'
12
+ | 'input'
13
+ | 'label'
14
+ | 'li'
15
+ | 'nav'
16
+ | 'ol'
17
+ | 'p'
18
+ | 'span'
19
+ | 'svg'
20
+ | 'ul'
21
+ | 'template'
22
+ | ({} & string);
23
+
24
+ export interface PrimitiveProps {
25
+ asChild?: boolean
26
+ as?: AsTag | Component
27
+ }
28
+
29
+ export const Primitive = defineComponent({
30
+ name: "Primitive",
31
+ inheritAttrs: false,
32
+ props: {
33
+ asChild: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ as: {
38
+ type: [String, Object] as PropType<AsTag | Component>,
39
+ default: 'div'
40
+ }
41
+ },
42
+ setup(props, { attrs, slots }) {
43
+ const asTag = props.asChild ? 'template' : props.as;
44
+
45
+ const SELF_CLOSING = ['area', 'img', 'input'];
46
+ if (typeof asTag === 'string' && SELF_CLOSING.includes(asTag)) {
47
+ return () => h(asTag, attrs);
48
+ }
49
+
50
+ if (asTag !== 'template') {
51
+ return () => h(props.as, attrs, { default: slots.default });
52
+ }
53
+
54
+ return () => h(Slot, attrs, { default: slots.default });
55
+ }
56
+ })
@@ -0,0 +1,45 @@
1
+ import { Comment, cloneVNode, defineComponent, mergeProps } from 'vue';
2
+ import {renderSlotFragments} from "../../utils/renderSlotFragments";
3
+
4
+ export const Slot = defineComponent({
5
+ name: 'PrimativeSlot',
6
+ inheritAttrs: false,
7
+ setup(_, { attrs, slots }) {
8
+ return () => {
9
+ if (!slots.default) {
10
+ return null;
11
+ }
12
+
13
+ const children = renderSlotFragments(slots.default());
14
+ const firstNonCommentChildIndex = children.findIndex(child => child.type !== Comment);
15
+ if (firstNonCommentChildIndex === -1) {
16
+ return children;
17
+ }
18
+
19
+ const firstNonCommentChild = children[firstNonCommentChildIndex];
20
+ delete firstNonCommentChild.props?.ref;
21
+
22
+ const mergedProps = firstNonCommentChild.props ? mergeProps(attrs, firstNonCommentChild.props) : attrs;
23
+
24
+ if (attrs.class && firstNonCommentChild.props?.class) {
25
+ delete firstNonCommentChild.props.class;
26
+ }
27
+
28
+ const cloned = cloneVNode(firstNonCommentChild, mergedProps);
29
+
30
+ for (const prop in mergedProps) {
31
+ if (prop.startsWith('on')) {
32
+ cloned.props ||= {};
33
+ cloned.props[prop] = mergedProps[prop];
34
+ }
35
+ }
36
+
37
+ if (children.length === 1) {
38
+ return cloned;
39
+ }
40
+
41
+ children[firstNonCommentChildIndex] = cloned;
42
+ return children;
43
+ }
44
+ }
45
+ })
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <span
2
+ <Primitive
3
+ as-child
3
4
  v-bind="$attrs"
4
- style="display: inline-flex"
5
5
  @mouseenter="show"
6
6
  @mouseleave="hide"
7
7
  ref="wrapper">
8
- <span ref="reference">
9
- <slot />
10
- </span>
8
+ <TooltipTrigger ref="reference" >
9
+ <slot/>
10
+ </TooltipTrigger>
11
11
 
12
12
  <Teleport :to="transferTo">
13
13
  <Transition
@@ -27,7 +27,7 @@
27
27
  </div>
28
28
  </Transition>
29
29
  </Teleport>
30
- </span>
30
+ </Primitive>
31
31
  </template>
32
32
 
33
33
  <script lang="ts">
@@ -38,19 +38,31 @@ import {
38
38
  type PropType,
39
39
  computed,
40
40
  watch,
41
- onUnmounted
41
+ onUnmounted, type Ref
42
42
  } from 'vue';
43
43
  import {
44
44
  type Placement,
45
45
  placementWhileList,
46
46
  usePopper
47
47
  } from '../../composables/usePopper';
48
+
48
49
  import { fade } from '../../styles/transitions.css';
49
50
  import * as style from './style';
50
51
  import { useZIndex } from '../../composables/useZIndex';
52
+ import {Primitive} from "../primative/primitive";
53
+ import TooltipTrigger from "@/components/tooltip/TooltipTrigger.vue";
54
+ import {createContext} from "../../utils/injection";
55
+
56
+ interface TooltipContext {
57
+ reference: Ref<HTMLElement | undefined>
58
+ onReferenceChange: (element: HTMLElement | undefined) => void
59
+ }
60
+
61
+ export const [injectionTooltipContext, providerTooltipContext] = createContext<TooltipContext>('Tooltip');
51
62
 
52
63
  export default defineComponent({
53
64
  name: 'MTooltip',
65
+ components: {TooltipTrigger, Primitive},
54
66
  props: {
55
67
  text: {
56
68
  type: String,
@@ -87,7 +99,7 @@ export default defineComponent({
87
99
  // @ts-ignore
88
100
  const transfer = toRef(props, 'transfer');
89
101
  const wrapper = ref<HTMLElement | null>(null);
90
- const reference = ref<HTMLElement | null>(null);
102
+ const reference = ref<HTMLElement>();
91
103
  const isOpen = ref(false);
92
104
  const zIndex = ref(props.zIndex ?? nextZIndex());
93
105
  const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
@@ -106,6 +118,11 @@ export default defineComponent({
106
118
  }
107
119
  });
108
120
 
121
+ providerTooltipContext({
122
+ reference,
123
+ onReferenceChange: element => reference.value = element
124
+ });
125
+
109
126
  const { popper, transferTo, updatePopper } = usePopper({
110
127
  placement,
111
128
  transfer,
@@ -179,6 +196,7 @@ export default defineComponent({
179
196
 
180
197
  return {
181
198
  reference,
199
+ offset,
182
200
  popper,
183
201
  transferTo,
184
202
  isOpen,
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ import {Primitive} from "../primative/primitive";
3
+ import { useForwardExpose } from "../../utils/useForwardExpose";
4
+ import {onMounted} from "vue";
5
+ import { injectionTooltipContext } from "./Tooltip.vue";
6
+
7
+ const { forwardRef, currentElement } = useForwardExpose();
8
+
9
+ const tooltipContext = injectionTooltipContext();
10
+
11
+ onMounted(() => {
12
+ tooltipContext.onReferenceChange(currentElement.value);
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <Primitive as-child :ref="forwardRef">
18
+ <slot />
19
+ </Primitive>
20
+ </template>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <MTooltip text="Hello<br />World">
2
+ <MTooltip text="Hello World">
3
3
  <MButton>Top</MButton>
4
4
  </MTooltip>
5
5
  </template>
@@ -0,0 +1,15 @@
1
+ import { Fragment, type VNode } from 'vue';
2
+
3
+ export function renderSlotFragments(children?: VNode[]): VNode[] {
4
+ if (!children) {
5
+ return [];
6
+ }
7
+
8
+ return children.flatMap((child) => {
9
+ if (child.type === Fragment) {
10
+ return renderSlotFragments(child.children as VNode[]);
11
+ }
12
+
13
+ return [child];
14
+ });
15
+ }