vatts 2.0.2 → 2.0.3-canary.1

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.
@@ -1,226 +1,226 @@
1
- <!--
2
- This file is part of the Vatts.js Project.
3
- Copyright (c) 2026 mfraz
4
-
5
- Licensed under the Apache License, Version 2.0 (the "License");
6
- you may not use this file except in compliance with the License.
7
- You may obtain a copy of the License at
8
-
9
- http://www.apache.org/licenses/LICENSE-2.0
10
-
11
- Unless required by applicable law or agreed to in writing, software
12
- distributed under the License is distributed on an "AS IS" BASIS,
13
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- See the License for the specific language governing permissions and
15
- limitations under the License.
16
- -->
17
- <script setup>
18
- import { ref, computed, onMounted, onUnmounted } from 'vue';
19
-
20
- // Definição das props
21
- const props = defineProps({
22
- hasBuildError: {
23
- type: Boolean,
24
- default: false
25
- }
26
- });
27
-
28
- // Eventos
29
- // Em vez de passar uma função callback como prop (React), emitimos um evento no Vue.
30
- const emit = defineEmits(['click-build-error']);
31
-
32
- const isVisible = ref(true);
33
- const hotState = ref('idle');
34
- const mounted = ref(false);
35
-
36
- const isReloading = computed(() => hotState.value === 'reloading');
37
- const isError = computed(() => !!props.hasBuildError);
38
-
39
- const handleBadgeClick = () => {
40
- if (isError.value) {
41
- emit('click-build-error');
42
- }
43
- };
44
-
45
- onMounted(() => {
46
- mounted.value = true;
47
-
48
- const handler = (ev) => {
49
- const detail = ev?.detail;
50
- if (!detail || !detail.state) return;
51
-
52
- if (detail.state === 'reloading' || detail.state === 'full-reload') {
53
- hotState.value = 'reloading';
54
- }
55
- if (detail.state === 'idle') {
56
- hotState.value = 'idle';
57
- }
58
- };
59
-
60
- if (typeof window !== 'undefined') {
61
- window.addEventListener('vatts:hotreload', handler);
62
- }
63
-
64
- onUnmounted(() => {
65
- if (typeof window !== 'undefined') {
66
- window.removeEventListener('vatts:hotreload', handler);
67
- }
68
- });
69
- });
70
- </script>
71
-
72
- <template>
73
- <Teleport to="body">
74
- <div
75
- v-if="isVisible && mounted"
76
- class="vatts-dev-badge"
77
- :class="{ 'clickable': isError }"
78
- @click="handleBadgeClick"
79
- >
80
- <!-- Loading Spinner ou Status Dot -->
81
- <div v-if="isReloading" class="vatts-spinner"></div>
82
- <div
83
- v-else
84
- class="vatts-status-dot"
85
- :class="{ 'reloading': isReloading, 'error': isError }"
86
- ></div>
87
-
88
- <!-- Logo & Texto -->
89
- <div class="vatts-logo">
90
- VATTS<span>.JS</span>
91
- <span v-if="isError" class="vatts-error-pill">ERROR</span>
92
- </div>
93
-
94
- <!-- Botão Fechar -->
95
- <button
96
- class="close-btn"
97
- @click.stop="isVisible = false"
98
- aria-label="Close badge"
99
- >
100
- ×
101
- </button>
102
- </div>
103
- </Teleport>
104
- </template>
105
-
106
- <style scoped>
107
- /* Importando fonte (opcional se já existir globalmente, mas mantendo consistência com o original) */
108
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&display=swap');
109
-
110
- @keyframes vatts-pulse {
111
- 0% { opacity: 0.4; }
112
- 50% { opacity: 1; }
113
- 100% { opacity: 0.4; }
114
- }
115
-
116
- @keyframes vatts-spin {
117
- 0% { transform: rotate(0deg); }
118
- 100% { transform: rotate(360deg); }
119
- }
120
-
121
- .vatts-dev-badge {
122
- position: fixed;
123
- bottom: 20px;
124
- right: 20px;
125
- /* Z-index alto para ficar acima de tudo */
126
- z-index: 2147483647;
127
-
128
- display: flex;
129
- align-items: center;
130
- gap: 12px;
131
- padding: 8px 14px;
132
- background: rgba(0, 0, 0, 0.85);
133
- backdrop-filter: blur(12px);
134
- -webkit-backdrop-filter: blur(12px);
135
-
136
- border-radius: 10px;
137
- color: #fff;
138
- font-family: 'Inter', system-ui, sans-serif;
139
- font-size: 11px;
140
- font-weight: 600;
141
- letter-spacing: 0.05em;
142
-
143
- /* Estilo Monocromático Next.js */
144
- border: 1px solid rgba(255, 255, 255, 0.1);
145
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
146
- transition: all 0.2s ease;
147
- cursor: default;
148
- user-select: none;
149
- }
150
-
151
- .vatts-dev-badge.clickable {
152
- cursor: pointer;
153
- }
154
-
155
- .vatts-dev-badge:hover {
156
- border-color: rgba(255, 255, 255, 0.3);
157
- transform: translateY(-2px);
158
- background: rgba(10, 10, 10, 0.95);
159
- }
160
-
161
- .vatts-status-dot {
162
- width: 7px;
163
- height: 7px;
164
- background: #ffffff; /* Branco para status OK */
165
- border-radius: 50%;
166
- box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
167
- animation: vatts-pulse 2.5s infinite ease-in-out;
168
- }
169
-
170
- .vatts-status-dot.reloading {
171
- background: #64748b; /* Slate */
172
- box-shadow: none;
173
- }
174
-
175
- .vatts-status-dot.error {
176
- background: #ef4444; /* Vermelho para erro */
177
- box-shadow: 0 0 10px #ef4444;
178
- animation: vatts-pulse 1s infinite ease-in-out;
179
- }
180
-
181
- .vatts-spinner {
182
- width: 10px;
183
- height: 10px;
184
- border-radius: 50%;
185
- border: 2px solid rgba(255,255,255,0.1);
186
- border-top-color: #ffffff;
187
- animation: vatts-spin 0.8s linear infinite;
188
- }
189
-
190
- .vatts-logo {
191
- color: #ffffff;
192
- font-weight: 800;
193
- display: flex;
194
- align-items: center;
195
- }
196
-
197
- .vatts-logo span {
198
- color: #64748b;
199
- }
200
-
201
- .vatts-error-pill {
202
- margin-left: 8px;
203
- padding: 2px 6px;
204
- border-radius: 4px;
205
- background: #ffffff;
206
- color: #000000;
207
- font-size: 9px;
208
- font-weight: 900;
209
- }
210
-
211
- .close-btn {
212
- background: none;
213
- border: none;
214
- color: rgba(255,255,255,0.2);
215
- cursor: pointer;
216
- font-size: 16px;
217
- padding: 0 0 0 4px;
218
- margin-left: 4px;
219
- display: flex;
220
- align-items: center;
221
- }
222
-
223
- .close-btn:hover {
224
- color: rgba(255,255,255,0.6);
225
- }
1
+ <!--
2
+ This file is part of the Vatts.js Project.
3
+ Copyright (c) 2026 mfraz
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ -->
17
+ <script setup>
18
+ import { ref, computed, onMounted, onUnmounted } from 'vue';
19
+
20
+ // Definição das props
21
+ const props = defineProps({
22
+ hasBuildError: {
23
+ type: Boolean,
24
+ default: false
25
+ }
26
+ });
27
+
28
+ // Eventos
29
+ // Em vez de passar uma função callback como prop (React), emitimos um evento no Vue.
30
+ const emit = defineEmits(['click-build-error']);
31
+
32
+ const isVisible = ref(true);
33
+ const hotState = ref('idle');
34
+ const mounted = ref(false);
35
+
36
+ const isReloading = computed(() => hotState.value === 'reloading');
37
+ const isError = computed(() => !!props.hasBuildError);
38
+
39
+ const handleBadgeClick = () => {
40
+ if (isError.value) {
41
+ emit('click-build-error');
42
+ }
43
+ };
44
+
45
+ onMounted(() => {
46
+ mounted.value = true;
47
+
48
+ const handler = (ev) => {
49
+ const detail = ev?.detail;
50
+ if (!detail || !detail.state) return;
51
+
52
+ if (detail.state === 'reloading' || detail.state === 'full-reload') {
53
+ hotState.value = 'reloading';
54
+ }
55
+ if (detail.state === 'idle') {
56
+ hotState.value = 'idle';
57
+ }
58
+ };
59
+
60
+ if (typeof window !== 'undefined') {
61
+ window.addEventListener('vatts:hotreload', handler);
62
+ }
63
+
64
+ onUnmounted(() => {
65
+ if (typeof window !== 'undefined') {
66
+ window.removeEventListener('vatts:hotreload', handler);
67
+ }
68
+ });
69
+ });
70
+ </script>
71
+
72
+ <template>
73
+ <Teleport to="body">
74
+ <div
75
+ v-if="isVisible && mounted"
76
+ class="vatts-dev-badge"
77
+ :class="{ 'clickable': isError }"
78
+ @click="handleBadgeClick"
79
+ >
80
+ <!-- Loading Spinner ou Status Dot -->
81
+ <div v-if="isReloading" class="vatts-spinner"></div>
82
+ <div
83
+ v-else
84
+ class="vatts-status-dot"
85
+ :class="{ 'reloading': isReloading, 'error': isError }"
86
+ ></div>
87
+
88
+ <!-- Logo & Texto -->
89
+ <div class="vatts-logo">
90
+ VATTS<span>.JS</span>
91
+ <span v-if="isError" class="vatts-error-pill">ERROR</span>
92
+ </div>
93
+
94
+ <!-- Botão Fechar -->
95
+ <button
96
+ class="close-btn"
97
+ @click.stop="isVisible = false"
98
+ aria-label="Close badge"
99
+ >
100
+ ×
101
+ </button>
102
+ </div>
103
+ </Teleport>
104
+ </template>
105
+
106
+ <style scoped>
107
+ /* Importando fonte (opcional se já existir globalmente, mas mantendo consistência com o original) */
108
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&display=swap');
109
+
110
+ @keyframes vatts-pulse {
111
+ 0% { opacity: 0.4; }
112
+ 50% { opacity: 1; }
113
+ 100% { opacity: 0.4; }
114
+ }
115
+
116
+ @keyframes vatts-spin {
117
+ 0% { transform: rotate(0deg); }
118
+ 100% { transform: rotate(360deg); }
119
+ }
120
+
121
+ .vatts-dev-badge {
122
+ position: fixed;
123
+ bottom: 20px;
124
+ right: 20px;
125
+ /* Z-index alto para ficar acima de tudo */
126
+ z-index: 2147483647;
127
+
128
+ display: flex;
129
+ align-items: center;
130
+ gap: 12px;
131
+ padding: 8px 14px;
132
+ background: rgba(0, 0, 0, 0.85);
133
+ backdrop-filter: blur(12px);
134
+ -webkit-backdrop-filter: blur(12px);
135
+
136
+ border-radius: 10px;
137
+ color: #fff;
138
+ font-family: 'Inter', system-ui, sans-serif;
139
+ font-size: 11px;
140
+ font-weight: 600;
141
+ letter-spacing: 0.05em;
142
+
143
+ /* Estilo Monocromático Next.js */
144
+ border: 1px solid rgba(255, 255, 255, 0.1);
145
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
146
+ transition: all 0.2s ease;
147
+ cursor: default;
148
+ user-select: none;
149
+ }
150
+
151
+ .vatts-dev-badge.clickable {
152
+ cursor: pointer;
153
+ }
154
+
155
+ .vatts-dev-badge:hover {
156
+ border-color: rgba(255, 255, 255, 0.3);
157
+ transform: translateY(-2px);
158
+ background: rgba(10, 10, 10, 0.95);
159
+ }
160
+
161
+ .vatts-status-dot {
162
+ width: 7px;
163
+ height: 7px;
164
+ background: #ffffff; /* Branco para status OK */
165
+ border-radius: 50%;
166
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
167
+ animation: vatts-pulse 2.5s infinite ease-in-out;
168
+ }
169
+
170
+ .vatts-status-dot.reloading {
171
+ background: #64748b; /* Slate */
172
+ box-shadow: none;
173
+ }
174
+
175
+ .vatts-status-dot.error {
176
+ background: #ef4444; /* Vermelho para erro */
177
+ box-shadow: 0 0 10px #ef4444;
178
+ animation: vatts-pulse 1s infinite ease-in-out;
179
+ }
180
+
181
+ .vatts-spinner {
182
+ width: 10px;
183
+ height: 10px;
184
+ border-radius: 50%;
185
+ border: 2px solid rgba(255,255,255,0.1);
186
+ border-top-color: #ffffff;
187
+ animation: vatts-spin 0.8s linear infinite;
188
+ }
189
+
190
+ .vatts-logo {
191
+ color: #ffffff;
192
+ font-weight: 800;
193
+ display: flex;
194
+ align-items: center;
195
+ }
196
+
197
+ .vatts-logo span {
198
+ color: #64748b;
199
+ }
200
+
201
+ .vatts-error-pill {
202
+ margin-left: 8px;
203
+ padding: 2px 6px;
204
+ border-radius: 4px;
205
+ background: #ffffff;
206
+ color: #000000;
207
+ font-size: 9px;
208
+ font-weight: 900;
209
+ }
210
+
211
+ .close-btn {
212
+ background: none;
213
+ border: none;
214
+ color: rgba(255,255,255,0.2);
215
+ cursor: pointer;
216
+ font-size: 16px;
217
+ padding: 0 0 0 4px;
218
+ margin-left: 4px;
219
+ display: flex;
220
+ align-items: center;
221
+ }
222
+
223
+ .close-btn:hover {
224
+ color: rgba(255,255,255,0.6);
225
+ }
226
226
  </style>