@ruixinkeji/prism-ui 1.0.7 → 1.0.8
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/components/PrismAIAssist/PrismAIAssist.vue +3 -3
- package/components/PrismAddressInput/PrismAddressInput.vue +4 -4
- package/components/PrismCityCascadeSelect/PrismCityCascadeSelect.vue +3 -3
- package/components/PrismCityPicker/PrismCityPicker.vue +3 -3
- package/components/PrismCitySelect/PrismCitySelect.vue +3 -3
- package/components/PrismCode/PrismCode.vue +3 -3
- package/components/PrismCodeInput/PrismCodeInput.vue +3 -3
- package/components/PrismDateTimePicker/PrismDateTimePicker.vue +3 -3
- package/components/PrismIdCardInput/PrismIdCardInput.vue +3 -3
- package/components/PrismImagePicker/PrismImagePicker.vue +3 -3
- package/components/PrismLicensePlateInput/PrismLicensePlateInput.vue +3 -3
- package/components/PrismNavBar/PrismNavBar.vue +5 -5
- package/components/PrismSecureInput/PrismSecureInput.vue +3 -3
- package/components/PrismSwitch/PrismSwitch.vue +3 -3
- package/components/PrismTabBar/PrismTabBar.vue +3 -3
- package/components/PrismVoiceInput/PrismVoiceInput.vue +3 -3
- package/composables/useTheme.js +111 -0
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-ai-assist" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-ai-assist" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<view class="ai-btn" :class="{ 'loading': isLoading }" @click="handleClick">
|
|
4
4
|
<text class="fa" :class="isLoading ? 'fa-spinner fa-spin' : 'fa-wand-magic-sparkles'"></text>
|
|
5
5
|
<text class="ai-text">{{ isLoading ? loadingText : text }}</text>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<script setup>
|
|
11
11
|
import { ref } from 'vue';
|
|
12
|
-
import {
|
|
12
|
+
import { useTheme } from '../../composables/useTheme';
|
|
13
13
|
|
|
14
14
|
const props = defineProps({
|
|
15
15
|
text: {
|
|
@@ -24,7 +24,7 @@ const props = defineProps({
|
|
|
24
24
|
|
|
25
25
|
const emit = defineEmits(['click']);
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const { isDarkMode } = useTheme();
|
|
28
28
|
const isLoading = ref(false);
|
|
29
29
|
|
|
30
30
|
function handleClick() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-address-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-address-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 模式1: textarea模式(默认) -->
|
|
4
4
|
<view class="address-wrapper" v-if="mode === 'textarea'">
|
|
5
5
|
<textarea
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
|
|
102
102
|
<script setup>
|
|
103
103
|
import { ref, computed, watch } from 'vue';
|
|
104
|
-
import {
|
|
104
|
+
import { useTheme } from '../../composables/useTheme';
|
|
105
105
|
|
|
106
106
|
const props = defineProps({
|
|
107
107
|
modelValue: {
|
|
@@ -153,7 +153,7 @@ const props = defineProps({
|
|
|
153
153
|
|
|
154
154
|
const emit = defineEmits(['update:modelValue', 'update:latitude', 'update:longitude', 'location-change']);
|
|
155
155
|
|
|
156
|
-
const
|
|
156
|
+
const { isDarkMode } = useTheme();
|
|
157
157
|
const addressValue = ref(props.modelValue);
|
|
158
158
|
const showListPopup = ref(false);
|
|
159
159
|
const showSelectPopup = ref(false);
|
|
@@ -163,7 +163,7 @@ const staticMapUrl = computed(() => {
|
|
|
163
163
|
if (!props.latitude || !props.longitude || !props.mapKey) return '';
|
|
164
164
|
const lat = props.latitude;
|
|
165
165
|
const lng = props.longitude;
|
|
166
|
-
const style =
|
|
166
|
+
const style = isDarkMode.value ? '&style=4' : '';
|
|
167
167
|
return `https://apis.map.qq.com/ws/staticmap/v2/?center=${lat},${lng}&zoom=16&size=600*300&maptype=roadmap&markers=size:large|color:red|${lat},${lng}&key=${props.mapKey}${style}`;
|
|
168
168
|
});
|
|
169
169
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-city-cascade-select" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-city-cascade-select" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 触发器 -->
|
|
4
4
|
<view class="select-trigger" @click="openSelect">
|
|
5
5
|
<slot>
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
|
|
128
128
|
<script setup>
|
|
129
129
|
import { ref, computed, watch } from 'vue';
|
|
130
|
-
import {
|
|
130
|
+
import { useTheme } from '../../composables/useTheme';
|
|
131
131
|
|
|
132
132
|
const props = defineProps({
|
|
133
133
|
modelValue: {
|
|
@@ -188,7 +188,7 @@ const props = defineProps({
|
|
|
188
188
|
|
|
189
189
|
const emit = defineEmits(['update:modelValue', 'change', 'confirm', 'cancel']);
|
|
190
190
|
|
|
191
|
-
const
|
|
191
|
+
const { isDarkMode } = useTheme();
|
|
192
192
|
const showSelect = ref(false);
|
|
193
193
|
const tempSelected = ref([]);
|
|
194
194
|
const currentLevel = ref(0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-city-picker" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-city-picker" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 触发器 -->
|
|
4
4
|
<view class="picker-trigger" @click="openPicker">
|
|
5
5
|
<slot>
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
|
|
158
158
|
<script setup>
|
|
159
159
|
import { ref, computed, watch, onMounted } from 'vue';
|
|
160
|
-
import {
|
|
160
|
+
import { useTheme } from '../../composables/useTheme';
|
|
161
161
|
import { rpx2px } from '../../utils/system';
|
|
162
162
|
|
|
163
163
|
const props = defineProps({
|
|
@@ -227,7 +227,7 @@ const props = defineProps({
|
|
|
227
227
|
|
|
228
228
|
const emit = defineEmits(['update:modelValue', 'change', 'confirm', 'cancel']);
|
|
229
229
|
|
|
230
|
-
const
|
|
230
|
+
const { isDarkMode } = useTheme();
|
|
231
231
|
const showPicker = ref(false);
|
|
232
232
|
const pickerIndex = ref([0, 0, 0]);
|
|
233
233
|
const tempSelected = ref([]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-city-select" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-city-select" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 触发器 -->
|
|
4
4
|
<view class="picker-trigger" @click="openPicker">
|
|
5
5
|
<slot>
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
|
|
104
104
|
<script setup>
|
|
105
105
|
import { ref, computed } from 'vue';
|
|
106
|
-
import {
|
|
106
|
+
import { useTheme } from '../../composables/useTheme';
|
|
107
107
|
import PrismGroupSticky from '../PrismGroupSticky/PrismGroupSticky.vue';
|
|
108
108
|
|
|
109
109
|
const props = defineProps({
|
|
@@ -143,7 +143,7 @@ const props = defineProps({
|
|
|
143
143
|
});
|
|
144
144
|
|
|
145
145
|
const emit = defineEmits(['update:modelValue', 'change', 'confirm']);
|
|
146
|
-
const
|
|
146
|
+
const { isDarkMode } = useTheme();
|
|
147
147
|
|
|
148
148
|
const showPicker = ref(false);
|
|
149
149
|
const searchKeyword = ref('');
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
* <PrismCode code="const a = 1;" language="JavaScript" :copyable="true" />
|
|
51
51
|
*/
|
|
52
52
|
import { ref, computed } from 'vue';
|
|
53
|
-
import {
|
|
53
|
+
import { useTheme } from '../../composables/useTheme';
|
|
54
54
|
|
|
55
55
|
const props = defineProps({
|
|
56
56
|
// 要展示的代码内容
|
|
@@ -83,7 +83,7 @@ const props = defineProps({
|
|
|
83
83
|
highlight: { type: Boolean, default: true }
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
const
|
|
86
|
+
const { isDarkMode } = useTheme();
|
|
87
87
|
const copied = ref(false);
|
|
88
88
|
const isExpanded = ref(props.defaultExpanded);
|
|
89
89
|
const foldedRanges = ref(new Set());
|
|
@@ -91,7 +91,7 @@ const foldedRanges = ref(new Set());
|
|
|
91
91
|
// 计算实际主题
|
|
92
92
|
const actualTheme = computed(() => {
|
|
93
93
|
if (props.theme === 'auto') {
|
|
94
|
-
return
|
|
94
|
+
return isDarkMode.value ? 'dark' : 'light';
|
|
95
95
|
}
|
|
96
96
|
return props.theme;
|
|
97
97
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-code-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-code-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<view class="code-boxes">
|
|
4
4
|
<view
|
|
5
5
|
v-for="(item, index) in codeLength"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
<script setup>
|
|
30
30
|
import { ref, computed, watch } from 'vue';
|
|
31
|
-
import {
|
|
31
|
+
import { useTheme } from '../../composables/useTheme';
|
|
32
32
|
|
|
33
33
|
const props = defineProps({
|
|
34
34
|
length: {
|
|
@@ -43,7 +43,7 @@ const props = defineProps({
|
|
|
43
43
|
|
|
44
44
|
const emit = defineEmits(['update:modelValue', 'complete']);
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const { isDarkMode } = useTheme();
|
|
47
47
|
const codeValue = ref(props.modelValue);
|
|
48
48
|
const isFocused = ref(false);
|
|
49
49
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-datetime-picker" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-datetime-picker" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 触发器 -->
|
|
4
4
|
<view class="picker-trigger" @click="openPicker">
|
|
5
5
|
<slot>
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
|
|
188
188
|
<script setup>
|
|
189
189
|
import { ref, computed, watch } from 'vue';
|
|
190
|
-
import {
|
|
190
|
+
import { useTheme } from '../../composables/useTheme';
|
|
191
191
|
import { rpx2px } from '../../utils/system';
|
|
192
192
|
import { getLunarDayStr } from '../../utils/lunar';
|
|
193
193
|
|
|
@@ -253,7 +253,7 @@ const props = defineProps({
|
|
|
253
253
|
|
|
254
254
|
const emit = defineEmits(['update:modelValue', 'change', 'confirm', 'cancel']);
|
|
255
255
|
|
|
256
|
-
const
|
|
256
|
+
const { isDarkMode } = useTheme();
|
|
257
257
|
const showPicker = ref(false);
|
|
258
258
|
const pickerIndex = ref([0, 0, 0, 0, 0, 0]);
|
|
259
259
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-id-card-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-id-card-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 身份证号输入框 -->
|
|
4
4
|
<view class="id-card-input-wrapper">
|
|
5
5
|
<input
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
<script setup>
|
|
37
37
|
import { ref, computed, watch } from 'vue';
|
|
38
|
-
import {
|
|
38
|
+
import { useTheme } from '../../composables/useTheme';
|
|
39
39
|
|
|
40
40
|
const props = defineProps({
|
|
41
41
|
modelValue: {
|
|
@@ -54,7 +54,7 @@ const props = defineProps({
|
|
|
54
54
|
|
|
55
55
|
const emit = defineEmits(['update:modelValue', 'complete', 'valid']);
|
|
56
56
|
|
|
57
|
-
const
|
|
57
|
+
const { isDarkMode } = useTheme();
|
|
58
58
|
const idValue = ref(props.modelValue);
|
|
59
59
|
const lastDisplayLength = ref(0);
|
|
60
60
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-image-picker" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-image-picker" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 主图片区域 -->
|
|
4
4
|
<view class="picker-main">
|
|
5
5
|
<!-- 已选图片预览 -->
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
|
|
67
67
|
<script setup>
|
|
68
68
|
import { ref } from 'vue';
|
|
69
|
-
import {
|
|
69
|
+
import { useTheme } from '../../composables/useTheme';
|
|
70
70
|
|
|
71
71
|
const props = defineProps({
|
|
72
72
|
modelValue: {
|
|
@@ -128,7 +128,7 @@ const props = defineProps({
|
|
|
128
128
|
|
|
129
129
|
const emit = defineEmits(['update:modelValue', 'change', 'upload', 'remove']);
|
|
130
130
|
|
|
131
|
-
const
|
|
131
|
+
const { isDarkMode } = useTheme();
|
|
132
132
|
const showSourcePopup = ref(false);
|
|
133
133
|
|
|
134
134
|
// 处理上传
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-license-plate-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-license-plate-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 车牌号输入框 -->
|
|
4
4
|
<view class="plate-boxes">
|
|
5
5
|
<!-- 第1位 -->
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
|
|
237
237
|
<script setup>
|
|
238
238
|
import { ref, computed, watch } from 'vue';
|
|
239
|
-
import {
|
|
239
|
+
import { useTheme } from '../../composables/useTheme';
|
|
240
240
|
|
|
241
241
|
const props = defineProps({
|
|
242
242
|
modelValue: {
|
|
@@ -247,7 +247,7 @@ const props = defineProps({
|
|
|
247
247
|
|
|
248
248
|
const emit = defineEmits(['update:modelValue', 'complete']);
|
|
249
249
|
|
|
250
|
-
const
|
|
250
|
+
const { isDarkMode } = useTheme();
|
|
251
251
|
|
|
252
252
|
const isNewEnergy = ref(false);
|
|
253
253
|
const showKeyboard = ref(false);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-nav-bar" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-nav-bar" :class="{ 'dark-mode': isDarkMode, 'glass-effect': glass }" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
3
3
|
<view class="nav-bar-content">
|
|
4
4
|
<view class="nav-bar-left">
|
|
5
5
|
<!-- 返回按钮 -->
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
<script setup>
|
|
25
25
|
import { computed } from 'vue';
|
|
26
|
-
import {
|
|
26
|
+
import { useTheme } from '../../composables/useTheme';
|
|
27
27
|
|
|
28
28
|
const props = defineProps({
|
|
29
29
|
title: {
|
|
@@ -48,7 +48,7 @@ const props = defineProps({
|
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const { isDarkMode, themeMode, statusBarHeight, toggleTheme } = useTheme();
|
|
52
52
|
|
|
53
53
|
// 主题图标
|
|
54
54
|
const themeIcon = computed(() => {
|
|
@@ -57,11 +57,11 @@ const themeIcon = computed(() => {
|
|
|
57
57
|
'dark': 'fa-moon',
|
|
58
58
|
'system': 'fa-circle-half-stroke'
|
|
59
59
|
};
|
|
60
|
-
return icons[
|
|
60
|
+
return icons[themeMode.value] || 'fa-moon';
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
function handleThemeClick() {
|
|
64
|
-
|
|
64
|
+
toggleTheme();
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function handleBack() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-secure-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-secure-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 密码输入框 -->
|
|
4
4
|
<view class="password-boxes" @click="showKeyboardModal">
|
|
5
5
|
<view
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
|
|
58
58
|
<script setup>
|
|
59
59
|
import { ref, computed, watch, onMounted } from 'vue';
|
|
60
|
-
import {
|
|
60
|
+
import { useTheme } from '../../composables/useTheme';
|
|
61
61
|
|
|
62
62
|
const props = defineProps({
|
|
63
63
|
modelValue: {
|
|
@@ -80,7 +80,7 @@ const props = defineProps({
|
|
|
80
80
|
|
|
81
81
|
const emit = defineEmits(['update:modelValue', 'complete']);
|
|
82
82
|
|
|
83
|
-
const
|
|
83
|
+
const { isDarkMode } = useTheme();
|
|
84
84
|
const passwordValue = ref(props.modelValue);
|
|
85
85
|
const isFocused = ref(false);
|
|
86
86
|
const showKeyboard = ref(false);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<view
|
|
3
3
|
class="prism-switch-component"
|
|
4
4
|
:class="{
|
|
5
|
-
'dark-mode':
|
|
5
|
+
'dark-mode': isDarkMode,
|
|
6
6
|
'active': modelValue,
|
|
7
7
|
'square': square,
|
|
8
8
|
'disabled': disabled,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
<script setup>
|
|
22
22
|
import { computed } from 'vue';
|
|
23
|
-
import {
|
|
23
|
+
import { useTheme } from '../../composables/useTheme';
|
|
24
24
|
|
|
25
25
|
const props = defineProps({
|
|
26
26
|
modelValue: {
|
|
@@ -56,7 +56,7 @@ const props = defineProps({
|
|
|
56
56
|
|
|
57
57
|
const emit = defineEmits(['update:modelValue', 'change']);
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const { isDarkMode } = useTheme();
|
|
60
60
|
|
|
61
61
|
function handleToggle() {
|
|
62
62
|
if (props.disabled) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-tabbar" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-tabbar" :class="{ 'dark-mode': isDarkMode, 'glass-effect': glass, 'wechat-browser': isWechatBrowser }">
|
|
3
3
|
<view
|
|
4
4
|
class="prism-tabbar-item"
|
|
5
5
|
v-for="(item, index) in tabList"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
<script setup>
|
|
19
19
|
import { computed, ref, onMounted } from 'vue';
|
|
20
|
-
import {
|
|
20
|
+
import { useTheme } from '../../composables/useTheme';
|
|
21
21
|
|
|
22
22
|
const props = defineProps({
|
|
23
23
|
current: {
|
|
@@ -39,7 +39,7 @@ const props = defineProps({
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
const
|
|
42
|
+
const { isDarkMode } = useTheme();
|
|
43
43
|
const currentPath = computed(() => props.current);
|
|
44
44
|
const tabList = computed(() => props.tabs);
|
|
45
45
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="prism-voice-input" :class="{ 'dark-mode':
|
|
2
|
+
<view class="prism-voice-input" :class="{ 'dark-mode': isDarkMode }">
|
|
3
3
|
<!-- 模式1: 按钮模式(默认) -->
|
|
4
4
|
<view
|
|
5
5
|
v-if="mode === 'button'"
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
<script setup>
|
|
69
69
|
import { ref, watch, onUnmounted } from 'vue';
|
|
70
|
-
import {
|
|
70
|
+
import { useTheme } from '../../composables/useTheme';
|
|
71
71
|
|
|
72
72
|
const props = defineProps({
|
|
73
73
|
// 模式:button(按钮)或 modal(弹窗)
|
|
@@ -95,7 +95,7 @@ const props = defineProps({
|
|
|
95
95
|
|
|
96
96
|
const emit = defineEmits(['update:visible', 'start', 'end', 'cancel', 'result', 'confirm']);
|
|
97
97
|
|
|
98
|
-
const
|
|
98
|
+
const { isDarkMode } = useTheme();
|
|
99
99
|
const isRecording = ref(false);
|
|
100
100
|
const cancelHint = ref(false);
|
|
101
101
|
const recordingTime = ref(0);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 主题检测 Composable
|
|
3
|
+
* 组件库内部使用,不依赖外部 store
|
|
4
|
+
*/
|
|
5
|
+
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
|
6
|
+
|
|
7
|
+
// 全局状态(单例模式,所有组件共享)
|
|
8
|
+
const isDarkMode = ref(false);
|
|
9
|
+
const themeMode = ref('system'); // 'light' | 'dark' | 'system'
|
|
10
|
+
const statusBarHeight = ref(0);
|
|
11
|
+
let initialized = false;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 初始化主题检测
|
|
15
|
+
*/
|
|
16
|
+
function initTheme() {
|
|
17
|
+
if (initialized) return;
|
|
18
|
+
initialized = true;
|
|
19
|
+
|
|
20
|
+
// 获取状态栏高度
|
|
21
|
+
try {
|
|
22
|
+
const systemInfo = uni.getSystemInfoSync();
|
|
23
|
+
statusBarHeight.value = systemInfo.statusBarHeight || 0;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
statusBarHeight.value = 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 检测系统深色模式
|
|
29
|
+
updateSystemTheme();
|
|
30
|
+
|
|
31
|
+
// 监听系统主题变化
|
|
32
|
+
// #ifdef H5
|
|
33
|
+
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
34
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
35
|
+
mediaQuery.addEventListener('change', updateSystemTheme);
|
|
36
|
+
}
|
|
37
|
+
// #endif
|
|
38
|
+
|
|
39
|
+
// #ifndef H5
|
|
40
|
+
uni.onThemeChange && uni.onThemeChange((res) => {
|
|
41
|
+
if (themeMode.value === 'system') {
|
|
42
|
+
isDarkMode.value = res.theme === 'dark';
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// #endif
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 更新系统主题
|
|
50
|
+
*/
|
|
51
|
+
function updateSystemTheme() {
|
|
52
|
+
if (themeMode.value !== 'system') return;
|
|
53
|
+
|
|
54
|
+
// #ifdef H5
|
|
55
|
+
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
56
|
+
isDarkMode.value = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
57
|
+
}
|
|
58
|
+
// #endif
|
|
59
|
+
|
|
60
|
+
// #ifndef H5
|
|
61
|
+
try {
|
|
62
|
+
const systemInfo = uni.getSystemInfoSync();
|
|
63
|
+
isDarkMode.value = systemInfo.theme === 'dark';
|
|
64
|
+
} catch (e) {
|
|
65
|
+
isDarkMode.value = false;
|
|
66
|
+
}
|
|
67
|
+
// #endif
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 使用主题
|
|
72
|
+
* @returns {{ isDarkMode: Ref<boolean>, themeMode: Ref<string>, setThemeMode: Function }}
|
|
73
|
+
*/
|
|
74
|
+
export function useTheme() {
|
|
75
|
+
onMounted(() => {
|
|
76
|
+
initTheme();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 设置主题模式
|
|
81
|
+
* @param {'light' | 'dark' | 'system'} mode
|
|
82
|
+
*/
|
|
83
|
+
function setThemeMode(mode) {
|
|
84
|
+
themeMode.value = mode;
|
|
85
|
+
if (mode === 'system') {
|
|
86
|
+
updateSystemTheme();
|
|
87
|
+
} else {
|
|
88
|
+
isDarkMode.value = mode === 'dark';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 切换主题模式
|
|
94
|
+
*/
|
|
95
|
+
function toggleTheme() {
|
|
96
|
+
const modes = ['light', 'dark', 'system'];
|
|
97
|
+
const currentIndex = modes.indexOf(themeMode.value);
|
|
98
|
+
const nextIndex = (currentIndex + 1) % modes.length;
|
|
99
|
+
setThemeMode(modes[nextIndex]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
isDarkMode,
|
|
104
|
+
themeMode,
|
|
105
|
+
statusBarHeight,
|
|
106
|
+
setThemeMode,
|
|
107
|
+
toggleTheme
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default useTheme;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruixinkeji/prism-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Prism UI - 现代化玻璃态设计 uni-app 组件库",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.esm.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"styles",
|
|
10
10
|
"theme",
|
|
11
11
|
"components",
|
|
12
|
+
"composables",
|
|
12
13
|
"fonts",
|
|
13
14
|
"store",
|
|
14
15
|
"utils",
|