@phill-component/icons 1.0.0 → 1.0.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.
- package/dist/mobile/uvue/icon-find-replace/find-replace.png +0 -0
- package/dist/mobile/uvue/icon-find-replace/icon-find-replace.uvue +75 -0
- package/dist/mobile/uvue/icon-h6/h6.png +0 -0
- package/dist/mobile/uvue/icon-h6/icon-h6.uvue +75 -0
- package/dist/mobile/vue/icon-find-replace.vue +58 -0
- package/dist/mobile/vue/icon-h6.vue +58 -0
- package/dist/web/vue/FindReplace.vue +53 -0
- package/dist/web/vue/H6.vue +53 -0
- package/dist/web/vue/index.js +2 -0
- package/package.json +4 -4
- package/scripts/install.js +1 -1
- package/scripts/publish.js +145 -0
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="rootStyle">
|
|
3
|
+
<!-- #ifdef H5 -->
|
|
4
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M42.354 40.854 36.01 34.51m0 0a9 9 0 0 1-15.364-6.364c0-5 4-9 9-9s9 4 9 9a8.97 8.97 0 0 1-2.636 6.364zm5.636-26.365h-36m10 16h-10m10 16h-10"/></svg>
|
|
5
|
+
<!-- #endif -->
|
|
6
|
+
<!-- #ifndef H5 -->
|
|
7
|
+
<image :src="imgSrc" :style="iconBoxStyle" />
|
|
8
|
+
<!-- #endif -->
|
|
9
|
+
<text v-if="label != ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
10
|
+
</view>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup lang="uts">
|
|
13
|
+
import { computed } from 'vue'
|
|
14
|
+
import imgSrc from '@/uni_modules/@phill-component/icons/mobile/uvue/icon-find-replace/find-replace.png'
|
|
15
|
+
const props = defineProps({
|
|
16
|
+
size: { type: [String, Number], default: '1em' },
|
|
17
|
+
color: { type: String, default: 'var(--tsm-color-primary)' },
|
|
18
|
+
label: { type: [String, Number], default: '' },
|
|
19
|
+
labelPos: { type: String, default: 'right' },
|
|
20
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
21
|
+
labelColor: { type: String, default: '' },
|
|
22
|
+
space: { type: [String, Number], default: '3px' },
|
|
23
|
+
width: { type: [String, Number], default: '' },
|
|
24
|
+
height: { type: [String, Number], default: '' },
|
|
25
|
+
hoverClass: { type: String, default: '' },
|
|
26
|
+
index: { type: [String, Number], default: '' },
|
|
27
|
+
stop: { type: Boolean, default: false }
|
|
28
|
+
})
|
|
29
|
+
const emit = defineEmits(['click'])
|
|
30
|
+
function toPx(v: any): string {
|
|
31
|
+
if (typeof v === 'number') return (v as number).toString() + 'px'
|
|
32
|
+
const s = (v as string)
|
|
33
|
+
return s != '' ? s : ''
|
|
34
|
+
}
|
|
35
|
+
const iconW = computed((): string => (props.width != '' ? toPx(props.width) : toPx(props.size)))
|
|
36
|
+
const iconH = computed((): string => (props.height != '' ? toPx(props.height) : toPx(props.size)))
|
|
37
|
+
const iconStyle = computed((): UTSJSONObject => {
|
|
38
|
+
return { 'color': props.color != '' ? props.color : 'inherit' } as UTSJSONObject
|
|
39
|
+
})
|
|
40
|
+
const iconBoxStyle = computed((): UTSJSONObject => ({ width: iconW.value, height: iconH.value } as UTSJSONObject))
|
|
41
|
+
const wrapStyle = computed((): UTSJSONObject => {
|
|
42
|
+
const map = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' } as UTSJSONObject
|
|
43
|
+
let dir: string = 'row'
|
|
44
|
+
const cand = map[props.labelPos] as string | null
|
|
45
|
+
if (cand != null && cand.length > 0) {
|
|
46
|
+
dir = cand
|
|
47
|
+
}
|
|
48
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dir } as UTSJSONObject
|
|
49
|
+
})
|
|
50
|
+
const rootStyle = computed((): UTSJSONObject => {
|
|
51
|
+
const s = wrapStyle.value
|
|
52
|
+
const i = iconStyle.value
|
|
53
|
+
for (const key in i) {
|
|
54
|
+
s[key] = i[key]
|
|
55
|
+
}
|
|
56
|
+
return s
|
|
57
|
+
})
|
|
58
|
+
const labelStyle = computed((): UTSJSONObject => {
|
|
59
|
+
const out = {} as UTSJSONObject
|
|
60
|
+
if (props.labelColor != '') out['color'] = props.labelColor
|
|
61
|
+
out['fontSize'] = toPx(props.labelSize)
|
|
62
|
+
out['marginLeft'] = props.labelPos == 'right' ? toPx(props.space) : 0
|
|
63
|
+
out['marginTop'] = props.labelPos == 'bottom' ? toPx(props.space) : 0
|
|
64
|
+
out['marginRight'] = props.labelPos == 'left' ? toPx(props.space) : 0
|
|
65
|
+
out['marginBottom'] = props.labelPos == 'top' ? toPx(props.space) : 0
|
|
66
|
+
return out
|
|
67
|
+
})
|
|
68
|
+
function onTap(e: UniPointerEvent) {
|
|
69
|
+
emit('click', props.index)
|
|
70
|
+
if (props.stop) e.stopPropagation()
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
73
|
+
<style scoped>
|
|
74
|
+
.icon__label { line-height: 1; }
|
|
75
|
+
</style>
|
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="rootStyle">
|
|
3
|
+
<!-- #ifdef H5 -->
|
|
4
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M6 6v18m0 0v18m0-18h20m0 0V6m0 18v18m6-7.5c0 3.038 2.239 5.5 5 5.5s5-2.462 5-5.5-2.239-5.5-5-5.5-5 2.462-5 5.5zm0 0v-5.73c0-4.444 3.867-7.677 8-7.263.437.044.736.08.952.115"/></svg>
|
|
5
|
+
<!-- #endif -->
|
|
6
|
+
<!-- #ifndef H5 -->
|
|
7
|
+
<image :src="imgSrc" :style="iconBoxStyle" />
|
|
8
|
+
<!-- #endif -->
|
|
9
|
+
<text v-if="label != ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
10
|
+
</view>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup lang="uts">
|
|
13
|
+
import { computed } from 'vue'
|
|
14
|
+
import imgSrc from '@/uni_modules/@phill-component/icons/mobile/uvue/icon-h6/h6.png'
|
|
15
|
+
const props = defineProps({
|
|
16
|
+
size: { type: [String, Number], default: '1em' },
|
|
17
|
+
color: { type: String, default: 'var(--tsm-color-primary)' },
|
|
18
|
+
label: { type: [String, Number], default: '' },
|
|
19
|
+
labelPos: { type: String, default: 'right' },
|
|
20
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
21
|
+
labelColor: { type: String, default: '' },
|
|
22
|
+
space: { type: [String, Number], default: '3px' },
|
|
23
|
+
width: { type: [String, Number], default: '' },
|
|
24
|
+
height: { type: [String, Number], default: '' },
|
|
25
|
+
hoverClass: { type: String, default: '' },
|
|
26
|
+
index: { type: [String, Number], default: '' },
|
|
27
|
+
stop: { type: Boolean, default: false }
|
|
28
|
+
})
|
|
29
|
+
const emit = defineEmits(['click'])
|
|
30
|
+
function toPx(v: any): string {
|
|
31
|
+
if (typeof v === 'number') return (v as number).toString() + 'px'
|
|
32
|
+
const s = (v as string)
|
|
33
|
+
return s != '' ? s : ''
|
|
34
|
+
}
|
|
35
|
+
const iconW = computed((): string => (props.width != '' ? toPx(props.width) : toPx(props.size)))
|
|
36
|
+
const iconH = computed((): string => (props.height != '' ? toPx(props.height) : toPx(props.size)))
|
|
37
|
+
const iconStyle = computed((): UTSJSONObject => {
|
|
38
|
+
return { 'color': props.color != '' ? props.color : 'inherit' } as UTSJSONObject
|
|
39
|
+
})
|
|
40
|
+
const iconBoxStyle = computed((): UTSJSONObject => ({ width: iconW.value, height: iconH.value } as UTSJSONObject))
|
|
41
|
+
const wrapStyle = computed((): UTSJSONObject => {
|
|
42
|
+
const map = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' } as UTSJSONObject
|
|
43
|
+
let dir: string = 'row'
|
|
44
|
+
const cand = map[props.labelPos] as string | null
|
|
45
|
+
if (cand != null && cand.length > 0) {
|
|
46
|
+
dir = cand
|
|
47
|
+
}
|
|
48
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dir } as UTSJSONObject
|
|
49
|
+
})
|
|
50
|
+
const rootStyle = computed((): UTSJSONObject => {
|
|
51
|
+
const s = wrapStyle.value
|
|
52
|
+
const i = iconStyle.value
|
|
53
|
+
for (const key in i) {
|
|
54
|
+
s[key] = i[key]
|
|
55
|
+
}
|
|
56
|
+
return s
|
|
57
|
+
})
|
|
58
|
+
const labelStyle = computed((): UTSJSONObject => {
|
|
59
|
+
const out = {} as UTSJSONObject
|
|
60
|
+
if (props.labelColor != '') out['color'] = props.labelColor
|
|
61
|
+
out['fontSize'] = toPx(props.labelSize)
|
|
62
|
+
out['marginLeft'] = props.labelPos == 'right' ? toPx(props.space) : 0
|
|
63
|
+
out['marginTop'] = props.labelPos == 'bottom' ? toPx(props.space) : 0
|
|
64
|
+
out['marginRight'] = props.labelPos == 'left' ? toPx(props.space) : 0
|
|
65
|
+
out['marginBottom'] = props.labelPos == 'top' ? toPx(props.space) : 0
|
|
66
|
+
return out
|
|
67
|
+
})
|
|
68
|
+
function onTap(e: UniPointerEvent) {
|
|
69
|
+
emit('click', props.index)
|
|
70
|
+
if (props.stop) e.stopPropagation()
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
73
|
+
<style scoped>
|
|
74
|
+
.icon__label { line-height: 1; }
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="[wrapStyle, iconStyle]">
|
|
3
|
+
<!-- #ifdef H5 -->
|
|
4
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M42.354 40.854 36.01 34.51m0 0a9 9 0 0 1-15.364-6.364c0-5 4-9 9-9s9 4 9 9a8.97 8.97 0 0 1-2.636 6.364zm5.636-26.365h-36m10 16h-10m10 16h-10"/></svg>
|
|
5
|
+
<!-- #endif -->
|
|
6
|
+
<!-- #ifndef H5 -->
|
|
7
|
+
<image :src="imgSrc" :style="iconBoxStyle" />
|
|
8
|
+
<!-- #endif -->
|
|
9
|
+
<text v-if="label !== ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
10
|
+
</view>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup>
|
|
13
|
+
import { computed } from 'vue'
|
|
14
|
+
import imgSrc from '@/uni_modules/@phill-component/icons/mobile/uvue/icon-find-replace/find-replace.png'
|
|
15
|
+
const props = defineProps({
|
|
16
|
+
size: { type: [String, Number], default: '1em' },
|
|
17
|
+
color: { type: String, default: 'var(--tsm-color-primary)' },
|
|
18
|
+
label: { type: [String, Number], default: '' },
|
|
19
|
+
labelPos: { type: String, default: 'right' },
|
|
20
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
21
|
+
labelColor: { type: String, default: '' },
|
|
22
|
+
space: { type: [String, Number], default: '3px' },
|
|
23
|
+
width: { type: [String, Number], default: '' },
|
|
24
|
+
height: { type: [String, Number], default: '' },
|
|
25
|
+
hoverClass: { type: String, default: '' },
|
|
26
|
+
index: { type: [String, Number], default: '' },
|
|
27
|
+
stop: { type: Boolean, default: false }
|
|
28
|
+
})
|
|
29
|
+
const emit = defineEmits(['click'])
|
|
30
|
+
const toPx = (v) => typeof v === 'number' ? (v + 'px') : (String(v||''));
|
|
31
|
+
const iconW = computed(() => props.width ? toPx(props.width) : toPx(props.size))
|
|
32
|
+
const iconH = computed(() => props.height ? toPx(props.height) : toPx(props.size))
|
|
33
|
+
const iconBoxStyle = computed(() => ({ width: iconW.value, height: iconH.value }))
|
|
34
|
+
const iconStyle = computed(() => {
|
|
35
|
+
return { color: props.color || 'inherit' }
|
|
36
|
+
})
|
|
37
|
+
const wrapStyle = computed(() => {
|
|
38
|
+
const dirMap = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' }
|
|
39
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dirMap[props.labelPos] || 'row' }
|
|
40
|
+
})
|
|
41
|
+
const labelStyle = computed(() => {
|
|
42
|
+
return {
|
|
43
|
+
color: props.labelColor || '',
|
|
44
|
+
fontSize: toPx(props.labelSize),
|
|
45
|
+
marginLeft: props.labelPos === 'right' ? toPx(props.space) : 0,
|
|
46
|
+
marginTop: props.labelPos === 'bottom' ? toPx(props.space) : 0,
|
|
47
|
+
marginRight: props.labelPos === 'left' ? toPx(props.space) : 0,
|
|
48
|
+
marginBottom: props.labelPos === 'top' ? toPx(props.space) : 0
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
function onTap(e) {
|
|
52
|
+
emit('click', props.index)
|
|
53
|
+
if (props.stop && e && e.stopPropagation) e.stopPropagation()
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
<style scoped>
|
|
57
|
+
.icon__label { line-height: 1; }
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="[wrapStyle, iconStyle]">
|
|
3
|
+
<!-- #ifdef H5 -->
|
|
4
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M6 6v18m0 0v18m0-18h20m0 0V6m0 18v18m6-7.5c0 3.038 2.239 5.5 5 5.5s5-2.462 5-5.5-2.239-5.5-5-5.5-5 2.462-5 5.5zm0 0v-5.73c0-4.444 3.867-7.677 8-7.263.437.044.736.08.952.115"/></svg>
|
|
5
|
+
<!-- #endif -->
|
|
6
|
+
<!-- #ifndef H5 -->
|
|
7
|
+
<image :src="imgSrc" :style="iconBoxStyle" />
|
|
8
|
+
<!-- #endif -->
|
|
9
|
+
<text v-if="label !== ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
10
|
+
</view>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup>
|
|
13
|
+
import { computed } from 'vue'
|
|
14
|
+
import imgSrc from '@/uni_modules/@phill-component/icons/mobile/uvue/icon-h6/h6.png'
|
|
15
|
+
const props = defineProps({
|
|
16
|
+
size: { type: [String, Number], default: '1em' },
|
|
17
|
+
color: { type: String, default: 'var(--tsm-color-primary)' },
|
|
18
|
+
label: { type: [String, Number], default: '' },
|
|
19
|
+
labelPos: { type: String, default: 'right' },
|
|
20
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
21
|
+
labelColor: { type: String, default: '' },
|
|
22
|
+
space: { type: [String, Number], default: '3px' },
|
|
23
|
+
width: { type: [String, Number], default: '' },
|
|
24
|
+
height: { type: [String, Number], default: '' },
|
|
25
|
+
hoverClass: { type: String, default: '' },
|
|
26
|
+
index: { type: [String, Number], default: '' },
|
|
27
|
+
stop: { type: Boolean, default: false }
|
|
28
|
+
})
|
|
29
|
+
const emit = defineEmits(['click'])
|
|
30
|
+
const toPx = (v) => typeof v === 'number' ? (v + 'px') : (String(v||''));
|
|
31
|
+
const iconW = computed(() => props.width ? toPx(props.width) : toPx(props.size))
|
|
32
|
+
const iconH = computed(() => props.height ? toPx(props.height) : toPx(props.size))
|
|
33
|
+
const iconBoxStyle = computed(() => ({ width: iconW.value, height: iconH.value }))
|
|
34
|
+
const iconStyle = computed(() => {
|
|
35
|
+
return { color: props.color || 'inherit' }
|
|
36
|
+
})
|
|
37
|
+
const wrapStyle = computed(() => {
|
|
38
|
+
const dirMap = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' }
|
|
39
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dirMap[props.labelPos] || 'row' }
|
|
40
|
+
})
|
|
41
|
+
const labelStyle = computed(() => {
|
|
42
|
+
return {
|
|
43
|
+
color: props.labelColor || '',
|
|
44
|
+
fontSize: toPx(props.labelSize),
|
|
45
|
+
marginLeft: props.labelPos === 'right' ? toPx(props.space) : 0,
|
|
46
|
+
marginTop: props.labelPos === 'bottom' ? toPx(props.space) : 0,
|
|
47
|
+
marginRight: props.labelPos === 'left' ? toPx(props.space) : 0,
|
|
48
|
+
marginBottom: props.labelPos === 'top' ? toPx(props.space) : 0
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
function onTap(e) {
|
|
52
|
+
emit('click', props.index)
|
|
53
|
+
if (props.stop && e && e.stopPropagation) e.stopPropagation()
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
<style scoped>
|
|
57
|
+
.icon__label { line-height: 1; }
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="[wrapStyle, iconStyle]">
|
|
3
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M42.354 40.854 36.01 34.51m0 0a9 9 0 0 1-15.364-6.364c0-5 4-9 9-9s9 4 9 9a8.97 8.97 0 0 1-2.636 6.364zm5.636-26.365h-36m10 16h-10m10 16h-10"/></svg>
|
|
4
|
+
<text v-if="label !== ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
5
|
+
</view>
|
|
6
|
+
</template>
|
|
7
|
+
<script setup>
|
|
8
|
+
import { computed } from 'vue'
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
size: { type: [String, Number], default: '1em' },
|
|
11
|
+
color: { type: String, default: 'inherit' },
|
|
12
|
+
label: { type: [String, Number], default: '' },
|
|
13
|
+
labelPos: { type: String, default: 'right' },
|
|
14
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
15
|
+
labelColor: { type: String, default: '' },
|
|
16
|
+
space: { type: [String, Number], default: '3px' },
|
|
17
|
+
width: { type: [String, Number], default: '' },
|
|
18
|
+
height: { type: [String, Number], default: '' },
|
|
19
|
+
hoverClass: { type: String, default: '' },
|
|
20
|
+
index: { type: [String, Number], default: '' },
|
|
21
|
+
stop: { type: Boolean, default: false }
|
|
22
|
+
})
|
|
23
|
+
const emit = defineEmits(['click'])
|
|
24
|
+
const toPx = (v) => typeof v === 'number' ? (v + 'px') : (String(v||''));
|
|
25
|
+
const iconW = computed(() => props.width ? toPx(props.width) : toPx(props.size))
|
|
26
|
+
const iconH = computed(() => props.height ? toPx(props.height) : toPx(props.size))
|
|
27
|
+
const iconBoxStyle = computed(() => ({ width: iconW.value, height: iconH.value }))
|
|
28
|
+
const iconStyle = computed(() => {
|
|
29
|
+
return { color: props.color || 'inherit' }
|
|
30
|
+
})
|
|
31
|
+
const wrapStyle = computed(() => {
|
|
32
|
+
const dirMap = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' }
|
|
33
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dirMap[props.labelPos] || 'row' }
|
|
34
|
+
})
|
|
35
|
+
const labelStyle = computed(() => {
|
|
36
|
+
return {
|
|
37
|
+
color: props.labelColor || '',
|
|
38
|
+
fontSize: toPx(props.labelSize),
|
|
39
|
+
marginLeft: props.labelPos === 'right' ? toPx(props.space) : 0,
|
|
40
|
+
marginTop: props.labelPos === 'bottom' ? toPx(props.space) : 0,
|
|
41
|
+
marginRight: props.labelPos === 'left' ? toPx(props.space) : 0,
|
|
42
|
+
marginBottom: props.labelPos === 'top' ? toPx(props.space) : 0
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
const imgSrc = '__IMG_SRC__'
|
|
46
|
+
function onTap(e) {
|
|
47
|
+
emit('click', props.index)
|
|
48
|
+
if (props.stop && e && e.stopPropagation) e.stopPropagation()
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
<style scoped>
|
|
52
|
+
.icon__label { line-height: 1; }
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="icon" @tap="onTap" :hover-class="hoverClass" :style="[wrapStyle, iconStyle]">
|
|
3
|
+
<svg v-bind="$attrs" :style="iconStyle" :width="iconW" :height="iconH" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-width="2" d="M6 6v18m0 0v18m0-18h20m0 0V6m0 18v18m6-7.5c0 3.038 2.239 5.5 5 5.5s5-2.462 5-5.5-2.239-5.5-5-5.5-5 2.462-5 5.5zm0 0v-5.73c0-4.444 3.867-7.677 8-7.263.437.044.736.08.952.115"/></svg>
|
|
4
|
+
<text v-if="label !== ''" class="icon__label" :style="labelStyle">{{ label }}</text>
|
|
5
|
+
</view>
|
|
6
|
+
</template>
|
|
7
|
+
<script setup>
|
|
8
|
+
import { computed } from 'vue'
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
size: { type: [String, Number], default: '1em' },
|
|
11
|
+
color: { type: String, default: 'inherit' },
|
|
12
|
+
label: { type: [String, Number], default: '' },
|
|
13
|
+
labelPos: { type: String, default: 'right' },
|
|
14
|
+
labelSize: { type: [String, Number], default: '15px' },
|
|
15
|
+
labelColor: { type: String, default: '' },
|
|
16
|
+
space: { type: [String, Number], default: '3px' },
|
|
17
|
+
width: { type: [String, Number], default: '' },
|
|
18
|
+
height: { type: [String, Number], default: '' },
|
|
19
|
+
hoverClass: { type: String, default: '' },
|
|
20
|
+
index: { type: [String, Number], default: '' },
|
|
21
|
+
stop: { type: Boolean, default: false }
|
|
22
|
+
})
|
|
23
|
+
const emit = defineEmits(['click'])
|
|
24
|
+
const toPx = (v) => typeof v === 'number' ? (v + 'px') : (String(v||''));
|
|
25
|
+
const iconW = computed(() => props.width ? toPx(props.width) : toPx(props.size))
|
|
26
|
+
const iconH = computed(() => props.height ? toPx(props.height) : toPx(props.size))
|
|
27
|
+
const iconBoxStyle = computed(() => ({ width: iconW.value, height: iconH.value }))
|
|
28
|
+
const iconStyle = computed(() => {
|
|
29
|
+
return { color: props.color || 'inherit' }
|
|
30
|
+
})
|
|
31
|
+
const wrapStyle = computed(() => {
|
|
32
|
+
const dirMap = { right: 'row', left: 'row-reverse', top: 'column-reverse', bottom: 'column' }
|
|
33
|
+
return { display: 'flex', alignItems: 'center', flexDirection: dirMap[props.labelPos] || 'row' }
|
|
34
|
+
})
|
|
35
|
+
const labelStyle = computed(() => {
|
|
36
|
+
return {
|
|
37
|
+
color: props.labelColor || '',
|
|
38
|
+
fontSize: toPx(props.labelSize),
|
|
39
|
+
marginLeft: props.labelPos === 'right' ? toPx(props.space) : 0,
|
|
40
|
+
marginTop: props.labelPos === 'bottom' ? toPx(props.space) : 0,
|
|
41
|
+
marginRight: props.labelPos === 'left' ? toPx(props.space) : 0,
|
|
42
|
+
marginBottom: props.labelPos === 'top' ? toPx(props.space) : 0
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
const imgSrc = '__IMG_SRC__'
|
|
46
|
+
function onTap(e) {
|
|
47
|
+
emit('click', props.index)
|
|
48
|
+
if (props.stop && e && e.stopPropagation) e.stopPropagation()
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
<style scoped>
|
|
52
|
+
.icon__label { line-height: 1; }
|
|
53
|
+
</style>
|
package/dist/web/vue/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { default as IconCalendar } from './Calendar.vue';
|
|
2
2
|
export { default as IconFileFold } from './FileFold.vue';
|
|
3
|
+
export { default as IconFindReplace } from './FindReplace.vue';
|
|
4
|
+
export { default as IconH6 } from './H6.vue';
|
|
3
5
|
export { default as IconHome } from './Home.vue';
|
|
4
6
|
export { default as IconSetting } from './Setting.vue';
|
|
5
7
|
export { default as IconTask } from './Task.vue';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phill-component/icons",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Unified icons for phillUI mobile and pc libraries",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
],
|
|
11
11
|
"sideEffects": false,
|
|
12
12
|
"bin": {
|
|
13
|
-
"
|
|
13
|
+
"icons": "scripts/install.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "node scripts/build.js",
|
|
17
|
-
"release
|
|
17
|
+
"release": "node scripts/publish.js"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
20
20
|
"icons",
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
"sharp": "^0.34.5"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {}
|
|
35
|
-
}
|
|
35
|
+
}
|
package/scripts/install.js
CHANGED
|
@@ -10,7 +10,7 @@ const path = require('path');
|
|
|
10
10
|
|
|
11
11
|
function resolvePackageRoot() {
|
|
12
12
|
// When executed from node_modules: __dirname -> <pkg>/scripts
|
|
13
|
-
// In workspace/dev: __dirname -> repo/packages/
|
|
13
|
+
// In workspace/dev: __dirname -> repo/packages/icons/scripts
|
|
14
14
|
const scriptsDir = __dirname;
|
|
15
15
|
const candidate = path.resolve(scriptsDir, '..'); // <pkg>
|
|
16
16
|
if (fs.existsSync(path.join(candidate, 'dist'))) return candidate;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const cp = require('child_process');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
function readJSON(p) {
|
|
8
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function normalizeNpmToken(input) {
|
|
12
|
+
let t = String(input || '').trim();
|
|
13
|
+
if (!t) return '';
|
|
14
|
+
if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
|
|
15
|
+
t = t.slice(1, -1).trim();
|
|
16
|
+
}
|
|
17
|
+
const m = t.match(/_authToken\s*=\s*([^\s]+)/);
|
|
18
|
+
if (m && m[1]) return m[1].trim();
|
|
19
|
+
return t;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizeNpmRegistry(input) {
|
|
23
|
+
let r = String(input || '').trim();
|
|
24
|
+
if (!r) r = 'https://registry.npmjs.org/';
|
|
25
|
+
if ((r.startsWith('"') && r.endsWith('"')) || (r.startsWith("'") && r.endsWith("'"))) {
|
|
26
|
+
r = r.slice(1, -1).trim();
|
|
27
|
+
}
|
|
28
|
+
if (!/^https?:\/\//.test(r)) r = `https://${r}`;
|
|
29
|
+
if (!r.endsWith('/')) r += '/';
|
|
30
|
+
return r;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function findProjectRoot(startDir) {
|
|
34
|
+
let dir = startDir;
|
|
35
|
+
while (true) {
|
|
36
|
+
const pkg = path.join(dir, 'package.json');
|
|
37
|
+
if (fs.existsSync(pkg)) {
|
|
38
|
+
try {
|
|
39
|
+
const json = JSON.parse(fs.readFileSync(pkg, 'utf8'));
|
|
40
|
+
if (json && json.private === true && json.name === 'phill-icon') return dir;
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
const parent = path.dirname(dir);
|
|
44
|
+
if (parent === dir) return null;
|
|
45
|
+
dir = parent;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function exec(command, args, options = {}) {
|
|
50
|
+
const res = cp.spawnSync(command, args, { encoding: 'utf8', ...options });
|
|
51
|
+
if (res.status !== 0) {
|
|
52
|
+
const err = new Error(res.stderr || res.stdout || `${command} failed`);
|
|
53
|
+
err.stdout = res.stdout;
|
|
54
|
+
err.stderr = res.stderr;
|
|
55
|
+
err.status = res.status;
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
return res.stdout || '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function main() {
|
|
62
|
+
const args = process.argv.slice(2);
|
|
63
|
+
const checkOnly = args.includes('--check');
|
|
64
|
+
const doPublish = process.env.PHILLUI_PUBLISH === '1';
|
|
65
|
+
|
|
66
|
+
const pkgDir = process.cwd();
|
|
67
|
+
const iconsPkgPath = path.join(pkgDir, 'package.json');
|
|
68
|
+
if (!fs.existsSync(iconsPkgPath)) {
|
|
69
|
+
console.error('[publish-icons] 未在 icons 包目录下执行。');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const iconsPkg = readJSON(iconsPkgPath);
|
|
73
|
+
|
|
74
|
+
if (checkOnly || !doPublish) {
|
|
75
|
+
console.log('[publish-icons] 校验通过。未执行发布(设置 PHILLUI_PUBLISH=1 才会发布)。');
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const npmToken = normalizeNpmToken(process.env.NPM_TOKEN);
|
|
80
|
+
const npmRegistry = normalizeNpmRegistry(process.env.NPM_REGISTRY);
|
|
81
|
+
|
|
82
|
+
const pkgNpmrc = path.join(pkgDir, '.npmrc');
|
|
83
|
+
const root = findProjectRoot(pkgDir);
|
|
84
|
+
const rootNpmrc = root ? path.join(root, '.npmrc') : null;
|
|
85
|
+
|
|
86
|
+
let tmpDir = null;
|
|
87
|
+
let userconfig = null;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// 预先检查版本
|
|
91
|
+
try {
|
|
92
|
+
const viewOut = exec('npm', ['view', iconsPkg.name, 'version', '--registry', npmRegistry], { env: process.env });
|
|
93
|
+
const remoteVersion = String(viewOut).trim();
|
|
94
|
+
if (remoteVersion === iconsPkg.version) {
|
|
95
|
+
console.log(`[publish-icons] ${iconsPkg.name}@${iconsPkg.version} 已存在,跳过。`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {}
|
|
99
|
+
|
|
100
|
+
if (npmToken) {
|
|
101
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'phill-icons-npmrc-'));
|
|
102
|
+
userconfig = path.join(tmpDir, '.npmrc');
|
|
103
|
+
const registryHost = new URL(npmRegistry).host;
|
|
104
|
+
fs.writeFileSync(
|
|
105
|
+
userconfig,
|
|
106
|
+
`registry=${npmRegistry}\n` +
|
|
107
|
+
`always-auth=true\n` +
|
|
108
|
+
`//${registryHost}/:_authToken=${npmToken}\n`
|
|
109
|
+
);
|
|
110
|
+
console.log(`[publish-icons] 使用临时 npmrc:${userconfig}`);
|
|
111
|
+
} else if (fs.existsSync(pkgNpmrc)) {
|
|
112
|
+
userconfig = pkgNpmrc;
|
|
113
|
+
console.log(`[publish-icons] 使用包内 npmrc:${userconfig}`);
|
|
114
|
+
} else if (rootNpmrc && fs.existsSync(rootNpmrc)) {
|
|
115
|
+
userconfig = rootNpmrc;
|
|
116
|
+
console.log(`[publish-icons] 使用根目录 npmrc:${userconfig}`);
|
|
117
|
+
} else {
|
|
118
|
+
console.error('[publish-icons] 缺少认证信息:请提供 NPM_TOKEN 或者提供可用的 .npmrc(包内/根目录)。');
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const env = { ...process.env, NPM_CONFIG_USERCONFIG: userconfig, npm_config_userconfig: userconfig };
|
|
123
|
+
|
|
124
|
+
// 验证身份
|
|
125
|
+
const whoami = exec('npm', ['whoami', '--userconfig', userconfig], { env }).trim();
|
|
126
|
+
console.log(`[publish-icons] 当前登录用户:${whoami}`);
|
|
127
|
+
|
|
128
|
+
console.log(`[publish-icons] 执行:npm publish --access public --userconfig ${userconfig}`);
|
|
129
|
+
exec('npm', ['publish', '--access', 'public', '--userconfig', userconfig], { env });
|
|
130
|
+
console.log(`[publish-icons] ${iconsPkg.name}@${iconsPkg.version} 发布成功!`);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
console.error('[publish-icons] 发布失败:', e.message);
|
|
133
|
+
if (e.stdout) console.error('STDOUT:', e.stdout.toString());
|
|
134
|
+
if (e.stderr) console.error('STDERR:', e.stderr.toString());
|
|
135
|
+
process.exit(e.status || 1);
|
|
136
|
+
} finally {
|
|
137
|
+
if (tmpDir) {
|
|
138
|
+
try {
|
|
139
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
140
|
+
} catch (e) {}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main();
|