@weni/unnnic-system 3.12.6-alpha-teleports.0 → 3.12.8-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.
- package/.vscode/extensions.json +3 -0
- package/CHANGELOG.md +1080 -0
- package/README.md +1 -9
- package/dist/{es-ebc7770b.mjs → es-52edeb71.mjs} +1 -1
- package/dist/{index-f117a889.mjs → index-756fe685.mjs} +9070 -8660
- package/dist/index.d.ts +1013 -311
- package/dist/{pt-br-b1a08da0.mjs → pt-br-24583c8c.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +181 -177
- package/dist/unnnic.umd.js +33 -33
- package/package.json +1 -1
- package/src/assets/scss/scheme-colors.scss +223 -223
- package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +1 -1
- package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +1 -2
- package/src/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue +60 -61
- package/src/components/Checkbox/Checkbox.vue +9 -3
- package/src/components/CheckboxGroup/CheckboxGroup.vue +7 -5
- package/src/components/Chip/Chip.vue +1 -1
- package/src/components/Drawer/Drawer.vue +20 -9
- package/src/components/Drawer/__tests__/Drawer.spec.js +11 -9
- package/src/components/Drawer/__tests__/__snapshots__/Drawer.spec.js.snap +9 -9
- package/src/components/FormElement/FormElement.vue +97 -88
- package/src/components/Input/BaseInput.vue +25 -5
- package/src/components/Input/Input.scss +2 -3
- package/src/components/Input/Input.vue +26 -3
- package/src/components/Input/TextInput.vue +64 -25
- package/src/components/Input/__test__/TextInput.spec.js +1 -1
- package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +5 -1
- package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +7 -1
- package/src/components/ModalDialog/ModalDialog.vue +11 -4
- package/src/components/MultiSelect/MultSelectOption.vue +49 -0
- package/src/components/MultiSelect/__tests__/MultiSelect.spec.js +557 -0
- package/src/components/MultiSelect/__tests__/MultiSelectOption.spec.js +229 -0
- package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelect.spec.js.snap +87 -0
- package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelectOption.spec.js.snap +51 -0
- package/src/components/MultiSelect/index.vue +265 -0
- package/src/components/Radio/Radio.vue +13 -7
- package/src/components/Radio/__test__/Radio.spec.js +3 -1
- package/src/components/RadioGroup/RadioGroup.vue +18 -10
- package/src/components/Select/__tests__/Select.spec.js +422 -0
- package/src/components/Select/__tests__/SelectItem.spec.js +330 -0
- package/src/components/Select/__tests__/__snapshots__/Popover.spec.js.snap +8 -0
- package/src/components/Select/__tests__/__snapshots__/Select.spec.js.snap +71 -0
- package/src/components/Select/__tests__/__snapshots__/SelectItem.spec.js.snap +15 -0
- package/src/components/Select/__tests__/__snapshots__/SelectOption.spec.js.snap +25 -0
- package/src/components/Select/__tests__/__snapshots__/SelectPopover.spec.js.snap +8 -0
- package/src/components/Select/index.vue +308 -0
- package/src/components/Switch/Switch.vue +11 -4
- package/src/components/TemplatePreview/TemplatePreview.vue +30 -27
- package/src/components/TemplatePreview/TemplatePreviewModal.vue +11 -11
- package/src/components/TemplatePreview/types.d.ts +3 -3
- package/src/components/Toast/Toast.vue +13 -9
- package/src/components/Toast/ToastManager.ts +1 -4
- package/src/components/Toast/__tests__/ToastManager.spec.js +6 -10
- package/src/components/ToolTip/ToolTip.vue +1 -1
- package/src/components/index.ts +10 -6
- package/src/components/ui/dialog/DialogContent.vue +5 -5
- package/src/components/ui/drawer/DrawerContent.vue +2 -4
- package/src/components/ui/popover/PopoverContent.vue +29 -13
- package/src/components/ui/popover/PopoverOption.vue +5 -1
- package/src/components/ui/tooltip/TooltipContent.vue +2 -5
- package/src/components/ui/tooltip/TooltipTrigger.vue +4 -2
- package/src/index.ts +2 -9
- package/src/lib/layer-manager.ts +52 -24
- package/src/locales/en.json +3 -1
- package/src/locales/es.json +3 -1
- package/src/locales/pt_br.json +3 -1
- package/src/stories/Input.mdx +3 -0
- package/src/stories/LayerManager.docs.mdx +9 -9
- package/src/stories/LayerManager.stories.js +11 -54
- package/src/stories/MultiSelect.stories.js +143 -45
- package/src/stories/Popover.stories.js +5 -0
- package/src/stories/Select.stories.js +161 -0
- package/src/stories/TemplatePreview.stories.js +27 -27
- package/src/stories/TemplatePreviewModal.stories.js +31 -31
- package/src/components/MultiSelect/MultiSelect.vue +0 -297
- package/src/lib/__tests__/teleport-target.spec.ts +0 -73
- package/src/lib/teleport-target.ts +0 -46
package/src/components/index.ts
CHANGED
|
@@ -28,15 +28,16 @@ import checkbox from './Checkbox/Checkbox.vue';
|
|
|
28
28
|
import checkboxGroup from './CheckboxGroup/CheckboxGroup.vue';
|
|
29
29
|
import collapse from './Collapse/Collapse.vue';
|
|
30
30
|
import radio from './Radio/Radio.vue';
|
|
31
|
+
import radioGroup from './RadioGroup/RadioGroup.vue';
|
|
31
32
|
import languageSelect from './Dropdown/LanguageSelect.vue';
|
|
32
33
|
import modal from './Modal/Modal.vue';
|
|
33
34
|
import modalUpload from './ModalUpload/ModalUpload.vue';
|
|
34
35
|
import { callAlert, callModal } from '../utils/call';
|
|
35
36
|
import selectSmart from './SelectSmart/SelectSmart.vue';
|
|
36
|
-
|
|
37
|
+
import select from './Select/index.vue';
|
|
37
38
|
import selectItem from './Select/SelectItem.vue';
|
|
38
39
|
// import selectListItem from './SelectListItem/SelectListItem.vue';
|
|
39
|
-
import multiSelect from './MultiSelect/
|
|
40
|
+
import multiSelect from './MultiSelect/index.vue';
|
|
40
41
|
import alert from './Alert/Alert.vue';
|
|
41
42
|
// import autocomplete from './Input/Autocomplete.vue';
|
|
42
43
|
// import autocompleteSelect from './AutocompleteSelect/AutocompleteSelect.vue';
|
|
@@ -162,16 +163,17 @@ export const components: ComponentsMap = {
|
|
|
162
163
|
unnnicCheckboxGroup: checkboxGroup,
|
|
163
164
|
unnnicCollapse: collapse,
|
|
164
165
|
unnnicRadio: radio,
|
|
166
|
+
unnnicRadioGroup: radioGroup,
|
|
165
167
|
unnnicLanguageSelect: languageSelect,
|
|
166
168
|
unnnicModal: modal,
|
|
167
169
|
unnnicModalNext: ModalNext,
|
|
168
170
|
unnnicModalDialog: ModalDialog,
|
|
169
171
|
unnnicModalUpload: modalUpload,
|
|
170
172
|
unnnicSelectSmart: selectSmart,
|
|
171
|
-
|
|
173
|
+
unnnicSelect: select,
|
|
172
174
|
unnnicSelectItem: selectItem,
|
|
173
175
|
// unnnicSelectListItem: selectListItem,
|
|
174
|
-
unnnicMultiSelect: multiSelect,
|
|
176
|
+
unnnicMultiSelect: multiSelect as VueComponent,
|
|
175
177
|
unnnicAlert: alert,
|
|
176
178
|
unnnicCallAlert: callAlert,
|
|
177
179
|
unnnicCallModal: callModal,
|
|
@@ -290,13 +292,14 @@ export const unnnicCheckbox = checkbox;
|
|
|
290
292
|
export const unnnicCheckboxGroup = checkboxGroup;
|
|
291
293
|
export const unnnicCollapse = collapse;
|
|
292
294
|
export const unnnicRadio = radio;
|
|
295
|
+
export const unnnicRadioGroup = radioGroup;
|
|
293
296
|
export const unnniclanguageSelect = languageSelect as VueComponent;
|
|
294
297
|
export const unnnicModal = modal;
|
|
295
298
|
export const unnnicModalDialog = ModalDialog;
|
|
296
299
|
export const unnnicModalNext = ModalNext;
|
|
297
300
|
export const unnnicModalUpload = modalUpload;
|
|
298
301
|
export const unnnicSelectSmart = selectSmart as VueComponent;
|
|
299
|
-
|
|
302
|
+
export const unnnicSelect = select as VueComponent;
|
|
300
303
|
export const unnnicSelectItem = selectItem;
|
|
301
304
|
// export const unnnicSelectListItem = selectListItem;
|
|
302
305
|
export const unnnicMultiSelect = multiSelect as VueComponent;
|
|
@@ -417,13 +420,14 @@ export const UnnnicCheckbox = checkbox;
|
|
|
417
420
|
export const UnnnicCheckboxGroup = checkboxGroup;
|
|
418
421
|
export const UnnnicCollapse = collapse;
|
|
419
422
|
export const UnnnicRadio = radio;
|
|
423
|
+
export const UnnnicRadioGroup = radioGroup;
|
|
420
424
|
export const UnnniclanguageSelect = languageSelect as VueComponent;
|
|
421
425
|
export const UnnnicModal = modal;
|
|
422
426
|
export const UnnnicModalDialog = ModalDialog;
|
|
423
427
|
export const UnnnicModalNext = ModalNext;
|
|
424
428
|
export const UnnnicModalUpload = modalUpload;
|
|
425
429
|
export const UnnnicSelectSmart = selectSmart as VueComponent;
|
|
426
|
-
|
|
430
|
+
export const UnnnicSelect = select as VueComponent;
|
|
427
431
|
export const UnnnicSelectItem = selectItem;
|
|
428
432
|
// export const UnnnicSelectListItem = selectListItem;
|
|
429
433
|
export const UnnnicMultiSelect = multiSelect as VueComponent;
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from 'reka-ui';
|
|
12
12
|
import { cn } from '@/lib/utils';
|
|
13
13
|
import { useLayerZIndex } from '@/lib/layer-manager';
|
|
14
|
-
import { useTeleportTarget } from '@/lib/teleport-target';
|
|
15
14
|
|
|
16
15
|
defineOptions({
|
|
17
16
|
name: 'UnnnicDialogContent',
|
|
@@ -37,9 +36,8 @@ const delegatedProps = reactiveOmit(props, 'class', 'parentClass');
|
|
|
37
36
|
|
|
38
37
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
39
38
|
|
|
40
|
-
const overlayZIndex = useLayerZIndex({ offset: -2 });
|
|
41
|
-
const modalZIndex = useLayerZIndex();
|
|
42
|
-
const portalTarget = useTeleportTarget();
|
|
39
|
+
const overlayZIndex = useLayerZIndex('modal', { offset: -2 });
|
|
40
|
+
const modalZIndex = useLayerZIndex('modal');
|
|
43
41
|
|
|
44
42
|
const contentClasses = computed(() =>
|
|
45
43
|
cn(
|
|
@@ -61,7 +59,7 @@ const ConditionalWrapper: Component = (_, { slots }) => {
|
|
|
61
59
|
</script>
|
|
62
60
|
|
|
63
61
|
<template>
|
|
64
|
-
<DialogPortal
|
|
62
|
+
<DialogPortal>
|
|
65
63
|
<DialogOverlay
|
|
66
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"
|
|
67
65
|
:style="{ zIndex: overlayZIndex }"
|
|
@@ -97,6 +95,8 @@ const ConditionalWrapper: Component = (_, { slots }) => {
|
|
|
97
95
|
top: 50%;
|
|
98
96
|
left: 50%;
|
|
99
97
|
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
|
|
100
100
|
transform: translate(-50%, -50%);
|
|
101
101
|
|
|
102
102
|
width: 100%;
|
|
@@ -6,7 +6,6 @@ import { useForwardPropsEmits } from 'reka-ui';
|
|
|
6
6
|
import { DrawerContent, DrawerPortal } from 'vaul-vue';
|
|
7
7
|
import { cn } from '@/lib/utils';
|
|
8
8
|
import { useLayerZIndex } from '@/lib/layer-manager';
|
|
9
|
-
import { useTeleportTarget } from '@/lib/teleport-target';
|
|
10
9
|
import DrawerOverlay from './DrawerOverlay.vue';
|
|
11
10
|
|
|
12
11
|
defineOptions({
|
|
@@ -32,12 +31,11 @@ const emits = defineEmits<DialogContentEmits>();
|
|
|
32
31
|
const delegatedProps = reactiveOmit(props, 'class');
|
|
33
32
|
const forwardedProps = useForwardPropsEmits(delegatedProps, emits);
|
|
34
33
|
|
|
35
|
-
const layerZIndex = useLayerZIndex();
|
|
36
|
-
const portalTarget = useTeleportTarget();
|
|
34
|
+
const layerZIndex = useLayerZIndex('drawer');
|
|
37
35
|
</script>
|
|
38
36
|
|
|
39
37
|
<template>
|
|
40
|
-
<DrawerPortal
|
|
38
|
+
<DrawerPortal>
|
|
41
39
|
<DrawerOverlay
|
|
42
40
|
v-if="showOverlay"
|
|
43
41
|
:style="{ zIndex: layerZIndex - 2 }"
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<PopoverPortal
|
|
2
|
+
<PopoverPortal>
|
|
3
3
|
<PopoverContent
|
|
4
4
|
v-bind="{ ...forwarded, ...$attrs }"
|
|
5
|
+
:style="{ width: contentWidth, zIndex: popoverZIndex }"
|
|
5
6
|
:class="
|
|
6
7
|
cn(
|
|
7
8
|
'unnnic-popover',
|
|
8
|
-
`unnnic-popover--size-${props.size}`,
|
|
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 }"
|
|
13
12
|
>
|
|
14
13
|
<section :class="`unnnic-popover__content ${props.class || ''}`">
|
|
15
14
|
<component
|
|
@@ -36,7 +35,6 @@ import { reactiveOmit } from '@vueuse/core';
|
|
|
36
35
|
import { PopoverContent, PopoverPortal, useForwardPropsEmits } from 'reka-ui';
|
|
37
36
|
import { cn } from '@/lib/utils';
|
|
38
37
|
import { useLayerZIndex } from '@/lib/layer-manager';
|
|
39
|
-
import { useTeleportTarget } from '@/lib/teleport-target';
|
|
40
38
|
|
|
41
39
|
defineOptions({
|
|
42
40
|
inheritAttrs: false,
|
|
@@ -46,7 +44,8 @@ const props = withDefaults(
|
|
|
46
44
|
defineProps<
|
|
47
45
|
PopoverContentProps & {
|
|
48
46
|
class?: HTMLAttributes['class'];
|
|
49
|
-
size?:
|
|
47
|
+
size?: string;
|
|
48
|
+
width?: string;
|
|
50
49
|
}
|
|
51
50
|
>(),
|
|
52
51
|
{
|
|
@@ -54,6 +53,7 @@ const props = withDefaults(
|
|
|
54
53
|
sideOffset: 4,
|
|
55
54
|
size: 'medium',
|
|
56
55
|
class: '',
|
|
56
|
+
width: '',
|
|
57
57
|
},
|
|
58
58
|
);
|
|
59
59
|
const emits = defineEmits<PopoverContentEmits>();
|
|
@@ -64,8 +64,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
|
64
64
|
|
|
65
65
|
const slots = useSlots() as Slots;
|
|
66
66
|
|
|
67
|
-
const popoverZIndex = useLayerZIndex();
|
|
68
|
-
const portalTarget = useTeleportTarget();
|
|
67
|
+
const popoverZIndex = useLayerZIndex('popover');
|
|
69
68
|
|
|
70
69
|
const getComponentName = (vnode: VNode): string | undefined => {
|
|
71
70
|
const componentType = vnode.type as { name?: string; __name?: string };
|
|
@@ -85,6 +84,18 @@ const footerChildren = computed(() => {
|
|
|
85
84
|
(vnode: VNode) => getComponentName(vnode) === 'UnnnicPopoverFooter',
|
|
86
85
|
);
|
|
87
86
|
});
|
|
87
|
+
|
|
88
|
+
const contentWidth = computed(() => {
|
|
89
|
+
if (props.width) return props.width;
|
|
90
|
+
|
|
91
|
+
const sizes = {
|
|
92
|
+
small: '240px',
|
|
93
|
+
medium: '320px',
|
|
94
|
+
large: '400px',
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return sizes[props.size as keyof typeof sizes];
|
|
98
|
+
});
|
|
88
99
|
</script>
|
|
89
100
|
|
|
90
101
|
<style lang="scss">
|
|
@@ -95,15 +106,20 @@ $popover-space: $unnnic-space-4;
|
|
|
95
106
|
.unnnic-popover {
|
|
96
107
|
border-radius: $unnnic-radius-2;
|
|
97
108
|
box-shadow: $unnnic-shadow-1;
|
|
109
|
+
border: 1px solid $unnnic-color-border-soft;
|
|
98
110
|
|
|
99
|
-
|
|
100
|
-
width:
|
|
111
|
+
&::-webkit-scrollbar {
|
|
112
|
+
width: $unnnic-spacing-inline-nano;
|
|
101
113
|
}
|
|
102
|
-
|
|
103
|
-
|
|
114
|
+
|
|
115
|
+
&::-webkit-scrollbar-thumb {
|
|
116
|
+
background: $unnnic-color-neutral-cleanest;
|
|
117
|
+
border-radius: $unnnic-border-radius-pill;
|
|
104
118
|
}
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
|
|
120
|
+
&::-webkit-scrollbar-track {
|
|
121
|
+
background: $unnnic-color-neutral-soft;
|
|
122
|
+
border-radius: $unnnic-border-radius-pill;
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
&__content {
|
|
@@ -76,7 +76,7 @@ const schemeColor = computed(() => {
|
|
|
76
76
|
.unnnic-popover-option {
|
|
77
77
|
cursor: pointer;
|
|
78
78
|
border-radius: $unnnic-radius-2;
|
|
79
|
-
padding: $unnnic-space-2;
|
|
79
|
+
padding: $unnnic-space-2 $unnnic-space-4;
|
|
80
80
|
font: $unnnic-font-emphasis;
|
|
81
81
|
display: flex;
|
|
82
82
|
gap: $unnnic-space-2;
|
|
@@ -98,6 +98,10 @@ const schemeColor = computed(() => {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
&__label {
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
text-overflow: ellipsis;
|
|
103
|
+
white-space: nowrap;
|
|
104
|
+
|
|
101
105
|
@each $name, $color in $unnnic-scheme-colors {
|
|
102
106
|
&.unnnic-popover-option__label--#{$name} {
|
|
103
107
|
color: $color;
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
} from 'reka-ui';
|
|
11
11
|
import { cn } from '@/lib/utils';
|
|
12
12
|
import { useLayerZIndex } from '@/lib/layer-manager';
|
|
13
|
-
import { useTeleportTarget } from '@/lib/teleport-target';
|
|
14
13
|
|
|
15
14
|
defineOptions({
|
|
16
15
|
inheritAttrs: false,
|
|
@@ -20,7 +19,6 @@ const props = withDefaults(
|
|
|
20
19
|
defineProps<TooltipContentProps & { class?: HTMLAttributes['class'] }>(),
|
|
21
20
|
{
|
|
22
21
|
sideOffset: 0,
|
|
23
|
-
class: undefined,
|
|
24
22
|
},
|
|
25
23
|
);
|
|
26
24
|
|
|
@@ -29,12 +27,11 @@ const emits = defineEmits<TooltipContentEmits>();
|
|
|
29
27
|
const delegatedProps = reactiveOmit(props, 'class');
|
|
30
28
|
|
|
31
29
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
32
|
-
const tooltipZIndex = useLayerZIndex();
|
|
33
|
-
const portalTarget = useTeleportTarget();
|
|
30
|
+
const tooltipZIndex = useLayerZIndex('tooltip');
|
|
34
31
|
</script>
|
|
35
32
|
|
|
36
33
|
<template>
|
|
37
|
-
<TooltipPortal
|
|
34
|
+
<TooltipPortal>
|
|
38
35
|
<TooltipContent
|
|
39
36
|
v-bind="{ ...forwarded, ...$attrs }"
|
|
40
37
|
:class="
|
package/src/index.ts
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import type { App } from 'vue';
|
|
2
2
|
import { components } from '@/components';
|
|
3
3
|
import './assets/scss/tailwind.scss';
|
|
4
|
-
import { setTeleportTarget, type TeleportTarget } from '@/lib/teleport-target';
|
|
5
4
|
|
|
6
5
|
interface UnnnicPlugin {
|
|
7
|
-
install(app: App
|
|
6
|
+
install(app: App): void;
|
|
8
7
|
[key: string]: any;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
export interface UnnnicPluginOptions {
|
|
12
|
-
teleportTarget?: TeleportTarget | null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
10
|
const Unnnic: UnnnicPlugin = {
|
|
16
|
-
install(app: App
|
|
17
|
-
setTeleportTarget(options?.teleportTarget ?? null);
|
|
18
|
-
|
|
11
|
+
install(app: App) {
|
|
19
12
|
Object.keys(components).forEach((name) => {
|
|
20
13
|
app.component(name, components[name] as any);
|
|
21
14
|
});
|
package/src/lib/layer-manager.ts
CHANGED
|
@@ -1,37 +1,62 @@
|
|
|
1
1
|
import { onBeforeUnmount, onMounted, ref, type Ref } from 'vue';
|
|
2
2
|
|
|
3
|
-
const
|
|
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
|
+
|
|
4
15
|
const DEFAULT_STEP = 5;
|
|
5
16
|
|
|
6
|
-
const
|
|
7
|
-
|
|
17
|
+
const activeValues: Record<LayerToken, number[]> = {
|
|
18
|
+
hide: [],
|
|
19
|
+
base: [],
|
|
20
|
+
drawer: [],
|
|
21
|
+
modal: [],
|
|
22
|
+
popover: [],
|
|
23
|
+
tooltip: [],
|
|
24
|
+
toast: [],
|
|
25
|
+
};
|
|
8
26
|
|
|
9
|
-
interface
|
|
27
|
+
interface Allocation {
|
|
10
28
|
id: symbol;
|
|
29
|
+
type: LayerToken;
|
|
11
30
|
value: number;
|
|
12
31
|
}
|
|
13
32
|
|
|
14
|
-
|
|
33
|
+
const allocations = new Map<symbol, Allocation>();
|
|
34
|
+
|
|
35
|
+
function acquire(type: LayerToken): Allocation {
|
|
15
36
|
const id = Symbol('layer');
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
: BASE_LAYER_Z_INDEX;
|
|
37
|
+
const list = activeValues[type];
|
|
38
|
+
const lastValue = list.length ? list[list.length - 1] : layerScale[type];
|
|
19
39
|
const value = lastValue + DEFAULT_STEP;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
const allocation: Allocation = { id, type, value };
|
|
41
|
+
|
|
42
|
+
list.push(value);
|
|
43
|
+
allocations.set(id, allocation);
|
|
44
|
+
|
|
45
|
+
return allocation;
|
|
23
46
|
}
|
|
24
47
|
|
|
25
|
-
function
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
48
|
+
function release(id: symbol) {
|
|
49
|
+
const allocation = allocations.get(id);
|
|
50
|
+
if (!allocation) {
|
|
28
51
|
return;
|
|
29
52
|
}
|
|
30
53
|
|
|
31
|
-
|
|
32
|
-
const
|
|
54
|
+
allocations.delete(id);
|
|
55
|
+
const list = activeValues[allocation.type];
|
|
56
|
+
const index = list.indexOf(allocation.value);
|
|
57
|
+
|
|
33
58
|
if (index !== -1) {
|
|
34
|
-
|
|
59
|
+
list.splice(index, 1);
|
|
35
60
|
}
|
|
36
61
|
}
|
|
37
62
|
|
|
@@ -39,23 +64,26 @@ export interface LayerZIndexOptions {
|
|
|
39
64
|
offset?: number;
|
|
40
65
|
}
|
|
41
66
|
|
|
42
|
-
export function useLayerZIndex(
|
|
43
|
-
|
|
44
|
-
|
|
67
|
+
export function useLayerZIndex(
|
|
68
|
+
type: LayerToken = 'base',
|
|
69
|
+
options?: LayerZIndexOptions,
|
|
70
|
+
): Ref<number> {
|
|
71
|
+
const initialValue = layerScale[type] + (options?.offset ?? 0);
|
|
72
|
+
const zIndex = ref(initialValue);
|
|
45
73
|
|
|
46
74
|
let allocationId: symbol | null = null;
|
|
47
75
|
|
|
48
76
|
const allocate = () => {
|
|
49
|
-
const
|
|
50
|
-
allocationId =
|
|
51
|
-
zIndex.value =
|
|
77
|
+
const allocation = acquire(type);
|
|
78
|
+
allocationId = allocation.id;
|
|
79
|
+
zIndex.value = allocation.value + (options?.offset ?? 0);
|
|
52
80
|
};
|
|
53
81
|
|
|
54
82
|
onMounted(allocate);
|
|
55
83
|
|
|
56
84
|
onBeforeUnmount(() => {
|
|
57
85
|
if (allocationId) {
|
|
58
|
-
|
|
86
|
+
release(allocationId);
|
|
59
87
|
allocationId = null;
|
|
60
88
|
}
|
|
61
89
|
});
|
package/src/locales/en.json
CHANGED
package/src/locales/es.json
CHANGED
package/src/locales/pt_br.json
CHANGED
package/src/stories/Input.mdx
CHANGED
|
@@ -42,6 +42,9 @@ The `Input` component is designed to provide an input field for users to enter t
|
|
|
42
42
|
| placeholder | `String` of the native input placeholder | `String` | `''` |
|
|
43
43
|
| iconLeft | `String` of the left icon | `String` | `undefined` |
|
|
44
44
|
| iconRight | `String` of the right icon | `String` | `false` |
|
|
45
|
+
| useFocusProp | `Boolean` to enable use focus by prop (ignore native css) | `true` \| `false` | `false` |
|
|
46
|
+
| focus | `Boolean` to enable focus component status | `true` \| `false` | `false` |
|
|
47
|
+
|
|
45
48
|
|
|
46
49
|
## Example
|
|
47
50
|
Some examples of uses of the `UnnnicInput`
|
|
@@ -4,7 +4,7 @@ import { Meta } from '@storybook/blocks';
|
|
|
4
4
|
|
|
5
5
|
# Layer Manager Overview
|
|
6
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.
|
|
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
8
|
|
|
9
9
|
## Why avoid manual z-index values?
|
|
10
10
|
|
|
@@ -14,25 +14,25 @@ The layer manager exists to keep every teleported component (dialogs, drawers, p
|
|
|
14
14
|
|
|
15
15
|
## How it works here
|
|
16
16
|
|
|
17
|
-
1. **
|
|
18
|
-
2. **Auto-increment** – every time a component mounts, it receives the next value in
|
|
19
|
-
3. **Scoped offsets** – overlays that belong to the same surface (e.g., `DialogOverlay` vs
|
|
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
20
|
|
|
21
21
|
```
|
|
22
|
-
const modalZ = useLayerZIndex();
|
|
23
|
-
const overlayZ = useLayerZIndex({ offset: -2 });
|
|
22
|
+
const modalZ = useLayerZIndex('modal');
|
|
23
|
+
const overlayZ = useLayerZIndex('modal', { offset: -2 });
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Benefits
|
|
27
27
|
|
|
28
|
-
- **Deterministic ordering** –
|
|
29
|
-
- **Safer refactors** –
|
|
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
30
|
|
|
31
31
|
## When to override
|
|
32
32
|
|
|
33
33
|
In rare cases you might still need a custom `z-index`. Prefer to:
|
|
34
34
|
|
|
35
|
-
1. Add a
|
|
35
|
+
1. Add a new token in the layer manager if the surface fits the existing pattern (e.g., `tour`).
|
|
36
36
|
2. Only apply inline overrides for truly one-off cases, and document why the global manager does not work there.
|
|
37
37
|
|
|
38
38
|
|
|
@@ -48,7 +48,7 @@ export default {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export const DialogWithTooltipAndPopover = {
|
|
51
|
-
name: 'Dialog
|
|
51
|
+
name: 'Dialog + Tooltip + Popover',
|
|
52
52
|
render: () => ({
|
|
53
53
|
components: {
|
|
54
54
|
Dialog,
|
|
@@ -110,7 +110,7 @@ export const DialogWithTooltipAndPopover = {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
export const DrawerWithTooltipAndPopover = {
|
|
113
|
-
name: 'Drawer
|
|
113
|
+
name: 'Drawer + Tooltip + Popover',
|
|
114
114
|
render: () => ({
|
|
115
115
|
components: {
|
|
116
116
|
Drawer,
|
|
@@ -174,7 +174,7 @@ export const DrawerWithTooltipAndPopover = {
|
|
|
174
174
|
};
|
|
175
175
|
|
|
176
176
|
export const DrawerNextToDialog = {
|
|
177
|
-
name: 'Drawer
|
|
177
|
+
name: 'Drawer + Dialog',
|
|
178
178
|
render: () => ({
|
|
179
179
|
components: {
|
|
180
180
|
Drawer,
|
|
@@ -188,6 +188,8 @@ export const DrawerNextToDialog = {
|
|
|
188
188
|
DialogContent,
|
|
189
189
|
DialogHeader,
|
|
190
190
|
DialogTitle,
|
|
191
|
+
DialogFooter,
|
|
192
|
+
DialogClose,
|
|
191
193
|
UnnnicButton,
|
|
192
194
|
},
|
|
193
195
|
setup() {
|
|
@@ -222,6 +224,11 @@ export const DrawerNextToDialog = {
|
|
|
222
224
|
<div style="padding: 24px; color: #67738B;">
|
|
223
225
|
This dialog must appear above the drawer and its overlay.
|
|
224
226
|
</div>
|
|
227
|
+
<DialogFooter>
|
|
228
|
+
<DialogClose>
|
|
229
|
+
<UnnnicButton text="Close dialog" type="tertiary" />
|
|
230
|
+
</DialogClose>
|
|
231
|
+
</DialogFooter>
|
|
225
232
|
</DialogContent>
|
|
226
233
|
</Dialog>
|
|
227
234
|
</div>
|
|
@@ -229,56 +236,6 @@ export const DrawerNextToDialog = {
|
|
|
229
236
|
}),
|
|
230
237
|
};
|
|
231
238
|
|
|
232
|
-
export const DrawerOpenedFromDialog = {
|
|
233
|
-
name: 'Dialog > Drawer',
|
|
234
|
-
render: () => ({
|
|
235
|
-
components: {
|
|
236
|
-
UnnnicButton,
|
|
237
|
-
Dialog,
|
|
238
|
-
DialogContent,
|
|
239
|
-
DialogHeader,
|
|
240
|
-
DialogTitle,
|
|
241
|
-
Drawer,
|
|
242
|
-
DrawerContent,
|
|
243
|
-
DrawerHeader,
|
|
244
|
-
DrawerTitle,
|
|
245
|
-
DrawerDescription,
|
|
246
|
-
},
|
|
247
|
-
setup() {
|
|
248
|
-
const dialogOpen = ref(false);
|
|
249
|
-
const drawerOpen = ref(false);
|
|
250
|
-
return { dialogOpen, drawerOpen };
|
|
251
|
-
},
|
|
252
|
-
template: `
|
|
253
|
-
<div>
|
|
254
|
-
<div style="display: flex; gap: 16px; flex-wrap: wrap; justify-content: center;">
|
|
255
|
-
<UnnnicButton text="Open dialog" type="primary" @click="dialogOpen = true" />
|
|
256
|
-
</div>
|
|
257
|
-
<Dialog v-model:open="dialogOpen">
|
|
258
|
-
<DialogContent>
|
|
259
|
-
<DialogHeader>
|
|
260
|
-
<DialogTitle>Dialog</DialogTitle>
|
|
261
|
-
</DialogHeader>
|
|
262
|
-
<div style="padding: 24px; color: #67738B;">
|
|
263
|
-
<UnnnicButton text="Open drawer" type="primary" @click="drawerOpen = true" />
|
|
264
|
-
</div>
|
|
265
|
-
</DialogContent>
|
|
266
|
-
</Dialog>
|
|
267
|
-
<Drawer v-model:open="drawerOpen">
|
|
268
|
-
<DrawerContent>
|
|
269
|
-
<DrawerHeader>
|
|
270
|
-
<DrawerTitle>Drawer</DrawerTitle>
|
|
271
|
-
</DrawerHeader>
|
|
272
|
-
<div style="padding: 24px; color: #67738B;">
|
|
273
|
-
Drawer should appear above the dialog.
|
|
274
|
-
</div>
|
|
275
|
-
</DrawerContent>
|
|
276
|
-
</Drawer>
|
|
277
|
-
</div>
|
|
278
|
-
`,
|
|
279
|
-
}),
|
|
280
|
-
};
|
|
281
|
-
|
|
282
239
|
export const NestedDialogs = {
|
|
283
240
|
name: 'Dialog nested',
|
|
284
241
|
render: () => ({
|
|
@@ -346,7 +303,7 @@ export const NestedDialogs = {
|
|
|
346
303
|
};
|
|
347
304
|
|
|
348
305
|
export const DialogWithToast = {
|
|
349
|
-
name: 'Dialog
|
|
306
|
+
name: 'Dialog + Toast',
|
|
350
307
|
render: () => ({
|
|
351
308
|
components: {
|
|
352
309
|
Dialog,
|