PluginProbe
The Innovative Form Builder – IvyForms / 0.2
The Innovative Form Builder – IvyForms v0.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.2, at frontend/src/views/_components/button/IvyIndicatorButton.vue

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