@sugarat/theme 0.5.11 → 0.5.12-beta.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.
Files changed (49) hide show
  1. package/node.d.ts +2 -4
  2. package/node.js +206 -156
  3. package/node.mjs +205 -154
  4. package/package.json +10 -15
  5. package/src/components/Alert.vue +269 -0
  6. package/src/components/Avatar.vue +65 -0
  7. package/src/components/BlogAlert.vue +8 -8
  8. package/src/components/BlogApp.vue +5 -8
  9. package/src/components/BlogArticleAnalyze.vue +99 -66
  10. package/src/components/BlogAuthor.vue +13 -15
  11. package/src/components/BlogBackToTop.vue +21 -24
  12. package/src/components/BlogButtonAfterArticle.vue +12 -15
  13. package/src/components/BlogCommentWrapper.vue +34 -41
  14. package/src/components/BlogDocCover.vue +1 -1
  15. package/src/components/BlogFooter.vue +26 -32
  16. package/src/components/BlogFriendLink.vue +91 -73
  17. package/src/components/BlogHomeBanner.vue +25 -31
  18. package/src/components/BlogHomeHeaderAvatar.vue +16 -23
  19. package/src/components/BlogHomeInfo.vue +2 -4
  20. package/src/components/BlogHomeOverview.vue +12 -15
  21. package/src/components/BlogHomeTags.vue +22 -31
  22. package/src/components/BlogHotArticle.vue +69 -80
  23. package/src/components/BlogImagePreview.vue +3 -3
  24. package/src/components/BlogItem.vue +14 -23
  25. package/src/components/BlogList.vue +15 -19
  26. package/src/components/BlogRecommendArticle.vue +56 -72
  27. package/src/components/BlogSidebar.vue +1 -1
  28. package/src/components/Button.vue +150 -0
  29. package/src/components/Carousel.vue +249 -0
  30. package/src/components/CarouselItem.vue +139 -0
  31. package/src/components/CommentArtalk.vue +1 -1
  32. package/src/components/Image.vue +33 -0
  33. package/src/components/ImageViewer.vue +407 -0
  34. package/src/components/Pagination.vue +369 -0
  35. package/src/components/Tag.vue +144 -0
  36. package/src/components/UserWorks.vue +132 -175
  37. package/src/composables/config/blog.ts +6 -1
  38. package/src/composables/config/index.ts +2 -2
  39. package/src/index.ts +12 -19
  40. package/src/node.ts +0 -3
  41. package/src/styles/el-base.css +340 -0
  42. package/src/styles/{index.scss → index.css} +56 -91
  43. package/src/utils/client/index.ts +17 -0
  44. package/src/utils/node/mdPlugins.ts +1 -1
  45. package/src/utils/node/theme.ts +5 -2
  46. package/src/utils/node/vitePlugins.ts +51 -18
  47. package/src/styles/scss/algolia.scss +0 -231
  48. package/src/styles/scss/global.scss +0 -156
  49. package/src/styles/scss/highlight.scss +0 -12
@@ -0,0 +1,139 @@
1
+ <script lang="ts" setup>
2
+ import { computed, getCurrentInstance, inject, onMounted, onUnmounted } from 'vue'
3
+
4
+ const instance = getCurrentInstance()
5
+ const uid = instance?.uid
6
+
7
+ const carousel = inject('carousel') as any
8
+ const { activeIndex, items, type, addItem, removeItem } = carousel
9
+
10
+ const index = computed(() => {
11
+ return items.value.findIndex((item: any) => item.uid === uid)
12
+ })
13
+
14
+ const isActive = computed(() => index.value === activeIndex.value)
15
+
16
+ // Card logic
17
+ const CARD_SCALE = 0.83
18
+
19
+ const cardStyle = computed(() => {
20
+ if (type.value !== 'card') {
21
+ // Normal mode: simplified translate
22
+ // const isPrev = index.value === activeIndex.value - 1 || (activeIndex.value === 0 && index.value === items.value.length - 1)
23
+ // const isNext = index.value === activeIndex.value + 1 || (activeIndex.value === items.value.length - 1 && index.value === 0)
24
+
25
+ // Simple show/hide for normal mode or use CSS transition
26
+ // Better: use transform
27
+ // const offset = index.value - activeIndex.value
28
+ // Handle loop wrap
29
+ // ... too complex to implement full logic in one go.
30
+ // Let's rely on simple absolute positioning and z-index for normal fade/slide
31
+
32
+ return {
33
+ transform: `translateX(${(index.value - activeIndex.value) * 100}%)`,
34
+ zIndex: isActive.value ? 2 : 1,
35
+ }
36
+ }
37
+
38
+ // Card Mode
39
+ // const parentWidth = instance?.parent?.vnode?.el?.offsetWidth || 0 // Need parent width
40
+ // Actually simpler:
41
+ // Active: translate(0) scale(1)
42
+ // Prev: translate(-50%) scale(0.83)
43
+ // Next: translate(50%) scale(0.83)
44
+ // Others: hidden or further
45
+
46
+ const active = activeIndex.value
47
+ const count = items.value.length
48
+ const idx = index.value
49
+
50
+ // Logic from Element Plus (simplified)
51
+ const processIndex = (index: number, activeIndex: number, length: number) => {
52
+ if (activeIndex === 0 && index === length - 1)
53
+ return -1
54
+ if (activeIndex === length - 1 && index === 0)
55
+ return length
56
+ if (index < activeIndex - 1 && activeIndex - index >= length / 2)
57
+ return length + 1
58
+ if (index > activeIndex + 1 && index - activeIndex >= length / 2)
59
+ return -2
60
+ return index
61
+ }
62
+
63
+ const calculatedIndex = processIndex(idx, active, count)
64
+
65
+ const inStage = Math.round(Math.abs(calculatedIndex - active)) <= 1
66
+
67
+ const translate = (() => {
68
+ if (calculatedIndex === active)
69
+ return 0
70
+ if (Math.abs(calculatedIndex - active) > 1)
71
+ return 0 // Should be hidden really
72
+ return calculatedIndex > active ? '50%' : '-50%'
73
+ })()
74
+
75
+ const scale = calculatedIndex === active ? 1 : CARD_SCALE
76
+ const zIndex = calculatedIndex === active ? 10 : 0 // Simplified
77
+
78
+ return {
79
+ transform: `translateX(${translate}) scale(${scale})`,
80
+ zIndex,
81
+ opacity: inStage ? 1 : 0, // Hide others
82
+ display: inStage ? 'block' : 'none', // optimize
83
+ }
84
+ })
85
+
86
+ onMounted(() => {
87
+ addItem({ uid })
88
+ })
89
+ onUnmounted(() => {
90
+ removeItem(uid)
91
+ })
92
+ </script>
93
+
94
+ <template>
95
+ <div
96
+ v-if="type !== 'card' || cardStyle.display !== 'none'"
97
+ class="sugar-carousel__item"
98
+ :class="{
99
+ 'is-active': isActive,
100
+ 'is-in-stage': type === 'card' && cardStyle.opacity === 1,
101
+ 'sugar-carousel__item--card': type === 'card',
102
+ }"
103
+ :style="cardStyle"
104
+ >
105
+ <div v-if="type === 'card'" v-show="!isActive" class="sugar-carousel__mask" />
106
+ <slot />
107
+ </div>
108
+ </template>
109
+
110
+ <style scoped>
111
+ .sugar-carousel__item {
112
+ position: absolute;
113
+ top: 0;
114
+ left: 0;
115
+ width: 100%;
116
+ height: 100%;
117
+ display: inline-block;
118
+ overflow: hidden;
119
+ z-index: 0;
120
+ transition: transform 0.4s ease-in-out;
121
+ background-color: transparent;
122
+ }
123
+
124
+ .sugar-carousel__item--card {
125
+ width: 50%;
126
+ left: 25%;
127
+ }
128
+
129
+ .sugar-carousel__mask {
130
+ position: absolute;
131
+ width: 100%;
132
+ height: 100%;
133
+ top: 0;
134
+ left: 0;
135
+ background-color: #fff;
136
+ opacity: 0.24;
137
+ transition: 0.2s;
138
+ }
139
+ </style>
@@ -69,7 +69,7 @@ watch(isDark, () => {
69
69
  <div v-if="open" ref="el" class="artalk-container" />
70
70
  </template>
71
71
 
72
- <style lang="scss" scoped>
72
+ <style scoped>
73
73
  .artalk-container {
74
74
  --at-color-main: var(--vp-c-brand-2);
75
75
  }
@@ -0,0 +1,33 @@
1
+ <script lang="ts" setup>
2
+ defineProps({
3
+ src: { type: String, default: '' },
4
+ alt: { type: String, default: '' },
5
+ loading: { type: String, default: 'eager' },
6
+ })
7
+ </script>
8
+
9
+ <template>
10
+ <div class="sugar-image">
11
+ <img
12
+ :src="src"
13
+ :alt="alt"
14
+ :loading="loading as any"
15
+ class="sugar-image__inner"
16
+ >
17
+ </div>
18
+ </template>
19
+
20
+ <style scoped>
21
+ .sugar-image {
22
+ position: relative;
23
+ display: inline-block;
24
+ overflow: hidden;
25
+ }
26
+ .sugar-image__inner {
27
+ width: 100%;
28
+ height: 100%;
29
+ vertical-align: top;
30
+ object-fit: inherit;
31
+ cursor: pointer;
32
+ }
33
+ </style>
@@ -0,0 +1,407 @@
1
+ <script lang="ts" setup>
2
+ import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
3
+ import { useScrollLock } from '@vueuse/core'
4
+
5
+ const props = defineProps({
6
+ urlList: {
7
+ type: Array as () => string[],
8
+ default: () => [],
9
+ },
10
+ initialIndex: {
11
+ type: Number,
12
+ default: 0,
13
+ },
14
+ infinite: {
15
+ type: Boolean,
16
+ default: true,
17
+ },
18
+ hideOnClickModal: {
19
+ type: Boolean,
20
+ default: false,
21
+ },
22
+ teleported: {
23
+ type: Boolean,
24
+ default: false,
25
+ },
26
+ })
27
+
28
+ const emit = defineEmits(['close', 'switch'])
29
+
30
+ const index = ref(props.initialIndex)
31
+ const isLocked = useScrollLock(document.body)
32
+
33
+ const currentImg = computed(() => props.urlList[index.value])
34
+ const isSingle = computed(() => props.urlList.length <= 1)
35
+ const isFirst = computed(() => index.value === 0)
36
+ const isLast = computed(() => index.value === props.urlList.length - 1)
37
+
38
+ const transform = reactive({
39
+ scale: 1,
40
+ deg: 0,
41
+ offsetX: 0,
42
+ offsetY: 0,
43
+ enableTransition: false,
44
+ })
45
+
46
+ const imgStyle = computed(() => ({
47
+ transform: `translate3d(${transform.offsetX}px, ${transform.offsetY}px, 0) scale(${transform.scale}) rotate(${transform.deg}deg)`,
48
+ transition: transform.enableTransition ? 'transform .3s' : '',
49
+ }))
50
+
51
+ function reset() {
52
+ transform.scale = 1
53
+ transform.deg = 0
54
+ transform.offsetX = 0
55
+ transform.offsetY = 0
56
+ transform.enableTransition = false
57
+ }
58
+
59
+ watch(index, () => {
60
+ reset()
61
+ })
62
+
63
+ function hide() {
64
+ isLocked.value = false
65
+ emit('close')
66
+ }
67
+
68
+ function prev() {
69
+ if (isFirst.value && !props.infinite)
70
+ return
71
+ const len = props.urlList.length
72
+ index.value = (index.value - 1 + len) % len
73
+ emit('switch', index.value)
74
+ }
75
+
76
+ function next() {
77
+ if (isLast.value && !props.infinite)
78
+ return
79
+ const len = props.urlList.length
80
+ index.value = (index.value + 1) % len
81
+ emit('switch', index.value)
82
+ }
83
+
84
+ function handleMaskClick() {
85
+ if (props.hideOnClickModal) {
86
+ hide()
87
+ }
88
+ }
89
+
90
+ // Actions
91
+ function handleActions(action: string) {
92
+ transform.enableTransition = true
93
+ switch (action) {
94
+ case 'zoomOut':
95
+ if (transform.scale > 0.2) {
96
+ transform.scale = parseFloat((transform.scale - 0.2).toFixed(3))
97
+ }
98
+ break
99
+ case 'zoomIn':
100
+ transform.scale = parseFloat((transform.scale + 0.2).toFixed(3))
101
+ break
102
+ case 'clockwise':
103
+ transform.deg += 90
104
+ break
105
+ case 'anticlockwise':
106
+ transform.deg -= 90
107
+ break
108
+ case 'original': // 1:1
109
+ reset()
110
+ break
111
+ }
112
+ }
113
+
114
+ function handleDownload() {
115
+ const a = document.createElement('a')
116
+ a.href = currentImg.value
117
+ a.target = '_blank'
118
+ a.download = ''
119
+ document.body.appendChild(a)
120
+ a.click()
121
+ document.body.removeChild(a)
122
+ }
123
+
124
+ // Drag Logic
125
+ const isDragging = ref(false)
126
+ let startX = 0
127
+ let startY = 0
128
+ let startOffsetX = 0
129
+ let startOffsetY = 0
130
+
131
+ function handleMouseDown(e: MouseEvent) {
132
+ if (e.button !== 0)
133
+ return
134
+ transform.enableTransition = false
135
+ isDragging.value = true
136
+ startX = e.clientX
137
+ startY = e.clientY
138
+ startOffsetX = transform.offsetX
139
+ startOffsetY = transform.offsetY
140
+ e.preventDefault()
141
+ }
142
+
143
+ function handleMouseMove(e: MouseEvent) {
144
+ if (!isDragging.value)
145
+ return
146
+ const deltaX = e.clientX - startX
147
+ const deltaY = e.clientY - startY
148
+ transform.offsetX = startOffsetX + deltaX
149
+ transform.offsetY = startOffsetY + deltaY
150
+ e.preventDefault()
151
+ }
152
+
153
+ function handleMouseUp() {
154
+ isDragging.value = false
155
+ }
156
+
157
+ // Wheel Zoom
158
+ function handleWheel(e: WheelEvent) {
159
+ const zoomRate = 0.1
160
+ const delta = e.deltaY < 0 ? 1 : -1
161
+ const newScale = parseFloat((transform.scale + delta * zoomRate).toFixed(3))
162
+ if (newScale >= 0.2) {
163
+ transform.scale = newScale
164
+ }
165
+ }
166
+
167
+ onMounted(() => {
168
+ isLocked.value = true
169
+ window.addEventListener('keydown', handleKeydown)
170
+ window.addEventListener('mouseup', handleMouseUp)
171
+ window.addEventListener('mousemove', handleMouseMove)
172
+ })
173
+
174
+ onUnmounted(() => {
175
+ isLocked.value = false
176
+ window.removeEventListener('keydown', handleKeydown)
177
+ window.removeEventListener('mouseup', handleMouseUp)
178
+ window.removeEventListener('mousemove', handleMouseMove)
179
+ })
180
+
181
+ function handleKeydown(e: KeyboardEvent) {
182
+ if (e.key === 'Escape') {
183
+ hide()
184
+ }
185
+ else if (e.key === 'ArrowLeft') {
186
+ prev()
187
+ }
188
+ else if (e.key === 'ArrowRight') {
189
+ next()
190
+ }
191
+ }
192
+ </script>
193
+
194
+ <template>
195
+ <Teleport to="body" :disabled="!teleported">
196
+ <transition name="viewer-fade">
197
+ <div class="sugar-image-viewer__wrapper" tabindex="-1" @wheel.prevent="handleWheel">
198
+ <div class="sugar-image-viewer__mask" @click="handleMaskClick" />
199
+
200
+ <!-- Close -->
201
+ <span class="sugar-image-viewer__btn sugar-image-viewer__close" @click="hide">
202
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z" /></svg>
203
+ </span>
204
+
205
+ <!-- Arrows -->
206
+ <template v-if="!isSingle">
207
+ <span
208
+ class="sugar-image-viewer__btn sugar-image-viewer__prev"
209
+ :class="{ 'is-disabled': !infinite && isFirst }"
210
+ @click="prev"
211
+ >
212
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M609.408 149.376 277.76 489.6a32 32 0 0 0 0 44.672l331.648 340.352a29.12 29.12 0 0 0 41.728 0 30.592 30.592 0 0 0 0-42.752L339.264 511.936l311.872-319.872a30.592 30.592 0 0 0 0-42.688 29.12 29.12 0 0 0-41.728 0z" /></svg>
213
+ </span>
214
+ <span
215
+ class="sugar-image-viewer__btn sugar-image-viewer__next"
216
+ :class="{ 'is-disabled': !infinite && isLast }"
217
+ @click="next"
218
+ >
219
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z" /></svg>
220
+ </span>
221
+ </template>
222
+
223
+ <!-- Actions Toolbar -->
224
+ <div class="sugar-image-viewer__actions">
225
+ <div class="sugar-image-viewer__actions__inner">
226
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleActions('zoomOut')"><path fill="currentColor" d="m795.904 750.72 124.992 124.928a32 32 0 0 1-45.248 45.248L750.656 795.904a416 416 0 1 1 45.248-45.248zM480 832a352 352 0 1 0 0-704 352 352 0 0 0 0 704M352 448h256a32 32 0 0 1 0 64H352a32 32 0 0 1 0-64" /></svg>
227
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleActions('zoomIn')"><path fill="currentColor" d="m795.904 750.72 124.992 124.928a32 32 0 0 1-45.248 45.248L750.656 795.904a416 416 0 1 1 45.248-45.248zM480 832a352 352 0 1 0 0-704 352 352 0 0 0 0 704m-32-384v-96a32 32 0 0 1 64 0v96h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64z" /></svg>
228
+ <i class="sugar-image-viewer__actions__divider" />
229
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleActions('original')"><path fill="currentColor" d="M784.512 230.272v-50.56a32 32 0 1 1 64 0v149.056a32 32 0 0 1-32 32H667.52a32 32 0 1 1 0-64h92.992A320 320 0 1 0 524.8 833.152a320 320 0 0 0 320-320h64a384 384 0 0 1-384 384 384 384 0 0 1-384-384 384 384 0 0 1 643.712-282.88" /></svg>
230
+ <i class="sugar-image-viewer__actions__divider" />
231
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleActions('anticlockwise')"><path fill="currentColor" d="M289.088 296.704h92.992a32 32 0 0 1 0 64H232.96a32 32 0 0 1-32-32V179.712a32 32 0 0 1 64 0v50.56a384 384 0 0 1 643.84 282.88 384 384 0 0 1-383.936 384 384 384 0 0 1-384-384h64a320 320 0 1 0 640 0 320 320 0 0 0-555.712-216.448z" /></svg>
232
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleActions('clockwise')"><path fill="currentColor" d="M771.776 794.88A384 384 0 0 1 128 512h64a320 320 0 0 0 555.712 216.448H654.72a32 32 0 1 1 0-64h149.056a32 32 0 0 1 32 32v148.928a32 32 0 1 1-64 0v-50.56zM276.288 295.616h92.992a32 32 0 0 1 0 64H220.16a32 32 0 0 1-32-32V178.56a32 32 0 0 1 64 0v50.56A384 384 0 0 1 896.128 512h-64a320 320 0 0 0-555.776-216.384z" /></svg>
233
+ <i class="sugar-image-viewer__actions__divider" />
234
+ <svg width="1em" height="1em" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" @click="handleDownload"><path fill="currentColor" d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64m384-253.696 236.288-236.352 45.248 45.248L508.8 704 192 387.2l45.248-45.248L480 584.704V128h64z" /></svg>
235
+ </div>
236
+ </div>
237
+
238
+ <!-- Canvas -->
239
+ <div class="sugar-image-viewer__canvas">
240
+ <img
241
+ :src="currentImg"
242
+ :style="imgStyle"
243
+ class="sugar-image-viewer__img"
244
+ @mousedown="handleMouseDown"
245
+ >
246
+ </div>
247
+ </div>
248
+ </transition>
249
+ </Teleport>
250
+ </template>
251
+
252
+ <style scoped>
253
+ .sugar-image-viewer__wrapper {
254
+ position: fixed;
255
+ top: 0;
256
+ right: 0;
257
+ bottom: 0;
258
+ left: 0;
259
+ z-index: 2000;
260
+ display: flex;
261
+ align-items: center;
262
+ justify-content: center;
263
+ }
264
+
265
+ .sugar-image-viewer__mask {
266
+ position: absolute;
267
+ width: 100%;
268
+ height: 100%;
269
+ top: 0;
270
+ left: 0;
271
+ opacity: 0.5;
272
+ background: #000;
273
+ }
274
+
275
+ .sugar-image-viewer__btn {
276
+ position: absolute;
277
+ z-index: 1;
278
+ display: flex;
279
+ align-items: center;
280
+ justify-content: center;
281
+ border-radius: 50%;
282
+ opacity: 0.8;
283
+ cursor: pointer;
284
+ box-sizing: border-box;
285
+ user-select: none;
286
+ background-color: #606266;
287
+ color: #fff;
288
+ width: 44px;
289
+ height: 44px;
290
+ font-size: 24px;
291
+ }
292
+ .sugar-image-viewer__btn:hover {
293
+ border-color: #fff;
294
+ background-color: #909399;
295
+ }
296
+ .sugar-image-viewer__btn.is-disabled {
297
+ cursor: not-allowed;
298
+ opacity: 0.3;
299
+ background-color: #606266;
300
+ }
301
+
302
+ .sugar-image-viewer__close {
303
+ top: 40px;
304
+ right: 40px;
305
+ }
306
+
307
+ .sugar-image-viewer__prev {
308
+ top: 50%;
309
+ transform: translateY(-50%);
310
+ left: 40px;
311
+ }
312
+
313
+ .sugar-image-viewer__next {
314
+ top: 50%;
315
+ transform: translateY(-50%);
316
+ right: 40px;
317
+ }
318
+
319
+ .sugar-image-viewer__actions {
320
+ left: 50%;
321
+ bottom: 30px;
322
+ transform: translateX(-50%);
323
+ min-width: 282px;
324
+ height: 44px;
325
+ padding: 0 23px;
326
+ background-color: #606266;
327
+ border-color: #fff;
328
+ border-radius: 22px;
329
+ position: absolute;
330
+ z-index: 1;
331
+ display: flex;
332
+ align-items: center;
333
+ justify-content: center;
334
+ opacity: 0.8;
335
+ box-sizing: border-box;
336
+ user-select: none;
337
+ }
338
+ .sugar-image-viewer__actions__inner {
339
+ width: 100%;
340
+ height: 100%;
341
+ text-align: justify;
342
+ cursor: default;
343
+ font-size: 23px;
344
+ color: #fff;
345
+ display: flex;
346
+ align-items: center;
347
+ justify-content: space-around;
348
+ gap: 12px;
349
+ }
350
+ .sugar-image-viewer__actions__inner svg {
351
+ cursor: pointer;
352
+ }
353
+ .sugar-image-viewer__actions__divider {
354
+ display: inline-block;
355
+ width: 1px;
356
+ height: 18px;
357
+ margin: 0 10px;
358
+ background: hsla(0, 0%, 100%, 0.5);
359
+ vertical-align: middle;
360
+ }
361
+
362
+ .sugar-image-viewer__canvas {
363
+ width: 100%;
364
+ height: 100%;
365
+ display: flex;
366
+ justify-content: center;
367
+ align-items: center;
368
+ z-index: 0;
369
+ }
370
+
371
+ .sugar-image-viewer__img {
372
+ max-width: 100%;
373
+ max-height: 100%;
374
+ user-select: none;
375
+ pointer-events: auto;
376
+ cursor: grab;
377
+ transition: transform 0.3s;
378
+ }
379
+ .sugar-image-viewer__img:active {
380
+ cursor: grabbing;
381
+ }
382
+
383
+ .viewer-fade-enter-active {
384
+ animation: viewer-fade-in 0.3s;
385
+ }
386
+
387
+ .viewer-fade-leave-active {
388
+ animation: viewer-fade-out 0.3s;
389
+ }
390
+
391
+ @keyframes viewer-fade-in {
392
+ 0% {
393
+ opacity: 0;
394
+ }
395
+ 100% {
396
+ opacity: 1;
397
+ }
398
+ }
399
+ @keyframes viewer-fade-out {
400
+ 0% {
401
+ opacity: 1;
402
+ }
403
+ 100% {
404
+ opacity: 0;
405
+ }
406
+ }
407
+ </style>