@teammodlr/ui-kit 2.3.22 → 3.0.0-beta.10

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 (113) hide show
  1. package/lib/components/avatar/Avatar.vue.d.ts +2 -2
  2. package/lib/components/badge/style/Badge.css.d.ts +2 -2
  3. package/lib/components/button/Button.vue.d.ts +7 -4
  4. package/lib/components/button/style/Button.css.d.ts +3 -3
  5. package/lib/components/cardcontextmenu/CardContextMenu.vue.d.ts +5 -8
  6. package/lib/components/cardcontextmenu/CardContextMenuItem.vue.d.ts +11 -2
  7. package/lib/components/cardcontextmenu/CardContextMenuTriggerProvider.vue.d.ts +2 -0
  8. package/lib/components/cardcontextmenu/style/Dropdown.css.d.ts +2 -1
  9. package/lib/components/cardcontextmenu/symbol.d.ts +1 -0
  10. package/lib/components/checkbox/Checkbox.vue.d.ts +15 -4
  11. package/lib/components/collapse/CollapseItem.vue.d.ts +3 -2
  12. package/lib/components/colorpicker/ColorPicker.vue.d.ts +8 -9
  13. package/lib/components/confirm/Confirm.vue.d.ts +9 -0
  14. package/lib/components/confirm/props.d.ts +4 -0
  15. package/lib/components/dialog/Dialog.vue.d.ts +13 -5
  16. package/lib/components/dialogprovider/DialogProvider.vue.d.ts +1 -0
  17. package/lib/components/dialogprovider/types.d.ts +1 -0
  18. package/lib/components/dropdown/Dropdown.vue.d.ts +3 -1
  19. package/lib/components/dropdown/DropdownItem.vue.d.ts +11 -1
  20. package/lib/components/dropdown/DropdownSeperator.vue.d.ts +1 -0
  21. package/lib/components/dropdown/DropdownTriggerProvider.vue.d.ts +2 -0
  22. package/lib/components/dropdown/style/Dropdown.css.d.ts +2 -1
  23. package/lib/components/dropdown/symbol.d.ts +2 -0
  24. package/lib/components/image/Image.vue.d.ts +1 -1
  25. package/lib/components/index.d.ts +1 -0
  26. package/lib/components/messageprovider/Message.vue.d.ts +1 -1
  27. package/lib/components/messageprovider/MessageProvider.vue.d.ts +24 -24
  28. package/lib/components/messageprovider/style/Message.css.d.ts +1 -1
  29. package/lib/components/messageprovider/style/Toaster.css.d.ts +1 -0
  30. package/lib/components/messageprovider/types.d.ts +5 -0
  31. package/lib/components/modal/Modal.vue.d.ts +18 -6
  32. package/lib/components/popover/Popover.vue.d.ts +113 -0
  33. package/lib/components/popover/style/Popover.css.d.ts +4 -0
  34. package/lib/components/popover/style/index.d.ts +1 -0
  35. package/lib/components/radio/Radio.vue.d.ts +2 -0
  36. package/lib/components/radiobuttongroup/RadioButtonGroup.vue.d.ts +1 -0
  37. package/lib/components/select/Select.vue.d.ts +23 -11
  38. package/lib/components/select/style/Select.css.d.ts +2 -0
  39. package/lib/components/switch/Switch.vue.d.ts +2 -0
  40. package/lib/components/tab/Tab.vue.d.ts +5 -2
  41. package/lib/components/tab/TabGroup.vue.d.ts +8 -3
  42. package/lib/components/textarea/Textarea.vue.d.ts +2 -1
  43. package/lib/components/tooltip/Tooltip.vue.d.ts +5 -20
  44. package/lib/components/tooltip/TooltipTrigger.vue.d.ts +1 -10
  45. package/lib/components/tree/Tree.vue.d.ts +3 -3
  46. package/lib/components/tree/TreeNode.vue.d.ts +26 -12
  47. package/lib/components/tree/types.d.ts +5 -5
  48. package/lib/index.cjs.js +5 -14
  49. package/lib/index.es.js +14813 -10079
  50. package/lib/style.css +1 -1
  51. package/package.json +12 -6
  52. package/src/components/avatar/Avatar.vue +32 -24
  53. package/src/components/button/Button.vue +24 -5
  54. package/src/components/cardcontextmenu/CardContextMenu.vue +68 -95
  55. package/src/components/cardcontextmenu/CardContextMenuItem.vue +40 -50
  56. package/src/components/cardcontextmenu/CardContextMenuSeperator.vue +9 -7
  57. package/src/components/cardcontextmenu/CardContextMenuTriggerProvider.vue +15 -0
  58. package/src/components/cardcontextmenu/style/Dropdown.css.ts +155 -2
  59. package/src/components/cardcontextmenu/symbol.ts +3 -0
  60. package/src/components/checkbox/Checkbox.vue +37 -12
  61. package/src/components/checkbox/style/Checkbox.css.ts +6 -6
  62. package/src/components/collapse/CollapseItem.vue +46 -21
  63. package/src/components/collapse/style/Collapse.css.ts +5 -1
  64. package/src/components/colorpicker/ColorPicker.vue +76 -45
  65. package/src/components/confirm/Confirm.vue +15 -8
  66. package/src/components/confirm/props.ts +4 -0
  67. package/src/components/dialog/Dialog.vue +183 -37
  68. package/src/components/dialog/style/Dialog.css.ts +15 -1
  69. package/src/components/dialogprovider/types.ts +1 -0
  70. package/src/components/dropdown/Dropdown.vue +46 -3
  71. package/src/components/dropdown/DropdownItem.vue +55 -25
  72. package/src/components/dropdown/DropdownSeperator.vue +19 -11
  73. package/src/components/dropdown/DropdownTriggerProvider.vue +15 -0
  74. package/src/components/dropdown/examples/context.vue +2 -2
  75. package/src/components/dropdown/style/Dropdown.css.ts +173 -4
  76. package/src/components/dropdown/symbol.ts +4 -0
  77. package/src/components/form/examples/basic.vue +19 -8
  78. package/src/components/index.ts +1 -0
  79. package/src/components/messageprovider/MessageProvider.vue +139 -90
  80. package/src/components/messageprovider/examples/basic.vue +3 -1
  81. package/src/components/messageprovider/examples/index.stories.ts +37 -1
  82. package/src/components/messageprovider/style/Toaster.css.ts +24 -0
  83. package/src/components/messageprovider/types.ts +10 -0
  84. package/src/components/modal/Modal.vue +142 -67
  85. package/src/components/modal/style/Modal.css.ts +26 -2
  86. package/src/components/popover/Popover.vue +155 -0
  87. package/src/components/popover/examples/arrow.vue +47 -0
  88. package/src/components/popover/examples/basic.vue +15 -0
  89. package/src/components/popover/examples/index.stories.ts +19 -0
  90. package/src/components/popover/examples/index.ts +4 -0
  91. package/src/components/popover/examples/placement.vue +59 -0
  92. package/src/components/popover/examples/variant.vue +30 -0
  93. package/src/components/popover/style/Popover.css.ts +203 -0
  94. package/src/components/popover/style/index.ts +1 -0
  95. package/src/components/radio/Radio.vue +31 -17
  96. package/src/components/radiobutton/RadioButton.vue +15 -2
  97. package/src/components/radiobuttongroup/RadioButtonGroup.vue +11 -4
  98. package/src/components/select/Select.vue +309 -148
  99. package/src/components/select/examples/basic.vue +1 -1
  100. package/src/components/select/style/Select.css.ts +15 -0
  101. package/src/components/slider/Slider.vue +1 -1
  102. package/src/components/switch/Switch.vue +30 -10
  103. package/src/components/switch/style/Switch.css.ts +3 -5
  104. package/src/components/tab/Tab.vue +29 -20
  105. package/src/components/tab/TabGroup.vue +29 -38
  106. package/src/components/textarea/Textarea.vue +8 -4
  107. package/src/components/tooltip/Tooltip.vue +52 -141
  108. package/src/components/tooltip/TooltipTrigger.vue +14 -17
  109. package/src/components/tooltip/style/Tooltip.css.ts +148 -29
  110. package/src/components/tree/Tree.vue +138 -100
  111. package/src/components/tree/TreeNode.vue +105 -98
  112. package/src/components/tree/types.ts +4 -4
  113. package/src/styles/transitions.css.ts +36 -16
@@ -21,6 +21,6 @@ const options = Array.from({ length: 50 }, (_, i) => ({
21
21
  const value = ref();
22
22
 
23
23
  function testThis(value: any, option: any) {
24
- alert('value: ' + value);
24
+ // alert('value: ' + value);
25
25
  }
26
26
  </script>
@@ -365,3 +365,18 @@ export const clearable = style({
365
365
  top: '0',
366
366
  display: 'flex'
367
367
  });
368
+
369
+ export const arrow = style({
370
+ width: themeVars.space[4],
371
+ height: themeVars.space[4],
372
+ position: 'absolute',
373
+ right: themeVars.space[3],
374
+ top: themeVars.space[3],
375
+ display: 'flex',
376
+ color: themeVars.color.gray[500],
377
+ transition: 'transform 0.3s ease',
378
+ });
379
+
380
+ export const arrowOpen = style({
381
+ transform: 'rotate(180deg)',
382
+ })
@@ -14,7 +14,7 @@
14
14
  </template>
15
15
 
16
16
  <script lang="ts">
17
- import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
17
+ import { defineComponent, ref, onUnmounted } from 'vue';
18
18
  import * as style from './style';
19
19
 
20
20
  export default defineComponent({
@@ -1,12 +1,18 @@
1
1
  <template>
2
- <label :class="style.base" @click.prevent="toggle">
3
- <input v-model="checked" type="checkbox" :aria-checked="checked ? 'true' : 'false'"
4
- :aria-disabled="(disabled || loading) ? 'true' : 'false'" :aria-labelledby="`${id}-label`"
5
- :disabled="disabled || loading" :name="name" :id="id" :class="style.input" v-bind="$attrs"
6
- v-on="inputListeners" />
7
-
8
- <span :class="classes">
9
- </span>
2
+ <label :class="style.base">
3
+ <SwitchRoot
4
+ v-model="checked"
5
+ :aria-checked="checked ? 'true' : 'false'"
6
+ :aria-disabled="(disabled || loading) ? 'true' : 'false'"
7
+ :aria-labelledby="`${id}-label`"
8
+ :disabled="disabled || loading"
9
+ :name="name"
10
+ :id="id"
11
+ :class="classes"
12
+ v-bind="$attrs"
13
+ @blur="onBlur"
14
+ @focus="onFocus"
15
+ />
10
16
 
11
17
  <span :class="style.label" :id="`${id}-label`">
12
18
  <template v-if="hasSlot">
@@ -23,6 +29,7 @@
23
29
 
24
30
  <script lang="ts">
25
31
  import { computed, defineComponent, type PropType, ref, toRef, watch } from 'vue';
32
+ import { SwitchRoot } from 'reka-ui';
26
33
  import { useInput } from '../../composables/useInput';
27
34
  import { useInteractive } from "../../composables/useInteractive";
28
35
  import type { Size } from '../../types/props';
@@ -30,6 +37,9 @@ import * as style from './style';
30
37
 
31
38
  export default defineComponent({
32
39
  name: "Switch",
40
+ components: {
41
+ SwitchRoot
42
+ },
33
43
  emits: useInput.emits(),
34
44
  props: {
35
45
  ...useInput.props(),
@@ -65,7 +75,7 @@ export default defineComponent({
65
75
  formDisabled,
66
76
  formLoading,
67
77
  inputListeners
68
- } = useInput(props, { focus, emit });
78
+ } = useInput(props, { focus, emit, withListeners: false });
69
79
 
70
80
  const disabled = computed(() => formDisabled || props.disabled || props.loading);
71
81
  const name = toRef(props, 'name');
@@ -102,6 +112,14 @@ export default defineComponent({
102
112
  checked.value = !checked.value;
103
113
  }
104
114
 
115
+ function onFocus(event: FocusEvent) {
116
+ emit('focus', event);
117
+ }
118
+
119
+ function onBlur(event: FocusEvent) {
120
+ emit('blur', event);
121
+ }
122
+
105
123
  expose({
106
124
  focus,
107
125
  blur,
@@ -125,7 +143,9 @@ export default defineComponent({
125
143
  hasSlot,
126
144
  inputListeners,
127
145
  focus,
128
- blur
146
+ blur,
147
+ onFocus,
148
+ onBlur
129
149
  }
130
150
  }
131
151
  })
@@ -41,6 +41,9 @@ export const toggle = style({
41
41
  background: vars.offBackground,
42
42
  transition: 'all .4s ease',
43
43
  selectors: {
44
+ ['&:focus-visible']: {
45
+ boxShadow: `0 0 0 2px ${themeVars.color.blue[200]}`
46
+ },
44
47
  ['&:after']: {
45
48
  position: 'relative',
46
49
  display: 'block',
@@ -128,8 +131,3 @@ export const size = styleVariants({
128
131
  }
129
132
  }
130
133
  });
131
-
132
- globalStyle(`${base} ${input}:focus + ${toggle}`, {
133
- vars: {},
134
- boxShadow: `0 0 0 2px ${themeVars.color.blue[200]}`
135
- });
@@ -1,26 +1,37 @@
1
1
  <template>
2
- <div ref="tabRef" :class="computedTabClasses" @click.prevent="handleClick" :disabled="disabled">
3
- <div :class="computedTabLabelClasses">
4
- <slot name="tab" :label="label" :value="value">
5
- {{ computedLabel }}
6
- </slot>
7
-
8
- </div>
9
- <div v-if="closable">
10
- <button role="button" :class="close" @click.stop="$emit('onClose', { value, label })"></button>
2
+ <TabsTrigger :value="computedValue" :disabled="disabled" as-child>
3
+ <div ref="tabRef" v-bind="attrs" :class="computedTabClasses" :disabled="disabled">
4
+ <div :class="computedTabLabelClasses">
5
+ <slot name="tab" :label="label" :value="value">
6
+ {{ computedLabel }}
7
+ </slot>
8
+ </div>
9
+ <div v-if="closable">
10
+ <button role="button" :class="close" @click.stop="$emit('onClose', { value, label })"></button>
11
+ </div>
11
12
  </div>
13
+ </TabsTrigger>
12
14
 
13
- <teleport v-if="selected && teleportTo" :to="teleportTo">
14
- <slot />
15
- </teleport>
16
- </div>
15
+ <teleport v-if="teleportTo && hasContent" :to="teleportTo">
16
+ <TabsContent :value="computedValue" as-child>
17
+ <div>
18
+ <slot />
19
+ </div>
20
+ </TabsContent>
21
+ </teleport>
17
22
  </template>
18
23
 
19
24
  <script lang="ts">
25
+ import { TabsContent, TabsTrigger } from 'reka-ui';
20
26
  import { computed, defineComponent, inject, onMounted, reactive, ref } from 'vue';
21
27
  import { tabButton, tabButtonActive, tabLabel, close, tabHasClose } from './style';
22
28
  export default defineComponent({
23
29
  name: "Tab",
30
+ inheritAttrs: false,
31
+ components: {
32
+ TabsContent,
33
+ TabsTrigger
34
+ },
24
35
  props: {
25
36
  value: {
26
37
  type: [String, Number]
@@ -38,11 +49,12 @@ export default defineComponent({
38
49
  }
39
50
  },
40
51
  emits: ['onClose'],
41
- setup(props, { emit }) {
52
+ setup(props, { attrs, slots }) {
42
53
  const computedValue = computed(() => props.value);
43
54
  const computedLabel = computed(() => props.label || props.value);
44
55
  const tabRef = ref<HTMLElement | null>(null);
45
- const teleportTo = ref(null);
56
+ const teleportTo = ref<HTMLElement | null>(null);
57
+ const hasContent = computed(() => !!slots.default);
46
58
 
47
59
  const tabs = inject("tabs", {
48
60
  tabsContentRef: ref(null),
@@ -73,10 +85,6 @@ export default defineComponent({
73
85
  return tabs.state.active === computedValue.value;
74
86
  });
75
87
 
76
- function handleClick() {
77
- tabs.selectTab(computedValue.value!);
78
- }
79
-
80
88
  onMounted(() => {
81
89
  teleportTo.value = tabs.tabsContentRef.value;
82
90
  });
@@ -87,9 +95,10 @@ export default defineComponent({
87
95
  tabRef,
88
96
  computedTabClasses,
89
97
  computedTabLabelClasses,
90
- handleClick,
91
98
  selected,
92
99
  teleportTo,
100
+ hasContent,
101
+ attrs,
93
102
  close
94
103
  }
95
104
  }
@@ -1,21 +1,33 @@
1
1
  <template>
2
- <div :class="computedTabsWrapperClasses">
3
- <div ref="wrapperRef">
4
- <div ref="tabsRef" :class="computedTabsClasses">
5
- <slot />
2
+ <TabsRoot
3
+ :model-value="currentValue"
4
+ :orientation="vertical ? 'vertical' : 'horizontal'"
5
+ :unmount-on-hide="true"
6
+ @update:model-value="selectTab"
7
+ >
8
+ <div :class="computedTabsWrapperClasses">
9
+ <div ref="wrapperRef">
10
+ <TabsList ref="tabsRef" :class="computedTabsClasses">
11
+ <slot />
12
+ </TabsList>
6
13
  </div>
14
+ <div ref="tabsContentRef" :class="computedTabContentClasses"></div>
7
15
  </div>
8
- <div ref="tabsContentRef" :class="computedTabContentClasses"></div>
9
- </div>
16
+ </TabsRoot>
10
17
  </template>
11
18
 
12
19
  <script lang="ts">
13
20
  import type { Size } from '../../types/props';
14
- import { computed, defineComponent, provide, reactive, ref, watchEffect, type PropType } from 'vue';
21
+ import { TabsList, TabsRoot } from 'reka-ui';
22
+ import { computed, defineComponent, provide, reactive, ref, type PropType } from 'vue';
15
23
  import { tabs, tabContent, tabsEvenly } from './style';
16
24
 
17
25
  export default defineComponent({
18
26
  name: "TabGroup",
27
+ components: {
28
+ TabsList,
29
+ TabsRoot
30
+ },
19
31
  props: {
20
32
  modelValue: {
21
33
  type: [String, Number],
@@ -41,33 +53,18 @@ export default defineComponent({
41
53
  validator: (value: string) => ['base', 'card'].includes(value)
42
54
  }
43
55
  },
44
- emit: [
56
+ emits: [
45
57
  'update:modelValue',
46
58
  'update:selected'
47
59
  ],
48
60
  setup(props, { emit }) {
49
61
  const wrapperRef = ref<HTMLElement>();
62
+ const tabsRef = ref<HTMLElement>();
50
63
  const tabsContentRef = ref<HTMLElement>();
51
- const contentRef = ref<HTMLElement>();
52
- const active = ref();
53
- const selectedActive = ref();
54
-
55
- // Watch for changes in modelValue
56
- watchEffect(() => {
57
- if (props.modelValue !== undefined) {
58
- active.value = props.modelValue;
59
- }
60
- });
61
-
62
- // Watch for changes in selected
63
- watchEffect(() => {
64
- if (props.selected !== undefined) {
65
- selectedActive.value = props.selected;
66
- }
67
- });
64
+ const currentValue = computed(() => props.modelValue ?? props.selected);
68
65
 
69
66
  const state = reactive({
70
- active: computed(() => active.value ?? selectedActive.value),
67
+ active: currentValue,
71
68
  type: computed(() => props.type)
72
69
  });
73
70
 
@@ -92,16 +89,8 @@ export default defineComponent({
92
89
  });
93
90
 
94
91
  function selectTab(tab: string | number) {
95
- // Update both modelValue and selected if they exist
96
- if (props.modelValue !== undefined) {
97
- active.value = tab;
98
- emit('update:modelValue', tab);
99
- }
100
-
101
- if (props.selected !== undefined) {
102
- selectedActive.value = tab;
103
- emit('update:selected', tab);
104
- }
92
+ emit('update:modelValue', tab);
93
+ emit('update:selected', tab);
105
94
  }
106
95
 
107
96
  provide("tabs", {
@@ -112,11 +101,13 @@ export default defineComponent({
112
101
 
113
102
  return {
114
103
  wrapperRef,
104
+ tabsRef,
115
105
  tabsContentRef,
116
- contentRef,
106
+ currentValue,
117
107
  computedTabsWrapperClasses,
118
108
  computedTabsClasses,
119
- computedTabContentClasses
109
+ computedTabContentClasses,
110
+ selectTab
120
111
  }
121
112
  }
122
113
  })
@@ -14,7 +14,7 @@
14
14
  :id="id"
15
15
  :placeholder="placeholder"
16
16
  :name="name"
17
- :value="modelValue || ''"
17
+ :value="textareaValue"
18
18
  :readonly="readonly"
19
19
  v-on="inputListeners"
20
20
  :class="inputComputedClasses"
@@ -31,7 +31,6 @@
31
31
  </template>
32
32
 
33
33
  <script lang="ts">
34
- // @ts-nocheck
35
34
  import type { PropType } from "vue";
36
35
  import type { Size } from "../../types/props";
37
36
  import {
@@ -90,8 +89,8 @@ export default defineComponent({
90
89
  },
91
90
  },
92
91
  emits: useInput.emits(),
93
- setup(props, { slots, emit, expose }) {
94
- const element = ref<HTMLInputElement|null>(null);
92
+ setup(props, { emit, expose }) {
93
+ const element = ref<HTMLTextAreaElement | null>(null);
95
94
  const { focus, blur } = useInteractive(element);
96
95
  const {
97
96
  id,
@@ -145,6 +144,10 @@ export default defineComponent({
145
144
  return formError.value || props.error;
146
145
  });
147
146
 
147
+ const textareaValue = computed(() => {
148
+ return props.modelValue == null ? '' : String(props.modelValue);
149
+ });
150
+
148
151
  const onClear = () => {
149
152
  emit('update:modelValue', '');
150
153
  };
@@ -165,6 +168,7 @@ export default defineComponent({
165
168
  wrapperComputedClasses,
166
169
  computedContainerClasses,
167
170
  name,
171
+ textareaValue,
168
172
  inputError,
169
173
  style,
170
174
 
@@ -1,68 +1,59 @@
1
1
  <template>
2
- <Primitive
3
- as-child
4
- v-bind="$attrs"
5
- @mouseenter="show"
6
- @mouseleave="hide"
7
- ref="wrapper">
8
- <TooltipTrigger ref="reference" >
9
- <slot/>
10
- </TooltipTrigger>
11
-
12
- <Teleport :to="transferTo">
13
- <Transition
14
- :enter-active-class="fade.enterActive"
15
- :leave-active-class="fade.leaveActive"
16
- :enter-from-class="fade.enterFrom"
17
- :leave-to-class="fade.leaveTo">
18
- <div
19
- role="tooltip"
2
+ <TooltipProvider :delay-duration="delay">
3
+ <TooltipRoot>
4
+ <TooltipTrigger as-child v-bind="$attrs">
5
+ <slot />
6
+ </TooltipTrigger>
7
+
8
+ <TooltipPortal :disabled="!transfer">
9
+ <TooltipContent
20
10
  :class="computedClasses"
21
- ref="popper"
22
- v-if="isOpen"
23
- :style="{ zIndex: zIndex }">
11
+ :side="resolvedSide"
12
+ :align="resolvedAlign"
13
+ :side-offset="4"
14
+ :style="{ zIndex: zIndex }"
15
+ >
24
16
  <slot :html="text" name="content">
25
17
  <span v-html="text" />
26
18
  </slot>
27
- </div>
28
- </Transition>
29
- </Teleport>
30
- </Primitive>
19
+ </TooltipContent>
20
+ </TooltipPortal>
21
+ </TooltipRoot>
22
+ </TooltipProvider>
31
23
  </template>
32
24
 
33
25
  <script lang="ts">
34
26
  import {
35
27
  defineComponent,
36
28
  ref,
37
- toRef,
38
29
  type PropType,
39
- computed,
40
- watch,
41
- onUnmounted, type Ref
30
+ computed
42
31
  } from 'vue';
32
+ import {
33
+ TooltipContent,
34
+ TooltipPortal,
35
+ TooltipProvider,
36
+ TooltipRoot,
37
+ TooltipTrigger,
38
+ type TooltipContentProps
39
+ } from 'reka-ui';
43
40
  import {
44
41
  type Placement,
45
- placementWhileList,
46
- usePopper
42
+ placementWhileList
47
43
  } from '../../composables/usePopper';
48
44
 
49
- import { fade } from '../../styles/transitions.css';
50
45
  import * as style from './style';
51
46
  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');
62
47
 
63
48
  export default defineComponent({
64
49
  name: 'MTooltip',
65
- components: {TooltipTrigger, Primitive},
50
+ components: {
51
+ TooltipContent,
52
+ TooltipPortal,
53
+ TooltipProvider,
54
+ TooltipRoot,
55
+ TooltipTrigger
56
+ },
66
57
  props: {
67
58
  text: {
68
59
  type: String,
@@ -95,41 +86,21 @@ export default defineComponent({
95
86
  },
96
87
  setup(props) {
97
88
  const { nextZIndex } = useZIndex();
98
- const placement = toRef(props, 'placement');
99
- // @ts-ignore
100
- const transfer = toRef(props, 'transfer');
101
- const wrapper = ref<HTMLElement | null>(null);
102
- const reference = ref<HTMLElement>();
103
- const isOpen = ref(false);
104
89
  const zIndex = ref(props.zIndex ?? nextZIndex());
105
- const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
106
- const offset = computed(() => {
107
- switch (placement.value) {
108
- case 'top':
109
- return [0, 8];
110
- case 'bottom':
111
- return [0, -8];
112
- case 'left':
113
- return [8, 0];
114
- case 'right':
115
- return [-8, 0];
116
- default:
117
- return [0, 0];
118
- }
119
- });
120
-
121
- providerTooltipContext({
122
- reference,
123
- onReferenceChange: element => reference.value = element
124
- });
125
-
126
- const { popper, transferTo, updatePopper } = usePopper({
127
- placement,
128
- transfer,
129
- reference,
130
- wrapper,
131
- // @ts-ignore
132
- offset: offset.value
90
+ const resolvedPlacement = computed(() => {
91
+ const [side, align] = props.placement.split('-');
92
+
93
+ return {
94
+ side: side === 'top' || side === 'right' || side === 'bottom' || side === 'left'
95
+ ? side
96
+ : undefined,
97
+ align: align === 'start' || align === 'center' || align === 'end'
98
+ ? align
99
+ : undefined
100
+ } as {
101
+ side?: TooltipContentProps['side'];
102
+ align?: TooltipContentProps['align'];
103
+ };
133
104
  });
134
105
 
135
106
  const computedClasses = computed(() => {
@@ -141,73 +112,13 @@ export default defineComponent({
141
112
  ];
142
113
  });
143
114
 
144
- watch(
145
- () => isOpen.value,
146
- (value: boolean) => {
147
- if (value) {
148
- updatePopper();
149
-
150
- zIndex.value = nextZIndex();
151
- }
152
- }
153
- );
154
-
155
- const toggle = () => {
156
- if (timeout.value) {
157
- clearTimeout(timeout.value);
158
- }
159
-
160
- if (props.delay && !isOpen.value) {
161
- timeout.value = setTimeout(() => {
162
- isOpen.value = !isOpen.value;
163
- }, props.delay);
164
- } else {
165
- isOpen.value = !isOpen.value;
166
- }
167
- };
168
-
169
- function show() {
170
- if (timeout.value) {
171
- clearTimeout(timeout.value);
172
- }
173
-
174
- if (props.delay) {
175
- timeout.value = setTimeout(() => {
176
- isOpen.value = true;
177
- }, props.delay);
178
- } else {
179
- isOpen.value = true;
180
- }
181
- }
182
-
183
- function hide() {
184
- if (timeout.value) {
185
- clearTimeout(timeout.value);
186
- }
187
-
188
- isOpen.value = false;
189
- }
190
-
191
- onUnmounted(() => {
192
- isOpen.value = false;
193
- if (timeout.value) {
194
- clearTimeout(timeout.value);
195
- }
196
- timeout.value = null;
197
- });
198
-
199
115
  return {
200
- reference,
201
- offset,
202
- popper,
203
- transferTo,
204
- isOpen,
205
- show,
206
- hide,
207
116
  computedClasses,
117
+ resolvedSide: computed(() => resolvedPlacement.value.side),
118
+ resolvedAlign: computed(() => resolvedPlacement.value.align),
119
+ transfer: computed(() => props.transfer),
208
120
  zIndex,
209
- style,
210
- fade
121
+ style
211
122
  };
212
123
  }
213
124
  });
@@ -1,20 +1,17 @@
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
1
  <template>
17
- <Primitive as-child :ref="forwardRef">
2
+ <TooltipTrigger as-child>
18
3
  <slot />
19
- </Primitive>
4
+ </TooltipTrigger>
20
5
  </template>
6
+
7
+ <script lang="ts">
8
+ import { defineComponent } from 'vue';
9
+ import { TooltipTrigger } from 'reka-ui';
10
+
11
+ export default defineComponent({
12
+ name: 'TooltipTrigger',
13
+ components: {
14
+ TooltipTrigger
15
+ }
16
+ });
17
+ </script>