@everchron/ec-shards 7.2.8 → 7.3.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/dist/ec-shards.common.js +405 -304
- package/dist/ec-shards.common.js.map +1 -1
- package/dist/ec-shards.css +1 -1
- package/dist/ec-shards.umd.js +405 -304
- package/dist/ec-shards.umd.js.map +1 -1
- package/dist/ec-shards.umd.min.js +2 -2
- package/dist/ec-shards.umd.min.js.map +1 -1
- package/package.json +3 -1
- package/src/assets/icons/basketball.svg +6 -0
- package/src/assets/icons/emoji.svg +6 -0
- package/src/assets/icons/flag.svg +4 -0
- package/src/assets/icons/food-drink.svg +7 -0
- package/src/assets/icons/hand.svg +5 -0
- package/src/assets/icons/leaf.svg +5 -0
- package/src/assets/icons/plane.svg +3 -0
- package/src/assets/icons/sparkle.svg +5 -0
- package/src/components/animations/animations.vue +38 -0
- package/src/components/emoji-picker/emoji-picker.vue +137 -0
- package/src/components/emoji-picker/emoji.vue +64 -0
- package/src/components/emoji-picker/list.vue +127 -0
- package/src/components/input-search/input-search.vue +3 -7
- package/src/components/modal/modal.vue +5 -11
- package/src/components/tab-button/tab-button.vue +21 -3
- package/src/stories/Changelog.stories.mdx +7 -0
- package/src/stories/emoji-picker/emoji-picker.stories.js +25 -0
- package/src/stories/tabs/tab-button.stories.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@everchron/ec-shards",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Everchron Shards UI Library",
|
|
6
6
|
"repository": "https://github.com/everchron/ec-shards.git",
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"*.svg"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"emoji.json": "^14.0.0",
|
|
29
|
+
"js-search-array": "^1.0.1",
|
|
28
30
|
"v-click-outside": "^2.1.3"
|
|
29
31
|
},
|
|
30
32
|
"peerDependencies": {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M15 24.75C20.3848 24.75 24.75 20.3848 24.75 15C24.75 9.61522 20.3848 5.25 15 5.25C9.61522 5.25 5.25 9.61522 5.25 15C5.25 20.3848 9.61522 24.75 15 24.75Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M16.025 5.30469C16.1797 6.75039 16.0087 8.21237 15.5246 9.58336C15.0405 10.9544 14.2557 12.1996 13.2276 13.2277C12.1995 14.2558 10.9542 15.0407 9.58324 15.5247C8.21225 16.0088 6.75026 16.1798 5.30457 16.0251" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M24.6953 13.9749C23.2496 13.8203 21.7876 13.9913 20.4166 14.4754C19.0457 14.9595 17.8004 15.7443 16.7723 16.7724C15.7442 17.8005 14.9594 19.0458 14.4753 20.4168C13.9912 21.7878 13.8202 23.2497 13.9749 24.6954" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M6.84515 9.66394C10.2941 10.0047 13.544 11.4388 16.1205 13.7568C18.697 16.0748 20.4653 19.1555 21.1675 22.5494" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M9.58331 12.8333C10.0112 12.3079 10.5962 12.01 11.2083 12.01C11.8204 12.01 12.3891 12.3079 12.8333 12.8333" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M17.1667 12.8333C17.5946 12.3079 18.1796 12.01 18.7917 12.01C19.4038 12.01 19.9725 12.3079 20.4167 12.8333" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M21.8943 8.10571C25.7019 11.9133 25.7019 18.0867 21.8943 21.8943C18.0867 25.7019 11.9134 25.7019 8.10577 21.8943C4.29816 18.0867 4.29816 11.9133 8.10577 8.10571C11.9134 4.2981 18.0867 4.2981 21.8943 8.10571Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M18.7916 17.912C18.7916 17.912 17.3692 19.3333 15 19.3333C12.6296 19.3333 11.2083 17.912 11.2083 17.912" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M12.8333 16.0834L13.4226 17.8514C13.7173 18.7365 14.5461 19.3334 15.4788 19.3334H22.5833C23.7804 19.3334 24.75 18.3638 24.75 17.1667V10.8346C24.75 9.63755 23.7804 8.66797 22.5833 8.66797H17.2403" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M11.75 24.75L6.20006 8.10133C5.73314 6.69842 6.77747 5.25 8.25622 5.25H15.0736C16.2707 5.25 17.2403 6.21958 17.2403 7.41667V13.9167C17.2403 15.1138 16.2707 16.0833 15.0736 16.0833H8.86072" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M17.1667 17.25V16.1666C17.1667 14.3715 15.7117 12.9166 13.9167 12.9166H8.5C6.70492 12.9166 5.25 14.3715 5.25 16.1666V17.25" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M15 23.75H7.41667C6.21958 23.75 5.25 22.7804 5.25 21.5833V20.5H17.1667V21.5833C17.1667 22.7804 16.1971 23.75 15 23.75Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M4.16666 17.25H18.25" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M13.5743 12.9166L13.1616 9.80959C13.076 9.15959 13.5808 8.58325 14.2362 8.58325H23.6667C24.3264 8.58325 24.8323 9.16717 24.7392 9.81933L22.8823 22.8193C22.8054 23.3534 22.3482 23.7499 21.8098 23.7499H19.4991" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
<path d="M22.7491 4.25H20.434C19.8967 4.25 19.4417 4.64325 19.3626 5.17408L18.8556 8.58333" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M13.399 14.665V5.59975C13.399 4.71669 14.1157 4 14.9988 4C15.8818 4 16.5985 4.71669 16.5985 5.59975V14.665" vector-effect="non-scaling-stroke" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M13.399 7.73269C13.399 6.84962 12.6823 6.13293 11.7993 6.13293C10.9162 6.13293 10.1995 6.84962 10.1995 7.73269V14.6649" vector-effect="non-scaling-stroke" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M16.5985 7.73269C16.5985 6.84962 17.3152 6.13293 18.1983 6.13293C19.0813 6.13293 19.798 6.84962 19.798 7.73269V13.5984V16.7979L21.8254 14.7705C22.4728 14.1232 23.5222 14.1232 24.1696 14.7705C24.7284 15.3294 24.8148 16.205 24.3765 16.8619L20.631 22.4803C19.4439 24.2602 17.4464 25.33 15.307 25.33H13.399C9.86462 25.33 7 22.4653 7 18.9309V13.5984V9.86569C7 8.98262 7.71669 8.26594 8.59975 8.26594C9.48281 8.26594 10.1995 8.98262 10.1995 9.86569" vector-effect="non-scaling-stroke" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M14.3889 22.8889C20.774 22.8889 22.3412 14.9427 26 12.8314C24.6679 11.0062 22.9195 9.52502 20.9001 8.51097C18.8807 7.49693 16.6485 6.97924 14.3889 7.0009" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M14.3889 22.8889C12.2819 22.8889 10.2612 22.0519 8.77133 20.562C7.28146 19.0721 6.44446 17.0514 6.44446 14.9444C6.44446 12.8374 7.28146 10.8167 8.77133 9.32687C10.2612 7.837 12.2819 7 14.3889 7" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M14.9766 14.3735C12.7367 14.7482 10.6012 15.5916 8.70972 16.8483C6.81822 18.1051 5.21332 19.747 4 21.6667" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M23.8833 9.15001L20.3083 12.725L22.2583 22.3667C22.3667 22.6917 22.2583 23.125 21.9333 23.3417L21.175 24.1C20.6333 24.6417 19.6583 24.425 19.4417 23.775L16.625 16.5167L12.9417 20.2L13.1583 22.5833C13.1583 22.9083 13.05 23.2333 12.8333 23.45L11.6417 24.6417L9.36668 20.85L5.57501 18.575L6.65835 17.1667C6.87501 16.95 7.20001 16.8417 7.52501 16.8417L9.90835 17.0583L13.5917 13.375L6.22501 10.5583C5.57501 10.2333 5.35835 9.36667 5.90001 8.82501L6.65835 8.06667C6.87501 7.85001 7.30835 7.74167 7.63335 7.74167L17.275 9.69167L20.85 6.11667C21.7167 5.25001 23.0167 5.25001 23.8833 6.11667C24.75 6.98334 24.75 8.28334 23.8833 9.15001Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M9.49996 6.25C9.49996 7.39927 9.04341 8.50147 8.23076 9.31413C7.4181 10.1268 6.3159 10.5833 5.16663 10.5833C6.3159 10.5833 7.4181 11.0399 8.23076 11.8525C9.04341 12.6652 9.49996 13.7674 9.49996 14.9167C9.49996 13.7674 9.95651 12.6652 10.7692 11.8525C11.5818 11.0399 12.684 10.5833 13.8333 10.5833C12.684 10.5833 11.5818 10.1268 10.7692 9.31413C9.95651 8.50147 9.49996 7.39927 9.49996 6.25Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M21.4167 19.25C21.4167 17.8134 20.846 16.4356 19.8302 15.4198C18.8143 14.404 17.4366 13.8333 16 13.8333C17.4366 13.8333 18.8143 13.2626 19.8302 12.2468C20.846 11.231 21.4167 9.85322 21.4167 8.41663C21.4167 9.85322 21.9873 11.231 23.0032 12.2468C24.019 13.2626 25.3967 13.8333 26.8333 13.8333C25.3967 13.8333 24.019 14.404 23.0032 15.4198C21.9873 16.4356 21.4167 17.8134 21.4167 19.25Z" stroke="currentColor" stroke-linecap="round" vector-effect="non-scaling-stroke" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M13.8333 17.625C13.8333 18.7743 13.3768 19.8765 12.5641 20.6891C11.7515 21.5018 10.6493 21.9583 9.5 21.9583C10.6493 21.9583 11.7515 22.4149 12.5641 23.2275C13.3768 24.0402 13.8333 25.1424 13.8333 26.2917C13.8333 25.1424 14.2899 24.0402 15.1025 23.2275C15.9152 22.4149 17.0174 21.9583 18.1667 21.9583C17.0174 21.9583 15.9152 21.5018 15.1025 20.6891C14.2899 19.8765 13.8333 18.7743 13.8333 17.625Z" stroke="currentColor" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
@@ -41,4 +41,42 @@
|
|
|
41
41
|
border-bottom-color: $color-gray-3;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
@keyframes bounceIn {
|
|
46
|
+
from,
|
|
47
|
+
20%,
|
|
48
|
+
40%,
|
|
49
|
+
60%,
|
|
50
|
+
80%,
|
|
51
|
+
to {
|
|
52
|
+
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
0% {
|
|
56
|
+
opacity: 0;
|
|
57
|
+
transform: scale3d(0.3, 0.3, 0.3);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
20% {
|
|
61
|
+
transform: scale3d(1.1, 1.1, 1.1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
40% {
|
|
65
|
+
transform: scale3d(0.9, 0.9, 0.9);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
60% {
|
|
69
|
+
opacity: 1;
|
|
70
|
+
transform: scale3d(1.03, 1.03, 1.03);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
80% {
|
|
74
|
+
transform: scale3d(0.97, 0.97, 0.97);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
to {
|
|
78
|
+
opacity: 1;
|
|
79
|
+
transform: scale3d(1, 1, 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
44
82
|
</style>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ecs-emoji-picker scrollbar scrollbar-sml" ref="picker" :class="bordered ? 'bordered' : ''" :style="pickerStyles">
|
|
3
|
+
<ecs-tab-bar>
|
|
4
|
+
<ecs-tab-button @click="switchTab('all')" :show="activeTab == 'all'" icon="search" aria-label="All Emojis" aria-controls="allCategories" />
|
|
5
|
+
<ecs-tab-button @click="switchTab('SmileysEmotion')" :show="activeTab == 'SmileysEmotion'" icon="emoji" aria-label="Smileys & Emotion" aria-controls="SmileysEmotion" />
|
|
6
|
+
<ecs-tab-button @click="switchTab('PeopleBody')" :show="activeTab == 'PeopleBody'" icon="hand" aria-label="People & Body" aria-controls="PeopleBody" />
|
|
7
|
+
<ecs-tab-button @click="switchTab('AnimalsNature')" :show="activeTab == 'AnimalsNature'" icon="leaf" aria-label="Animals & Nature" aria-controls="AnimalsNature" />
|
|
8
|
+
<ecs-tab-button @click="switchTab('FoodDrink')" :show="activeTab == 'FoodDrink'" icon="food-drink" aria-label="Food & Drink" aria-controls="FoodDrink" />
|
|
9
|
+
<ecs-tab-button @click="switchTab('TravelPlaces')" :show="activeTab == 'TravelPlaces'" icon="plane" aria-label="Travel & Places" aria-controls="TravelPlaces" />
|
|
10
|
+
<ecs-tab-button @click="switchTab('Activities')" :show="activeTab == 'Activities'" icon="basketball" aria-label="Activities" aria-controls="Activities" />
|
|
11
|
+
<ecs-tab-button @click="switchTab('Objects')" :show="activeTab == 'Objects'" icon="key" aria-label="Objects" aria-controls="Objects" />
|
|
12
|
+
<ecs-tab-button @click="switchTab('Symbols')" :show="activeTab == 'Symbols'" icon="warning" aria-label="Symbols" aria-controls="Symbols" />
|
|
13
|
+
<ecs-tab-button @click="switchTab('Flags')" :show="activeTab == 'Flags'" icon="flag" aria-label="Flags" aria-controls="Flags" />
|
|
14
|
+
</ecs-tab-bar>
|
|
15
|
+
<div v-if="activeTab == 'all'" class="search">
|
|
16
|
+
<ecs-input-search v-model="search" :show-clear="showClear" placeholder="Search all emoji" type="subtle" />
|
|
17
|
+
</div>
|
|
18
|
+
<ecs-emoji-list @emoji="onEmojiSelected" :search="search" :filter-tab="activeTab" />
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
import EcsInputSearch from '../input-search/input-search'
|
|
24
|
+
import EcsTabBar from '../tab-bar/tab-bar'
|
|
25
|
+
import EcsTabButton from '../tab-button/tab-button'
|
|
26
|
+
import EcsEmojiList from './list.vue';
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
components: {
|
|
30
|
+
EcsInputSearch,
|
|
31
|
+
EcsTabBar,
|
|
32
|
+
EcsTabButton,
|
|
33
|
+
EcsEmojiList
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
props: {
|
|
37
|
+
/** Defines the width of the Emoji Picker component. */
|
|
38
|
+
width: {
|
|
39
|
+
type: Number,
|
|
40
|
+
default: 420,
|
|
41
|
+
validator: (value) => {
|
|
42
|
+
return value >= 420;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
/** Defines the height of the Emoji Picker component. If not set, the sticky scroll element are bound to the parent scroll container (or window). */
|
|
46
|
+
height: {
|
|
47
|
+
type: Number
|
|
48
|
+
},
|
|
49
|
+
/** Determines if the Emoji picker should be bordered. */
|
|
50
|
+
bordered: {
|
|
51
|
+
type: Boolean
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
data() {
|
|
56
|
+
return {
|
|
57
|
+
search: '',
|
|
58
|
+
activeTab: 'all'
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
computed: {
|
|
63
|
+
showClear() {
|
|
64
|
+
return this.search.length > 0;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
conditionalHeight() {
|
|
68
|
+
return this.bordered ? (this.height || 400) : this.height;
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
pickerStyles() {
|
|
72
|
+
return {
|
|
73
|
+
width: `${this.width}px`,
|
|
74
|
+
height: `${this.conditionalHeight}px`,
|
|
75
|
+
overflow: this.bordered || this.height ? 'auto' : 'unset'
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
methods: {
|
|
81
|
+
switchTab(tab) {
|
|
82
|
+
this.activeTab = tab;
|
|
83
|
+
this.$refs.picker.scrollTop = 0;
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
onEmojiSelected(emoji) {
|
|
87
|
+
/** Returns an object that contains the selected emoji code and character. */
|
|
88
|
+
this.$emit('emoji', {
|
|
89
|
+
code: emoji.codes,
|
|
90
|
+
char: emoji.char
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<style lang="scss" scoped>
|
|
98
|
+
@import "../../tokens/build/scss/tokens.scss";
|
|
99
|
+
|
|
100
|
+
.ecs-emoji-picker{
|
|
101
|
+
border-radius: 6px;
|
|
102
|
+
z-index: 1;
|
|
103
|
+
|
|
104
|
+
&.bordered{
|
|
105
|
+
border: 1px solid $color-gray-4;
|
|
106
|
+
|
|
107
|
+
.ecs-tab-bar{
|
|
108
|
+
padding-left: $spacing-5;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.search{
|
|
114
|
+
width: 100%;
|
|
115
|
+
position: sticky;
|
|
116
|
+
top: 41px;
|
|
117
|
+
background: rgba($color-white, .6);
|
|
118
|
+
padding: $spacing-10;
|
|
119
|
+
backdrop-filter: blur(24px);
|
|
120
|
+
box-shadow: 0 1px 0 rgba($color-gray-14, .1);
|
|
121
|
+
z-index: 2;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.ecs-tab-bar{
|
|
125
|
+
background: rgba($color-white, .6);
|
|
126
|
+
backdrop-filter: blur(24px);
|
|
127
|
+
position: sticky;
|
|
128
|
+
top: 0;
|
|
129
|
+
z-index: 3;
|
|
130
|
+
border-radius: 6px 6px 0 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ecs-tab-button :deep(.icon){
|
|
134
|
+
width: 24px;
|
|
135
|
+
height: 24px;
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
@click="click(id, char)"
|
|
4
|
+
:id="id"
|
|
5
|
+
class="emoji">
|
|
6
|
+
{{ char }}
|
|
7
|
+
</button>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
export default {
|
|
12
|
+
props: {
|
|
13
|
+
char: String,
|
|
14
|
+
id: String,
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
methods: {
|
|
18
|
+
click(emojiId, emojiChar) {
|
|
19
|
+
// Emit clicked emoji with id
|
|
20
|
+
this.$emit('emoji', emojiId, emojiChar);
|
|
21
|
+
|
|
22
|
+
// Add class with animation after click, remove after timeout
|
|
23
|
+
document.getElementById(emojiId).classList.add('clicked');
|
|
24
|
+
window.setTimeout(() => {
|
|
25
|
+
document.getElementById(emojiId).classList.remove('clicked');
|
|
26
|
+
}, 800);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style lang="scss" scoped>
|
|
33
|
+
@import "../../tokens/build/scss/tokens.scss";
|
|
34
|
+
|
|
35
|
+
.emoji{
|
|
36
|
+
font-size: 24px;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
transition: 0.15s transform, 0.15s background-color;
|
|
39
|
+
text-align: center;
|
|
40
|
+
margin: $spacing-10;
|
|
41
|
+
padding: 0;
|
|
42
|
+
width: $spacing-40;
|
|
43
|
+
height: $spacing-40;
|
|
44
|
+
line-height: $spacing-40;
|
|
45
|
+
background: $color-gray-2;
|
|
46
|
+
border-radius: 50%;
|
|
47
|
+
user-select: none;
|
|
48
|
+
|
|
49
|
+
&:focus-visible{
|
|
50
|
+
outline: 2px solid $color-blue-9;
|
|
51
|
+
outline-offset: 2px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:hover{
|
|
55
|
+
transform: scale(1.1);
|
|
56
|
+
background: $color-gray-3;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.clicked {
|
|
60
|
+
animation: bounceIn;
|
|
61
|
+
animation-duration: .8s;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="categories" id="allCategories">
|
|
3
|
+
<div
|
|
4
|
+
v-for="category in filteredCategories"
|
|
5
|
+
v-if="filterTab === 'all' || filterTab === sanitize(category)"
|
|
6
|
+
:key="category"
|
|
7
|
+
:id="sanitize(category)"
|
|
8
|
+
class="category">
|
|
9
|
+
<h2 :style="{top: filterTab === 'all' ? '89px' : '41px'}">{{ category }}</h2>
|
|
10
|
+
<div class="list">
|
|
11
|
+
<ecs-emoji
|
|
12
|
+
v-for="emoji in getEmojiList(emojiArray, category, search)"
|
|
13
|
+
@emoji="emitEmoji(emoji)"
|
|
14
|
+
:char="emoji.char"
|
|
15
|
+
:key="emoji.codes"
|
|
16
|
+
:id="emoji.codes"
|
|
17
|
+
:title="emoji.name" />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
import EcsEmoji from './emoji.vue';
|
|
25
|
+
import emoji from 'emoji.json';
|
|
26
|
+
import searchArray from 'js-search-array';
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
components: { EcsEmoji },
|
|
30
|
+
|
|
31
|
+
props: {
|
|
32
|
+
search: String,
|
|
33
|
+
filterTab: String
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
data() {
|
|
37
|
+
return {
|
|
38
|
+
// Bind emojiArray as emoji.json list
|
|
39
|
+
emojiArray: [],
|
|
40
|
+
categories: [],
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
computed: {
|
|
45
|
+
filteredCategories() {
|
|
46
|
+
return this.categories.filter((category) => {
|
|
47
|
+
const emojis = this.getEmojiList(this.emojiArray, category, this.search);
|
|
48
|
+
return emojis.length > 0;
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
sanitize() {
|
|
53
|
+
return (str) => str.replace(/[^a-zA-Z0-9]/g, '');
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
methods: {
|
|
58
|
+
emitEmoji(emoji) {
|
|
59
|
+
this.$emit('emoji', emoji);
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
getEmojiList(emojiArray, category, search) {
|
|
63
|
+
if (search.length < 3) {
|
|
64
|
+
// Return array with all emojis for category, filter out codes with spaces to remove skin-tone variations from returned list. Allow flags to have skin-tone variations.
|
|
65
|
+
return emojiArray.filter(
|
|
66
|
+
(emoji) => emoji.group === category
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Return array with searched emoji for category if length > 3
|
|
71
|
+
return searchArray(search, emojiArray.filter(
|
|
72
|
+
(emoji) => emoji.group === category
|
|
73
|
+
), 'name');
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
mounted() {
|
|
78
|
+
// List of blacklisted emojis
|
|
79
|
+
const blacklist = new Set(['☺️', '☺', '☹️', '☹', '☠', '❣', '❤', '🕳️', '👁🗨️', '👁️🗨', '👁🗨', '🗨', '🗯️']);
|
|
80
|
+
// Filter array
|
|
81
|
+
const filtered = emoji.filter((item) => {
|
|
82
|
+
if (item.group === 'Flags') {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return !blacklist.has(item.char) && item.group !== 'Component' && !item.codes.includes(' ');
|
|
86
|
+
})
|
|
87
|
+
// Set variable with emojis as filtered list
|
|
88
|
+
this.emojiArray = filtered;
|
|
89
|
+
// Get list of categories
|
|
90
|
+
this.categories = [...new Set(filtered.map((emoji) => emoji.group))];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<style lang="scss" scoped>
|
|
96
|
+
@import "../../tokens/build/scss/tokens.scss";
|
|
97
|
+
|
|
98
|
+
.list{
|
|
99
|
+
display: flex;
|
|
100
|
+
flex-wrap: wrap;
|
|
101
|
+
justify-content: space-between;
|
|
102
|
+
|
|
103
|
+
&:after{
|
|
104
|
+
content: '';
|
|
105
|
+
flex: auto;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
button{
|
|
109
|
+
display: inline-block;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.category{
|
|
114
|
+
content-visibility: auto;
|
|
115
|
+
|
|
116
|
+
h2{
|
|
117
|
+
font-size: $type-scale-2-font-size;
|
|
118
|
+
line-height: $type-scale-2-line-height;
|
|
119
|
+
color: $color-gray-10;
|
|
120
|
+
background: rgba($color-white, .9);
|
|
121
|
+
backdrop-filter: blur(24px);
|
|
122
|
+
padding: $spacing-5 $spacing-10;
|
|
123
|
+
position: sticky;
|
|
124
|
+
z-index: 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
</style>
|
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
|
|
90
90
|
iconSize() {
|
|
91
91
|
if(this.size === 'sml') {
|
|
92
|
+
return '20px'
|
|
93
|
+
} else if(this.size === 'md') {
|
|
92
94
|
return '24px'
|
|
93
95
|
} else {
|
|
94
96
|
return '30px'
|
|
@@ -148,16 +150,10 @@
|
|
|
148
150
|
.icon{
|
|
149
151
|
position: absolute;
|
|
150
152
|
top: 50%;
|
|
151
|
-
left:
|
|
153
|
+
left: 4px;
|
|
152
154
|
transform: translateY(-50%);
|
|
153
155
|
pointer-events: none;
|
|
154
156
|
}
|
|
155
|
-
|
|
156
|
-
&-lg{
|
|
157
|
-
.icon{
|
|
158
|
-
left: 4px;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
157
|
}
|
|
162
158
|
|
|
163
159
|
.ecs-search-input{
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<!-- @slot Slot for the modal footer content. -->
|
|
18
18
|
<slot name="footer"></slot>
|
|
19
19
|
</div>
|
|
20
|
-
<div v-if="$slots.dialog" class="ecs-modal-inner-dialog" :
|
|
20
|
+
<div v-if="$slots.dialog" class="ecs-modal-inner-dialog" :class="innerDialog ? 'open' : ''">
|
|
21
21
|
<!-- @slot Slot for dialogs that should render _within_ the modal. -->
|
|
22
22
|
<slot name="dialog"></slot>
|
|
23
23
|
<transition name="fade">
|
|
@@ -62,11 +62,6 @@
|
|
|
62
62
|
innerDialog: {
|
|
63
63
|
type: Boolean,
|
|
64
64
|
default: false
|
|
65
|
-
},
|
|
66
|
-
/** Allows to adjust the top offset of the inner dialog area (e.g. for dynamic header heights). */
|
|
67
|
-
innerDialogOffset: {
|
|
68
|
-
type: Number,
|
|
69
|
-
default: 48
|
|
70
65
|
}
|
|
71
66
|
},
|
|
72
67
|
|
|
@@ -191,9 +186,7 @@
|
|
|
191
186
|
|
|
192
187
|
.ecs-modal-inner-dialog{
|
|
193
188
|
position: absolute;
|
|
194
|
-
|
|
195
|
-
right: 0;
|
|
196
|
-
bottom: 0;
|
|
189
|
+
inset: 0;
|
|
197
190
|
z-index: 3;
|
|
198
191
|
display: none;
|
|
199
192
|
overflow: hidden;
|
|
@@ -201,10 +194,11 @@
|
|
|
201
194
|
&:before{
|
|
202
195
|
content: "";
|
|
203
196
|
position: absolute;
|
|
204
|
-
height:
|
|
197
|
+
height: $spacing-10;
|
|
205
198
|
left: 0px;
|
|
206
199
|
right: 0px;
|
|
207
|
-
top:
|
|
200
|
+
top: -4px;
|
|
201
|
+
border-radius: 100%;
|
|
208
202
|
z-index: 2;
|
|
209
203
|
background: linear-gradient(180deg, rgba(32, 33, 39, 0.12) 0%, rgba(32, 33, 39, 0) 100%);
|
|
210
204
|
transition: .3s;
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
:class="[
|
|
4
4
|
subtab ? `ecs-tab-button-child` : '',
|
|
5
5
|
show ? `show` : '',
|
|
6
|
-
badge ? `ecs-tab-button-badge` : ''
|
|
6
|
+
badge ? `ecs-tab-button-badge` : '',
|
|
7
|
+
!$slots.default && icon ? `icon-only` : '', ]"
|
|
7
8
|
:disabled="disabled"
|
|
8
9
|
:aria-selected="show ? 'true' : 'false'"
|
|
9
10
|
:aria-controls="ariaControls"
|
|
11
|
+
:aria-label="ariaLabel"
|
|
10
12
|
role="tab"
|
|
11
13
|
ref="tabButton"
|
|
12
14
|
@click="handleClick">
|
|
@@ -68,6 +70,10 @@
|
|
|
68
70
|
/** The ID of the tab panel that is controlled by this button. Always pass an ID to improve accessibility. */
|
|
69
71
|
ariaControls: {
|
|
70
72
|
type: String
|
|
73
|
+
},
|
|
74
|
+
/** The label of the tab button, in case the default slot contains no text, or no meaningful description of the tab content. Always pass a label to improve accessibility. */
|
|
75
|
+
ariaLabel: {
|
|
76
|
+
type: String
|
|
71
77
|
}
|
|
72
78
|
},
|
|
73
79
|
|
|
@@ -81,6 +87,10 @@
|
|
|
81
87
|
if (!this.ariaControls || this.ariaControls.trim() === '') {
|
|
82
88
|
console.warn('Warning: ariaControls must be provided on tab buttons, to improve accessibility.');
|
|
83
89
|
}
|
|
90
|
+
|
|
91
|
+
if (!this.$slots.default && (!this.ariaLabel || this.ariaLabel.trim() === '')) {
|
|
92
|
+
console.warn('Warning: ariaLabel must be provided on tab buttons without text, to improve accessibility.');
|
|
93
|
+
}
|
|
84
94
|
},
|
|
85
95
|
|
|
86
96
|
beforeUnmount() {
|
|
@@ -240,8 +250,12 @@
|
|
|
240
250
|
border-radius: $border-radius-x-small 2px 0 0;
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
|
|
244
|
-
margin-right:
|
|
253
|
+
&.icon-only{
|
|
254
|
+
margin-right: $spacing-10;
|
|
255
|
+
|
|
256
|
+
.icon{
|
|
257
|
+
margin: 0 -4px;
|
|
258
|
+
}
|
|
245
259
|
}
|
|
246
260
|
|
|
247
261
|
.icon{
|
|
@@ -256,6 +270,10 @@
|
|
|
256
270
|
.hover{
|
|
257
271
|
inset: 6px 0;
|
|
258
272
|
}
|
|
273
|
+
|
|
274
|
+
&:last-child{
|
|
275
|
+
margin-right: 0;
|
|
276
|
+
}
|
|
259
277
|
}
|
|
260
278
|
}
|
|
261
279
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import EcsEmojiPicker from '@components/emoji-picker/emoji-picker';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Input/Emoji Picker',
|
|
5
|
+
component: EcsEmojiPicker
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const emojiPicker = () => ({
|
|
9
|
+
components: { EcsEmojiPicker },
|
|
10
|
+
data() {
|
|
11
|
+
return {
|
|
12
|
+
emojis: '',
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
methods: {
|
|
16
|
+
onEmojiSelected(emoji) {
|
|
17
|
+
this.emojis += emoji.char;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
template: `
|
|
21
|
+
<div>
|
|
22
|
+
<span>Emojis: {{ emojis }}</span>
|
|
23
|
+
<ecs-emoji-picker @emoji="onEmojiSelected" bordered />
|
|
24
|
+
</div>`,
|
|
25
|
+
});
|
|
@@ -20,6 +20,7 @@ export const standardRow = () => ({
|
|
|
20
20
|
<ecs-tab-button show>Settings</ecs-tab-button>
|
|
21
21
|
<ecs-tab-button badge>Calendar</ecs-tab-button>
|
|
22
22
|
<ecs-tab-button>Versions</ecs-tab-button>
|
|
23
|
+
<ecs-tab-button icon="calendar"></ecs-tab-button>
|
|
23
24
|
</ecs-tab-bar>`,
|
|
24
25
|
});
|
|
25
26
|
|