renusify 2.4.3 → 2.5.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.
@@ -12,7 +12,7 @@
12
12
  width: 40px;
13
13
  height: 40px;
14
14
  position: absolute;
15
- transition: 2s all map.get(base.$transition, 'swing');
15
+ transition: 0.5s all map.get(base.$transition, 'swing');
16
16
  @include mixins.rtl() {
17
17
  right: -40px;
18
18
  }
@@ -25,7 +25,9 @@
25
25
  height: 100%;
26
26
  overflow: auto;
27
27
  position: absolute;
28
- transition: .5s all map.get(base.$transition, 'swing');
28
+ transition: .3s all map.get(base.$transition, 'swing');
29
+ background-color: var(--color-sheet);
30
+ color: var(--color-on-sheet);
29
31
  @include mixins.rtl() {
30
32
  right: -300px;
31
33
  }
@@ -40,7 +42,7 @@
40
42
  height: 100vh;
41
43
  z-index: map.get(base.$z-index, 'important');
42
44
  background-color: var(--color-overlay);
43
- transition: 1s width map.get(base.$transition, 'swing');
45
+ transition: .1s width map.get(base.$transition, 'swing');
44
46
  overflow: hidden;
45
47
  @include mixins.rtl() {
46
48
  right: 0;
@@ -54,7 +56,7 @@
54
56
  width: 100vw;
55
57
  }
56
58
  .toolbar-side {
57
- transition: 2s all map.get(base.$transition, 'swing');
59
+ transition: 0.3s all map.get(base.$transition, 'swing');
58
60
  @include mixins.rtl() {
59
61
  right: 0;
60
62
  }
@@ -94,7 +96,6 @@
94
96
  &:before {
95
97
  content: '-';
96
98
  position: absolute;
97
- color: #9e9e9e;
98
99
  @include mixins.rtl() {
99
100
  right: -8px;
100
101
  }
@@ -105,15 +106,15 @@
105
106
  }
106
107
 
107
108
  .menu-list {
108
- transition: 1s map.get(base.$transition, 'swing');
109
+ transition: 0.3s map.get(base.$transition, 'swing');
109
110
  min-width: 200px;
110
111
  max-height: 500px;
111
112
  overflow-y: auto;
112
113
  @include mixins.rtl() {
113
- border-right: 1px solid #9e9e9e;
114
+ border-right: 1px solid;
114
115
  }
115
116
  @include mixins.ltr() {
116
- border-left: 1px solid #9e9e9e;
117
+ border-left: 1px solid;
117
118
  }
118
119
  }
119
120
 
@@ -128,7 +129,7 @@
128
129
  position: relative;
129
130
 
130
131
  .toolbar-childs {
131
- transition: 1s map.get(base.$transition, 'swing');
132
+ transition: 0.3s map.get(base.$transition, 'swing');
132
133
  position: absolute;
133
134
  top: 40px;
134
135
  max-height: 0;
@@ -3,34 +3,59 @@
3
3
  </template>
4
4
 
5
5
  <script>
6
-
7
6
  export default {
8
- name: "r-chart",
7
+ name: 'r-chart',
9
8
  props: {
9
+ url: {type: String, default: 'https://codenus.com/storage/chart/apexcharts.js'},
10
+ dark: Boolean,
10
11
  options: Object
11
12
  },
12
13
  data() {
13
14
  return {
14
15
  chartShape: null,
15
- Chart: null
16
- };
16
+ timeout_id: null
17
+ }
17
18
  },
18
- mounted(){
19
- import('./apexcharts.js').then((d) => {
20
- this.Chart=d.default;
19
+ mounted() {
20
+ let children = document.querySelectorAll('[name=\'apexcharts\']')
21
+ if (children.length === 0) {
22
+ let el = document.createElement('script')
23
+ el.setAttribute('src', this.url)
24
+ el.setAttribute('name', 'apexcharts')
25
+ document.head.append(el)
26
+ }
27
+ if (this.dark) {
28
+ if (!this.options['theme']) {
29
+ this.options['theme'] = {}
30
+ }
31
+ this.options['theme']['mode'] = 'dark'
32
+ }
33
+
34
+ this.timeout_id = setTimeout(() => {
21
35
  this.build()
22
- })
36
+ }, 10)
37
+
23
38
  },
24
39
  methods: {
25
- build() {
26
- this.chartShape = new this.Chart(this.$refs.chart, this.options);
27
- this.chartShape.render()
40
+ build(n = 0) {
41
+ try {
42
+ this.chartShape = new ApexCharts(this.$refs.chart, this.options)
43
+ this.chartShape.render()
44
+ } catch (e) {
45
+ this.timeout_id = setTimeout(() => {
46
+ this.build(n + 1)
47
+ }, 100)
48
+ if (n > 30) {
49
+ console.error(e)
50
+ }
51
+ }
28
52
  }
29
53
  },
30
54
  beforeUnmount() {
31
- this.chartShape.destroy();
55
+ clearTimeout(this.timeout_id)
56
+ this.chartShape.destroy()
32
57
  }
33
- };
58
+ }
34
59
  </script>
35
60
  <style lang="scss">
36
61
  @use "../../style/variables/base";
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <r-input v-bind="$attrs" :readonly="readonly" :model-value="modelValue" @click.prevent="show=true">
3
- <input
4
- :value="modelValue?$d(modelValueDate,withTime?'long':'medium',locale):null"
5
- />
3
+ <div :class="`${$r.prefix}date-color-input`">
4
+ {{ modelValue ? $d(modelValueDate, withTime ? 'long' : 'medium', locale) : null }}
5
+ </div>
6
6
  </r-input>
7
7
  <r-modal :model-value="show" @update:model-value="close()" :closebtn="false" closable class="text-center">
8
8
  <div v-if="!showTime" :class="`${$r.prefix}date-input`">
@@ -364,6 +364,9 @@ export default {
364
364
  <style lang="scss">
365
365
  @use "../../../style/variables/base";
366
366
 
367
+ .#{base.$prefix}date-color-input {
368
+ color: var(--color-on-sheet);
369
+ }
367
370
  .#{base.$prefix}date-input {
368
371
  position: relative;
369
372
  display: inline-block;
@@ -51,23 +51,12 @@ export default {
51
51
  },
52
52
  watch: {
53
53
  'modelValue': function (newVal) {
54
- this.number = newVal
54
+ if (newVal !== undefined) {
55
+ this.number = newVal
56
+ }
55
57
  }
56
58
  },
57
59
  methods: {
58
- setSplit(n) {
59
- if (n && this.split > 0) {
60
- const x = this.split
61
- n = n.toString()
62
- const step = n.indexOf('.')
63
- const re = '\\d(?=(\\d{' + (x) + '})+' + (step > -1 ? '\\.' : '$') + ')';
64
- return n.replace(new RegExp(re, 'g'), '$&,');
65
- }
66
- return n
67
- },
68
- set_step(number) {
69
-
70
- },
71
60
  emit() {
72
61
  if (this.number === '' || this.number === null) {
73
62
  this.number = undefined
@@ -79,7 +68,8 @@ export default {
79
68
  d = this.max
80
69
  }
81
70
  if (this.min !== undefined && d < this.min) {
82
- d = this.min
71
+ this.$emit('update:modelValue', undefined)
72
+ return
83
73
  }
84
74
 
85
75
  this.number = d
@@ -95,7 +85,7 @@ export default {
95
85
  this.number = n - this.step
96
86
  this.emit()
97
87
  }
98
- },
88
+ }
99
89
  }
100
90
  </script>
101
91
 
@@ -15,7 +15,7 @@
15
15
  @focusin="active=true"
16
16
  @focusout="active=false"
17
17
  @input="emit"
18
- autocomplete="no"
18
+ :autocomplete="autocomplete"
19
19
  ref="input"
20
20
  v-model="lazyValue"
21
21
  />
@@ -61,6 +61,7 @@ export default {
61
61
  specialChar: Boolean,
62
62
  number: Boolean,
63
63
  minLength: {type: Number, default: 8},
64
+ autocomplete: {type: String, default: "no"},
64
65
  },
65
66
  emits: ['update:modelValue'],
66
67
  data() {
@@ -85,7 +85,7 @@ emits:['update:modelValue','change'],
85
85
  width: 100%;
86
86
  height: 100%;
87
87
  border-radius: 10px;
88
- background-color: var(--color-sheet-container);
88
+ background-color: var(--color-border);
89
89
  }
90
90
 
91
91
  .switch-dot {
@@ -1,18 +1,13 @@
1
1
  <template>
2
2
  <div v-intersect.[modifier]="check" :class="{
3
3
  [$r.prefix+'img']:true,
4
- 'img-hoverZoom':hoverZoom,'img-hoverDark':hoverDark,'img-hoverTitle':hoverTitle}"
4
+ 'img-hoverZoom':hoverZoom,'img-hoverDark':hoverDark,'img-hover-preview':preview}"
5
5
  ref="rImg">
6
- <div v-if="hoverTitle" class="title-3 color-white-text img-title w-full pa-1"
7
- :class="{
8
- 'title-hs':titleHs,
9
- 'title-hc':titleHc,
10
- 'title-he':titleHe,
11
- 'title-vs':titleVs,
12
- 'title-vc':titleVc,
13
- 'title-ve':titleVe
14
- }"
15
- >{{ alt }}
6
+ <div v-if="preview" class="img-preview w-full h-full d-flex v-center h-center"
7
+ >
8
+ <r-btn icon @click="show_preview=true">
9
+ <r-icon v-html="$r.icons.eye"></r-icon>
10
+ </r-btn>
16
11
  </div>
17
12
  <img v-if="load &&!isSvg" ref="img" :alt="alt" :height="size.height>0?size.height:'auto'" :src="link" :style="{'height':size.height>0?undefined:'auto',
18
13
  'width':size.width>0?undefined:'auto'
@@ -21,6 +16,9 @@
21
16
  draggable="false"/>
22
17
  <svg-img v-else-if="load &&isSvg&&link" :link="link" :size="size">
23
18
  </svg-img>
19
+ <teleport v-if="preview&&show_preview" :to="`.${$r.prefix}app`">
20
+ <preview-img :src="preview" @close="show_preview=false"></preview-img>
21
+ </teleport>
24
22
  </div>
25
23
  </template>
26
24
  <script>
@@ -28,12 +26,16 @@ import {defineAsyncComponent} from 'vue'
28
26
 
29
27
  export default {
30
28
  name: 'r-img',
31
- components: {SvgImg:defineAsyncComponent(()=>import('./svgImg.vue'))},
29
+ components: {
30
+ SvgImg: defineAsyncComponent(() => import('./svgImg.vue')),
31
+ previewImg: defineAsyncComponent(() => import('./preview.vue')),
32
+ },
32
33
  props: {
33
34
  src: {
34
35
  type: String,
35
36
  required: true
36
37
  },
38
+ preview: String,
37
39
  alt: {
38
40
  type: String,
39
41
  required: true
@@ -55,19 +57,13 @@ export default {
55
57
  autoSize: Boolean,
56
58
  hoverZoom: Boolean,
57
59
  hoverDark: Boolean,
58
- hoverTitle: Boolean,
59
- titleHs: Boolean,
60
- titleHc: Boolean,
61
- titleHe: Boolean,
62
- titleVs: Boolean,
63
- titleVc: Boolean,
64
- titleVe: Boolean,
65
60
  isSvg: Boolean,
66
61
  svgCache: {type: Number, default: 86400},
67
62
  wPH: Number
68
63
  },
69
64
  data() {
70
65
  return {
66
+ show_preview: false,
71
67
  load: false,
72
68
  view: false,
73
69
  modifier: this.lazy !== 'no' ? 'once' : 'pre',
@@ -180,6 +176,7 @@ export default {
180
176
  }
181
177
  </script>
182
178
  <style lang="scss">
179
+ @use "sass:map";
183
180
  @use "../../style/variables/base";
184
181
 
185
182
  .#{base.$prefix}img {
@@ -211,44 +208,65 @@ export default {
211
208
  }
212
209
  }
213
210
 
214
- &.img-hoverTitle {
211
+ &.img-hover-preview {
215
212
  &:hover {
216
- .img-title {
213
+ .img-preview {
214
+ background: rgba(0, 0, 0, 0.5);
217
215
  max-width: 100%;
218
216
  }
219
217
  }
220
218
  }
221
219
 
222
- .img-title {
220
+ .img-preview {
221
+ transition: 0.1s all ease;
223
222
  position: absolute;
224
223
  z-index: 1;
224
+ top: 0;
225
+ left: 0;
225
226
  max-width: 0;
226
227
  overflow: hidden;
228
+ }
229
+ }
227
230
 
228
- &.title-hs {
229
- text-align: start;
230
- }
231
-
232
- &.title-hc {
233
- text-align: center;
234
- }
235
-
236
- &.title-he {
237
- text-align: end;
238
- }
231
+ .#{base.$prefix}img-preview-container {
232
+ width: 100vw;
233
+ height: 100vh;
234
+ overflow: hidden;
235
+ position: fixed;
236
+ touch-action: none;
237
+ background: var(--color-overlay);
238
+ backdrop-filter: blur(3px) grayscale(30%);
239
+ z-index: map.get(base.$z-index, 'important');
240
+ top: 0;
241
+ left: 0;
239
242
 
240
- &.title-vs {
241
- top: 10px
242
- }
243
+ .image-wrapper {
244
+ position: absolute;
245
+ will-change: transform;
246
+ }
243
247
 
244
- &.title-vc {
245
- top: 50%
246
- }
248
+ .image-wrapper img {
249
+ display: block;
250
+ }
247
251
 
248
- &.title-ve {
249
- bottom: 10px
250
- }
252
+ .controls {
253
+ position: absolute;
254
+ bottom: 10px;
255
+ left: 50%;
256
+ transform: translateX(-50%);
257
+ background: rgba(0, 0, 0, 0.5);
258
+ color: white;
259
+ padding: 5px 10px;
260
+ border-radius: 5px;
261
+ display: flex;
262
+ gap: 10px;
263
+ align-items: center;
264
+ z-index: 2;
265
+ }
251
266
 
267
+ .controls button {
268
+ padding: 2px 8px;
269
+ cursor: pointer;
252
270
  }
253
271
  }
254
272
  </style>
@@ -0,0 +1,237 @@
1
+ <template>
2
+ <div ref="container"
3
+ :class="{ [$r.prefix+'img-preview-container']:true}">
4
+ <div
5
+ :style="wrapperStyle"
6
+ class="image-wrapper"
7
+ @mousedown="startDrag"
8
+ @touchstart="startDrag"
9
+ @wheel.prevent="handleWheel"
10
+ >
11
+ <span :style="imageHolderStyle">
12
+ <img
13
+ :src="src"
14
+ :style="imageStyle"
15
+ alt="Preview image"
16
+ @load="handleImageLoad"
17
+ >
18
+ </span>
19
+ </div>
20
+
21
+ <div v-if="showControls" class="controls">
22
+ <button @click="zoomIn">
23
+ <r-icon v-html="$r.icons.plus"></r-icon>
24
+ </button>
25
+ <button @click="zoomOut">
26
+ <r-icon v-html="$r.icons.minus"></r-icon>
27
+ </button>
28
+ <button class="font-weight-bold" @click="rotate">↻</button>
29
+ <button @click="reset">R</button>
30
+ <button @click="$emit('close',true)">
31
+ <r-icon v-html="$r.icons.close"></r-icon>
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </template>
36
+
37
+ <script>
38
+ import {computed, onBeforeUnmount, onMounted, ref} from 'vue';
39
+
40
+ export default {
41
+ props: {
42
+ src: {
43
+ type: String,
44
+ required: true
45
+ },
46
+ maxScale: {
47
+ type: Number,
48
+ default: 5
49
+ },
50
+ minScale: {
51
+ type: Number,
52
+ default: 0.1
53
+ },
54
+ showControls: {
55
+ type: Boolean,
56
+ default: true
57
+ }
58
+ },
59
+
60
+ setup(props) {
61
+ const container = ref(null);
62
+ const scale = ref(1);
63
+ const rotation = ref(0);
64
+ const position = ref({x: 0, y: 0});
65
+ const isDragging = ref(false);
66
+ const dragStart = ref({x: 0, y: 0});
67
+ const naturalSize = ref({width: 0, height: 0});
68
+ const containerSize = ref({width: 0, height: 0});
69
+
70
+ const wrapperStyle = computed(() => ({
71
+ transform: `translate(${position.value.x}px, ${position.value.y}px)`,
72
+ cursor: isDragging.value ? 'grabbing' : 'grab'
73
+ }));
74
+
75
+ const imageStyle = computed(() => ({
76
+ transform: `scale(${scale.value})`,
77
+ transformOrigin: '0 0',
78
+ width: naturalSize.value.width ? `${naturalSize.value.width}px` : 'auto',
79
+ height: naturalSize.value.height ? `${naturalSize.value.height}px` : 'auto',
80
+ display: 'block'
81
+ }));
82
+ const imageHolderStyle = computed(() => ({
83
+ transform: `rotate(${rotation.value}deg)`,
84
+ transformOrigin: 'center center',
85
+ width: naturalSize.value.width ? `${naturalSize.value.width * scale.value}px` : 'auto',
86
+ height: naturalSize.value.height ? `${naturalSize.value.height * scale.value}px` : 'auto',
87
+ display: 'block'
88
+ }));
89
+
90
+ const handleImageLoad = (event) => {
91
+ naturalSize.value = {
92
+ width: event.target.naturalWidth,
93
+ height: event.target.naturalHeight
94
+ };
95
+ updateContainerSize();
96
+ centerImage();
97
+ };
98
+
99
+ const updateContainerSize = () => {
100
+ if (container.value) {
101
+ containerSize.value = {
102
+ width: container.value.clientWidth,
103
+ height: container.value.clientHeight
104
+ };
105
+ }
106
+ };
107
+
108
+ const centerImage = () => {
109
+ if (!container.value || !naturalSize.value.width) return;
110
+
111
+ const widthRatio = containerSize.value.width / naturalSize.value.width;
112
+ const heightRatio = containerSize.value.height / naturalSize.value.height;
113
+ const initialScale = Math.min(widthRatio, heightRatio, 1); // Don't scale up initially
114
+
115
+ scale.value = initialScale;
116
+ rotation.value = 0;
117
+
118
+ position.value = {
119
+ x: (containerSize.value.width - naturalSize.value.width * scale.value) / 2,
120
+ y: (containerSize.value.height - naturalSize.value.height * scale.value) / 2
121
+ };
122
+ };
123
+
124
+ const rotate = () => {
125
+ if (!container.value) return;
126
+ rotation.value = (rotation.value + 22.5) % 360;
127
+ };
128
+
129
+ const zoom = (factor, clientX, clientY) => {
130
+ if (!container.value) return;
131
+
132
+ const oldScale = scale.value;
133
+ scale.value = Math.min(
134
+ Math.max(scale.value * factor, props.minScale),
135
+ props.maxScale
136
+ );
137
+
138
+ const rect = container.value.getBoundingClientRect();
139
+ const containerX = clientX - rect.left;
140
+ const containerY = clientY - rect.top;
141
+
142
+ const imageX = (containerX - position.value.x) / oldScale;
143
+ const imageY = (containerY - position.value.y) / oldScale;
144
+
145
+ position.value.x = containerX - imageX * scale.value;
146
+ position.value.y = containerY - imageY * scale.value;
147
+ };
148
+
149
+ const zoomIn = () => {
150
+ if (!container.value) return;
151
+ const rect = container.value.getBoundingClientRect();
152
+ zoom(1.2, rect.left + rect.width / 2, rect.top + rect.height / 2);
153
+ };
154
+
155
+ const zoomOut = () => {
156
+ if (!container.value) return;
157
+ const rect = container.value.getBoundingClientRect();
158
+ zoom(0.8, rect.left + rect.width / 2, rect.top + rect.height / 2);
159
+ };
160
+
161
+ const reset = () => {
162
+ centerImage();
163
+ };
164
+
165
+ const startDrag = (e) => {
166
+ if (isDragging.value) return
167
+ isDragging.value = true;
168
+ const clientX = e.clientX || e.touches[0].clientX;
169
+ const clientY = e.clientY || e.touches[0].clientY;
170
+
171
+ dragStart.value = {
172
+ x: clientX - position.value.x,
173
+ y: clientY - position.value.y
174
+ };
175
+
176
+ e.preventDefault();
177
+ };
178
+
179
+ const handleDrag = (e) => {
180
+ if (!isDragging.value) return;
181
+
182
+ const clientX = e.clientX || (e.touches && e.touches[0].clientX);
183
+ const clientY = e.clientY || (e.touches && e.touches[0].clientY);
184
+
185
+ if (clientX === undefined || clientY === undefined) return;
186
+
187
+ position.value = {
188
+ x: clientX - dragStart.value.x,
189
+ y: clientY - dragStart.value.y
190
+ };
191
+ e.preventDefault();
192
+ };
193
+
194
+ const endDrag = () => {
195
+ isDragging.value = false;
196
+ };
197
+
198
+ const handleWheel = (e) => {
199
+ const factor = e.deltaY < 0 ? 1.1 : 0.9;
200
+ zoom(factor, e.clientX, e.clientY);
201
+ };
202
+
203
+ onMounted(() => {
204
+ window.addEventListener('mousemove', handleDrag);
205
+ window.addEventListener('mouseup', endDrag);
206
+ window.addEventListener('touchmove', handleDrag, {passive: false});
207
+ window.addEventListener('touchend', endDrag);
208
+ window.addEventListener('resize', updateContainerSize);
209
+ });
210
+
211
+ onBeforeUnmount(() => {
212
+ window.removeEventListener('mousemove', handleDrag);
213
+ window.removeEventListener('mouseup', endDrag);
214
+ window.removeEventListener('touchmove', handleDrag);
215
+ window.removeEventListener('touchend', endDrag);
216
+ window.removeEventListener('resize', updateContainerSize);
217
+ });
218
+
219
+ return {
220
+ container,
221
+ scale,
222
+ rotation,
223
+ position,
224
+ wrapperStyle,
225
+ imageStyle,
226
+ imageHolderStyle,
227
+ handleImageLoad,
228
+ startDrag,
229
+ handleWheel,
230
+ zoomIn,
231
+ zoomOut,
232
+ reset,
233
+ rotate
234
+ };
235
+ }
236
+ };
237
+ </script>