@energysage/es-ds-components 3.0.11 → 3.1.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/components/es-popover.vue +130 -102
- package/components/es-tooltip.vue +171 -0
- package/nuxt.config.ts +1 -0
- package/package.json +3 -2
|
@@ -1,113 +1,141 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
const props = defineProps({
|
|
5
|
-
target: {
|
|
6
|
-
type: String,
|
|
7
|
-
required: true,
|
|
8
|
-
},
|
|
9
|
-
triggers: {
|
|
10
|
-
type: String,
|
|
11
|
-
required: false,
|
|
12
|
-
default: 'focus',
|
|
13
|
-
},
|
|
14
|
-
show: {
|
|
15
|
-
type: Boolean,
|
|
16
|
-
required: false,
|
|
17
|
-
default: false,
|
|
18
|
-
},
|
|
19
|
-
variant: {
|
|
20
|
-
type: String,
|
|
21
|
-
required: false,
|
|
22
|
-
default: 'dark',
|
|
23
|
-
validator: (val: string) => ['light', 'dark'].includes(val as string),
|
|
24
|
-
},
|
|
25
|
-
});
|
|
2
|
+
import { PopoverArrow, PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from 'reka-ui';
|
|
26
3
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
targetElement.addEventListener(trigger, showPanel);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
4
|
+
interface IProps {
|
|
5
|
+
collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
|
|
6
|
+
show?: boolean | undefined;
|
|
7
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
8
|
+
triggerClass?: string;
|
|
9
|
+
triggerDescription?: string;
|
|
10
|
+
variant?: 'light' | 'dark';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
withDefaults(defineProps<IProps>(), {
|
|
14
|
+
collisionPadding: 0,
|
|
15
|
+
show: undefined,
|
|
16
|
+
side: 'top',
|
|
17
|
+
triggerClass: '',
|
|
18
|
+
triggerDescription: 'More information',
|
|
19
|
+
variant: 'dark',
|
|
46
20
|
});
|
|
47
21
|
|
|
48
|
-
|
|
49
|
-
() => props.show,
|
|
50
|
-
(newVal) => {
|
|
51
|
-
if (newVal) {
|
|
52
|
-
const targetElement = document.getElementById(props.target);
|
|
53
|
-
if (targetElement) {
|
|
54
|
-
const event = new MouseEvent('click', {
|
|
55
|
-
view: window,
|
|
56
|
-
bubbles: true,
|
|
57
|
-
cancelable: true,
|
|
58
|
-
});
|
|
59
|
-
targetElement.dispatchEvent(event);
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
closePanel();
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
);
|
|
22
|
+
const emit = defineEmits(['update:show']);
|
|
66
23
|
</script>
|
|
67
24
|
|
|
68
25
|
<template>
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class="
|
|
91
|
-
@click="closePanel">
|
|
92
|
-
<icon-x
|
|
93
|
-
height="20px"
|
|
94
|
-
width="20px" />
|
|
95
|
-
</button>
|
|
96
|
-
</h3>
|
|
97
|
-
</template>
|
|
98
|
-
<!-- Popover Content -->
|
|
99
|
-
<div class="popover-body">
|
|
100
|
-
<div class="d-flex">
|
|
101
|
-
<slot />
|
|
102
|
-
<button
|
|
103
|
-
v-if="!hasTitle"
|
|
104
|
-
class="es-popover-close p-0 pl-50 mb-auto bg-transparent"
|
|
105
|
-
@click="closePanel">
|
|
26
|
+
<popover-root
|
|
27
|
+
:open="show"
|
|
28
|
+
@update:open="(val) => emit('update:show', val)">
|
|
29
|
+
<popover-trigger
|
|
30
|
+
class="es-popover-trigger p-0"
|
|
31
|
+
:class="{ [triggerClass]: true }">
|
|
32
|
+
<span class="sr-only">{{ triggerDescription }}</span>
|
|
33
|
+
<slot name="trigger" />
|
|
34
|
+
</popover-trigger>
|
|
35
|
+
<popover-portal>
|
|
36
|
+
<popover-content
|
|
37
|
+
class="es-popover-content position-relative"
|
|
38
|
+
:class="{
|
|
39
|
+
'text-white': variant === 'dark',
|
|
40
|
+
'es-popover-content--light': variant === 'light',
|
|
41
|
+
}"
|
|
42
|
+
:collision-padding="collisionPadding"
|
|
43
|
+
:side="side">
|
|
44
|
+
<popover-close
|
|
45
|
+
class="es-popover-close position-absolute"
|
|
46
|
+
:class="{ 'es-popover-close--light': variant === 'light' }">
|
|
47
|
+
<span class="sr-only">Close</span>
|
|
106
48
|
<icon-x
|
|
107
49
|
height="20px"
|
|
108
50
|
width="20px" />
|
|
109
|
-
</
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
51
|
+
</popover-close>
|
|
52
|
+
<popover-arrow
|
|
53
|
+
class="es-popover-arrow"
|
|
54
|
+
:class="{ 'es-popover-arrow--light': variant === 'light' }"
|
|
55
|
+
:height="12"
|
|
56
|
+
rounded
|
|
57
|
+
:width="22" />
|
|
58
|
+
<div class="pr-300">
|
|
59
|
+
<slot />
|
|
60
|
+
</div>
|
|
61
|
+
<slot name="cta" />
|
|
62
|
+
</popover-content>
|
|
63
|
+
</popover-portal>
|
|
64
|
+
</popover-root>
|
|
113
65
|
</template>
|
|
66
|
+
|
|
67
|
+
<style lang="scss" scoped>
|
|
68
|
+
@use '@energysage/es-ds-styles/scss/mixins/border-radius' as border-radius;
|
|
69
|
+
@use '@energysage/es-ds-styles/scss/variables' as variables;
|
|
70
|
+
|
|
71
|
+
@keyframes fadeIn {
|
|
72
|
+
from {
|
|
73
|
+
opacity: 0;
|
|
74
|
+
}
|
|
75
|
+
to {
|
|
76
|
+
opacity: 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@keyframes fadeOut {
|
|
81
|
+
from {
|
|
82
|
+
opacity: 1;
|
|
83
|
+
}
|
|
84
|
+
to {
|
|
85
|
+
opacity: 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.es-popover-trigger {
|
|
90
|
+
align-items: center;
|
|
91
|
+
background-color: transparent;
|
|
92
|
+
border: none;
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
vertical-align: middle;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
:deep(.es-popover-content) {
|
|
99
|
+
background-color: variables.$dark-blue;
|
|
100
|
+
@include border-radius.border-radius(variables.$popover-border-radius);
|
|
101
|
+
box-shadow: variables.$popover-box-shadow;
|
|
102
|
+
padding: variables.$popover-header-padding-y variables.$popover-header-padding-x;
|
|
103
|
+
width: 250px;
|
|
104
|
+
z-index: variables.$zindex-popover;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:deep(.es-popover-content[data-state='open']) {
|
|
108
|
+
animation: fadeIn 150ms ease;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:deep(.es-popover-content[data-state='closed']) {
|
|
112
|
+
animation: fadeOut 150ms ease;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
:deep(.es-popover-content--light) {
|
|
116
|
+
background-color: variables.$white;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
:deep(.es-popover-arrow) {
|
|
120
|
+
fill: variables.$dark-blue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:deep(.es-popover-arrow--light) {
|
|
124
|
+
fill: variables.$white;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:deep(.es-popover-close) {
|
|
128
|
+
background-color: transparent;
|
|
129
|
+
border: none;
|
|
130
|
+
color: variables.$white;
|
|
131
|
+
height: 28px;
|
|
132
|
+
right: 1rem;
|
|
133
|
+
padding: 0;
|
|
134
|
+
top: 0.75rem;
|
|
135
|
+
width: 28px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:deep(.es-popover-close--light) {
|
|
139
|
+
color: variables.$blue-600;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui';
|
|
3
|
+
|
|
4
|
+
interface IProps {
|
|
5
|
+
collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>;
|
|
6
|
+
delayDuration?: number;
|
|
7
|
+
show?: boolean | undefined;
|
|
8
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
9
|
+
triggerClass?: string;
|
|
10
|
+
variant?: 'light' | 'dark';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
withDefaults(defineProps<IProps>(), {
|
|
14
|
+
collisionPadding: 0,
|
|
15
|
+
delayDuration: 0,
|
|
16
|
+
show: undefined,
|
|
17
|
+
side: 'top',
|
|
18
|
+
triggerClass: '',
|
|
19
|
+
variant: 'dark',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits(['update:show']);
|
|
23
|
+
|
|
24
|
+
const deviceSupportsTouch = ref(false);
|
|
25
|
+
const internalShow = ref(false);
|
|
26
|
+
|
|
27
|
+
// provide a workaround for the case where scroll-flipping causes the tooltip
|
|
28
|
+
// to get in a state where it won't reopen on hover (allow user to click to open)
|
|
29
|
+
const handleClick = () => {
|
|
30
|
+
internalShow.value = true;
|
|
31
|
+
emit('update:show', true);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// keep the internal boolean up to date when the state changes
|
|
35
|
+
// and also emit the update event up and out
|
|
36
|
+
const handleUpdateOpen = (val: boolean) => {
|
|
37
|
+
internalShow.value = val;
|
|
38
|
+
emit('update:show', val);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
onMounted(() => {
|
|
42
|
+
// detect if the device supports touch events or not
|
|
43
|
+
const mediaQueryResult = window.matchMedia('(hover: none)') as MediaQueryList;
|
|
44
|
+
deviceSupportsTouch.value = mediaQueryResult?.matches || false;
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<tooltip-provider
|
|
50
|
+
v-if="!deviceSupportsTouch"
|
|
51
|
+
:delay-duration="delayDuration"
|
|
52
|
+
:disable-closing-trigger="true">
|
|
53
|
+
<tooltip-root
|
|
54
|
+
:open="show || internalShow"
|
|
55
|
+
@update:open="handleUpdateOpen">
|
|
56
|
+
<tooltip-trigger
|
|
57
|
+
class="es-tooltip-trigger p-0"
|
|
58
|
+
:class="{ [triggerClass]: true }"
|
|
59
|
+
@click="handleClick">
|
|
60
|
+
<slot name="trigger" />
|
|
61
|
+
</tooltip-trigger>
|
|
62
|
+
<tooltip-portal>
|
|
63
|
+
<tooltip-content
|
|
64
|
+
class="es-tooltip-content"
|
|
65
|
+
:class="{
|
|
66
|
+
'text-white': variant === 'dark',
|
|
67
|
+
'es-tooltip-content--light': variant === 'light',
|
|
68
|
+
}"
|
|
69
|
+
:collision-padding="collisionPadding"
|
|
70
|
+
:side="side">
|
|
71
|
+
<tooltip-arrow
|
|
72
|
+
class="es-tooltip-arrow"
|
|
73
|
+
:class="{ 'es-tooltip-arrow--light': variant === 'light' }"
|
|
74
|
+
:height="12"
|
|
75
|
+
rounded
|
|
76
|
+
:width="22" />
|
|
77
|
+
<slot />
|
|
78
|
+
</tooltip-content>
|
|
79
|
+
</tooltip-portal>
|
|
80
|
+
</tooltip-root>
|
|
81
|
+
</tooltip-provider>
|
|
82
|
+
<es-popover
|
|
83
|
+
v-else
|
|
84
|
+
:collision-padding="collisionPadding"
|
|
85
|
+
:show="show"
|
|
86
|
+
:side="side"
|
|
87
|
+
:trigger-class="triggerClass"
|
|
88
|
+
:variant="variant"
|
|
89
|
+
@update:show="(val) => emit('update:show', val)">
|
|
90
|
+
<template #trigger>
|
|
91
|
+
<slot name="trigger" />
|
|
92
|
+
</template>
|
|
93
|
+
<slot />
|
|
94
|
+
</es-popover>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<style lang="scss" scoped>
|
|
98
|
+
@use '@energysage/es-ds-styles/scss/mixins/border-radius' as border-radius;
|
|
99
|
+
@use '@energysage/es-ds-styles/scss/variables' as variables;
|
|
100
|
+
|
|
101
|
+
@keyframes fadeIn {
|
|
102
|
+
from {
|
|
103
|
+
opacity: 0;
|
|
104
|
+
}
|
|
105
|
+
to {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@keyframes fadeOut {
|
|
111
|
+
from {
|
|
112
|
+
opacity: 1;
|
|
113
|
+
}
|
|
114
|
+
to {
|
|
115
|
+
opacity: 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.es-tooltip-trigger {
|
|
120
|
+
align-items: center;
|
|
121
|
+
background-color: transparent;
|
|
122
|
+
border: none;
|
|
123
|
+
display: inline-flex;
|
|
124
|
+
justify-content: center;
|
|
125
|
+
vertical-align: middle;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
:deep(.es-tooltip-content) {
|
|
129
|
+
background-color: variables.$dark-blue;
|
|
130
|
+
@include border-radius.border-radius(variables.$popover-border-radius);
|
|
131
|
+
box-shadow: variables.$popover-box-shadow;
|
|
132
|
+
padding: variables.$popover-header-padding-y variables.$popover-header-padding-x;
|
|
133
|
+
width: 250px;
|
|
134
|
+
z-index: variables.$zindex-popover;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
:deep(.es-tooltip-content[data-state='open']) {
|
|
138
|
+
animation: fadeIn 150ms ease;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
:deep(.es-tooltip-content[data-state='closed']) {
|
|
142
|
+
animation: fadeOut 150ms ease;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
:deep(.es-tooltip-content--light) {
|
|
146
|
+
background-color: variables.$white;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
:deep(.es-tooltip-arrow) {
|
|
150
|
+
fill: variables.$dark-blue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
:deep(.es-tooltip-arrow--light) {
|
|
154
|
+
fill: variables.$white;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
:deep(.es-tooltip-close) {
|
|
158
|
+
background-color: transparent;
|
|
159
|
+
border: none;
|
|
160
|
+
color: variables.$white;
|
|
161
|
+
height: 28px;
|
|
162
|
+
right: 1rem;
|
|
163
|
+
padding: 0;
|
|
164
|
+
top: 0.75rem;
|
|
165
|
+
width: 28px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
:deep(.es-tooltip-close--light) {
|
|
169
|
+
color: variables.$blue-600;
|
|
170
|
+
}
|
|
171
|
+
</style>
|
package/nuxt.config.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@energysage/es-ds-components",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "An EnergySage Vue component library",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"author": "EnergySage",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@energysage/es-ds-styles": "^3.0
|
|
20
|
+
"@energysage/es-ds-styles": "^3.1.0",
|
|
21
21
|
"@nuxt/eslint": "^1.0.1",
|
|
22
22
|
"@nuxtjs/google-fonts": "^3.2.0",
|
|
23
23
|
"@vuelidate/core": "^2.0.3",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"nuxt-primevue": "^3.0.0",
|
|
29
29
|
"primevue": "^3.53.0",
|
|
30
30
|
"prismjs": "^1.29.0",
|
|
31
|
+
"reka-ui": "^2.2.0",
|
|
31
32
|
"vue": "^3.5.6"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|