@weni/unnnic-system 3.11.3-alpha.3 → 3.12.1-alpha.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 (66) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/components/AudioRecorder/AudioHandler.vue.d.ts +0 -17
  3. package/dist/components/AudioRecorder/AudioRecorder.vue.d.ts +0 -34
  4. package/dist/components/Card/Card.vue.d.ts +0 -17
  5. package/dist/components/Card/CardStatusesContainer.vue.d.ts +0 -17
  6. package/dist/components/Card/SimpleCard.vue.d.ts +0 -17
  7. package/dist/components/Card/TitleCard.vue.d.ts +0 -17
  8. package/dist/components/CardInformation/CardInformation.vue.d.ts +0 -17
  9. package/dist/components/ChartBar/ChartBar.vue.d.ts +0 -17
  10. package/dist/components/ChartLine/ChartLine.vue.d.ts +0 -17
  11. package/dist/components/ChatText/ChatText.vue.d.ts +0 -17
  12. package/dist/components/ChatsMessage/ChatsMessage.vue.d.ts +0 -17
  13. package/dist/components/DataArea/DataArea.vue.d.ts +0 -17
  14. package/dist/components/DateFilter/DateFilter.vue.d.ts +3 -3
  15. package/dist/components/FormElement/FormElement.vue.d.ts +2 -2
  16. package/dist/components/Input/Input.vue.d.ts +3 -3
  17. package/dist/components/Label/Label.vue.d.ts +1 -1
  18. package/dist/components/Label/Label.vue.d.ts.map +1 -1
  19. package/dist/components/ModalNext/ModalNext.vue.d.ts +3 -3
  20. package/dist/components/MoodRating/MoodRating.vue.d.ts +0 -17
  21. package/dist/components/Slider/Slider.vue.d.ts +0 -17
  22. package/dist/components/Switch/Switch.vue.d.ts +1 -1
  23. package/dist/components/Tab/Tab.vue.d.ts +0 -17
  24. package/dist/components/TextArea/TextArea.vue.d.ts +3 -3
  25. package/dist/components/Toast/Toast.vue.d.ts.map +1 -1
  26. package/dist/components/ToolTip/ToolTip.vue.d.ts +0 -17
  27. package/dist/components/ToolTip/ToolTip.vue.d.ts.map +1 -1
  28. package/dist/components/ui/dialog/DialogContent.vue.d.ts.map +1 -1
  29. package/dist/components/ui/drawer/DrawerContent.vue.d.ts +1 -0
  30. package/dist/components/ui/drawer/DrawerContent.vue.d.ts.map +1 -1
  31. package/dist/components/ui/popover/PopoverContent.vue.d.ts.map +1 -1
  32. package/dist/components/ui/popover/PopoverTrigger.vue.d.ts.map +1 -1
  33. package/dist/components/ui/tooltip/Tooltip.vue.d.ts.map +1 -1
  34. package/dist/components/ui/tooltip/TooltipContent.vue.d.ts.map +1 -1
  35. package/dist/components/ui/tooltip/TooltipTrigger.vue.d.ts.map +1 -1
  36. package/dist/components/ui/tooltip/index.d.ts +0 -1
  37. package/dist/components/ui/tooltip/index.d.ts.map +1 -1
  38. package/dist/{es-99b102dc.mjs → es-38bd0c9c.mjs} +1 -1
  39. package/dist/{index-c20fa852.mjs → index-561a4027.mjs} +6304 -6265
  40. package/dist/lib/layer-manager.d.ts +16 -0
  41. package/dist/lib/layer-manager.d.ts.map +1 -0
  42. package/dist/{pt-br-b17e69b4.mjs → pt-br-14a3c647.mjs} +1 -1
  43. package/dist/style.css +1 -1
  44. package/dist/unnnic.mjs +1 -1
  45. package/dist/unnnic.umd.js +33 -33
  46. package/package.json +1 -1
  47. package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +1 -1
  48. package/src/components/Toast/Toast.vue +4 -1
  49. package/src/components/ToolTip/ToolTip.vue +31 -36
  50. package/src/components/ToolTip/__tests__/ToolTip.spec.js +0 -6
  51. package/src/components/index.ts +19 -19
  52. package/src/components/ui/dialog/DialogContent.vue +6 -0
  53. package/src/components/ui/drawer/DrawerContent.vue +12 -2
  54. package/src/components/ui/popover/PopoverContent.vue +4 -0
  55. package/src/components/ui/popover/PopoverTrigger.vue +5 -1
  56. package/src/components/ui/tooltip/Tooltip.vue +9 -3
  57. package/src/components/ui/tooltip/TooltipContent.vue +3 -2
  58. package/src/components/ui/tooltip/TooltipTrigger.vue +4 -0
  59. package/src/components/ui/tooltip/index.ts +0 -1
  60. package/src/lib/layer-manager.ts +84 -0
  61. package/src/stories/DrawerNext.stories.js +1 -0
  62. package/src/stories/LayerManager.docs.mdx +40 -0
  63. package/src/stories/LayerManager.stories.js +364 -0
  64. package/dist/components/ui/tooltip/TooltipProvider.vue.d.ts +0 -19
  65. package/dist/components/ui/tooltip/TooltipProvider.vue.d.ts.map +0 -1
  66. package/src/components/ui/tooltip/TooltipProvider.vue +0 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weni/unnnic-system",
3
- "version": "3.11.3-alpha.3",
3
+ "version": "3.12.1-alpha.0",
4
4
  "type": "commonjs",
5
5
  "files": [
6
6
  "dist",
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`UnnnicAlert.vue > matches the snapshot 1`] = `
4
4
  "<transition-stub data-v-c3231c18="" name="toast-slide" appear="true" persisted="false" css="true" data-testid="toast-transition">
5
- <aside data-v-c3231c18="" class="unnnic-toast unnnic-toast--success" role="status" aria-live="polite" data-testid="toast">
5
+ <aside data-v-c3231c18="" class="unnnic-toast unnnic-toast--success" role="status" aria-live="polite" data-testid="toast" style="z-index: 1405;">
6
6
  <section data-v-c3231c18="" class="unnnic-toast__content" data-testid="toast-content">
7
7
  <header data-v-c3231c18="" class="unnnic-toast__header" data-testid="toast-header"><span data-v-26446d8e="" data-v-c3231c18="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--green-500 unnnic-icon-size--ant unnnic-icon__size--ant" data-testid="toast-type-icon" translate="no">check_circle</span>
8
8
  <h3 data-v-c3231c18="" class="unnnic-toast__title" data-testid="toast-title">Test Alert</h3><span data-v-26446d8e="" data-v-c3231c18="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--neutral-dark unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable unnnic-toast__close" data-testid="toast-close-icon" translate="no">close</span>
@@ -11,6 +11,7 @@
11
11
  :role="validType === 'error' ? 'alert' : 'status'"
12
12
  :aria-live="validType === 'error' ? 'assertive' : 'polite'"
13
13
  data-testid="toast"
14
+ :style="{ zIndex: toastZIndex }"
14
15
  >
15
16
  <section
16
17
  class="unnnic-toast__content"
@@ -74,6 +75,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue';
74
75
 
75
76
  import UnnnicIcon from '@/components/Icon.vue';
76
77
  import UnnnicButton from '@/components/Button/Button.vue';
78
+ import { useLayerZIndex } from '@/lib/layer-manager';
77
79
 
78
80
  import type { ToastProps, ToastEmits } from './types';
79
81
  import type { SchemeColor } from '@/types/scheme-colors';
@@ -113,6 +115,8 @@ const typeConfig = computed(() => {
113
115
  return configMap[validType.value];
114
116
  });
115
117
 
118
+ const toastZIndex = useLayerZIndex('toast');
119
+
116
120
  const handleClose = () => {
117
121
  isVisible.value = false;
118
122
  emit('close');
@@ -156,7 +160,6 @@ onUnmounted(() => {
156
160
  position: fixed;
157
161
  bottom: $unnnic-space-4;
158
162
  right: $unnnic-space-4;
159
- z-index: 9999;
160
163
 
161
164
  display: flex;
162
165
  align-items: flex-end;
@@ -1,50 +1,45 @@
1
1
  <template>
2
- <TooltipProvider>
3
- <Tooltip
4
- :disabled="!(enabled || forceOpen)"
5
- :open="forceOpen || undefined"
6
- data-testid="tooltip-wrapper"
7
- >
8
- <TooltipTrigger data-testid="tooltip-trigger">
9
- <slot />
10
- </TooltipTrigger>
2
+ <Tooltip
3
+ :disabled="!(enabled || forceOpen)"
4
+ :open="forceOpen || undefined"
5
+ data-testid="tooltip-wrapper"
6
+ >
7
+ <TooltipTrigger data-testid="tooltip-trigger">
8
+ <slot />
9
+ </TooltipTrigger>
11
10
 
12
- <TooltipContent
13
- :class="['unnnic-tooltip-label', `unnnic-tooltip-label-${side}`]"
14
- :style="{ maxWidth: maxWidth }"
15
- :side="side"
16
- data-testid="tooltip-content"
11
+ <TooltipContent
12
+ :class="['unnnic-tooltip-label', `unnnic-tooltip-label-${side}`]"
13
+ :style="{ maxWidth: maxWidth }"
14
+ :side="side"
15
+ data-testid="tooltip-content"
16
+ >
17
+ <template v-if="enableHtml">
18
+ <!-- eslint-disable-next-line vue/no-v-html -->
19
+ <section
20
+ v-html="text"
21
+ data-testid="tooltip-html-content"
22
+ ></section>
23
+ </template>
24
+ <template
25
+ v-for="(line, index) in text.split('\n')"
26
+ v-else
27
+ :key="index"
17
28
  >
18
- <template v-if="enableHtml">
19
- <!-- eslint-disable-next-line vue/no-v-html -->
20
- <section
21
- v-html="text"
22
- data-testid="tooltip-html-content"
23
- ></section>
24
- </template>
25
- <template
26
- v-for="(line, index) in text.split('\n')"
27
- v-else
28
- :key="index"
29
- >
30
- {{ line }}
31
- <br />
32
- </template>
33
- </TooltipContent>
34
- </Tooltip>
35
- </TooltipProvider>
29
+ {{ line }}
30
+ <br />
31
+ </template>
32
+ </TooltipContent>
33
+ </Tooltip>
36
34
  </template>
37
35
 
38
36
  <script>
39
- import { Tooltip, TooltipProvider } from '../ui/tooltip';
40
- import TooltipContent from '../ui/tooltip/TooltipContent.vue';
41
- import TooltipTrigger from '../ui/tooltip/TooltipTrigger.vue';
37
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
42
38
 
43
39
  export default {
44
40
  name: 'UnnnicTooltip',
45
41
  components: {
46
42
  Tooltip,
47
- TooltipProvider,
48
43
  TooltipTrigger,
49
44
  TooltipContent,
50
45
  },
@@ -236,12 +236,6 @@ describe('ToolTip', () => {
236
236
  });
237
237
 
238
238
  describe('Component Structure', () => {
239
- it('should have TooltipProvider component', () => {
240
- expect(wrapper.findComponent({ name: 'TooltipProvider' }).exists()).toBe(
241
- true,
242
- );
243
- });
244
-
245
239
  it('should have Tooltip component', () => {
246
240
  expect(wrapper.findComponent({ name: 'Tooltip' }).exists()).toBe(true);
247
241
  });
@@ -93,6 +93,12 @@ import DataTable from './DataTable/index.vue';
93
93
  import Chip from './Chip/Chip.vue';
94
94
  import Toast from './Toast/Toast.vue';
95
95
  import { toast } from './Toast/ToastManager';
96
+ import Popover from './ui/popover/Popover.vue';
97
+ import PopoverContent from './ui/popover/PopoverContent.vue';
98
+ import PopoverTrigger from './ui/popover/PopoverTrigger.vue';
99
+ import PopoverFooter from './ui/popover/PopoverFooter.vue';
100
+ import TemplatePreview from './TemplatePreview/TemplatePreview.vue';
101
+ import TemplatePreviewModal from './TemplatePreview/TemplatePreviewModal.vue';
96
102
  import Tabs from './ui/tabs/Tabs.vue';
97
103
  import TabsList from './ui/tabs/TabsList.vue';
98
104
  import TabsTrigger from './ui/tabs/TabsTrigger.vue';
@@ -103,12 +109,6 @@ import {
103
109
  SegmentedControlTrigger,
104
110
  SegmentedControlContent,
105
111
  } from './ui/segmented-control';
106
- import Popover from './ui/popover/Popover.vue';
107
- import PopoverContent from './ui/popover/PopoverContent.vue';
108
- import PopoverTrigger from './ui/popover/PopoverTrigger.vue';
109
- import PopoverFooter from './ui/popover/PopoverFooter.vue';
110
- import TemplatePreview from './TemplatePreview/TemplatePreview.vue';
111
- import TemplatePreviewModal from './TemplatePreview/TemplatePreviewModal.vue';
112
112
  import PageHeader from './PageHeader/PageHeader.vue';
113
113
  import Dialog from './ui/dialog/Dialog.vue';
114
114
  import DialogContent from './ui/dialog/DialogContent.vue';
@@ -236,11 +236,11 @@ export const components: ComponentsMap = {
236
236
  unnnicTabsList: TabsList,
237
237
  unnnicTabsTrigger: TabsTrigger,
238
238
  unnnicTabsContent: TabsContent,
239
- unnnicPageHeader: PageHeader,
240
239
  unnnicSegmentedControl: SegmentedControl,
241
240
  unnnicSegmentedControlList: SegmentedControlList,
242
241
  unnnicSegmentedControlTrigger: SegmentedControlTrigger,
243
242
  unnnicSegmentedControlContent: SegmentedControlContent,
243
+ unnnicPageHeader: PageHeader,
244
244
  unnnicDialog: Dialog,
245
245
  unnnicDialogContent: DialogContent,
246
246
  unnnicDialogFooter: DialogFooter,
@@ -353,6 +353,12 @@ export const unnnicSelectTime = SelectTime as VueComponent;
353
353
  export const unnnicChip = Chip;
354
354
  export const unnnicToast = Toast;
355
355
  export const unnnicToastManager = toast;
356
+ export const unnnicPopover = Popover;
357
+ export const unnnicPopoverContent = PopoverContent;
358
+ export const unnnicPopoverTrigger = PopoverTrigger;
359
+ export const unnnicPopoverFooter = PopoverFooter;
360
+ export const unnnicTemplatePreview = TemplatePreview as VueComponent;
361
+ export const unnnicTemplatePreviewModal = TemplatePreviewModal as VueComponent;
356
362
  export const unnnicTabs = Tabs;
357
363
  export const unnnicTabsList = TabsList;
358
364
  export const unnnicTabsTrigger = TabsTrigger;
@@ -361,12 +367,6 @@ export const unnnicSegmentedControl = SegmentedControl;
361
367
  export const unnnicSegmentedControlList = SegmentedControlList;
362
368
  export const unnnicSegmentedControlTrigger = SegmentedControlTrigger;
363
369
  export const unnnicSegmentedControlContent = SegmentedControlContent;
364
- export const unnnicPopover = Popover;
365
- export const unnnicPopoverContent = PopoverContent;
366
- export const unnnicPopoverTrigger = PopoverTrigger;
367
- export const unnnicPopoverFooter = PopoverFooter;
368
- export const unnnicTemplatePreview = TemplatePreview as VueComponent;
369
- export const unnnicTemplatePreviewModal = TemplatePreviewModal as VueComponent;
370
370
  export const unnnicPageHeader = PageHeader;
371
371
  export const unnnicDialog = Dialog;
372
372
  export const unnnicDialogContent = DialogContent;
@@ -479,6 +479,12 @@ export const UnnnicSelectTime = SelectTime as VueComponent;
479
479
  export const UnnnicChip = Chip;
480
480
  export const UnnnicToast = Toast;
481
481
  export const UnnnicToastManager = toast;
482
+ export const UnnnicPopover = Popover;
483
+ export const UnnnicPopoverContent = PopoverContent;
484
+ export const UnnnicPopoverTrigger = PopoverTrigger;
485
+ export const UnnnicPopoverFooter = PopoverFooter;
486
+ export const UnnnicTemplatePreview = TemplatePreview as VueComponent;
487
+ export const UnnnicTemplatePreviewModal = TemplatePreviewModal as VueComponent;
482
488
  export const UnnnicTabs = Tabs;
483
489
  export const UnnnicTabsList = TabsList;
484
490
  export const UnnnicTabsTrigger = TabsTrigger;
@@ -487,12 +493,6 @@ export const UnnnicSegmentedControl = SegmentedControl;
487
493
  export const UnnnicSegmentedControlList = SegmentedControlList;
488
494
  export const UnnnicSegmentedControlTrigger = SegmentedControlTrigger;
489
495
  export const UnnnicSegmentedControlContent = SegmentedControlContent;
490
- export const UnnnicPopover = Popover;
491
- export const UnnnicPopoverContent = PopoverContent;
492
- export const UnnnicPopoverTrigger = PopoverTrigger;
493
- export const UnnnicPopoverFooter = PopoverFooter;
494
- export const UnnnicTemplatePreview = TemplatePreview as VueComponent;
495
- export const UnnnicTemplatePreviewModal = TemplatePreviewModal as VueComponent;
496
496
  export const UnnnicPageHeader = PageHeader;
497
497
  export const UnnnicDialog = Dialog;
498
498
  export const UnnnicDialogContent = DialogContent;
@@ -10,6 +10,7 @@ import {
10
10
  useForwardPropsEmits,
11
11
  } from 'reka-ui';
12
12
  import { cn } from '@/lib/utils';
13
+ import { useLayerZIndex } from '@/lib/layer-manager';
13
14
 
14
15
  defineOptions({
15
16
  name: 'UnnnicDialogContent',
@@ -35,6 +36,9 @@ const delegatedProps = reactiveOmit(props, 'class', 'parentClass');
35
36
 
36
37
  const forwarded = useForwardPropsEmits(delegatedProps, emits);
37
38
 
39
+ const overlayZIndex = useLayerZIndex('modal', { offset: -2 });
40
+ const modalZIndex = useLayerZIndex('modal');
41
+
38
42
  const contentClasses = computed(() =>
39
43
  cn(
40
44
  'unnnic-dialog-content',
@@ -58,12 +62,14 @@ const ConditionalWrapper: Component = (_, { slots }) => {
58
62
  <DialogPortal>
59
63
  <DialogOverlay
60
64
  class="unnnic-dialog-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
65
+ :style="{ zIndex: overlayZIndex }"
61
66
  />
62
67
 
63
68
  <ConditionalWrapper>
64
69
  <DialogContent
65
70
  v-bind="forwarded"
66
71
  :class="contentClasses"
72
+ :style="{ zIndex: modalZIndex }"
67
73
  >
68
74
  <slot />
69
75
  </DialogContent>
@@ -5,6 +5,7 @@ import { reactiveOmit } from '@vueuse/core';
5
5
  import { useForwardPropsEmits } from 'reka-ui';
6
6
  import { DrawerContent, DrawerPortal } from 'vaul-vue';
7
7
  import { cn } from '@/lib/utils';
8
+ import { useLayerZIndex } from '@/lib/layer-manager';
8
9
  import DrawerOverlay from './DrawerOverlay.vue';
9
10
 
10
11
  defineOptions({
@@ -20,6 +21,7 @@ const props = withDefaults(
20
21
  }
21
22
  >(),
22
23
  {
24
+ class: undefined,
23
25
  size: 'medium',
24
26
  showOverlay: true,
25
27
  },
@@ -28,11 +30,16 @@ const emits = defineEmits<DialogContentEmits>();
28
30
 
29
31
  const delegatedProps = reactiveOmit(props, 'class');
30
32
  const forwardedProps = useForwardPropsEmits(delegatedProps, emits);
33
+
34
+ const layerZIndex = useLayerZIndex('drawer');
31
35
  </script>
32
36
 
33
37
  <template>
34
38
  <DrawerPortal>
35
- <DrawerOverlay v-if="showOverlay" />
39
+ <DrawerOverlay
40
+ v-if="showOverlay"
41
+ :style="{ zIndex: layerZIndex - 2 }"
42
+ />
36
43
  <DrawerContent
37
44
  v-bind="forwardedProps"
38
45
  :class="
@@ -42,7 +49,10 @@ const forwardedProps = useForwardPropsEmits(delegatedProps, emits);
42
49
  props.class,
43
50
  )
44
51
  "
45
- :style="{ '--initial-transform': 'calc(100% + 8px)' }"
52
+ :style="{
53
+ '--initial-transform': 'calc(100% + 8px)',
54
+ zIndex: layerZIndex,
55
+ }"
46
56
  >
47
57
  <slot />
48
58
  </DrawerContent>
@@ -9,6 +9,7 @@
9
9
  'bg-popover text-popover-foreground outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
10
10
  )
11
11
  "
12
+ :style="{ zIndex: popoverZIndex }"
12
13
  >
13
14
  <section :class="`unnnic-popover__content ${props.class || ''}`">
14
15
  <component
@@ -34,6 +35,7 @@ import { computed, useSlots } from 'vue';
34
35
  import { reactiveOmit } from '@vueuse/core';
35
36
  import { PopoverContent, PopoverPortal, useForwardPropsEmits } from 'reka-ui';
36
37
  import { cn } from '@/lib/utils';
38
+ import { useLayerZIndex } from '@/lib/layer-manager';
37
39
 
38
40
  defineOptions({
39
41
  inheritAttrs: false,
@@ -61,6 +63,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
61
63
 
62
64
  const slots = useSlots();
63
65
 
66
+ const popoverZIndex = useLayerZIndex('popover');
67
+
64
68
  const getComponentName = (vnode: VNode): string | undefined => {
65
69
  const componentType = vnode.type as { name?: string; __name?: string };
66
70
  return componentType?.name || componentType?.__name;
@@ -14,10 +14,14 @@ const props = defineProps<PopoverTriggerProps>();
14
14
  </PopoverTrigger>
15
15
  </template>
16
16
 
17
- <style scoped>
17
+ <style lang="scss" scoped>
18
18
  .unnnic-popover-trigger {
19
19
  border: none;
20
20
  background: transparent;
21
21
  padding: 0;
22
+
23
+ & > * {
24
+ width: 100%;
25
+ }
22
26
  }
23
27
  </style>
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { TooltipRootEmits, TooltipRootProps } from 'reka-ui';
3
3
  import { TooltipRoot, useForwardPropsEmits } from 'reka-ui';
4
+ import { TooltipProvider } from 'reka-ui';
4
5
 
5
6
  const props = defineProps<TooltipRootProps>();
6
7
  const emits = defineEmits<TooltipRootEmits>();
@@ -9,7 +10,12 @@ const forwarded = useForwardPropsEmits(props, emits);
9
10
  </script>
10
11
 
11
12
  <template>
12
- <TooltipRoot v-bind="forwarded">
13
- <slot />
14
- </TooltipRoot>
13
+ <TooltipProvider
14
+ :delayDuration="100"
15
+ disableClosingTrigger
16
+ >
17
+ <TooltipRoot v-bind="forwarded">
18
+ <slot />
19
+ </TooltipRoot>
20
+ </TooltipProvider>
15
21
  </template>
@@ -9,6 +9,7 @@ import {
9
9
  useForwardPropsEmits,
10
10
  } from 'reka-ui';
11
11
  import { cn } from '@/lib/utils';
12
+ import { useLayerZIndex } from '@/lib/layer-manager';
12
13
 
13
14
  defineOptions({
14
15
  inheritAttrs: false,
@@ -26,6 +27,7 @@ const emits = defineEmits<TooltipContentEmits>();
26
27
  const delegatedProps = reactiveOmit(props, 'class');
27
28
 
28
29
  const forwarded = useForwardPropsEmits(delegatedProps, emits);
30
+ const tooltipZIndex = useLayerZIndex('tooltip');
29
31
  </script>
30
32
 
31
33
  <template>
@@ -39,6 +41,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
39
41
  props.class,
40
42
  )
41
43
  "
44
+ :style="{ zIndex: tooltipZIndex }"
42
45
  >
43
46
  <slot />
44
47
 
@@ -51,8 +54,6 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
51
54
  @use '@/assets/scss/unnnic' as *;
52
55
 
53
56
  .tooltip__content {
54
- z-index: 10001;
55
-
56
57
  background-color: $unnnic-color-gray-900;
57
58
  color: $unnnic-color-white;
58
59
  border-radius: $unnnic-radius-1;
@@ -18,5 +18,9 @@ const props = defineProps<TooltipTriggerProps>();
18
18
  <style lang="scss" scoped>
19
19
  .unnnic-tooltip-trigger {
20
20
  display: inline-block;
21
+
22
+ & > * {
23
+ width: 100%;
24
+ }
21
25
  }
22
26
  </style>
@@ -1,4 +1,3 @@
1
1
  export { default as Tooltip } from './Tooltip.vue';
2
2
  export { default as TooltipContent } from './TooltipContent.vue';
3
- export { default as TooltipProvider } from './TooltipProvider.vue';
4
3
  export { default as TooltipTrigger } from './TooltipTrigger.vue';
@@ -0,0 +1,84 @@
1
+ import { onBeforeUnmount, onMounted, ref, type Ref } from 'vue';
2
+
3
+ export const layerScale = {
4
+ hide: -1,
5
+ base: 0,
6
+ drawer: 1000,
7
+ modal: 1100,
8
+ popover: 1200,
9
+ tooltip: 1300,
10
+ toast: 1400,
11
+ } as const;
12
+
13
+ export type LayerToken = keyof typeof layerScale;
14
+
15
+ const DEFAULT_STEP = 5;
16
+
17
+ const counters: Record<LayerToken, number> = {
18
+ hide: 0,
19
+ base: 0,
20
+ drawer: 0,
21
+ modal: 0,
22
+ popover: 0,
23
+ tooltip: 0,
24
+ toast: 0,
25
+ };
26
+
27
+ interface Allocation {
28
+ id: symbol;
29
+ type: LayerToken;
30
+ value: number;
31
+ }
32
+
33
+ const allocations = new Map<symbol, Allocation>();
34
+
35
+ function acquire(type: LayerToken): Allocation {
36
+ const id = Symbol('layer');
37
+ counters[type] = (counters[type] ?? 0) + 1;
38
+ const value = layerScale[type] + counters[type] * DEFAULT_STEP;
39
+ const allocation: Allocation = { id, type, value };
40
+ allocations.set(id, allocation);
41
+ return allocation;
42
+ }
43
+
44
+ function release(id: symbol) {
45
+ const allocation = allocations.get(id);
46
+ if (!allocation) {
47
+ return;
48
+ }
49
+
50
+ allocations.delete(id);
51
+ const current = Math.max((counters[allocation.type] ?? 1) - 1, 0);
52
+ counters[allocation.type] = current;
53
+ }
54
+
55
+ export interface LayerZIndexOptions {
56
+ offset?: number;
57
+ }
58
+
59
+ export function useLayerZIndex(
60
+ type: LayerToken = 'base',
61
+ options?: LayerZIndexOptions,
62
+ ): Ref<number> {
63
+ const initialValue = layerScale[type] + (options?.offset ?? 0);
64
+ const zIndex = ref(initialValue);
65
+
66
+ let allocationId: symbol | null = null;
67
+
68
+ const allocate = () => {
69
+ const allocation = acquire(type);
70
+ allocationId = allocation.id;
71
+ zIndex.value = allocation.value + (options?.offset ?? 0);
72
+ };
73
+
74
+ onMounted(allocate);
75
+
76
+ onBeforeUnmount(() => {
77
+ if (allocationId) {
78
+ release(allocationId);
79
+ allocationId = null;
80
+ }
81
+ });
82
+
83
+ return zIndex;
84
+ }
@@ -189,6 +189,7 @@ export const Sizes = {
189
189
  components: {
190
190
  Drawer,
191
191
  DrawerContent,
192
+ DrawerClose,
192
193
  DrawerTrigger,
193
194
  DrawerHeader,
194
195
  DrawerTitle,
@@ -0,0 +1,40 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Utilities/Layer Manager/Overview" />
4
+
5
+ # Layer Manager Overview
6
+
7
+ The layer manager exists to keep every teleported component (dialogs, drawers, popovers, tooltips, toasts, etc.) in a predictable stacking order without sprinkling arbitrary `z-index: 9999` rules across the codebase. Defining semantic bands (drawer, modal, popover, tooltip, toast) and allocating values automatically whenever a component mounts. [Reference](https://v1.chakra-ui.com/docs/components/recipes/z-index)
8
+
9
+ ## Why avoid manual z-index values?
10
+
11
+ - **Unbounded numbers** – once one component uses `z-index: 9999`, the next overlay needs more. This escalates quickly and still breaks when stacking contexts change.
12
+ - **Stacking contexts** – `position`, `transform`, `opacity`, `filter`, and even flex or grid children can create new contexts that ignore global z-index rules. Portaled content plus a manager side-steps this entirely.
13
+ - **Shared ownership** – dialogs, drawers, dropdowns, and popovers often live in different packages. A single allocator means each feature does not need to know what values others are using.
14
+
15
+ ## How it works here
16
+
17
+ 1. **Tokens, not numbers** – components request a token such as `modal`, `popover`, or `tooltip`. The manager maps those tokens to a base band (e.g., modals start at 1200, popovers at 1400).
18
+ 2. **Auto-increment** – every time a component mounts, it receives the next value in its band so nested dialogs or infinite toasts still stack correctly.
19
+ 3. **Scoped offsets** – overlays that belong to the same surface (e.g., `DialogOverlay` vs `DialogContent`) simply call `useLayerZIndex` with a small negative offset so the overlay sits just beneath the content that opened it.
20
+
21
+ ```
22
+ const modalZ = useLayerZIndex('modal');
23
+ const overlayZ = useLayerZIndex('modal', { offset: -2 });
24
+ ```
25
+
26
+ ## Benefits
27
+
28
+ - **Deterministic ordering** – open a drawer, then a popover, then a dialog, then a tooltip and the visual order will always follow the semantic bands.
29
+ - **Safer refactors** – tokens can be remapped (e.g., raise the entire `tooltip` band) without touching every component.
30
+
31
+ ## When to override
32
+
33
+ In rare cases you might still need a custom `z-index`. Prefer to:
34
+
35
+ 1. Add a new token in the layer manager if the surface fits the existing pattern (e.g., `tour`).
36
+ 2. Only apply inline overrides for truly one-off cases, and document why the global manager does not work there.
37
+
38
+
39
+ Use the `Layer Manager` stories in Storybook to verify real interactions (dialog + tooltip/popover, drawer + dialog, nested dialogs, dialog + toast) whenever you add a new teleported component.
40
+