cynx-lib 1.3.84 → 1.3.85

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 (40) hide show
  1. package/gen.js +77 -77
  2. package/package.json +5 -1
  3. package/ui/components/Drawer.jsx +208 -208
  4. package/ui/components/Pagination.jsx +145 -145
  5. package/ui/components/PrivacyBlur.jsx +603 -603
  6. package/utils/index.cjs +5 -0
  7. package/utils/index.js +22 -20
  8. package/utils/utils/duration.js +139 -139
  9. package/utils/utils/oidc.js +214 -214
  10. package/utils/utils/realtime.js +1634 -1634
  11. package/utils/utils/session.cjs +15 -2
  12. package/utils/utils/session.js +67 -58
  13. package/utils/utils/session_manager.cjs +490 -0
  14. package/utils/utils/session_manager.js +549 -0
  15. package/utils/utils/storage.js +393 -393
  16. package/utils/utils/ui.js +111 -111
  17. package/vue/components/Badge.vue +79 -79
  18. package/vue/components/Button.vue +209 -209
  19. package/vue/components/Checkbox.vue +103 -103
  20. package/vue/components/CircularProgress.vue +383 -383
  21. package/vue/components/Divider.vue +94 -94
  22. package/vue/components/Drawer.vue +243 -243
  23. package/vue/components/InfoBadge.vue +223 -223
  24. package/vue/components/Input.vue +341 -341
  25. package/vue/components/LinearProgress.vue +268 -268
  26. package/vue/components/Modal.vue +226 -226
  27. package/vue/components/Pagination.vue +199 -199
  28. package/vue/components/Select.vue +713 -713
  29. package/vue/components/Sidebar.vue +955 -955
  30. package/vue/components/Skeleton.vue +91 -91
  31. package/vue/components/Spinner.vue +263 -263
  32. package/vue/components/StatusTag.vue +89 -89
  33. package/vue/components/TabBar.vue +176 -176
  34. package/vue/components/Table.vue +388 -388
  35. package/vue/components/TimePicker.vue +399 -399
  36. package/vue/components/Toggle.vue +115 -115
  37. package/vue/components/XTable.vue +119 -119
  38. package/vue/composables/useAutoSkeletonRows.ts +71 -71
  39. package/vue/index.d.ts +67 -67
  40. package/vue/index.js +86 -86
@@ -1,268 +1,268 @@
1
- <script setup lang="ts">
2
- import { computed, ref, onMounted, onBeforeUnmount, watch } from "vue";
3
-
4
- const SIZES: Record<string, { height: number; fontSize: string }> = {
5
- xs: { height: 4, fontSize: ".68rem" },
6
- sm: { height: 5, fontSize: ".75rem" },
7
- md: { height: 6, fontSize: ".82rem" },
8
- lg: { height: 8, fontSize: ".9rem" },
9
- xl: { height: 10, fontSize: "1rem" },
10
- };
11
-
12
- interface Segment {
13
- value: number;
14
- color?: string;
15
- label?: string;
16
- }
17
-
18
- const props = withDefaults(
19
- defineProps<{
20
- value?: number;
21
- segments?: Segment[];
22
- size?: "xs" | "sm" | "md" | "lg" | "xl";
23
- customSize?: number;
24
- color?: string;
25
- trackColor?: string;
26
- label?: string;
27
- showPercent?: boolean;
28
- animated?: boolean;
29
- rounded?: boolean;
30
- indeterminate?: boolean;
31
- speed?: number;
32
- height?: number | string;
33
- gap?: number | string;
34
- labelGap?: number | string;
35
- className?: string;
36
- style?: Record<string, any>;
37
- }>(),
38
- {
39
- value: 0,
40
- size: "md",
41
- color: "var(--blue, #3b82f6)",
42
- trackColor: "var(--bd2, #e0e0e4)",
43
- label: "",
44
- showPercent: true,
45
- animated: true,
46
- rounded: true,
47
- indeterminate: false,
48
- speed: 1,
49
- gap: 5,
50
- labelGap: 2,
51
- className: "",
52
- style: () => ({}),
53
- }
54
- );
55
-
56
- const base = computed(() => SIZES[props.size] || SIZES.md);
57
- const barHeight = computed(() => {
58
- if (props.height != null) {
59
- return typeof props.height === "number" ? `${props.height}px` : props.height;
60
- }
61
- if (props.customSize != null) {
62
- return `${props.customSize}px`;
63
- }
64
- return `${base.value.height}px`;
65
- });
66
-
67
- const barHeightNum = computed(() => {
68
- if (typeof props.height === "number") return props.height;
69
- if (typeof props.height === "string" && props.height.endsWith("px")) {
70
- return parseFloat(props.height) || base.value.height;
71
- }
72
- if (props.customSize != null) return props.customSize;
73
- return base.value.height;
74
- });
75
-
76
- const fontSize = computed(() => {
77
- if (props.customSize) {
78
- return `${Math.max(11, props.customSize * 1.6)}px`;
79
- }
80
- return base.value.fontSize;
81
- });
82
-
83
- const pct = computed(() => Math.min(100, Math.max(0, props.value || 0)));
84
- const radius = computed(() => (props.rounded ? `${barHeightNum.value / 2}px` : "0px"));
85
- const transitionStyle = computed(() =>
86
- props.animated ? "flex .5s cubic-bezier(0.4,0,0.2,1)" : "none"
87
- );
88
-
89
- const hasSegments = computed(
90
- () => Array.isArray(props.segments) && props.segments.length > 0
91
- );
92
- const rawSum = computed(() =>
93
- hasSegments.value
94
- ? props.segments!.reduce((sum, s) => sum + (Number(s.value) || 0), 0)
95
- : 0
96
- );
97
-
98
- const gapStyle = computed(() =>
99
- typeof props.gap === "number" ? `${props.gap}px` : props.gap
100
- );
101
- const labelGapStyle = computed(() =>
102
- typeof props.labelGap === "number" ? `${props.labelGap}px` : props.labelGap
103
- );
104
-
105
- const barRef = ref<HTMLElement | null>(null);
106
- let raf: number | null = null;
107
-
108
- const startIndeterminate = () => {
109
- if (raf) cancelAnimationFrame(raf);
110
- if (!props.indeterminate || !barRef.value) return;
111
- let pos = -40;
112
- let direction = 1;
113
- let lastTime = performance.now();
114
-
115
- function tick(now: number) {
116
- const dt = (now - lastTime) / 16.67;
117
- lastTime = now;
118
- pos += direction * 1.2 * props.speed * dt;
119
- if (pos > 100) {
120
- pos = 100;
121
- direction = -1;
122
- }
123
- if (pos < -40) {
124
- pos = -40;
125
- direction = 1;
126
- }
127
- if (barRef.value) {
128
- barRef.value.style.left = pos + "%";
129
- barRef.value.style.width = "40%";
130
- }
131
- raf = requestAnimationFrame(tick);
132
- }
133
- raf = requestAnimationFrame(tick);
134
- };
135
-
136
- onMounted(() => {
137
- if (props.indeterminate) startIndeterminate();
138
- });
139
-
140
- watch(
141
- () => [props.indeterminate, props.speed],
142
- () => {
143
- if (props.indeterminate) {
144
- startIndeterminate();
145
- } else if (raf) {
146
- cancelAnimationFrame(raf);
147
- raf = null;
148
- }
149
- }
150
- );
151
-
152
- onBeforeUnmount(() => {
153
- if (raf) cancelAnimationFrame(raf);
154
- });
155
- </script>
156
-
157
- <template>
158
- <div
159
- :class="className"
160
- :style="{
161
- display: 'inline-flex',
162
- flexDirection: 'column',
163
- gap: labelGapStyle,
164
- width: '100%',
165
- ...style,
166
- }"
167
- >
168
- <div
169
- v-if="label || showPercent"
170
- style="display: flex; justify-content: space-between; align-items: baseline"
171
- >
172
- <span
173
- v-if="label"
174
- :style="{
175
- fontSize: fontSize,
176
- fontWeight: 600,
177
- color: 'var(--primary-text, #1a1a2e)',
178
- }"
179
- >
180
- {{ label }}
181
- </span>
182
- <span
183
- v-if="showPercent && !indeterminate && !hasSegments"
184
- :style="{
185
- fontSize: fontSize,
186
- fontWeight: 600,
187
- color: 'var(--muted, #9ca3af)',
188
- fontVariantNumeric: 'tabular-nums',
189
- marginLeft: label ? 0 : 'auto',
190
- }"
191
- >
192
- {{ Math.round(pct) }}%
193
- </span>
194
- </div>
195
-
196
- <div
197
- :style="{
198
- height: barHeight,
199
- borderRadius: radius,
200
- background: 'transparent',
201
- position: 'relative',
202
- display: 'flex',
203
- gap: gapStyle,
204
- overflow: 'hidden',
205
- }"
206
- >
207
- <template v-if="indeterminate">
208
- <div
209
- :style="{
210
- flex: 1,
211
- borderRadius: radius,
212
- background: trackColor,
213
- }"
214
- />
215
- <div
216
- ref="barRef"
217
- :style="{
218
- position: 'absolute',
219
- top: 0,
220
- height: '100%',
221
- width: '40%',
222
- borderRadius: radius,
223
- background: color,
224
- opacity: 0.85,
225
- }"
226
- />
227
- </template>
228
-
229
- <template v-else-if="hasSegments && rawSum > 0">
230
- <template v-for="(seg, idx) in segments" :key="idx">
231
- <div
232
- v-if="Number(seg.value) > 0"
233
- :title="seg.label ? `${seg.label}: ${seg.value}` : undefined"
234
- :style="{
235
- flex: (Number(seg.value) / rawSum) * 100,
236
- height: '100%',
237
- borderRadius: radius,
238
- background: seg.color || color,
239
- transition: transitionStyle,
240
- }"
241
- />
242
- </template>
243
- </template>
244
-
245
- <template v-else>
246
- <div
247
- ref="barRef"
248
- :style="{
249
- flex: pct > 0 ? pct : 0,
250
- minWidth: pct > 0 ? `${barHeightNum}px` : 0,
251
- borderRadius: radius,
252
- background: color,
253
- transition: transitionStyle,
254
- }"
255
- />
256
- <div
257
- v-if="pct < 100"
258
- :style="{
259
- flex: 100 - pct,
260
- borderRadius: radius,
261
- background: trackColor,
262
- transition: transitionStyle,
263
- }"
264
- />
265
- </template>
266
- </div>
267
- </div>
268
- </template>
1
+ <script setup lang="ts">
2
+ import { computed, ref, onMounted, onBeforeUnmount, watch } from "vue";
3
+
4
+ const SIZES: Record<string, { height: number; fontSize: string }> = {
5
+ xs: { height: 4, fontSize: ".68rem" },
6
+ sm: { height: 5, fontSize: ".75rem" },
7
+ md: { height: 6, fontSize: ".82rem" },
8
+ lg: { height: 8, fontSize: ".9rem" },
9
+ xl: { height: 10, fontSize: "1rem" },
10
+ };
11
+
12
+ interface Segment {
13
+ value: number;
14
+ color?: string;
15
+ label?: string;
16
+ }
17
+
18
+ const props = withDefaults(
19
+ defineProps<{
20
+ value?: number;
21
+ segments?: Segment[];
22
+ size?: "xs" | "sm" | "md" | "lg" | "xl";
23
+ customSize?: number;
24
+ color?: string;
25
+ trackColor?: string;
26
+ label?: string;
27
+ showPercent?: boolean;
28
+ animated?: boolean;
29
+ rounded?: boolean;
30
+ indeterminate?: boolean;
31
+ speed?: number;
32
+ height?: number | string;
33
+ gap?: number | string;
34
+ labelGap?: number | string;
35
+ className?: string;
36
+ style?: Record<string, any>;
37
+ }>(),
38
+ {
39
+ value: 0,
40
+ size: "md",
41
+ color: "var(--blue, #3b82f6)",
42
+ trackColor: "var(--bd2, #e0e0e4)",
43
+ label: "",
44
+ showPercent: true,
45
+ animated: true,
46
+ rounded: true,
47
+ indeterminate: false,
48
+ speed: 1,
49
+ gap: 5,
50
+ labelGap: 2,
51
+ className: "",
52
+ style: () => ({}),
53
+ }
54
+ );
55
+
56
+ const base = computed(() => SIZES[props.size] || SIZES.md);
57
+ const barHeight = computed(() => {
58
+ if (props.height != null) {
59
+ return typeof props.height === "number" ? `${props.height}px` : props.height;
60
+ }
61
+ if (props.customSize != null) {
62
+ return `${props.customSize}px`;
63
+ }
64
+ return `${base.value.height}px`;
65
+ });
66
+
67
+ const barHeightNum = computed(() => {
68
+ if (typeof props.height === "number") return props.height;
69
+ if (typeof props.height === "string" && props.height.endsWith("px")) {
70
+ return parseFloat(props.height) || base.value.height;
71
+ }
72
+ if (props.customSize != null) return props.customSize;
73
+ return base.value.height;
74
+ });
75
+
76
+ const fontSize = computed(() => {
77
+ if (props.customSize) {
78
+ return `${Math.max(11, props.customSize * 1.6)}px`;
79
+ }
80
+ return base.value.fontSize;
81
+ });
82
+
83
+ const pct = computed(() => Math.min(100, Math.max(0, props.value || 0)));
84
+ const radius = computed(() => (props.rounded ? `${barHeightNum.value / 2}px` : "0px"));
85
+ const transitionStyle = computed(() =>
86
+ props.animated ? "flex .5s cubic-bezier(0.4,0,0.2,1)" : "none"
87
+ );
88
+
89
+ const hasSegments = computed(
90
+ () => Array.isArray(props.segments) && props.segments.length > 0
91
+ );
92
+ const rawSum = computed(() =>
93
+ hasSegments.value
94
+ ? props.segments!.reduce((sum, s) => sum + (Number(s.value) || 0), 0)
95
+ : 0
96
+ );
97
+
98
+ const gapStyle = computed(() =>
99
+ typeof props.gap === "number" ? `${props.gap}px` : props.gap
100
+ );
101
+ const labelGapStyle = computed(() =>
102
+ typeof props.labelGap === "number" ? `${props.labelGap}px` : props.labelGap
103
+ );
104
+
105
+ const barRef = ref<HTMLElement | null>(null);
106
+ let raf: number | null = null;
107
+
108
+ const startIndeterminate = () => {
109
+ if (raf) cancelAnimationFrame(raf);
110
+ if (!props.indeterminate || !barRef.value) return;
111
+ let pos = -40;
112
+ let direction = 1;
113
+ let lastTime = performance.now();
114
+
115
+ function tick(now: number) {
116
+ const dt = (now - lastTime) / 16.67;
117
+ lastTime = now;
118
+ pos += direction * 1.2 * props.speed * dt;
119
+ if (pos > 100) {
120
+ pos = 100;
121
+ direction = -1;
122
+ }
123
+ if (pos < -40) {
124
+ pos = -40;
125
+ direction = 1;
126
+ }
127
+ if (barRef.value) {
128
+ barRef.value.style.left = pos + "%";
129
+ barRef.value.style.width = "40%";
130
+ }
131
+ raf = requestAnimationFrame(tick);
132
+ }
133
+ raf = requestAnimationFrame(tick);
134
+ };
135
+
136
+ onMounted(() => {
137
+ if (props.indeterminate) startIndeterminate();
138
+ });
139
+
140
+ watch(
141
+ () => [props.indeterminate, props.speed],
142
+ () => {
143
+ if (props.indeterminate) {
144
+ startIndeterminate();
145
+ } else if (raf) {
146
+ cancelAnimationFrame(raf);
147
+ raf = null;
148
+ }
149
+ }
150
+ );
151
+
152
+ onBeforeUnmount(() => {
153
+ if (raf) cancelAnimationFrame(raf);
154
+ });
155
+ </script>
156
+
157
+ <template>
158
+ <div
159
+ :class="className"
160
+ :style="{
161
+ display: 'inline-flex',
162
+ flexDirection: 'column',
163
+ gap: labelGapStyle,
164
+ width: '100%',
165
+ ...style,
166
+ }"
167
+ >
168
+ <div
169
+ v-if="label || showPercent"
170
+ style="display: flex; justify-content: space-between; align-items: baseline"
171
+ >
172
+ <span
173
+ v-if="label"
174
+ :style="{
175
+ fontSize: fontSize,
176
+ fontWeight: 600,
177
+ color: 'var(--primary-text, #1a1a2e)',
178
+ }"
179
+ >
180
+ {{ label }}
181
+ </span>
182
+ <span
183
+ v-if="showPercent && !indeterminate && !hasSegments"
184
+ :style="{
185
+ fontSize: fontSize,
186
+ fontWeight: 600,
187
+ color: 'var(--muted, #9ca3af)',
188
+ fontVariantNumeric: 'tabular-nums',
189
+ marginLeft: label ? 0 : 'auto',
190
+ }"
191
+ >
192
+ {{ Math.round(pct) }}%
193
+ </span>
194
+ </div>
195
+
196
+ <div
197
+ :style="{
198
+ height: barHeight,
199
+ borderRadius: radius,
200
+ background: 'transparent',
201
+ position: 'relative',
202
+ display: 'flex',
203
+ gap: gapStyle,
204
+ overflow: 'hidden',
205
+ }"
206
+ >
207
+ <template v-if="indeterminate">
208
+ <div
209
+ :style="{
210
+ flex: 1,
211
+ borderRadius: radius,
212
+ background: trackColor,
213
+ }"
214
+ />
215
+ <div
216
+ ref="barRef"
217
+ :style="{
218
+ position: 'absolute',
219
+ top: 0,
220
+ height: '100%',
221
+ width: '40%',
222
+ borderRadius: radius,
223
+ background: color,
224
+ opacity: 0.85,
225
+ }"
226
+ />
227
+ </template>
228
+
229
+ <template v-else-if="hasSegments && rawSum > 0">
230
+ <template v-for="(seg, idx) in segments" :key="idx">
231
+ <div
232
+ v-if="Number(seg.value) > 0"
233
+ :title="seg.label ? `${seg.label}: ${seg.value}` : undefined"
234
+ :style="{
235
+ flex: (Number(seg.value) / rawSum) * 100,
236
+ height: '100%',
237
+ borderRadius: radius,
238
+ background: seg.color || color,
239
+ transition: transitionStyle,
240
+ }"
241
+ />
242
+ </template>
243
+ </template>
244
+
245
+ <template v-else>
246
+ <div
247
+ ref="barRef"
248
+ :style="{
249
+ flex: pct > 0 ? pct : 0,
250
+ minWidth: pct > 0 ? `${barHeightNum}px` : 0,
251
+ borderRadius: radius,
252
+ background: color,
253
+ transition: transitionStyle,
254
+ }"
255
+ />
256
+ <div
257
+ v-if="pct < 100"
258
+ :style="{
259
+ flex: 100 - pct,
260
+ borderRadius: radius,
261
+ background: trackColor,
262
+ transition: transitionStyle,
263
+ }"
264
+ />
265
+ </template>
266
+ </div>
267
+ </div>
268
+ </template>