@mptw/skylens-ui 1.4.109 → 1.5.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 (130) hide show
  1. package/AGENTS.md +59 -0
  2. package/CLAUDE.md +36 -0
  3. package/README.md +7 -7
  4. package/app/app.config.ts +14 -0
  5. package/app/app.vue +5 -0
  6. package/app/assets/css/layout.css +134 -0
  7. package/app/assets/css/main.css +189 -0
  8. package/{components → app/components}/SLAlertModal.vue +24 -16
  9. package/{components → app/components}/SLBreadcrumbs.vue +12 -8
  10. package/app/components/SLButton.vue +370 -0
  11. package/{components → app/components}/SLCalendarButton.vue +40 -34
  12. package/{components → app/components}/SLCalendarPopup.vue +79 -53
  13. package/{components → app/components}/SLCard.vue +57 -41
  14. package/{components → app/components}/SLChart.vue +6 -3
  15. package/{components → app/components}/SLCheckbox.vue +92 -49
  16. package/{components → app/components}/SLCircleButton.vue +25 -16
  17. package/{components → app/components}/SLCollapsableBlock.vue +44 -33
  18. package/{components → app/components}/SLCollapsableMulitPillSelect.vue +20 -15
  19. package/{components → app/components}/SLConfirmModal.vue +9 -6
  20. package/{components → app/components}/SLContextMenu.vue +88 -48
  21. package/{components → app/components}/SLDateInput.vue +109 -92
  22. package/{components → app/components}/SLDatePicker.vue +9 -7
  23. package/{components → app/components}/SLDistributor.vue +1 -1
  24. package/{components → app/components}/SLDownloadButton.vue +39 -29
  25. package/{components → app/components}/SLDraggable.vue +2 -2
  26. package/{components → app/components}/SLDropdown.vue +33 -25
  27. package/{components → app/components}/SLDropdownItem.vue +9 -5
  28. package/{components → app/components}/SLElementWithTitle.vue +12 -7
  29. package/{components → app/components}/SLEyeCheckbox.vue +44 -31
  30. package/{components → app/components}/SLFileInput.vue +23 -16
  31. package/{components → app/components}/SLGenderAgeSelect.vue +52 -36
  32. package/{components → app/components}/SLHourRangeInput.vue +45 -32
  33. package/{components → app/components}/SLIOSSwitch.vue +81 -60
  34. package/{components → app/components}/SLIcon.vue +4 -3
  35. package/{components → app/components}/SLIconButton.vue +31 -29
  36. package/{components → app/components}/SLInfoTip.vue +51 -40
  37. package/{components → app/components}/SLInsightSitePage.vue +12 -7
  38. package/{components → app/components}/SLLegend.vue +19 -12
  39. package/app/components/SLLinearProgressBar.vue +22 -0
  40. package/{components → app/components}/SLLink.vue +12 -8
  41. package/{components → app/components}/SLLoading.vue +34 -31
  42. package/{components → app/components}/SLMapChart.vue +5 -4
  43. package/{components → app/components}/SLModal.vue +90 -66
  44. package/{components → app/components}/SLMonthCalendarButton.vue +91 -45
  45. package/{components → app/components}/SLMonthPicker.vue +42 -37
  46. package/{components → app/components}/SLMultiEmailInput.vue +163 -113
  47. package/{components → app/components}/SLMultiSelect.vue +37 -26
  48. package/{components → app/components}/SLNoData.vue +16 -11
  49. package/app/components/SLNotification.vue +155 -0
  50. package/{components → app/components}/SLPageModal.vue +14 -9
  51. package/{components → app/components}/SLPagination.vue +45 -33
  52. package/{components → app/components}/SLPillCheckbox.vue +50 -42
  53. package/{components → app/components}/SLPillLabel.vue +43 -28
  54. package/{components → app/components}/SLPopupMenuButton.vue +26 -17
  55. package/{components → app/components}/SLProfileButton.vue +28 -20
  56. package/{components → app/components}/SLProjectShareItem.vue +30 -17
  57. package/{components → app/components}/SLRadioButton.vue +41 -33
  58. package/{components → app/components}/SLRadioButtonGroup.vue +28 -23
  59. package/app/components/SLRadioGroup.vue +221 -0
  60. package/{components → app/components}/SLRangeInput.vue +53 -38
  61. package/{components → app/components}/SLRegionsMapChart.vue +5 -4
  62. package/{components → app/components}/SLRightSider.vue +50 -40
  63. package/{components → app/components}/SLSearchInput.vue +24 -19
  64. package/{components → app/components}/SLSelect.vue +114 -87
  65. package/{components → app/components}/SLSelectAllToggle.vue +52 -37
  66. package/app/components/SLSidebarNav.vue +487 -0
  67. package/{components → app/components}/SLSidebarNavGroupItem.vue +13 -10
  68. package/{components → app/components}/SLSidebarNavGroupItemSection.vue +240 -179
  69. package/{components → app/components}/SLSidebarNavLinkItem.vue +131 -109
  70. package/{components → app/components}/SLSidebarNavSectionItem.vue +21 -18
  71. package/{components → app/components}/SLSitePage.vue +35 -24
  72. package/{components → app/components}/SLSkyInsightSitePage.vue +13 -8
  73. package/{components → app/components}/SLSortByDropdown.vue +35 -22
  74. package/{components → app/components}/SLSpinIcon.vue +6 -3
  75. package/{components → app/components}/SLStayRangeInput.vue +47 -36
  76. package/{components → app/components}/SLTab.vue +7 -2
  77. package/app/components/SLTable.vue +472 -0
  78. package/{components → app/components}/SLTableTooltip.vue +44 -30
  79. package/app/components/SLTabs.vue +528 -0
  80. package/{components → app/components}/SLTextInput.vue +162 -134
  81. package/{components → app/components}/SLTextarea.vue +40 -29
  82. package/{components → app/components}/SLToast.vue +19 -11
  83. package/{components → app/components}/SLToggleButton.vue +18 -11
  84. package/{components → app/components}/SLTwoLayerMultiSelect.vue +180 -85
  85. package/{components → app/components}/SLTwoLayerSelect.vue +47 -37
  86. package/{components → app/components}/SLTwoLayerSingleSelect.vue +52 -33
  87. package/{components → app/components}/SLWarnModal.vue +9 -7
  88. package/app/interface/commons.ts +7 -0
  89. package/{utils → app/utils}/index.ts +213 -146
  90. package/eslint.config.js +3 -0
  91. package/nuxt.config.ts +17 -14
  92. package/package.json +10 -9
  93. package/skills-lock.json +59 -0
  94. package/tsconfig.json +1 -6
  95. package/.eslintrc.cjs +0 -4
  96. package/app.config.ts +0 -5
  97. package/assets/css/layout.styl +0 -98
  98. package/assets/css/tailwind.css +0 -3
  99. package/components/SLButton.vue +0 -337
  100. package/components/SLLinearProgressBar.vue +0 -35
  101. package/components/SLNotification.vue +0 -151
  102. package/components/SLRadioGroup.vue +0 -209
  103. package/components/SLSidebarNav.vue +0 -427
  104. package/components/SLTable.vue +0 -455
  105. package/components/SLTabs.vue +0 -475
  106. package/interface/commons.ts +0 -7
  107. package/pages/index.vue +0 -15
  108. package/tailwind.config.js +0 -271
  109. /package/{assets → app/assets}/css/fonts/MEShPlus-font-icon.eot +0 -0
  110. /package/{assets → app/assets}/css/fonts/MEShPlus-font-icon.svg +0 -0
  111. /package/{assets → app/assets}/css/fonts/MEShPlus-font-icon.ttf +0 -0
  112. /package/{assets → app/assets}/css/fonts/MEShPlus-font-icon.woff +0 -0
  113. /package/{assets → app/assets}/css/icons.css +0 -0
  114. /package/{assets → app/assets}/images/commons/app-logo-white.png +0 -0
  115. /package/{assets → app/assets}/images/commons/app-logo.png +0 -0
  116. /package/{assets → app/assets}/images/commons/empty-box.png +0 -0
  117. /package/{interface → app/interface}/IDateRange.ts +0 -0
  118. /package/{interface → app/interface}/IHourRange.ts +0 -0
  119. /package/{interface → app/interface}/IInputOption.ts +0 -0
  120. /package/{interface → app/interface}/ILegendItem.ts +0 -0
  121. /package/{interface → app/interface}/IOrganization.ts +0 -0
  122. /package/{interface → app/interface}/IPopupMenuButton.ts +0 -0
  123. /package/{interface → app/interface}/IStayRange.ts +0 -0
  124. /package/{interface → app/interface}/ITableField.ts +0 -0
  125. /package/{interface → app/interface}/IWeb.ts +0 -0
  126. /package/{interface → app/interface}/NavConfigType.ts +0 -0
  127. /package/{models → app/models}/DateRange.ts +0 -0
  128. /package/{plugins → app/plugins}/v-calendar.ts +0 -0
  129. /package/{utils → app/utils}/constants.ts +0 -0
  130. /package/{utils → app/utils}/generateSheet.ts +0 -0
@@ -18,10 +18,10 @@
18
18
  </template>
19
19
 
20
20
  <script lang="ts">
21
- import { fromEvent, Subscription } from 'rxjs';
22
- import type IDateRange from '~/interface/IDateRange';
21
+ import { fromEvent, Subscription } from "rxjs";
22
+ import type IDateRange from "~ui/app/interface/IDateRange";
23
23
 
24
- const WatermarkImage = '/assets/images/commons/watermark-2.svg';
24
+ const WatermarkImage = "/assets/images/commons/watermark-2.svg";
25
25
  const keys = { 37: 1, 38: 1, 30: 1, 40: 1 };
26
26
 
27
27
  function preventDefault(e: Event) {
@@ -36,7 +36,7 @@ function preventDefaultForScrollKeys(e: Event) {
36
36
  }
37
37
 
38
38
  export default defineComponent({
39
- name: 'SLContextMenu',
39
+ name: "SLContextMenu",
40
40
  props: {
41
41
  target: {
42
42
  type: HTMLElement,
@@ -44,7 +44,7 @@ export default defineComponent({
44
44
  },
45
45
  filename: {
46
46
  type: String,
47
- default: '',
47
+ default: "",
48
48
  },
49
49
  dateRanges: {
50
50
  type: Array as PropType<(IDateRange | null)[]>,
@@ -64,30 +64,45 @@ export default defineComponent({
64
64
  },
65
65
  customStyle: {
66
66
  type: Object as PropType<Partial<CSSStyleDeclaration>>,
67
- default: () => { },
67
+ default: () => {},
68
68
  },
69
69
  },
70
- emits: ['action'],
70
+ emits: ["action"],
71
71
  setup(props, { emit }) {
72
72
  let supportsPassive = false;
73
73
 
74
74
  try {
75
- window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
76
- get: function () { supportsPassive = true; }
77
- }));
78
- } catch (e) { }
75
+ window.addEventListener(
76
+ "test",
77
+ null,
78
+ Object.defineProperty({}, "passive", {
79
+ get: function () {
80
+ supportsPassive = true;
81
+ },
82
+ }),
83
+ );
84
+ } catch (e) {}
79
85
 
80
86
  const wheelOpt = supportsPassive ? { passive: false } : false;
81
- const wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
82
-
83
- const { target, filename, dateRanges, padding, watermark, customFilter, customStyle } = toRefs(props);
87
+ const wheelEvent =
88
+ "onwheel" in document.createElement("div") ? "wheel" : "mousewheel";
89
+
90
+ const {
91
+ target,
92
+ filename,
93
+ dateRanges,
94
+ padding,
95
+ watermark,
96
+ customFilter,
97
+ customStyle,
98
+ } = toRefs(props);
84
99
 
85
100
  const el = shallowRef<HTMLDivElement | null>(null);
86
101
  const isShow = ref(false);
87
102
  const contextMenuX = ref(0);
88
103
  const contextMenuY = ref(0);
89
104
  const isShowCopyMsg = ref(false);
90
- const copyMsg = ref('');
105
+ const copyMsg = ref("");
91
106
  const isCopySuccess = ref(false);
92
107
 
93
108
  let contextMenuSubscriber: Subscription | null = null;
@@ -95,8 +110,8 @@ export default defineComponent({
95
110
  let clearMsgTimeoutId: any = null;
96
111
 
97
112
  const contextMenuActions = computed(() => [
98
- { key: 'saveAs', label: '另存圖檔(.png)' },
99
- { key: 'copy', label: '複製圖檔' },
113
+ { key: "saveAs", label: "另存圖檔(.png)" },
114
+ { key: "copy", label: "複製圖檔" },
100
115
  ]);
101
116
  const contextMenuStyle = computed(() => ({
102
117
  top: `${contextMenuY.value}px`,
@@ -105,35 +120,51 @@ export default defineComponent({
105
120
 
106
121
  async function onClickAction(key: string) {
107
122
  hide();
108
- if (key === 'saveAs') {
109
- const dataURL = await domToPngDataUrl(target.value, customFilter.value, customStyle.value, padding.value, dateRanges.value, watermark.value, WatermarkImage);
123
+ if (key === "saveAs") {
124
+ const dataURL = await domToPngDataUrl(
125
+ target.value,
126
+ customFilter.value,
127
+ customStyle.value,
128
+ padding.value,
129
+ dateRanges.value,
130
+ watermark.value,
131
+ WatermarkImage,
132
+ );
110
133
  if (!dataURL) {
111
134
  console.log("Can not generate data URL!");
112
135
  return;
113
136
  }
114
137
  downloadURL(dataURL, `${filename.value}.png`);
115
- } else if (key === 'copy') {
138
+ } else if (key === "copy") {
116
139
  if (!navigator.clipboard?.write || !window.ClipboardItem) {
117
140
  console.log("Can not copy image to clipboard!");
118
141
  return;
119
142
  }
120
143
 
121
- const dataURL = await domToPngDataUrl(target.value, customFilter.value, customStyle.value, padding.value, dateRanges.value, watermark.value, WatermarkImage);
144
+ const dataURL = await domToPngDataUrl(
145
+ target.value,
146
+ customFilter.value,
147
+ customStyle.value,
148
+ padding.value,
149
+ dateRanges.value,
150
+ watermark.value,
151
+ WatermarkImage,
152
+ );
122
153
  if (!dataURL) {
123
154
  console.log("Can not generate data URL!");
124
155
  return;
125
156
  }
126
157
 
127
158
  const blob = dataURLtoBlob(dataURL);
128
- const data = [new window.ClipboardItem({ 'image/png': blob })];
159
+ const data = [new window.ClipboardItem({ "image/png": blob })];
129
160
 
130
161
  try {
131
162
  await navigator.clipboard.write(data);
132
- copyMsg.value = '成功複製圖檔到剪貼簿';
163
+ copyMsg.value = "成功複製圖檔到剪貼簿";
133
164
  isShowCopyMsg.value = true;
134
165
  isCopySuccess.value = true;
135
166
  } catch (e) {
136
- copyMsg.value = '無法複製圖檔到剪貼簿';
167
+ copyMsg.value = "無法複製圖檔到剪貼簿";
137
168
  isShowCopyMsg.value = true;
138
169
  isCopySuccess.value = false;
139
170
  }
@@ -168,22 +199,22 @@ export default defineComponent({
168
199
  clearTimeout(clearMsgTimeoutId);
169
200
  }
170
201
  clearMsgTimeoutId = setTimeout(() => {
171
- copyMsg.value = '';
202
+ copyMsg.value = "";
172
203
  }, 300);
173
204
  }
174
205
 
175
206
  function subscribeScrollEvents() {
176
- window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
207
+ window.addEventListener("DOMMouseScroll", preventDefault, false); // older FF
177
208
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
178
- window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
179
- window.addEventListener('keydown', preventDefaultForScrollKeys, false);
209
+ window.addEventListener("touchmove", preventDefault, wheelOpt); // mobile
210
+ window.addEventListener("keydown", preventDefaultForScrollKeys, false);
180
211
  }
181
212
 
182
213
  function unsubscribeScrollEvents() {
183
- window.removeEventListener('DOMMouseScroll', preventDefault, false);
214
+ window.removeEventListener("DOMMouseScroll", preventDefault, false);
184
215
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
185
- window.removeEventListener('touchmove', preventDefault, wheelOpt);
186
- window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
216
+ window.removeEventListener("touchmove", preventDefault, wheelOpt);
217
+ window.removeEventListener("keydown", preventDefaultForScrollKeys, false);
187
218
  }
188
219
 
189
220
  watch(isShow, () => {
@@ -202,7 +233,10 @@ export default defineComponent({
202
233
 
203
234
  onMounted(() => {
204
235
  if (el.value && el.value.parentElement) {
205
- contextMenuSubscriber = fromEvent(el.value.parentElement, 'contextmenu').subscribe((e) => {
236
+ contextMenuSubscriber = fromEvent(
237
+ el.value.parentElement,
238
+ "contextmenu",
239
+ ).subscribe((e) => {
206
240
  onRightClick(e as PointerEvent);
207
241
  });
208
242
  }
@@ -232,25 +266,31 @@ export default defineComponent({
232
266
  });
233
267
  </script>
234
268
 
235
- <style lang="stylus" scoped>
236
- .sl-context-menu-wrapper
237
- @apply hidden
269
+ <style scoped>
270
+ @reference '~ui/app/assets/css/main.css';
238
271
 
239
- .sl-context-menu-container
240
- @apply fixed top-0 left-0 w-full h-full
272
+ .sl-context-menu-wrapper {
273
+ @apply hidden;
274
+ }
241
275
 
242
- &-modal
243
- @apply absolute top-0 left-0 w-full h-full
276
+ .sl-context-menu-container {
277
+ @apply fixed top-0 left-0 w-full h-full;
278
+ }
244
279
 
245
- .sl-context-menu
246
- @apply absolute top-0 left-0 m-0 border border-primary-600 rounded overflow-hidden shadow-popup-sm
280
+ .sl-context-menu-container-modal {
281
+ @apply absolute top-0 left-0 w-full h-full;
282
+ }
247
283
 
248
- &-item
249
- @apply block s('min-w-[160px]') p-3 bg-white text-base text-gray-2
250
- @apply s('hover:bg-primary-100') s('hover:text-primary')
284
+ .sl-context-menu-container .sl-context-menu {
285
+ @apply absolute top-0 left-0 m-0 border border-primary-600 rounded overflow-hidden shadow-popup-sm;
286
+ }
251
287
 
252
- .toast.copy-msg-toast
253
- :deep(.toast-wrapper)
254
- @apply s('bg-black/80') shadow-popup-sm
288
+ .sl-context-menu-container .sl-context-menu-item {
289
+ @apply block min-w-[160px] p-3 bg-white text-base text-gray-2;
290
+ @apply hover:bg-primary-100 hover:text-primary;
291
+ }
255
292
 
256
- </style>
293
+ .toast.copy-msg-toast :deep(.toast-wrapper) {
294
+ @apply bg-black/80 shadow-popup-sm;
295
+ }
296
+ </style>
@@ -71,7 +71,7 @@ import { DatePicker } from "v-calendar";
71
71
  import "v-calendar/style.css";
72
72
  import type { PopoverVisibility } from "v-calendar/dist/types/src/utils/popovers";
73
73
  import { isDate, differenceInCalendarDays } from "date-fns";
74
- import type IDateRange from "~ui/interface/IDateRange";
74
+ import type IDateRange from "~ui/app/interface/IDateRange";
75
75
 
76
76
  type DatePickerType = InstanceType<typeof DatePicker> & {
77
77
  hidePopover: () => void;
@@ -180,12 +180,12 @@ export default defineComponent({
180
180
  const startDate = ref<Date | null>(
181
181
  isDate(modelValue.value)
182
182
  ? (modelValue.value as Date)
183
- : (modelValue.value as IDateRange)?.start || null
183
+ : (modelValue.value as IDateRange)?.start || null,
184
184
  );
185
185
  const endDate = ref<Date | null>(
186
186
  isDate(modelValue.value)
187
187
  ? null
188
- : (modelValue.value as IDateRange)?.end || null
188
+ : (modelValue.value as IDateRange)?.end || null,
189
189
  );
190
190
 
191
191
  const dateInputClass = computed(() => {
@@ -364,98 +364,115 @@ export default defineComponent({
364
364
  });
365
365
  </script>
366
366
 
367
- <style lang="stylus">
368
- .date-input
369
- &.date-input-xs
370
- .input-group
371
- &-prepend
372
- @apply s('pl-2.75') pr-4 rounded-l-lg
367
+ <style>
368
+ @reference '~ui/app/assets/css/main.css';
373
369
 
374
- .inputs
375
- @apply pl-0 rounded-r-lg
376
-
377
- .input-group
378
- .inputs
379
- div
380
- input
381
- @apply s('w-[5.875rem]') text-center
382
-
383
- &.date-input-range.date-input-dateTime
384
- .input-group
385
- .inputs
386
- div
387
- input
388
- @apply s('w-[10.5rem]')
389
-
390
- &.inline
391
- @apply flex
392
-
393
- & > label
394
- @apply flex-grow-0 flex-shrink-0 mb-0 mr-2 py-2 border-t border-b border-transparent
370
+ .date-input.date-input-xs .input-group-prepend {
371
+ @apply pl-2.75 pr-4 rounded-l-lg;
372
+ }
395
373
 
396
- .form-control
397
- @apply flex-grow
398
-
399
- &.disabled, &.readonly
400
- .input-group
401
- .input-group-prepend, .inputs
402
- @apply border-primary-500 bg-primary-100
403
-
404
-
405
- & > label
406
- @apply mb-2 text-base leading-normal text-pgray-2
407
-
408
- .is-invalid
409
- .input-group, .input-group.is-focus
410
- .input-group-prepend
411
- @apply border-danger-light
412
-
413
- .inputs
414
- @apply border-danger-light
415
-
416
- .icon
417
- @apply inline-block
418
-
419
- .invalid-feedback
420
- @apply block
374
+ .date-input.date-input-xs .input-group .inputs {
375
+ @apply pl-0 rounded-r-lg;
376
+ }
421
377
 
378
+ .date-input.date-input-xs .input-group .inputs div input {
379
+ @apply w-[5.875rem] text-center;
380
+ }
422
381
 
382
+ .date-input.date-input-range.date-input-dateTime
423
383
  .input-group
424
- @apply flex flex-nowrap w-full text-base leading-normal
425
-
426
- &.is-focus
427
- .input
428
- @apply border-primary
429
-
430
- &.is-fill, &.is-focus
431
- .input
432
- .float-label
433
- @apply s('ml-1.5') s('-mt-2.25') py-0 s('px-0.5') bg-white text-primary text-xs transition-input-focus
434
-
435
- &-prepend
436
- @apply flex-grow-0 flex-shrink-0 flex items-center relative pl-4 pr-6 rounded-l border border-r-0 border-primary-500 bg-white text-base leading-none
437
-
438
- &:after
439
- content ''
440
- @apply block absolute top-2 s('right-1.75') bottom-2 w-px bg-primary
441
-
442
- .inputs
443
- @apply relative flex-grow flex items-center p-2 bg-white rounded-r border border-l-0 border-primary-500 text-base text-pgray-2
444
-
445
- input
446
- @apply flex-grow bg-transparent text-base text-pgray-2 text-left placeholder-pgray-4 s('focus:outline-none')
447
- width: calc((100% - 25px) / 2)
448
-
449
- .date-range-split
450
- @apply flex-grow-0 flex-shrink-0 s('mx-0.5')
451
-
452
- .icon
453
- @apply absolute right-0 mr-2 text-danger-light hidden
454
-
455
- .input-info
456
- @apply mt-1 text-xs text-pgray-3
457
-
458
- .invalid-feedback
459
- @apply hidden text-danger text-xs
384
+ .inputs
385
+ div
386
+ input {
387
+ @apply w-[10.5rem];
388
+ }
389
+
390
+ .date-input.inline {
391
+ @apply flex;
392
+ }
393
+
394
+ .date-input.inline > label {
395
+ @apply grow-0 shrink-0 mb-0 mr-2 py-2 border-t border-b border-transparent;
396
+ }
397
+
398
+ .date-input.inline .form-control {
399
+ @apply grow;
400
+ }
401
+
402
+ .date-input.disabled .input-group .input-group-prepend,
403
+ .date-input.disabled .input-group .inputs,
404
+ .date-input.readonly .input-group .input-group-prepend,
405
+ .date-input.readonly .input-group .inputs {
406
+ @apply border-primary-500 bg-primary-100;
407
+ }
408
+
409
+ .date-input > label {
410
+ @apply mb-2 text-base leading-[1.3125] text-pgray-2;
411
+ }
412
+
413
+ .date-input .is-invalid .input-group .input-group-prepend,
414
+ .date-input .is-invalid .input-group.is-focus .input-group-prepend {
415
+ @apply border-danger-light;
416
+ }
417
+
418
+ .date-input .is-invalid .input-group .inputs,
419
+ .date-input .is-invalid .input-group.is-focus .inputs {
420
+ @apply border-danger-light;
421
+ }
422
+
423
+ .date-input .is-invalid .input-group .inputs .icon,
424
+ .date-input .is-invalid .input-group.is-focus .inputs .icon {
425
+ @apply inline-block;
426
+ }
427
+
428
+ .date-input .is-invalid .invalid-feedback {
429
+ @apply block;
430
+ }
431
+
432
+ .date-input .input-group {
433
+ @apply flex flex-nowrap w-full text-base leading-[1.3125];
434
+ }
435
+
436
+ .date-input .input-group.is-focus .input {
437
+ @apply border-primary;
438
+ }
439
+
440
+ .date-input .input-group.is-fill .input .float-label,
441
+ .date-input .input-group.is-focus .input .float-label {
442
+ @apply ml-1.5 -mt-2.25 py-0 px-0.5 bg-white text-primary text-xs transition-(--transition-input-focus);
443
+ }
444
+
445
+ .date-input .input-group .input-group-prepend {
446
+ @apply grow-0 shrink-0 flex items-center relative pl-4 pr-6 rounded-l border border-r-0 border-primary-500 bg-white text-base leading-none;
447
+ }
448
+
449
+ .date-input .input-group .input-group-prepend::after {
450
+ content: "";
451
+ @apply block absolute top-2 right-1.75 bottom-2 w-px bg-primary;
452
+ }
453
+
454
+ .date-input .input-group .inputs {
455
+ @apply relative grow flex items-center p-2 bg-white rounded-r border border-l-0 border-primary-500 text-base text-pgray-2;
456
+ }
457
+
458
+ .date-input .input-group .inputs input {
459
+ @apply grow bg-transparent text-base text-pgray-2 text-left placeholder-pgray-4 focus:outline-none;
460
+ width: calc((100% - 25px) / 2);
461
+ }
462
+
463
+ .date-input .input-group .inputs .date-range-split {
464
+ @apply grow-0 shrink-0 mx-0.5;
465
+ }
466
+
467
+ .date-input .input-group .inputs .icon {
468
+ @apply absolute right-0 mr-2 text-danger-light hidden;
469
+ }
470
+
471
+ .date-input .input-info {
472
+ @apply mt-1 text-xs text-pgray-3;
473
+ }
474
+
475
+ .date-input .invalid-feedback {
476
+ @apply hidden text-danger text-xs;
477
+ }
460
478
  </style>
461
-
@@ -29,7 +29,7 @@ import {
29
29
  max as dateMax,
30
30
  isDate,
31
31
  } from "date-fns";
32
- import type IDateRange from "~ui/interface/IDateRange";
32
+ import type IDateRange from "~ui/app/interface/IDateRange";
33
33
 
34
34
  type DatePickerType = InstanceType<typeof DatePicker>;
35
35
 
@@ -83,7 +83,7 @@ export default defineComponent({
83
83
 
84
84
  const draggingMinDate = subDays(
85
85
  draggingStartDate.value as Date,
86
- maxDays.value - 1
86
+ maxDays.value - 1,
87
87
  );
88
88
 
89
89
  return minDate.value
@@ -95,7 +95,7 @@ export default defineComponent({
95
95
 
96
96
  const draggingMaxDate = addDays(
97
97
  draggingStartDate.value as Date,
98
- maxDays.value - 1
98
+ maxDays.value - 1,
99
99
  );
100
100
 
101
101
  return maxDate.value
@@ -136,8 +136,10 @@ export default defineComponent({
136
136
  });
137
137
  </script>
138
138
 
139
- <style lang="stylus">
140
- .custom-date-picker
141
- .vc-pane-container
142
- @apply border-0
139
+ <style>
140
+ @reference '~ui/app/assets/css/main.css';
141
+
142
+ .custom-date-picker .vc-pane-container {
143
+ @apply border-0;
144
+ }
143
145
  </style>
@@ -27,4 +27,4 @@ export default defineComponent({
27
27
  });
28
28
  </script>
29
29
 
30
- <style lang="stylus"></style>
30
+ <style></style>
@@ -31,20 +31,15 @@ import { fromEvent, Subscription } from "rxjs";
31
31
  import { createPopper } from "@popperjs/core";
32
32
  import type { Instance as PopperInstance, Placement } from "@popperjs/core";
33
33
  import ExcelJS from "exceljs";
34
- import {
35
- downloadURL,
36
- downloadBlob,
37
- gaev,
38
- ga4ev,
39
- } from "~ui/utils";
40
- import type IDateRange from "~ui/interface/IDateRange";
34
+ import { downloadURL, downloadBlob, gaev, ga4ev } from "~ui/app/utils";
35
+ import type IDateRange from "~ui/app/interface/IDateRange";
41
36
 
42
37
  // http://www.excelcodex.com/2012/06/worksheets-naming-conventions/
43
38
  function safeSheetName(name: string) {
44
39
  return name.replace(/[\\/*?:[\]]/g, "").substring(0, 31);
45
40
  }
46
41
 
47
- const WatermarkImage = '/assets/images/commons/watermark-2.svg';
42
+ const WatermarkImage = "/assets/images/commons/watermark-2.svg";
48
43
 
49
44
  export default defineComponent({
50
45
  name: "SLDownloadButton",
@@ -93,7 +88,7 @@ export default defineComponent({
93
88
  },
94
89
  customStyle: {
95
90
  type: Object as PropType<Partial<CSSStyleDeclaration>>,
96
- default: () => { },
91
+ default: () => {},
97
92
  },
98
93
  evCategory: {
99
94
  type: String,
@@ -204,7 +199,7 @@ export default defineComponent({
204
199
  const workbook = new ExcelJS.Workbook();
205
200
  sheets.value.map((sheetData) => {
206
201
  const sheet = workbook.addWorksheet(
207
- sheetData?.sheetName ? safeSheetName(sheetData.sheetName) : ""
202
+ sheetData?.sheetName ? safeSheetName(sheetData.sheetName) : "",
208
203
  );
209
204
  (sheetData?.sheetData || []).forEach((rowData) => {
210
205
  sheet.addRow(rowData);
@@ -215,12 +210,20 @@ export default defineComponent({
215
210
  downloadBlob(
216
211
  buffer,
217
212
  `${fileName.value}.xlsx`,
218
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
213
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
219
214
  );
220
215
  return;
221
216
  }
222
217
 
223
- const dataURL = await domToPngDataUrl(imageTarget.value, customFilter.value, customStyle.value, padding.value, dateRanges.value, watermark.value, WatermarkImage);
218
+ const dataURL = await domToPngDataUrl(
219
+ imageTarget.value,
220
+ customFilter.value,
221
+ customStyle.value,
222
+ padding.value,
223
+ dateRanges.value,
224
+ watermark.value,
225
+ WatermarkImage,
226
+ );
224
227
  if (!dataURL) {
225
228
  console.log("Can not generate data URL!");
226
229
  return;
@@ -269,27 +272,34 @@ export default defineComponent({
269
272
  });
270
273
  </script>
271
274
 
272
- <style lang="stylus">
273
- .download-button
274
- @apply inline-block
275
+ <style>
276
+ @reference '~ui/app/assets/css/main.css';
275
277
 
276
- &.disabled
277
- .download-button-toggle
278
- @apply border-pgray-5 text-pgray-5 cursor-default
278
+ .download-button {
279
+ @apply inline-block;
280
+ }
281
+
282
+ .download-button.disabled .download-button-toggle {
283
+ @apply border-pgray-5 text-pgray-5 cursor-default;
284
+ }
279
285
 
280
- &-toggle
281
- @apply inline-flex justify-center items-center s('w-[28px]') s('h-[28px]') bg-white border border-primary-600 rounded text-lg text-primary-600
286
+ .download-button-toggle {
287
+ @apply inline-flex justify-center items-center w-[28px] h-[28px] bg-white border border-primary-600 rounded text-lg text-primary-600;
288
+ }
282
289
 
283
- &.active
284
- @apply bg-primary-600 text-white
290
+ .download-button-toggle.active {
291
+ @apply bg-primary-600 text-white;
292
+ }
285
293
 
286
- .download-button-popup
287
- @apply z-60 absolute flex flex-col bg-white border border-primary-500 rounded overflow-hidden shadow invisible pointer-events-none
294
+ .download-button-popup {
295
+ @apply z-60 absolute flex flex-col bg-white border border-primary-500 rounded overflow-hidden shadow-default invisible pointer-events-none;
296
+ }
288
297
 
289
- &[data-show]
290
- @apply visible pointer-events-auto
298
+ .download-button-popup[data-show] {
299
+ @apply visible pointer-events-auto;
300
+ }
291
301
 
292
- .download-option
293
- @apply block p-2 bg-white text-sm text-pgray-3
294
- @apply s('hover:bg-primary-100') s('hover:text-primary')
302
+ .download-button-popup .download-option {
303
+ @apply block p-2 bg-white text-sm text-pgray-3 hover:bg-primary-100 hover:text-primary;
304
+ }
295
305
  </style>
@@ -58,7 +58,7 @@ export default defineComponent({
58
58
  }
59
59
 
60
60
  const elIndex = Array.from(draggableEl.value.children).indexOf(
61
- dragEl
61
+ dragEl,
62
62
  );
63
63
 
64
64
  if (elIndex === -1) {
@@ -148,4 +148,4 @@ export default defineComponent({
148
148
  });
149
149
  </script>
150
150
 
151
- <style lang="stylus"></style>
151
+ <style></style>