PluginProbe
The Innovative Form Builder – IvyForms / 0.1.2
The Innovative Form Builder – IvyForms v0.1.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / button / IvyIndicatorButton.vue

IvyIndicatorButton.vue in The Innovative Form Builder – IvyForms 0.1.2, at frontend/src/views/_components/button/IvyIndicatorButton.vue

197 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <button
3 class="ivyforms-indicator-button__wrapper"
4 :class="{ 'is-active': isActive, 'is-fab': props.color === 'fab' }"
5 :style="{ background: getBackgroundColor() }"
6 @click="toggleActiveState"
7 @mouseenter="isHovered = true"
8 @mouseleave="isHovered = false"
9 >
10 <IvyIcon :name="currentIcon" :color="getIconColor()" type="outline" size="l"> </IvyIcon>
11 <span
12 v-if="showIndicator"
13 class="ivyforms-indicator-button__indicator"
14 :class="`priority-${props.indicatorPriority}`"
15 @click.stop="hideIndicator"
16 ></span>
17 </button>
18 </template>
19
20 <script setup lang="ts">
21 import { ref, watch, computed } from 'vue'
22
23 interface Props {
24 type: 'sort' | 'filter' | 'folder' | 'datepicker' | 'import' | 'export'
25 color?: 'fab' | 'tertiary'
26 indicator?: boolean
27 indicatorPriority?: 'primary' | 'secondary' | 'amber'
28 customHideIndicator?: () => void
29 }
30
31 const props = withDefaults(defineProps<Props>(), {
32 type: 'sort',
33 color: 'tertiary',
34 indicator: false,
35 indicatorPriority: 'secondary',
36 customHideIndicator: undefined,
37 })
38
39 const showIndicator = ref(props.indicator)
40 const isActive = ref(false)
41 const isHovered = ref(false)
42
43 // Toggle active state
44 const toggleActiveState = () => {
45 isActive.value = !isActive.value
46 }
47
48 // Logic for the indicator
49 const hideIndicator = () => {
50 if (props.customHideIndicator) {
51 props.customHideIndicator()
52 } else {
53 showIndicator.value = false
54 }
55 isActive.value = false
56 }
57
58 watch(
59 () => props.indicator,
60 (newValue) => {
61 showIndicator.value = newValue
62 },
63 )
64
65 const getIconName = (type: Props['type']) => {
66 const icons = {
67 sort: { default: 'sort-default', hover: 'sort-from-top', active: 'sort-from-top' },
68 filter: { default: 'filter', hover: 'filter', active: 'filter' },
69 folder: { default: 'folder', hover: 'folder', active: 'folder' },
70 datepicker: { default: 'calendar-dot', hover: 'calendar-dot', active: 'calendar-dot' },
71 import: { default: 'import', hover: 'import', active: 'import' },
72 export: { default: 'export', hover: 'export', active: 'export' },
73 }
74
75 return isActive.value
76 ? icons[type].active
77 : isHovered.value
78 ? icons[type].hover
79 : icons[type].default
80 }
81
82 const getBackgroundColor = () => {
83 if (props.color === 'tertiary') {
84 return 'var(--map-base-dusk-fill--4)'
85 }
86 return 'var(--map-ground-level-3)'
87 }
88
89 const getIconColor = () => {
90 if (props.color !== 'tertiary') {
91 return isHovered.value || isActive.value
92 ? 'var(--map-base-purple-symbol-0)'
93 : 'var(--map-base-dusk-symbol-2)'
94 }
95 return 'var(--map-base-dusk-symbol-2)'
96 }
97
98 // Computed property for icon name
99 const currentIcon = computed(() => getIconName(props.type))
100 </script>
101
102 <style lang="scss">
103 .ivyforms-indicator-button__wrapper {
104 position: relative;
105 display: flex;
106 height: 40px;
107 width: 40px;
108 align-items: center;
109 padding: 0;
110 align-self: stretch;
111 border-radius: 8px;
112 cursor: pointer;
113 border: none;
114 outline: none;
115
116 &.is-fab {
117 box-shadow: 0 4px 15px 0 rgba(0, 0, 0, 0.05);
118
119 &:hover {
120 .ivyforms-icon__svg {
121 // Global & Arrows
122 &.category-global,
123 &.category-arrows {
124 fill: var(--map-base-purple-fill--1);
125 }
126 }
127 }
128 }
129
130 &:not(.is-fab) {
131 &:hover {
132 position: relative;
133
134 &::after {
135 content: '';
136 position: absolute;
137 top: 0;
138 left: 0;
139 width: 100%;
140 height: 100%;
141 background-color: var(--map-bw-o90);
142 opacity: 0.05;
143 border-radius: inherit;
144 pointer-events: none;
145 }
146 }
147 }
148
149 // Icon
150 .ivyforms-icon {
151 padding: var(--Spacing-sm, 8px) 8px;
152 }
153
154 // Show indicator 'x' on hover
155 &:hover,
156 &:focus {
157 .ivyforms-indicator-button__indicator {
158 font-size: 10px;
159 color: $primitive-white;
160 content: '×';
161
162 &::after {
163 content: '×';
164 font-size: 10px;
165 font-weight: bold;
166 color: $primitive-white;
167 line-height: 10px;
168 }
169 }
170 }
171
172 // Indicator
173 .ivyforms-indicator-button__indicator {
174 width: 12px;
175 height: 12px;
176 position: absolute;
177 top: 1px;
178 right: 1px;
179 border-radius: 50%;
180 display: flex;
181 align-items: center;
182 justify-content: center;
183 background: var(--map-status-success-fill-0);
184 cursor: pointer;
185 font-size: 0;
186
187 &.priority-secondary {
188 background: var(--map-base-purple-fill--1);
189 }
190
191 &.priority-amber {
192 background: var(--map-status-warning-fill-0);
193 }
194 }
195 }
196 </style>
197