@peng_kai/kit 0.0.14 → 0.0.15

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,59 +1,59 @@
1
- <script setup lang="ts">
2
- import { computed } from "vue";
3
- import { useElementSize } from '@vueuse/core'
4
-
5
- const props = defineProps<{
6
- selector: string
7
- }>()
8
-
9
- const $content = document.querySelector(props.selector) as HTMLElement
10
- const $contentParent = $content.parentElement
11
- const { height: contentParentH } = useElementSize($contentParent)
12
- const { height: contentH } = useElementSize($content)
13
- const visible = computed(() => contentParentH.value * 2 < contentH.value)
14
-
15
- function scrollTo(top: number) {
16
- $contentParent?.scrollTo({ top })
17
- }
18
- </script>
19
-
20
- <template>
21
- <div v-if="visible" class="wrapper">
22
- <div class="btn" @click="scrollTo(0)">
23
- <i class="i-fluent:arrow-previous-24-filled rotate-90" />
24
- </div>
25
- <div class="btn" @click="scrollTo($contentParent?.scrollHeight ?? Infinity)">
26
- <i class="i-fluent:arrow-previous-24-filled rotate-270" />
27
- </div>
28
- <!-- <div v-if="showReturn" class="btn" @click="toLastY()">
29
- <i class="i-fluent:arrow-hook-down-left-24-filled rotate-270" />
30
- </div> -->
31
- </div>
32
- </template>
33
-
34
- <style lang="scss" scoped>
35
- .wrapper {
36
- font-size: 18px;
37
- }
38
-
39
- .btn {
40
- display: flex;
41
- width: 2em;
42
- height: 2em;
43
- align-items: center;
44
- justify-content: center;
45
- border-radius: 2px;
46
- background: #bcbcbc;
47
- color: #000;
48
- cursor: pointer;
49
- opacity: 0.7;
50
-
51
- &:active {
52
- transform: scale(0.9);
53
- }
54
-
55
- & + & {
56
- margin-top: 1px;
57
- }
58
- }
59
- </style>
1
+ <script setup lang="ts">
2
+ import { computed } from "vue";
3
+ import { useElementSize } from '@vueuse/core'
4
+
5
+ const props = defineProps<{
6
+ selector: string
7
+ }>()
8
+
9
+ const $content = document.querySelector(props.selector) as HTMLElement
10
+ const $contentParent = $content.parentElement
11
+ const { height: contentParentH } = useElementSize($contentParent)
12
+ const { height: contentH } = useElementSize($content)
13
+ const visible = computed(() => contentParentH.value * 2 < contentH.value)
14
+
15
+ function scrollTo(top: number) {
16
+ $contentParent?.scrollTo({ top })
17
+ }
18
+ </script>
19
+
20
+ <template>
21
+ <div v-if="visible" class="wrapper">
22
+ <div class="btn" @click="scrollTo(0)">
23
+ <i class="i-fluent:arrow-previous-24-filled rotate-90" />
24
+ </div>
25
+ <div class="btn" @click="scrollTo($contentParent?.scrollHeight ?? Infinity)">
26
+ <i class="i-fluent:arrow-previous-24-filled rotate-270" />
27
+ </div>
28
+ <!-- <div v-if="showReturn" class="btn" @click="toLastY()">
29
+ <i class="i-fluent:arrow-hook-down-left-24-filled rotate-270" />
30
+ </div> -->
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .wrapper {
36
+ font-size: 18px;
37
+ }
38
+
39
+ .btn {
40
+ display: flex;
41
+ width: 2em;
42
+ height: 2em;
43
+ align-items: center;
44
+ justify-content: center;
45
+ border-radius: 2px;
46
+ background: #bcbcbc;
47
+ color: #000;
48
+ cursor: pointer;
49
+ opacity: 0.7;
50
+
51
+ &:active {
52
+ transform: scale(0.9);
53
+ }
54
+
55
+ & + & {
56
+ margin-top: 1px;
57
+ }
58
+ }
59
+ </style>
@@ -1,13 +1,13 @@
1
- import Hash from './src/Hash.vue'
2
- import Amount from './src/Amount.vue'
3
- import Datetime from './src/Datetime.vue'
4
- import Duration from './src/Duration.vue'
5
-
6
- export { createTagGetter } from './src/createTagGetter'
7
-
8
- export const Text = {
9
- Hash,
10
- Amount,
11
- Datetime,
12
- Duration,
13
- }
1
+ import Hash from './src/Hash.vue'
2
+ import Amount from './src/Amount.vue'
3
+ import Datetime from './src/Datetime.vue'
4
+ import Duration from './src/Duration.vue'
5
+
6
+ export { createTagGetter } from './src/createTagGetter'
7
+
8
+ export const Text = {
9
+ Hash,
10
+ Amount,
11
+ Datetime,
12
+ Duration,
13
+ }
@@ -1,114 +1,114 @@
1
- <script lang="ts">
2
- import { computed } from "vue";
3
- import bigNumber from 'bignumber.js'
4
- import isNil from 'lodash-es/isNil'
5
-
6
- /**
7
- * 当 symbol 为以下值时,使用预设的 Logo
8
- */
9
- const presetSymbols: Record<string, string> = {
10
- USDT: 'https://api.iconify.design/cryptocurrency-color:usdt.svg',
11
- TRX: 'https://api.iconify.design/cryptocurrency-color:trx.svg',
12
- USDC: 'https://api.iconify.design/cryptocurrency-color:usdc.svg',
13
- ETH: 'https://api.iconify.design/cryptocurrency-color:eth.svg',
14
- BNB: 'https://api.iconify.design/cryptocurrency-color:bnb.svg',
15
- BUSD: 'https://assets.coingecko.com/coins/images/9576/large/BUSD.png',
16
- MATIC: 'https://api.iconify.design/cryptocurrency-color:matic.svg',
17
- SOL: 'https://api.iconify.design/cryptocurrency-color:sol.svg',
18
- }
19
- </script>
20
-
21
- <script setup lang="ts">
22
- const props = withDefaults(
23
- defineProps<{
24
- /** 金额 */
25
- amount?: string | number
26
- /** 符号Logo, 可以是币种Logo的URL、法定货币符号($) */
27
- symbol?: string
28
- /** 精度 */
29
- precision?: number
30
- /** 单位,如币种名称 */
31
- unit?: string
32
- /** 保留小数的位数 */
33
- fractionDigits?: number
34
- /** 是否填充 0 */
35
- padZero?: boolean
36
- /** 金额是否红/绿显示 */
37
- colorful?: boolean
38
- /** 是否是大约数 */
39
- approx?: boolean
40
- }>(),
41
- {
42
- padZero: false,
43
- fractionDigits: 18,
44
- colorful: false,
45
- },
46
- )
47
-
48
- const amountText = computed(() => {
49
- const _amount = props.amount
50
-
51
- if (isNil(_amount))
52
- return '-'
53
-
54
- let bn = bigNumber(_amount)
55
- bn = !isNil(props.precision) ? bn.dividedBy(10 ** props.precision) : bn
56
- let bnt = bn.toFormat(props.fractionDigits)
57
- bnt = props.padZero ? bnt : bnt.replace(/\.?0+$/, '')
58
-
59
- return bnt
60
- })
61
- const amountColor = computed(() => {
62
- const num = Number.parseFloat(props.amount as string)
63
-
64
- if (!props.colorful || (Number.isNaN(num) ? true : num === 0))
65
- return ''
66
-
67
- return num > 0 ? '#52c41a' : (num < 0 ? '#ff4d4f' : '#000')
68
- })
69
- const symbol = computed(() => presetSymbols[props.symbol!] ?? props.symbol ?? '')
70
- </script>
71
-
72
- <template>
73
- <div class="amount-wrapper" :style="{ '--amount-color': amountColor }">
74
- <!-- 约等于 -->
75
- <span v-if="props.approx" class="color-$amount-color">≈</span>
76
-
77
- <!-- 符号 -->
78
- <img v-if="symbol.startsWith('http')" class="symbol-logo" :src="symbol" :alt="props.unit"> <!-- 图片Logo -->
79
- <span v-else class="color-$amount-color">{{ symbol }}</span> <!-- 文本Logo,如法定币种符号(¥、$) -->
80
-
81
- <!-- 金额 -->
82
- <span class="color-$amount-color amount">{{ amountText }}</span>
83
-
84
- <!-- 单位 -->
85
- <span v-if="props.unit" class="unit">{{ props.unit }}</span>
86
- </div>
87
- </template>
88
-
89
- <style lang="scss">
90
- .amount-wrapper {
91
- display: flex;
92
- align-items: center;
93
-
94
- .symbol-logo {
95
- display: block;
96
- width: 1.1em;
97
- height: 1.1em;
98
- margin-right: 0.2em;
99
- }
100
-
101
- .amount {
102
- font-family: 'dinm';
103
- }
104
-
105
- .currency-name {
106
- margin-left: 0.2em;
107
- }
108
-
109
- .unit {
110
- display: inline-block;
111
- margin-left: 0.2em;
112
- }
113
- }
114
- </style>
1
+ <script lang="ts">
2
+ import { computed } from "vue";
3
+ import bigNumber from 'bignumber.js'
4
+ import isNil from 'lodash-es/isNil'
5
+
6
+ /**
7
+ * 当 symbol 为以下值时,使用预设的 Logo
8
+ */
9
+ const presetSymbols: Record<string, string> = {
10
+ USDT: 'https://api.iconify.design/cryptocurrency-color:usdt.svg',
11
+ TRX: 'https://api.iconify.design/cryptocurrency-color:trx.svg',
12
+ USDC: 'https://api.iconify.design/cryptocurrency-color:usdc.svg',
13
+ ETH: 'https://api.iconify.design/cryptocurrency-color:eth.svg',
14
+ BNB: 'https://api.iconify.design/cryptocurrency-color:bnb.svg',
15
+ BUSD: 'https://assets.coingecko.com/coins/images/9576/large/BUSD.png',
16
+ MATIC: 'https://api.iconify.design/cryptocurrency-color:matic.svg',
17
+ SOL: 'https://api.iconify.design/cryptocurrency-color:sol.svg',
18
+ }
19
+ </script>
20
+
21
+ <script setup lang="ts">
22
+ const props = withDefaults(
23
+ defineProps<{
24
+ /** 金额 */
25
+ amount?: string | number
26
+ /** 符号Logo, 可以是币种Logo的URL、法定货币符号($) */
27
+ symbol?: string
28
+ /** 精度 */
29
+ precision?: number
30
+ /** 单位,如币种名称 */
31
+ unit?: string
32
+ /** 保留小数的位数 */
33
+ fractionDigits?: number
34
+ /** 是否填充 0 */
35
+ padZero?: boolean
36
+ /** 金额是否红/绿显示 */
37
+ colorful?: boolean
38
+ /** 是否是大约数 */
39
+ approx?: boolean
40
+ }>(),
41
+ {
42
+ padZero: false,
43
+ fractionDigits: 18,
44
+ colorful: false,
45
+ },
46
+ )
47
+
48
+ const amountText = computed(() => {
49
+ const _amount = props.amount
50
+
51
+ if (isNil(_amount))
52
+ return '-'
53
+
54
+ let bn = bigNumber(_amount)
55
+ bn = !isNil(props.precision) ? bn.dividedBy(10 ** props.precision) : bn
56
+ let bnt = bn.toFormat(props.fractionDigits)
57
+ bnt = props.padZero ? bnt : bnt.replace(/\.?0+$/, '')
58
+
59
+ return bnt
60
+ })
61
+ const amountColor = computed(() => {
62
+ const num = Number.parseFloat(props.amount as string)
63
+
64
+ if (!props.colorful || (Number.isNaN(num) ? true : num === 0))
65
+ return ''
66
+
67
+ return num > 0 ? '#52c41a' : (num < 0 ? '#ff4d4f' : '#000')
68
+ })
69
+ const symbol = computed(() => presetSymbols[props.symbol!] ?? props.symbol ?? '')
70
+ </script>
71
+
72
+ <template>
73
+ <div class="amount-wrapper" :style="{ '--amount-color': amountColor }">
74
+ <!-- 约等于 -->
75
+ <span v-if="props.approx" class="color-$amount-color">≈</span>
76
+
77
+ <!-- 符号 -->
78
+ <img v-if="symbol.startsWith('http')" class="symbol-logo" :src="symbol" :alt="props.unit"> <!-- 图片Logo -->
79
+ <span v-else class="color-$amount-color">{{ symbol }}</span> <!-- 文本Logo,如法定币种符号(¥、$) -->
80
+
81
+ <!-- 金额 -->
82
+ <span class="color-$amount-color amount">{{ amountText }}</span>
83
+
84
+ <!-- 单位 -->
85
+ <span v-if="props.unit" class="unit">{{ props.unit }}</span>
86
+ </div>
87
+ </template>
88
+
89
+ <style lang="scss">
90
+ .amount-wrapper {
91
+ display: flex;
92
+ align-items: center;
93
+
94
+ .symbol-logo {
95
+ display: block;
96
+ width: 1.1em;
97
+ height: 1.1em;
98
+ margin-right: 0.2em;
99
+ }
100
+
101
+ .amount {
102
+ font-family: 'dinm';
103
+ }
104
+
105
+ .currency-name {
106
+ margin-left: 0.2em;
107
+ }
108
+
109
+ .unit {
110
+ display: inline-block;
111
+ margin-left: 0.2em;
112
+ }
113
+ }
114
+ </style>
@@ -1,44 +1,44 @@
1
- <script setup lang="ts">
2
- import { Tooltip as ATooltip } from "ant-design-vue";
3
- import { computed } from "vue";
4
- import { getDependencies } from "../../../../kitDependencies";
5
-
6
- defineOptions({
7
- inheritAttrs: false,
8
- })
9
-
10
- const props = withDefaults(
11
- defineProps<{
12
- timestamp?: number | string
13
- template?: string
14
- }>(),
15
- {
16
- template: 'MM-DD HH:mm:ss',
17
- },
18
- )
19
- const {dayjs} = getDependencies()!
20
- const timestamp = computed(() => {
21
- let tsStr = String(props.timestamp)
22
-
23
- if (tsStr.length === 10)
24
- tsStr += '000'
25
- if (tsStr.length !== 13)
26
- return
27
-
28
- const tsNum = Number.parseInt(tsStr)
29
-
30
- return Number.isNaN(tsNum) ? undefined : tsNum
31
- })
32
- </script>
33
-
34
- <template>
35
- <ATooltip destroyTooltipOnHide>
36
- <template v-if="timestamp" #title>
37
- <div>{{ dayjs(timestamp).fromNow?.() }}</div>
38
- <div>{{ dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') }}</div>
39
- </template>
40
- <span v-bind="$attrs">{{ timestamp ? dayjs(timestamp).format(props.template) : '-' }}</span>
41
- </ATooltip>
42
- </template>
43
-
44
- <style scoped lang="scss"></style>
1
+ <script setup lang="ts">
2
+ import { Tooltip as ATooltip } from "ant-design-vue";
3
+ import { computed } from "vue";
4
+ import { getDependencies } from "../../../../kitDependencies";
5
+
6
+ defineOptions({
7
+ inheritAttrs: false,
8
+ })
9
+
10
+ const props = withDefaults(
11
+ defineProps<{
12
+ timestamp?: number | string
13
+ template?: string
14
+ }>(),
15
+ {
16
+ template: 'MM-DD HH:mm:ss',
17
+ },
18
+ )
19
+ const {dayjs} = getDependencies()!
20
+ const timestamp = computed(() => {
21
+ let tsStr = String(props.timestamp)
22
+
23
+ if (tsStr.length === 10)
24
+ tsStr += '000'
25
+ if (tsStr.length !== 13)
26
+ return
27
+
28
+ const tsNum = Number.parseInt(tsStr)
29
+
30
+ return Number.isNaN(tsNum) ? undefined : tsNum
31
+ })
32
+ </script>
33
+
34
+ <template>
35
+ <ATooltip destroyTooltipOnHide>
36
+ <template v-if="timestamp" #title>
37
+ <div>{{ dayjs(timestamp).fromNow?.() }}</div>
38
+ <div>{{ dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss') }}</div>
39
+ </template>
40
+ <span v-bind="$attrs">{{ timestamp ? dayjs(timestamp).format(props.template) : '-' }}</span>
41
+ </ATooltip>
42
+ </template>
43
+
44
+ <style scoped lang="scss"></style>
@@ -1,26 +1,26 @@
1
- <script setup lang="ts">
2
- import { computed } from "vue";
3
-
4
- const props = defineProps<{
5
- seconds: number
6
- }>()
7
-
8
- const formattedDuration = computed(() => {
9
- const days = Math.floor(props.seconds / (3600 * 24))
10
- const hours = Math.floor((props.seconds % (3600 * 24)) / 3600)
11
- const minutes = Math.floor((props.seconds % 3600) / 60)
12
- const seconds = props.seconds % 60
13
- let formattedDuration = ''
14
-
15
- days >= 1 && (formattedDuration += `${Math.floor(days)}天 `)
16
- hours >= 1 && (formattedDuration += `${Math.floor(hours)}小时 `)
17
- minutes >= 1 && (formattedDuration += `${Math.floor(minutes)}分钟 `)
18
- seconds >= 1 && (formattedDuration += `${Math.floor(seconds)}秒`)
19
-
20
- return formattedDuration
21
- })
22
- </script>
23
-
24
- <template>
25
- <span>{{ formattedDuration }}</span>
26
- </template>
1
+ <script setup lang="ts">
2
+ import { computed } from "vue";
3
+
4
+ const props = defineProps<{
5
+ seconds: number
6
+ }>()
7
+
8
+ const formattedDuration = computed(() => {
9
+ const days = Math.floor(props.seconds / (3600 * 24))
10
+ const hours = Math.floor((props.seconds % (3600 * 24)) / 3600)
11
+ const minutes = Math.floor((props.seconds % 3600) / 60)
12
+ const seconds = props.seconds % 60
13
+ let formattedDuration = ''
14
+
15
+ days >= 1 && (formattedDuration += `${Math.floor(days)}天 `)
16
+ hours >= 1 && (formattedDuration += `${Math.floor(hours)}小时 `)
17
+ minutes >= 1 && (formattedDuration += `${Math.floor(minutes)}分钟 `)
18
+ seconds >= 1 && (formattedDuration += `${Math.floor(seconds)}秒`)
19
+
20
+ return formattedDuration
21
+ })
22
+ </script>
23
+
24
+ <template>
25
+ <span>{{ formattedDuration }}</span>
26
+ </template>
@@ -1,40 +1,40 @@
1
- <script setup lang="ts">
2
- import { Tooltip as ATooltip, TypographyLink as ATypographyLink } from "ant-design-vue";
3
- import { computed } from "vue";
4
- import { desensitize, getScanBrowser } from '../../../../utils'
5
-
6
- type HashType = Parameters<typeof getScanBrowser>[2]
7
-
8
- defineOptions({
9
- inheritAttrs: false,
10
- })
11
-
12
- const props = withDefaults(
13
- defineProps<{
14
- hash: string
15
- hide?: boolean
16
- chain?: string
17
- type?: HashType
18
- }>(),
19
- {
20
- hide: true,
21
- },
22
- )
23
-
24
- const href = computed(() => {
25
- const { hash, chain, type } = props
26
-
27
- if (!hash || !chain || !type)
28
- return
29
- return getScanBrowser(chain, hash, type)
30
- })
31
- </script>
32
-
33
- <template>
34
- <ATypographyLink :href="href" :copyable="{ text: props.hash, tooltip: false }" target="_blank">
35
- <ATooltip>
36
- <template v-if="props.hide" #title>{{ props.hash }}</template>
37
- <span v-bind="$attrs">{{ props.hide ? desensitize(props.hash) : props.hash }}</span>
38
- </ATooltip>
39
- </ATypographyLink>
40
- </template>
1
+ <script setup lang="ts">
2
+ import { Tooltip as ATooltip, TypographyLink as ATypographyLink } from "ant-design-vue";
3
+ import { computed } from "vue";
4
+ import { desensitize, getScanBrowser } from '../../../../utils'
5
+
6
+ type HashType = Parameters<typeof getScanBrowser>[2]
7
+
8
+ defineOptions({
9
+ inheritAttrs: false,
10
+ })
11
+
12
+ const props = withDefaults(
13
+ defineProps<{
14
+ hash: string
15
+ hide?: boolean
16
+ chain?: string
17
+ type?: HashType
18
+ }>(),
19
+ {
20
+ hide: true,
21
+ },
22
+ )
23
+
24
+ const href = computed(() => {
25
+ const { hash, chain, type } = props
26
+
27
+ if (!hash || !chain || !type)
28
+ return
29
+ return getScanBrowser(chain, hash, type)
30
+ })
31
+ </script>
32
+
33
+ <template>
34
+ <ATypographyLink :href="href" :copyable="{ text: props.hash, tooltip: false }" target="_blank">
35
+ <ATooltip>
36
+ <template v-if="props.hide" #title>{{ props.hash }}</template>
37
+ <span v-bind="$attrs">{{ props.hide ? desensitize(props.hash) : props.hash }}</span>
38
+ </ATooltip>
39
+ </ATypographyLink>
40
+ </template>
@@ -1,13 +1,13 @@
1
- import { computed, h } from "vue";
2
- import { Tag as ATag } from 'ant-design-vue'
3
- import type { TagProps } from 'ant-design-vue'
4
-
5
- export function createTagGetter(typeMapFn: () => { [code: number | string]: [ text: string, color: TagProps['color'] ] }) {
6
- const typeMap = computed(typeMapFn)
7
-
8
- return (type: number) => {
9
- const [text, color] = typeMap.value[type] ?? []
10
-
11
- return text ? h(ATag, { color }, () => text) : h('span', null, '-')
12
- }
13
- }
1
+ import { computed, h } from "vue";
2
+ import { Tag as ATag } from 'ant-design-vue'
3
+ import type { TagProps } from 'ant-design-vue'
4
+
5
+ export function createTagGetter(typeMapFn: () => { [code: number | string]: [ text: string, color: TagProps['color'] ] }) {
6
+ const typeMap = computed(typeMapFn)
7
+
8
+ return (type: number) => {
9
+ const [text, color] = typeMap.value[type] ?? []
10
+
11
+ return text ? h(ATag, { color }, () => text) : h('span', null, '-')
12
+ }
13
+ }
@@ -9,8 +9,7 @@ export function getTitle(route?: Pick<RouteLocationNormalizedLoaded, 'meta'>) {
9
9
  export function getMenusByRouter(router: Router) {
10
10
  const menuOrderRE = /^(?<key>\w*)@(?<order>\d+)$/
11
11
  const routes = router.getRoutes()
12
-
13
- return routes
12
+ const menus = routes
14
13
  .filter(route => menuOrderRE.test((route.meta.menuOrder ?? '')))
15
14
  .map((route) => {
16
15
  const res = route.meta!.menuOrder!.match(menuOrderRE)
@@ -21,10 +20,18 @@ export function getMenusByRouter(router: Router) {
21
20
  key: name,
22
21
  label: route.meta.title ?? name,
23
22
  icon: route.meta.icon,
24
- trigger: parentKey ? () => router.push({ name }) : () => {},
23
+ trigger: () => router.push({ name }),
25
24
  order,
26
25
  }
27
26
 
28
27
  return { parentKey, menu }
29
28
  })
29
+
30
+ // 将含有子菜单的菜单的 trigger 设置为空函数
31
+ const hasSubMenus = menus.filter(menu => menus.some(m => m.parentKey === menu.menu.key))
32
+ hasSubMenus.forEach((menu) => {
33
+ menu.menu.trigger = (() => {}) as any
34
+ })
35
+
36
+ return menus
30
37
  }