Commit 7e8760d
Changed files (4)
src
components
comment
styles
src/components/comment/Twikoo.astro
@@ -1,4 +1,5 @@
---
+import '@/styles/twikoo.css?url';
import { CDN } from '@constants/cdn';
---
src/components/comment/Waline.astro
@@ -1,5 +1,6 @@
---
import { commentConfig, siteConfig } from '@/config';
+import '@/styles/waline.css?url';
const walineConfig = commentConfig.waline!;
const pathName = walineConfig.path ? walineConfig.path(Astro.url.pathname) : Astro.url.pathname;
src/styles/twikoo.css
@@ -0,0 +1,691 @@
+/* stylelint-disable no-descending-specificity */
+/* stylelint-disable selector-class-pattern */
+@reference './global.css';
+
+.twikoo {
+ @apply relative flex h-fit w-full flex-col items-center;
+
+ input,
+ textarea,
+ select {
+ border: none;
+ }
+}
+
+.tk-comments {
+ @apply w-full;
+
+ .tk-row {
+ @apply flex w-full flex-row gap-2;
+ }
+
+ .tk-col {
+ @apply flex w-full flex-col gap-2;
+ }
+
+ /* 回复框样式 */
+ .tk-submit {
+ @apply relative my-2 w-full;
+
+ .tk-avatar {
+ display: none;
+ }
+
+ /* 输入框部分样式 */
+ .tk-col {
+ @apply flex-col-reverse;
+ }
+
+ /* 文本框输入样式 */
+ .el-textarea {
+ @apply border-base-300 relative w-full overflow-hidden rounded-xl border pb-9;
+
+ textarea {
+ @apply bg-base-200/50 w-full p-4;
+
+ resize: none;
+
+ &:focus {
+ outline: none;
+ }
+
+ &::placeholder {
+ @apply text-base-content/50;
+ }
+ }
+
+ .el-input__count {
+ @apply text-base-content/50 absolute right-10 bottom-2 text-sm;
+ }
+ }
+
+ /* 个人信息输入框样式 */
+ .tk-meta-input {
+ @apply flex w-[calc(100%-3.5rem)] flex-col items-center gap-2 md:w-[calc(100%-6.75rem)] md:flex-row;
+ }
+
+ .actions {
+ @apply relative w-full;
+
+ .tk-row-actions-start {
+ @apply absolute bottom-[8.15rem] ml-3 flex flex-row items-center gap-2 md:bottom-[3.15rem];
+
+ input {
+ display: none;
+ }
+ }
+
+ button {
+ @apply border-base-300 bg-primary absolute py-[0.95rem] md:py-[0.3rem];
+
+ &.tk-preview {
+ @apply right-0 bottom-[3.7rem] md:right-[3.35rem] md:bottom-0;
+ }
+
+ &.tk-send {
+ @apply right-0 bottom-0;
+ }
+ }
+ }
+
+ .__markdown {
+ @apply absolute right-3 bottom-[7.75rem] md:bottom-[2.75rem];
+ }
+
+ &:has(.tk-cancel) {
+ .tk-meta-input {
+ @apply w-[calc(100%-3.5rem)] md:w-[calc(100%-10rem)];
+ }
+
+ .actions button {
+ @apply py-[0.3rem];
+
+ &.tk-preview {
+ @apply bottom-[4.9rem] md:bottom-0;
+ }
+
+ &.tk-cancel {
+ @apply bg-error text-error-content right-0 bottom-[2.4rem] md:right-[6.7rem] md:bottom-0;
+ }
+ }
+ }
+
+ .tk-preview-container {
+ @apply border-base-300 bg-base-100 mt-2 w-full rounded-xl border p-2;
+ }
+ }
+
+ /* 表情框样式 */
+ .OwO-body {
+ /* stylelint-disable-next-line scss/operator-no-unspaced */
+ @apply border-base-300 bg-base-200/90 absolute top-9 -left-3 z-20 hidden w-[calc(100vw-3rem)] max-w-[30rem] rounded-xl border duration-300;
+ }
+
+ .OwO-open .OwO-body {
+ @apply block;
+ }
+
+ .OwO-items {
+ @apply hidden max-h-48 overflow-y-auto p-2;
+
+ &.OwO-items-show {
+ @apply block;
+ }
+ }
+
+ .OwO-item {
+ @apply inline-block cursor-pointer rounded-md px-2 py-1 text-center text-xs duration-300;
+
+ img {
+ @apply inline-block h-14 w-14;
+ }
+
+ &:hover {
+ @apply backdrop-brightness-150;
+ }
+ }
+
+ .OwO-bar {
+ @apply flex w-full flex-row flex-wrap items-center rounded-b-xl text-start text-xs;
+ }
+
+ .OwO-packages {
+ @apply flex flex-wrap items-center px-4 text-nowrap;
+
+ > li {
+ @apply hover:bg-primary/50 flex h-8 cursor-pointer items-center px-3 text-center duration-300;
+
+ &.OwO-package-active {
+ @apply bg-primary/50;
+ }
+ }
+ }
+
+ .tk-comments-container {
+ /* 评论整体样式 */
+ @apply mt-4 flex w-full flex-col gap-4;
+
+ .tk-comments-title {
+ @apply flex flex-row items-center justify-between px-2;
+
+ .tk-comments-count {
+ @apply text-lg font-bold;
+ }
+
+ .tk-icon {
+ @apply mx-2 cursor-pointer;
+ }
+ }
+
+ .tk-comment {
+ @apply relative scroll-m-20;
+ }
+
+ > .tk-comment {
+ @apply max-md:border-base-300 max-md:bg-base-200/50 p-4 max-md:rounded-xl max-md:border;
+
+ > .tk-avatar {
+ @apply top-3;
+ }
+ }
+
+ .tk-replies {
+ @apply mt-4 ml-6 flex flex-col gap-2;
+
+ &:not(.tk-replies-expand) {
+ @apply max-h-32 overflow-y-hidden;
+ }
+ }
+
+ /* 详细样式 */
+ .tk-avatar {
+ @apply border-base-300 absolute top-0 h-8 min-h-8 w-8 min-w-8 overflow-hidden rounded-full border;
+ }
+
+ .tk-main > .tk-row {
+ @apply mb-2 ml-[2.5rem] w-[calc(100%-3rem)] justify-between;
+ }
+
+ .tk-meta {
+ a {
+ @apply hover:text-primary duration-300;
+ }
+
+ small {
+ @apply text-base-content/50;
+ }
+
+ .tk-actions {
+ @apply opacity-0 duration-300;
+ }
+ }
+
+ /* 评论操作样式 */
+ .tk-main:not(:has(.tk-replies:hover)):hover > .tk-row .tk-meta .tk-actions {
+ @apply opacity-100;
+ }
+
+ .tk-action {
+ .tk-action-link {
+ @apply border-base-300 relative flex items-center justify-center rounded-xl border px-2 py-1 text-center duration-300;
+
+ .tk-action-icon-solid {
+ @apply absolute left-2 opacity-0 duration-300;
+ }
+
+ .tk-action-count {
+ @apply text-sm;
+
+ &:not(:empty) {
+ @apply ml-2;
+ }
+ }
+
+ &:first-child {
+ display: none;
+ }
+
+ &:hover {
+ @apply bg-primary;
+
+ .tk-action-icon-solid {
+ @apply opacity-100;
+ }
+ }
+ }
+ }
+
+ .tk-content {
+ @apply relative mx-2 mb-3;
+ }
+
+ .tk-extras {
+ @apply flex flex-row gap-3;
+
+ .tk-extra {
+ @apply border-base-300 text-base-content/50 flex flex-row items-center justify-center gap-2 rounded-md border p-1 text-center text-xs;
+ }
+
+ .tk-icon {
+ @apply hidden;
+ }
+ }
+
+ .tk-replies .tk-content > span:first-child {
+ /* 回复提示(回复:xxx)样式 */
+ @apply text-base-content/50 text-xs;
+ }
+
+ .tk-expand-wrap,
+ .tk-collapse-wrap {
+ @apply mt-1 flex items-center justify-center text-center;
+ }
+
+ .tk-expand {
+ @apply bg-base-200/50 hover:bg-primary/50 w-full cursor-pointer rounded-md py-1 text-sm duration-300;
+ }
+ }
+
+ /* 图标样式 */
+ .tk-submit-action-icon {
+ @apply fill-primary inline-block max-h-6 min-h-6 max-w-6 min-w-6 cursor-pointer;
+ }
+
+ .tk-action-icon {
+ @apply fill-primary inline-block max-h-5 min-h-5 max-w-5 min-w-5 overflow-clip;
+ }
+
+ .tk-icon {
+ @apply fill-primary inline-block max-h-4 min-h-4 max-w-4 min-w-4 overflow-clip;
+ }
+
+ .tk-tag {
+ @apply border-base-300 rounded-lg border p-1 text-xs;
+ }
+}
+
+.tk-footer {
+ @apply mt-4 w-full text-right text-sm;
+
+ a {
+ @apply text-primary;
+ }
+}
+
+.tk-admin-container {
+ @apply absolute z-10 h-3/4 w-full overflow-hidden bg-black/30 backdrop-blur-sm;
+
+ &:not(:has(.tk-admin.__show)) {
+ display: none;
+ }
+
+ .tk-admin {
+ @apply relative flex h-full w-full items-center justify-center text-center;
+
+ .tk-admin-close {
+ @apply fill-primary absolute top-[0.65rem] right-2 z-50 h-4 w-4;
+
+ @variant md {
+ @apply top-4 right-3 h-8 w-8;
+ }
+ }
+
+ > div {
+ @apply flex h-full w-full items-center justify-center;
+ }
+ }
+
+ .tk-login {
+ @apply flex flex-col items-center gap-4 p-4;
+
+ .tk-login-title {
+ @apply text-2xl font-bold;
+ }
+ }
+
+ .tk-panel {
+ @apply h-full w-full overflow-y-scroll;
+
+ .tk-panel-title {
+ @apply top-0 left-0 z-40 flex w-full flex-row items-center justify-between p-4;
+
+ /* 管理面板标题 */
+ div {
+ @apply text-xl font-bold;
+ }
+
+ a {
+ @apply border-base-300 bg-base-200/50 hover:bg-primary mx-6 rounded-xl border px-3 py-1 text-xs duration-300;
+ }
+ }
+
+ .tk-tabs {
+ @apply border-base-300 flex flex-row items-center justify-between border-b-2 px-4 text-center text-lg;
+
+ .tk-tab {
+ @apply hover:bg-primary w-full min-w-fit cursor-pointer py-1 duration-300;
+
+ &.__active {
+ @apply border-primary border-b-2;
+ }
+ }
+ }
+
+ .tk-admin-warn {
+ @apply m-2 rounded-sm border-l-4 border-yellow-400 bg-yellow-100 p-4 text-start text-yellow-700;
+
+ a {
+ @apply font-semibold text-yellow-900;
+ }
+ }
+
+ /* 评论管理样式 */
+ .tk-admin-comment {
+ @apply p-4;
+ }
+
+ .tk-admin-comment-filter {
+ @apply flex flex-row items-center justify-between gap-2 p-4;
+
+ div {
+ @apply w-full;
+
+ input {
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border px-2 py-1;
+
+ &:focus {
+ outline: none;
+ }
+ }
+ }
+
+ select {
+ @apply border-base-300 bg-base-200/50 w-1/4 rounded-xl border p-2;
+ }
+ }
+
+ .tk-admin-comment-list {
+ @apply px-3 text-start;
+ }
+
+ .tk-admin-comment-item {
+ @apply border-base-300 border-b-2 py-1;
+ }
+
+ .tk-admin-comment-meta {
+ @apply flex flex-row flex-wrap items-center gap-2 text-start;
+
+ .tk-avatar {
+ @apply border-base-300 h-8 w-8 overflow-hidden rounded-full border;
+ }
+
+ a {
+ @apply hover:text-primary duration-300;
+ }
+
+ span:last-child,
+ .tk-time {
+ @apply text-base-content/50 text-sm;
+ }
+ }
+
+ .tk-pagination {
+ @apply flex flex-row flex-wrap items-center justify-between p-4;
+
+ > div {
+ @apply flex flex-row items-center gap-2;
+ }
+
+ input {
+ @apply border-base-300 bg-base-200/50 w-16 rounded-xl border px-2 py-1;
+
+ &::-webkit-outer-spin-button,
+ &::-webkit-inner-spin-button {
+ appearance: none;
+ }
+
+ &[type='number'] {
+ appearance: textfield;
+ }
+
+ &:focus {
+ outline: none;
+ }
+ }
+ }
+
+ .tk-pagination-pager {
+ @apply hover:bg-primary cursor-pointer rounded-md px-2 py-1;
+
+ &.__current {
+ @apply bg-primary;
+ }
+ }
+
+ /* 配置管理样式 */
+ .tk-admin-config {
+ @apply p-4;
+ }
+
+ .tk-admin-config-groups {
+ @apply flex flex-col items-center gap-3 px-4;
+ }
+
+ details {
+ @apply border-base-300 w-full overflow-hidden rounded-xl border duration-300;
+
+ summary {
+ @apply hover:bg-primary/50 w-full px-3 py-1 text-start text-2xl duration-300;
+
+ &::marker {
+ margin-right: 1.5rem;
+ }
+ }
+
+ &[open] {
+ summary {
+ @apply bg-primary/50;
+ }
+ }
+ }
+
+ .tk-admin-config-item {
+ @apply mt-4 grid w-full items-center gap-2 px-4;
+
+ grid-template-columns: 25% 75%;
+
+ .tk-admin-config-title {
+ @apply text-end text-lg;
+ }
+
+ input {
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border px-2 py-1;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .tk-admin-config-desc {
+ @apply text-base-content/50 text-start text-sm whitespace-pre-wrap;
+ }
+ }
+
+ /* 导入样式 */
+ .tk-admin-import {
+ @apply flex flex-col items-start gap-4 p-4;
+
+ .tk-admin-import-label {
+ @apply text-start text-xl font-bold;
+ }
+
+ select {
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border p-2;
+ }
+
+ input {
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border px-2 py-1;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .el-textarea {
+ @apply h-full w-full;
+
+ textarea {
+ @apply border-base-300 bg-base-200/50 h-full w-full rounded-xl border px-2 py-1;
+
+ &:focus {
+ outline: none;
+ }
+ }
+ }
+ }
+
+ /* 导出样式 */
+ .tk-admin-export {
+ @apply p-4;
+ }
+ }
+}
+
+.el-input-group {
+ @apply border-base-300 bg-base-200/50 flex w-full flex-row items-center overflow-hidden rounded-xl border text-sm;
+
+ div {
+ @apply bg-primary/50 w-fit px-2 py-1 whitespace-nowrap;
+ }
+
+ input {
+ @apply w-full bg-transparent px-2 py-1;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .el-button {
+ @apply border-none bg-none p-0;
+ }
+}
+
+.el-button {
+ @apply border-base-300 bg-primary rounded-xl border px-2 py-1 text-center text-sm text-nowrap duration-300;
+
+ &:not(.is-disabled) {
+ @apply hover:scale-105 hover:brightness-110 active:scale-95 active:brightness-90;
+ }
+
+ &.is-disabled {
+ @apply cursor-not-allowed brightness-75;
+ }
+}
+
+/* Markdown 样式 */
+.tk-content,
+.tk-preview-container {
+ /* 文本样式 */
+ @apply break-normal hyphens-auto whitespace-pre-wrap md:break-words md:hyphens-manual;
+
+ /* 标题通用样式 */
+ h1,
+ h2,
+ h3,
+ h4,
+ h5 {
+ display: inline;
+ width: 100%;
+ margin: 1rem 0 0.5rem;
+ scroll-margin-top: 4rem;
+ font-weight: bold;
+ }
+
+ /* 基础文本元素 */
+ p {
+ margin: 0.5rem 0;
+ }
+
+ a {
+ @apply text-primary underline decoration-dashed;
+
+ &[data-footnote-ref],
+ &[data-footnote-backref] {
+ scroll-margin-top: 4rem;
+ }
+ }
+
+ /* 代码样式 */
+ .code-toolbar {
+ @apply relative w-full;
+
+ .toolbar {
+ @apply absolute top-1 right-3 flex flex-row-reverse items-center justify-between gap-4 text-xs;
+ }
+
+ .copy-to-clipboard-button {
+ @apply border-base-300 bg-primary rounded-md border px-2 py-1 opacity-0 duration-300;
+ }
+
+ &:hover .copy-to-clipboard-button {
+ @apply opacity-100;
+ }
+
+ pre {
+ @apply rounded-md;
+ }
+ }
+
+ code:not(pre code) {
+ padding: 0 0.25rem;
+
+ @apply bg-primary/10 text-primary rounded-md;
+ }
+
+ /* 媒体元素 */
+ img:not(.tk-owo-emotion) {
+ position: relative;
+ margin: 1rem auto;
+ max-width: 75%;
+ max-height: 40rem;
+
+ @apply rounded-md;
+ }
+
+ img.tk-owo-emotion {
+ @apply inline-block h-[2em] self-baseline;
+ }
+
+ /* 分割线样式 */
+ hr {
+ margin: 1.5rem 0.25rem;
+ border: 1px dashed;
+ }
+
+ /* 引用块样式 */
+ blockquote {
+ padding: 0.25rem 0.25rem 0.25rem 0.75rem;
+
+ @apply border-primary bg-primary/10 my-2 rounded-sm border-l-4;
+ }
+
+ /* 折叠块样式 */
+ details {
+ @apply border-base-300 w-full overflow-hidden rounded-xl border duration-300;
+
+ summary {
+ @apply hover:bg-primary/50 w-full px-3 py-1 text-start text-2xl duration-300;
+
+ &::marker {
+ margin-right: 1.5rem;
+ }
+ }
+
+ &[open] {
+ summary {
+ @apply bg-primary/50;
+ }
+ }
+ }
+}
src/styles/waline.css
@@ -0,0 +1,44 @@
+:root {
+ /* 字体大小 */
+ --waline-font-size: 1rem;
+
+ /* 常规颜色 */
+ --waline-white: #fff;
+ --waline-light-grey: #999;
+ --waline-dark-grey: #666;
+
+ /* 主题色 */
+ --waline-theme-color: var(--color-primary);
+ --waline-active-color: var(--color-secondary);
+
+ /* 布局颜色 */
+ --waline-color: var(--color-base-content);
+ --waline-bg-color: var(--color-base-100);
+ --waline-bg-color-light: var(--color-base-200);
+ --waline-bg-color-hover: var(--color-base-200);
+ --waline-border-color: var(--color-base-200);
+ --waline-disable-bg-color: color-mix(in oklab, var(--color-base-200) 25%, transparent);
+ --waline-disable-color: color-mix(in oklab, var(--color-base-content) 75%, transparent);
+ --waline-code-bg-color: var(--color-base-100);
+
+ /* 特殊颜色 */
+ --waline-bq-color: #f0f0f0;
+
+ /* 头像 */
+ --waline-avatar-size: 3.25rem;
+ --waline-m-avatar-size: calc(var(--waline-avatar-size) * 9 / 13);
+
+ /* 徽章 */
+ --waline-badge-color: var(--color-accent);
+ --waline-badge-font-size: 0.775em;
+
+ /* 信息 */
+ --waline-info-bg-color: color-mix(in oklab, var(--color-base-content) 15%, transparent);
+ --waline-info-color: color-mix(in oklab, var(--color-base-content) 60%, transparent);
+ --waline-info-font-size: 0.625em;
+
+ /* 渲染选择 */
+ --waline-border: 1px solid var(--waline-border-color);
+ --waline-avatar-radius: 50%;
+ --waline-box-shadow: none;
+}