@coffic/cosy-ui 0.9.71 → 0.9.72
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/app.css +1 -1
- package/dist/index-astro.ts +1 -0
- package/dist/src/components/apple-phone/applePhonePropsBase.ts +36 -0
- package/dist/src/components/apple-phone/constants.ts +48 -0
- package/dist/src-astro/apple-phone/ApplePhone.astro +141 -0
- package/dist/src-astro/apple-phone/PhoneFrame.astro +21 -0
- package/dist/src-astro/apple-phone/StatusBarContent.astro +94 -0
- package/dist/src-astro/apple-phone/index.ts +5 -0
- package/dist/src-astro/apple-phone/props.ts +6 -0
- package/dist/src-astro/env.d.ts +6 -0
- package/dist/src-vue/apple-phone/ApplePhone.vue +71 -119
- package/dist/src-vue/apple-phone/PhoneFrame.vue +19 -0
- package/dist/src-vue/apple-phone/props.ts +6 -0
- package/package.json +3 -2
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Deep Purple - Landscape.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Gold - Landscape.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Gold - Portrait.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Silver - Landscape.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Silver - Portrait.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Space Black - Landscape.png +0 -0
- /package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Space Black - Portrait.png +0 -0
- /package/dist/{src-vue/apple-phone/assets/iPhone 14 Pro - Deep Purple - Portrait.png → src/components/apple-phone/assets/iPhone14ProDeepPurplePortrait.png} +0 -0
package/dist/index-astro.ts
CHANGED
|
@@ -47,6 +47,7 @@ export * from "./src-astro/loading-overlay";
|
|
|
47
47
|
export * from "./src-astro/login";
|
|
48
48
|
export * from "./src-astro/logout";
|
|
49
49
|
export * from "./src-astro/mac-window";
|
|
50
|
+
export * from "./src-astro/apple-phone";
|
|
50
51
|
export * from "./src-astro/main";
|
|
51
52
|
export * from "./src-astro/modal";
|
|
52
53
|
export * from "./src-astro/module";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BackgroundColor } from "../../../src/common/backgrounds";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ApplePhone 组件的基础属性接口(与框架无关)
|
|
5
|
+
*/
|
|
6
|
+
export interface IApplePhonePropsBase {
|
|
7
|
+
/**
|
|
8
|
+
* 窗口高度选项
|
|
9
|
+
* @default 'lg'
|
|
10
|
+
*/
|
|
11
|
+
height?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 窗口标题
|
|
15
|
+
* @default ''
|
|
16
|
+
*/
|
|
17
|
+
title?: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 是否显示阴影效果
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
withShadow?: boolean;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 是否显示 iPhone 边框
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
showFrame?: boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 内容区域背景色
|
|
33
|
+
* @default undefined
|
|
34
|
+
*/
|
|
35
|
+
backgroundColor?: BackgroundColor;
|
|
36
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApplePhone 组件的常量定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// iPhone边框图片尺寸
|
|
6
|
+
export const IPHONE_FRAME_WIDTH = 1339;
|
|
7
|
+
export const IPHONE_FRAME_HEIGHT = 2716;
|
|
8
|
+
|
|
9
|
+
// iPhone边框图片-状态栏离上边框的距离
|
|
10
|
+
export const IPHONE_FRAME_STATUS_BAR_TOP = 115;
|
|
11
|
+
|
|
12
|
+
// iPhone边框图片-状态栏高度
|
|
13
|
+
export const IPHONE_FRAME_STATUS_BAR_HEIGHT = 110;
|
|
14
|
+
|
|
15
|
+
// 比例计算
|
|
16
|
+
export const MAIN_CONTENT_WIDTH_ASPECT_RATIO = 1179 / IPHONE_FRAME_WIDTH;
|
|
17
|
+
export const MAIN_CONTENT_HEIGHT_ASPECT_RATIO = 2556 / IPHONE_FRAME_HEIGHT;
|
|
18
|
+
export const IPHONE_FRAME_STATUS_BAR_HEIGHT_ASPECT_RATIO =
|
|
19
|
+
IPHONE_FRAME_STATUS_BAR_HEIGHT / IPHONE_FRAME_HEIGHT;
|
|
20
|
+
export const IPHONE_FRAME_STATUS_BAR_TOP_ASPECT_RATIO =
|
|
21
|
+
IPHONE_FRAME_STATUS_BAR_TOP / IPHONE_FRAME_HEIGHT;
|
|
22
|
+
|
|
23
|
+
// 预定义的高度选项
|
|
24
|
+
export const HEIGHT_CLASSES = {
|
|
25
|
+
sm: "cosy:h-64", // 256px
|
|
26
|
+
md: "cosy:h-80", // 320px
|
|
27
|
+
lg: "cosy:h-96", // 384px
|
|
28
|
+
xl: "cosy:h-[480px]", // 480px
|
|
29
|
+
"2xl": "cosy:h-[560px]", // 560px
|
|
30
|
+
"3xl": "cosy:h-[640px]", // 640px
|
|
31
|
+
"4xl": "cosy:h-[720px]", // 720px
|
|
32
|
+
"5xl": "cosy:h-[800px]", // 800px
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
// 高度值映射
|
|
36
|
+
export const HEIGHT_VALUES = {
|
|
37
|
+
sm: 256,
|
|
38
|
+
md: 320,
|
|
39
|
+
lg: 384,
|
|
40
|
+
xl: 480,
|
|
41
|
+
"2xl": 560,
|
|
42
|
+
"3xl": 640,
|
|
43
|
+
"4xl": 720,
|
|
44
|
+
"5xl": 800,
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
// 默认高度
|
|
48
|
+
export const DEFAULT_HEIGHT: keyof typeof HEIGHT_VALUES = "lg";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* @component ApplePhone
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* ApplePhone 组件模拟 iPhone 设备的外观,包含状态栏、时间显示和设备边框。
|
|
7
|
+
* 适用于创建移动应用界面原型或展示移动端设计效果。
|
|
8
|
+
*
|
|
9
|
+
* @usage
|
|
10
|
+
* 基本用法:
|
|
11
|
+
* ```astro
|
|
12
|
+
* <ApplePhone title="我的应用">
|
|
13
|
+
* <div>应用内容</div>
|
|
14
|
+
* </ApplePhone>
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* 自定义高度和背景色:
|
|
18
|
+
* ```astro
|
|
19
|
+
* <ApplePhone height="xl" backgroundColor="primary/10">
|
|
20
|
+
* <div>应用内容</div>
|
|
21
|
+
* </ApplePhone>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* 不显示边框:
|
|
25
|
+
* ```astro
|
|
26
|
+
* <ApplePhone showFrame={false}>
|
|
27
|
+
* <div>应用内容</div>
|
|
28
|
+
* </ApplePhone>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @props
|
|
32
|
+
* @prop {'sm'|'md'|'lg'|'xl'|'2xl'|'3xl'|'4xl'|'5xl'} [height='lg'] - 窗口高度选项
|
|
33
|
+
* - sm: 256px (h-64)
|
|
34
|
+
* - md: 320px (h-80)
|
|
35
|
+
* - lg: 384px (h-96) - 默认值
|
|
36
|
+
* - xl: 480px
|
|
37
|
+
* - 2xl: 560px
|
|
38
|
+
* - 3xl: 640px
|
|
39
|
+
* - 4xl: 720px
|
|
40
|
+
* - 5xl: 800px
|
|
41
|
+
* @prop {String} [title=''] - 窗口标题
|
|
42
|
+
* @prop {Boolean} [withShadow=true] - 是否显示阴影效果
|
|
43
|
+
* @prop {Boolean} [showFrame=true] - 是否显示 iPhone 边框
|
|
44
|
+
* @prop {BackgroundColor} [backgroundColor=''] - 内容区域背景色,等同于为其内部的 Container 设置背景色
|
|
45
|
+
*
|
|
46
|
+
* @slots
|
|
47
|
+
* @slot default - 主要内容区域
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
import "../../style";
|
|
51
|
+
import { Container } from "../container";
|
|
52
|
+
import { AlertDialog } from "../alert-dialog";
|
|
53
|
+
import type { IApplePhonePropsBase } from "../../src/components/apple-phone/applePhonePropsBase";
|
|
54
|
+
import StatusBarContent from "./StatusBarContent.astro";
|
|
55
|
+
import PhoneFrame from "./PhoneFrame.astro";
|
|
56
|
+
import {
|
|
57
|
+
IPHONE_FRAME_WIDTH,
|
|
58
|
+
IPHONE_FRAME_HEIGHT,
|
|
59
|
+
MAIN_CONTENT_WIDTH_ASPECT_RATIO,
|
|
60
|
+
MAIN_CONTENT_HEIGHT_ASPECT_RATIO,
|
|
61
|
+
IPHONE_FRAME_STATUS_BAR_HEIGHT_ASPECT_RATIO,
|
|
62
|
+
IPHONE_FRAME_STATUS_BAR_TOP_ASPECT_RATIO,
|
|
63
|
+
HEIGHT_CLASSES,
|
|
64
|
+
HEIGHT_VALUES,
|
|
65
|
+
DEFAULT_HEIGHT,
|
|
66
|
+
} from "../../src/components/apple-phone/constants";
|
|
67
|
+
|
|
68
|
+
// Props 定义 - 使用共享接口
|
|
69
|
+
interface Props extends IApplePhonePropsBase {}
|
|
70
|
+
|
|
71
|
+
const {
|
|
72
|
+
height = DEFAULT_HEIGHT,
|
|
73
|
+
title = "",
|
|
74
|
+
withShadow = true,
|
|
75
|
+
showFrame = true,
|
|
76
|
+
backgroundColor = undefined,
|
|
77
|
+
} = Astro.props as Props;
|
|
78
|
+
|
|
79
|
+
// 计算当前高度的缩放比例
|
|
80
|
+
const currentHeight = HEIGHT_VALUES[height];
|
|
81
|
+
const scaleRatio = currentHeight / 500;
|
|
82
|
+
|
|
83
|
+
// 生成唯一的ID
|
|
84
|
+
const uniqueId = `apple-phone-${Math.random().toString(36).substr(2, 9)}`;
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
<div
|
|
88
|
+
class={`cosy:relative not-prose cosy:mx-auto ${HEIGHT_CLASSES[height]}`}
|
|
89
|
+
style={`aspect-ratio: ${IPHONE_FRAME_WIDTH}/${IPHONE_FRAME_HEIGHT};`}
|
|
90
|
+
apple-phone>
|
|
91
|
+
<!-- iPhone 边框 -->
|
|
92
|
+
{showFrame && <PhoneFrame />}
|
|
93
|
+
|
|
94
|
+
<!-- 顶部状态栏 -->
|
|
95
|
+
<div
|
|
96
|
+
style={`position: absolute; top: ${IPHONE_FRAME_STATUS_BAR_TOP_ASPECT_RATIO * 100}%; height: ${IPHONE_FRAME_STATUS_BAR_HEIGHT_ASPECT_RATIO * 100}%; width: ${MAIN_CONTENT_WIDTH_ASPECT_RATIO * 100}%; left: 50%; transform: translate(-50%, 0); padding-left: 5%; padding-right: 5%; z-index: 50;`}>
|
|
97
|
+
<!-- StatusBarContent 组件 -->
|
|
98
|
+
<StatusBarContent scaleRatio={scaleRatio} />
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<!-- 内容区域 -->
|
|
102
|
+
<div
|
|
103
|
+
class="cosy:inset-0 cosy:h-full cosy:flex cosy:flex-col"
|
|
104
|
+
style={`width: ${MAIN_CONTENT_WIDTH_ASPECT_RATIO * 100}%; height: ${MAIN_CONTENT_HEIGHT_ASPECT_RATIO * 100}%; left: 50%; top: 50%; transform: translate(-50%, -50%); position: absolute; z-index: 20;`}>
|
|
105
|
+
<Container
|
|
106
|
+
rounded="lg"
|
|
107
|
+
height="full"
|
|
108
|
+
background={backgroundColor || 'accent/90'}>
|
|
109
|
+
<div
|
|
110
|
+
class="cosy:h-full cosy:overflow-y-auto cosy:overscroll-y-contain">
|
|
111
|
+
<slot />
|
|
112
|
+
</div>
|
|
113
|
+
</Container>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<AlertDialog id={`${uniqueId}-alert`} message="" />
|
|
118
|
+
|
|
119
|
+
<script>
|
|
120
|
+
// 全局函数,用于处理状态栏时间更新
|
|
121
|
+
function updateTime() {
|
|
122
|
+
const now = new Date();
|
|
123
|
+
const hours = now.getHours().toString().padStart(2, '0');
|
|
124
|
+
const minutes = now.getMinutes().toString().padStart(2, '0');
|
|
125
|
+
return `${hours}:${minutes}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 更新时间显示
|
|
129
|
+
function updateStatusBarTime() {
|
|
130
|
+
const timeElements = document.querySelectorAll('.time-text');
|
|
131
|
+
timeElements.forEach((element) => {
|
|
132
|
+
(element as HTMLElement).textContent = updateTime();
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 初始化并设置定时器
|
|
137
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
138
|
+
updateStatusBarTime();
|
|
139
|
+
setInterval(updateStatusBarTime, 60000); // 每分钟更新一次
|
|
140
|
+
});
|
|
141
|
+
</script>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* @component PhoneFrame
|
|
4
|
+
* @description ApplePhone 组件的内部边框组件,用于显示 iPhone 设备的边框
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Image } from "../image";
|
|
8
|
+
import iphoneFrame from "../../src/components/apple-phone/assets/iPhone14ProDeepPurplePortrait.png";
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<div
|
|
12
|
+
style="
|
|
13
|
+
max-width: 100%;
|
|
14
|
+
max-height: 100%;
|
|
15
|
+
position: absolute;
|
|
16
|
+
top: 0;
|
|
17
|
+
left: 0;
|
|
18
|
+
z-index: 100;
|
|
19
|
+
">
|
|
20
|
+
<Image src={iphoneFrame} alt="iPhone frame" />
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* @component StatusBarContent
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* StatusBarContent 组件显示 iPhone 状态栏的内容,包括时间、信号、WiFi 和电池图标。
|
|
7
|
+
* 组件会自动更新时间显示,并支持根据设备大小进行缩放。
|
|
8
|
+
*
|
|
9
|
+
* @usage
|
|
10
|
+
* 基本用法:
|
|
11
|
+
* ```astro
|
|
12
|
+
* <StatusBarContent />
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 带缩放比例:
|
|
16
|
+
* ```astro
|
|
17
|
+
* <StatusBarContent scaleRatio={1.5} />
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @props
|
|
21
|
+
* @prop {Number} [scaleRatio=1] - 缩放比例,用于根据设备大小调整文字和图标大小
|
|
22
|
+
*
|
|
23
|
+
* @slots
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import "../../style";
|
|
27
|
+
import { IPhoneSignalIcon, IPhoneWifiIcon, IPhoneBatteryIcon } from "../icons";
|
|
28
|
+
|
|
29
|
+
interface Props {
|
|
30
|
+
scaleRatio?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { scaleRatio = 1 } = Astro.props as Props;
|
|
34
|
+
|
|
35
|
+
// 计算缩放后的字体大小
|
|
36
|
+
const scaledFontSize = `${14 * scaleRatio}px`;
|
|
37
|
+
|
|
38
|
+
// 计算缩放后的图标尺寸
|
|
39
|
+
const scaledIconSize = `${15 * scaleRatio}px`;
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
<div class="cosy:flex cosy:items-center cosy:h-full cosy:justify-between">
|
|
43
|
+
<!-- 左侧时间 -->
|
|
44
|
+
<span
|
|
45
|
+
class="cosy:font-medium time-text"
|
|
46
|
+
style={`font-size: ${scaledFontSize}; line-height: 1; transition: font-size 0.2s ease;`}>
|
|
47
|
+
12:00
|
|
48
|
+
</span>
|
|
49
|
+
|
|
50
|
+
<!-- 右侧状态图标 -->
|
|
51
|
+
<div
|
|
52
|
+
class="cosy:flex cosy:flex-row cosy:items-center cosy:space-x-1 cosy:h-full">
|
|
53
|
+
<!-- 信号图标 -->
|
|
54
|
+
<div
|
|
55
|
+
class="cosy:flex cosy:items-center cosy:justify-center"
|
|
56
|
+
style={`width: ${scaledIconSize}; height: ${scaledIconSize}; min-width: 0; min-height: 0;`}>
|
|
57
|
+
<IPhoneSignalIcon class="status-icon" />
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<!-- WiFi图标 -->
|
|
61
|
+
<div
|
|
62
|
+
class="cosy:flex cosy:items-center cosy:justify-center"
|
|
63
|
+
style={`width: ${scaledIconSize}; height: ${scaledIconSize}; min-width: 0; min-height: 0;`}>
|
|
64
|
+
<IPhoneWifiIcon class="status-icon" />
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- 电池图标 -->
|
|
68
|
+
<div
|
|
69
|
+
class="cosy:flex cosy:items-center cosy:justify-center"
|
|
70
|
+
style={`width: ${scaledIconSize}; height: ${scaledIconSize}; min-width: 0; min-height: 0;`}>
|
|
71
|
+
<IPhoneBatteryIcon class="battery-icon" />
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<style>
|
|
77
|
+
/* 确保图标渲染更平滑 */
|
|
78
|
+
svg {
|
|
79
|
+
shape-rendering: geometricPrecision;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* 状态图标通用样式 */
|
|
83
|
+
.status-icon,
|
|
84
|
+
.battery-icon {
|
|
85
|
+
color: #000000;
|
|
86
|
+
fill: currentColor;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.status-icon svg,
|
|
90
|
+
.battery-icon svg {
|
|
91
|
+
width: 100%;
|
|
92
|
+
height: 100%;
|
|
93
|
+
}
|
|
94
|
+
</style>
|
package/dist/src-astro/env.d.ts
CHANGED
|
@@ -1,139 +1,89 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import StatusBarContent from './StatusBarContent.vue';
|
|
2
|
+
import "../../style";
|
|
3
|
+
import { AlertDialog, Container } from "../../index-vue";
|
|
4
|
+
import { ref } from "vue";
|
|
5
|
+
import StatusBarContent from "./StatusBarContent.vue";
|
|
6
|
+
import PhoneFrame from "./PhoneFrame.vue";
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @component ApplePhone
|
|
10
|
+
* @description ApplePhone 组件模拟 iPhone 设备的外观,包含状态栏、时间显示和设备边框。
|
|
11
|
+
* 适用于创建移动应用界面原型或展示移动端设计效果。
|
|
12
|
+
* @props
|
|
13
|
+
* @prop {'sm'|'md'|'lg'|'xl'|'2xl'|'3xl'|'4xl'|'5xl'} [height='lg'] - 窗口高度选项
|
|
14
|
+
* - sm: 256px (h-64)
|
|
15
|
+
* - md: 320px (h-80)
|
|
16
|
+
* - lg: 384px (h-96) - 默认值
|
|
17
|
+
* - xl: 480px
|
|
18
|
+
* - 2xl: 560px
|
|
19
|
+
* - 3xl: 640px
|
|
20
|
+
* - 4xl: 720px
|
|
21
|
+
* - 5xl: 800px
|
|
22
|
+
* @prop {String} [title=''] - 窗口标题
|
|
23
|
+
* @prop {Boolean} [withShadow=true] - 是否显示阴影效果
|
|
24
|
+
* @prop {Boolean} [showFrame=true] - 是否显示 iPhone 边框
|
|
25
|
+
* @prop {BackgroundColor} [backgroundColor=''] - 内容区域背景色,等同于为其内部的 Container 设置背景色
|
|
26
|
+
* @slots
|
|
27
|
+
* @slot default - 主要内容区域
|
|
28
|
+
* @emits
|
|
29
|
+
*/
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
type HeightOption = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl';
|
|
31
|
+
import type { IApplePhoneProps } from "./props";
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
title?: string;
|
|
38
|
-
withShadow?: boolean;
|
|
39
|
-
showFrame?: boolean;
|
|
40
|
-
backgroundColor?: BackgroundColor;
|
|
41
|
-
}
|
|
33
|
+
// 类型定义
|
|
34
|
+
type HeightOption = "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl";
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
45
|
-
height: 'lg',
|
|
46
|
-
title: '',
|
|
47
|
-
withShadow: true,
|
|
48
|
-
showFrame: true,
|
|
49
|
-
backgroundColor: undefined,
|
|
50
|
-
});
|
|
36
|
+
interface Props extends IApplePhoneProps {}
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
38
|
+
// Props 定义
|
|
39
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
40
|
+
height: "lg",
|
|
41
|
+
title: "",
|
|
42
|
+
withShadow: true,
|
|
43
|
+
showFrame: true,
|
|
44
|
+
backgroundColor: undefined,
|
|
45
|
+
});
|
|
60
46
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
47
|
+
import {
|
|
48
|
+
IPHONE_FRAME_WIDTH,
|
|
49
|
+
IPHONE_FRAME_HEIGHT,
|
|
50
|
+
MAIN_CONTENT_WIDTH_ASPECT_RATIO,
|
|
51
|
+
MAIN_CONTENT_HEIGHT_ASPECT_RATIO,
|
|
52
|
+
IPHONE_FRAME_STATUS_BAR_HEIGHT_ASPECT_RATIO,
|
|
53
|
+
IPHONE_FRAME_STATUS_BAR_TOP_ASPECT_RATIO,
|
|
54
|
+
HEIGHT_CLASSES,
|
|
55
|
+
HEIGHT_VALUES,
|
|
56
|
+
} from "../../src/components/apple-phone/constants";
|
|
71
57
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
md: 'cosy:h-80', // 320px
|
|
76
|
-
lg: 'cosy:h-96', // 384px
|
|
77
|
-
xl: 'cosy:h-[480px]', // 480px
|
|
78
|
-
'2xl': 'cosy:h-[560px]', // 560px
|
|
79
|
-
'3xl': 'cosy:h-[640px]', // 640px
|
|
80
|
-
'4xl': 'cosy:h-[720px]', // 720px
|
|
81
|
-
'5xl': 'cosy:h-[800px]', // 800px
|
|
82
|
-
};
|
|
58
|
+
// 响应式数据
|
|
59
|
+
const showAlertDialog = ref(false);
|
|
60
|
+
const alertMessage = ref("");
|
|
83
61
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const heightValues = {
|
|
91
|
-
sm: 256,
|
|
92
|
-
md: 320,
|
|
93
|
-
lg: 384,
|
|
94
|
-
xl: 480,
|
|
95
|
-
'2xl': 560,
|
|
96
|
-
'3xl': 640,
|
|
97
|
-
'4xl': 720,
|
|
98
|
-
'5xl': 800,
|
|
99
|
-
};
|
|
100
|
-
const currentHeight = heightValues[props.height];
|
|
101
|
-
// 基于特定高度计算缩放比例
|
|
102
|
-
return currentHeight / 500;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// 计算属性
|
|
106
|
-
const iphoneFrameSrc = (iphoneFrame as any).src || iphoneFrame;
|
|
62
|
+
// 计算当前高度的缩放比例
|
|
63
|
+
const getScaleRatio = () => {
|
|
64
|
+
const currentHeight = HEIGHT_VALUES[props.height];
|
|
65
|
+
// 基于特定高度计算缩放比例
|
|
66
|
+
return currentHeight / 500;
|
|
67
|
+
};
|
|
107
68
|
</script>
|
|
108
69
|
|
|
109
70
|
<template>
|
|
110
71
|
<div
|
|
111
|
-
:class="['cosy:relative not-prose cosy:mx-auto',
|
|
72
|
+
:class="['cosy:relative not-prose cosy:mx-auto', HEIGHT_CLASSES[height]]"
|
|
112
73
|
:style="{
|
|
113
|
-
aspectRatio: `${
|
|
74
|
+
aspectRatio: `${IPHONE_FRAME_WIDTH}/${IPHONE_FRAME_HEIGHT}`,
|
|
114
75
|
}"
|
|
115
76
|
apple-phone>
|
|
116
77
|
<!-- iPhone 边框 -->
|
|
117
|
-
<
|
|
118
|
-
v-if="showFrame"
|
|
119
|
-
style="
|
|
120
|
-
max-width: 100%;
|
|
121
|
-
max-height: 100%;
|
|
122
|
-
position: absolute;
|
|
123
|
-
top: 0;
|
|
124
|
-
left: 0;
|
|
125
|
-
z-index: 100;
|
|
126
|
-
"
|
|
127
|
-
:src="iphoneFrameSrc"
|
|
128
|
-
alt="iPhone frame" />
|
|
78
|
+
<PhoneFrame v-if="showFrame" />
|
|
129
79
|
|
|
130
80
|
<!-- 顶部状态栏 -->
|
|
131
81
|
<div
|
|
132
82
|
:style="{
|
|
133
83
|
position: 'absolute',
|
|
134
|
-
top:
|
|
135
|
-
height:
|
|
136
|
-
width:
|
|
84
|
+
top: IPHONE_FRAME_STATUS_BAR_TOP_ASPECT_RATIO * 100 + '%',
|
|
85
|
+
height: IPHONE_FRAME_STATUS_BAR_HEIGHT_ASPECT_RATIO * 100 + '%',
|
|
86
|
+
width: MAIN_CONTENT_WIDTH_ASPECT_RATIO * 100 + '%',
|
|
137
87
|
left: '50%',
|
|
138
88
|
transform: 'translate(-50%, 0)',
|
|
139
89
|
paddingLeft: '5%',
|
|
@@ -145,10 +95,10 @@
|
|
|
145
95
|
|
|
146
96
|
<!-- 内容区域 -->
|
|
147
97
|
<div
|
|
148
|
-
class="cosy:inset-0 cosy:h-full"
|
|
98
|
+
class="cosy:inset-0 cosy:h-full cosy:flex cosy:flex-col"
|
|
149
99
|
:style="{
|
|
150
|
-
width:
|
|
151
|
-
height:
|
|
100
|
+
width: MAIN_CONTENT_WIDTH_ASPECT_RATIO * 100 + '%',
|
|
101
|
+
height: MAIN_CONTENT_HEIGHT_ASPECT_RATIO * 100 + '%',
|
|
152
102
|
// 水平居中
|
|
153
103
|
left: '50%',
|
|
154
104
|
// 垂直居中
|
|
@@ -159,9 +109,11 @@
|
|
|
159
109
|
}">
|
|
160
110
|
<Container
|
|
161
111
|
rounded="lg"
|
|
162
|
-
|
|
112
|
+
height="full"
|
|
163
113
|
:background="backgroundColor || 'accent/90'">
|
|
164
|
-
<
|
|
114
|
+
<div class="cosy:h-full cosy:overflow-y-auto cosy:overscroll-y-contain">
|
|
115
|
+
<slot />
|
|
116
|
+
</div>
|
|
165
117
|
</Container>
|
|
166
118
|
</div>
|
|
167
119
|
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import iphoneFrame from "../../src/components/apple-phone/assets/iPhone14ProDeepPurplePortrait.png";
|
|
3
|
+
|
|
4
|
+
const iphoneFrameSrc = (iphoneFrame as any).src || iphoneFrame;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div
|
|
9
|
+
style="
|
|
10
|
+
max-width: 100%;
|
|
11
|
+
max-height: 100%;
|
|
12
|
+
position: absolute;
|
|
13
|
+
top: 0;
|
|
14
|
+
left: 0;
|
|
15
|
+
z-index: 100;
|
|
16
|
+
">
|
|
17
|
+
<img :src="iphoneFrameSrc" alt="iPhone frame" />
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffic/cosy-ui",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.72",
|
|
4
4
|
"description": "An astro component library",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "nookery",
|
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
"@tailwindcss/vite": "^4.1.11",
|
|
70
70
|
"@tsconfig/node22": "^22.0.2",
|
|
71
71
|
"@types/fs-extra": "^11.0.4",
|
|
72
|
-
"@types/node": "^
|
|
72
|
+
"@types/node": "^24.8.1",
|
|
73
|
+
"astro": "^5.14.5",
|
|
73
74
|
"daisyui": "^5.0.50",
|
|
74
75
|
"globals": "^16.3.0",
|
|
75
76
|
"rollup-plugin-copy": "^3.5.0",
|
|
File without changes
|
/package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Gold - Landscape.png
RENAMED
|
File without changes
|
/package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Gold - Portrait.png
RENAMED
|
File without changes
|
/package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Silver - Landscape.png
RENAMED
|
File without changes
|
/package/dist/{src-vue → src/components}/apple-phone/assets/iPhone 14 Pro - Silver - Portrait.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|