CSS 使人抓狂

This commit is contained in:
CrescentLeaf
2025-04-20 00:58:52 +08:00
parent 65ff48dabc
commit f305225eb3
8 changed files with 242 additions and 28 deletions

View File

@@ -1,3 +0,0 @@
const Events = {
}

View File

@@ -13,13 +13,70 @@
<link rel="stylesheet" href="https://unpkg.com/mdui@2/mdui.css" /> <link rel="stylesheet" href="https://unpkg.com/mdui@2/mdui.css" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" /> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet" /> <link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet" />
<script src="https://unpkg.com/split.js/dist/split.min.js"></script>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script> <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<title>TheWhiteSilk</title> <title>TheWhiteSilk</title>
<style>
/* 滑条*/
.no-scroll-bar::-webkit-scrollbar {
width: 0px !important;
}
/* https://blog.csdn.net/qq_39347364/article/details/111996581*/
*::-webkit-scrollbar {
width: 7px;
height: 10px;
}
*::-webkit-scrollbar-track {
width: 6px;
background: rgba(#101F1C, 0.1);
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
*::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, .5);
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
transition: background-color .3s;
cursor: pointer;
}
*::-webkit-scrollbar-thumb:hover {
background-color: rgba(144, 147, 153, .3);
}
/* 使用系统字体 在部分系统表现很好*/
/* 我们至今仍未能知道桌面端浏览器字体的秘密*/
*:not(.material-icons, .mdui-icon, mdui-icon, .fa, .google-symbols) {
font-family: -apple-system, system-ui, -webkit-system-font !important;
}
body {
display: flex;
margin: 0 0 0 0;
}
/* 防止小尺寸图片模糊*/
* {
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
-ms-interpolation-mode: nearest-neighbor;
}
</style>
</head> </head>
<body> <body>
@@ -31,13 +88,15 @@
<script type="module"> <script type="module">
import App from './ui/App.js' import App from './ui/App.js'
ReactDOM.createRoot(document.getElementById('app')).render(React.createElement(App, null)) ReactDOM.createRoot(document.getElementById('app')).render(React.createElement(App, null))
let onResize = () => { let onResize = () => {
document.body.style.setProperty('--whitesilk-widget-message-maxwidth', mdui.breakpoint().down('md') ? "80%" : "70%") document.body.style.setProperty('--whitesilk-widget-message-maxwidth', mdui.breakpoint().down('md') ? "80%" : "70%")
document.body.style.setProperty('--whitesilk-window-width', window.innerWidth + 'px')
document.body.style.setProperty('--whitesilk-window-height', window.innerHeight + 'px')
} }
window.addEventListener('resize', onResize) window.addEventListener('resize', onResize)
onResize() onResize()
</script> </script>
</body> </body>

View File

@@ -1,6 +1,8 @@
import Message from "./chat/Message.js" import Message from "./chat/Message.js"
import MessageContainer from "./chat/MessageContainer.js" import MessageContainer from "./chat/MessageContainer.js"
import ContactsListItem from "./main/ContactsListItem.js"
import RecentsListItem from "./main/RecentsListItem.js" import RecentsListItem from "./main/RecentsListItem.js"
import useEventListener from './useEventListener.js'
export default function App() { export default function App() {
const [recentsList, setRecentsList] = React.useState([ const [recentsList, setRecentsList] = React.useState([
@@ -15,15 +17,85 @@ export default function App() {
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png", avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey", nickName: "Maya Fey",
content: "我是绫里真宵, 是一名灵媒师~" content: "我是绫里真宵, 是一名灵媒师~"
} },
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "麻油衣酱",
content: "成步堂君, 我又坐牢了("
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey",
content: "我是绫里真宵, 是一名灵媒师~"
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "麻油衣酱",
content: "成步堂君, 我又坐牢了("
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey",
content: "我是绫里真宵, 是一名灵媒师~"
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "麻油衣酱",
content: "成步堂君, 我又坐牢了("
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey",
content: "我是绫里真宵, 是一名灵媒师~"
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "麻油衣酱",
content: "成步堂君, 我又坐牢了("
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey",
content: "我是绫里真宵, 是一名灵媒师~"
},
]) ])
const [contactsList, setContactsList] = React.useState([]) const [contactsMap, setContactsMap] = React.useState({
默认分组: [
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "麻油衣酱",
},
{
userId: 0,
avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png",
nickName: "Maya Fey",
}
],
})
const [navigationItemSelected, setNavigationItemSelected] = React.useState('Recents')
const navigationRailRef = React.useRef(null)
useEventListener(navigationRailRef, 'change', (event) => {
setNavigationItemSelected(event.target.value)
})
return ( return (
<div style={{ <div style={{
display: "flex", display: "flex",
position: 'relative',
width: 'calc(var(--whitesilk-window-width) - 80px)',
height: 'var(--whitesilk-window-height)',
}}> }}>
<mdui-navigation-rail contained value="Recents"> <mdui-navigation-rail contained value="Recents" ref={navigationRailRef}>
<mdui-button-icon icon="menu" slot="top"></mdui-button-icon> <mdui-button-icon icon="menu" slot="top"></mdui-button-icon>
<mdui-navigation-rail-item icon="watch_later--outlined" value="Recents"></mdui-navigation-rail-item> <mdui-navigation-rail-item icon="watch_later--outlined" value="Recents"></mdui-navigation-rail-item>
@@ -33,24 +105,39 @@ export default function App() {
</mdui-navigation-rail> </mdui-navigation-rail>
{ {
// 侧边列表 // 侧边列表
// 囊括内容: 最近, 联系人
// 最近 对应 聊天页面
// 联系人 对应 ???
} }
<mdui-list style={{ <mdui-list style={{
width: "22.4%" width: "35%",
overflowY: 'auto',
paddingRight: '10px'
}}> }}>
{ {
recentsList.map((v) => navigationItemSelected == "Recents" ?
<RecentsListItem // 最近聊天
title={v.nickName} recentsList.map((v) =>
avatar={v.avatar} <RecentsListItem
content={v.content} /> nickName={v.nickName}
) avatar={v.avatar}
content={v.content} />
) :
// 联系人列表
Object.keys(contactsMap).map((v) =>
<>
<mdui-list-subheader>{v}</mdui-list-subheader>
{
contactsMap[v].map((v2) =>
<ContactsListItem
nickName={v2.nickName}
avatar={v2.avatar} />
)
}
</>
)
} }
</mdui-list> </mdui-list>
<div style={{ <div style={{
height: '100%', height: 'calc(var(--whitesilk-window-height) - 16px)',
marginRight: '10px',
}}> }}>
<mdui-divider vertical></mdui-divider> <mdui-divider vertical></mdui-divider>
</div> </div>
@@ -59,6 +146,7 @@ export default function App() {
} }
<div style={{ <div style={{
width: '100%', width: '100%',
height: '100%',
}}> }}>
<mdui-top-app-bar style={{ <mdui-top-app-bar style={{
position: 'relative', position: 'relative',
@@ -67,7 +155,43 @@ export default function App() {
<mdui-top-app-bar-title>Title</mdui-top-app-bar-title> <mdui-top-app-bar-title>Title</mdui-top-app-bar-title>
<mdui-button-icon icon="more_vert"></mdui-button-icon> <mdui-button-icon icon="more_vert"></mdui-button-icon>
</mdui-top-app-bar> </mdui-top-app-bar>
<MessageContainer> <MessageContainer style={{
overflowY: 'auto',
height: '100%',
}}>
<Message
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message
direction="right"
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message
direction="right"
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message
direction="right"
nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">
Test
</Message>
<Message <Message
nickName="Fey" nickName="Fey"
avatar="https://www.court-records.net/mugshot/aa6-004-maya.png"> avatar="https://www.court-records.net/mugshot/aa6-004-maya.png">

View File

@@ -2,7 +2,7 @@
* 消息容器 * 消息容器
* @returns { React.JSX.Element } * @returns { React.JSX.Element }
*/ */
export default function MessageContainer({ children, ...props } = {}) { export default function MessageContainer({ children, style, ...props } = {}) {
return ( return (
<div style={{ <div style={{
display: 'flex', display: 'flex',
@@ -10,7 +10,8 @@ export default function MessageContainer({ children, ...props } = {}) {
justifyContent: 'flex-end', justifyContent: 'flex-end',
alignItems: 'center', alignItems: 'center',
paddingTop: '10px', paddingTop: '10px',
paddingBottom: '14px' paddingBottom: '14px',
...style,
}} }}
{...props}> {...props}>
{children} {children}

View File

@@ -0,0 +1,16 @@
import Avatar from "../Avatar.js"
export default function ContactsListItem({ nickName, avatar }) {
return (
<mdui-list-item rounded style={{
marginTop: '3px',
marginBottom: '3px',
width: '100%',
}}>
<span style={{
width: "100%",
}}>{nickName}</span>
<Avatar src={avatar} text="title" slot="icon" />
</mdui-list-item>
)
}

View File

@@ -1,17 +1,17 @@
import Avatar from "../Avatar.js" import Avatar from "../Avatar.js"
export default function RecentsListItem({ title, avatar, content }) { export default function RecentsListItem({ nickName, avatar, content }) {
return ( return (
<mdui-list-item rounded style={{ <mdui-list-item rounded style={{
marginTop: '3px', marginTop: '3px',
marginBottom: '3px', marginBottom: '3px',
}}> }}>
{title} {nickName}
<Avatar src={avatar} text="title" slot="icon" /> <Avatar src={avatar} text={nickName} slot="icon" />
<span slot="description" <span slot="description"
style={{ style={{
display: "inline-block", /* 或者 block */ width: "100%",
maxWidth: "100%", /* 或者固定宽度如 200px */ display: "inline-block",
whiteSpace: "nowrap", /* 禁止换行 */ whiteSpace: "nowrap", /* 禁止换行 */
overflow: "hidden", /* 隐藏溢出内容 */ overflow: "hidden", /* 隐藏溢出内容 */
textOverflow: "ellipsis", /* 显示省略号 */ textOverflow: "ellipsis", /* 显示省略号 */

View File

@@ -0,0 +1,17 @@
/**
* @callback callback
* @param { Event } event
*/
/**
* 绑定事件
* @param { React.Ref } ref
* @param { String } eventName
* @param { callback } callback
*/
export default function useEventListener(ref, eventName, callback) {
React.useEffect(() => {
ref.current.addEventListener(eventName, callback)
return () => ref.current.removeEventListener(eventName, callback)
}, [ref, eventName, callback])
}