mirror of
https://github.com/sendevia/website.git
synced 2026-03-06 07:40:50 +08:00
feat(ButtonGroup): add new ButtonGroup component to render multiple buttons from external link data
This commit is contained in:
@@ -4,7 +4,6 @@ interface Props {
|
||||
size?: "xs" | "s" | "m" | "l" | "xl";
|
||||
color?: "elevated" | "filled" | "tonal" | "outlined" | "standard" | "text";
|
||||
icon?: string;
|
||||
text?: string;
|
||||
href?: string;
|
||||
target?: "_blank" | "_self" | "_parent" | "_top";
|
||||
}
|
||||
@@ -23,11 +22,12 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
:href="href"
|
||||
class="MaterialButton"
|
||||
:class="[props.shape, props.size, props.color, props.icon ? 'icon' : '']"
|
||||
:target="props.target"
|
||||
>
|
||||
<span v-if="props.icon">
|
||||
{{ props.icon }}
|
||||
</span>
|
||||
{{ props.text }}
|
||||
<slot></slot>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
|
||||
61
.vitepress/theme/components/ButtonGroup.vue
Normal file
61
.vitepress/theme/components/ButtonGroup.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<script setup lang="ts">
|
||||
interface ExternalLink {
|
||||
type: string;
|
||||
label: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
links?: ExternalLink[];
|
||||
size?: "xs" | "s" | "m" | "l" | "xl";
|
||||
layout?: "horizontal" | "vertical";
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
links: () => [],
|
||||
size: "s",
|
||||
layout: "horizontal",
|
||||
});
|
||||
|
||||
const getButtonColor = (type: string) => {
|
||||
switch (type) {
|
||||
case "download":
|
||||
return "tonal";
|
||||
case "normal":
|
||||
default:
|
||||
return "tonal";
|
||||
}
|
||||
};
|
||||
|
||||
const getButtonIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case "download":
|
||||
return "download";
|
||||
case "normal":
|
||||
return "open_in_new";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="links && links.length > 0" class="ButtonGroup" :class="[props.size, props.layout]">
|
||||
<MaterialButton
|
||||
v-for="(item, index) in links"
|
||||
:key="index"
|
||||
:href="item.link"
|
||||
:size="props.size"
|
||||
:color="getButtonColor(item.type)"
|
||||
:icon="getButtonIcon(item.type)"
|
||||
:target="'_blank'"
|
||||
>
|
||||
{{ item.label }}
|
||||
</MaterialButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "sass:meta";
|
||||
@include meta.load-css("../styles/components/ButtonGroup");
|
||||
</style>
|
||||
@@ -9,6 +9,7 @@ import NotFound from "./layouts/NotFound.vue";
|
||||
import AppBar from "./components/AppBar.vue";
|
||||
import ArticleMasonry from "./components/ArticleMasonry.vue";
|
||||
import Button from "./components/Button.vue";
|
||||
import ButtonGroup from "./components/ButtonGroup.vue";
|
||||
import Card from "./components/Card.vue";
|
||||
import Footer from "./components/Footer.vue";
|
||||
import Header from "./components/Header.vue";
|
||||
@@ -33,6 +34,7 @@ export default {
|
||||
|
||||
app.component("AppBar", AppBar);
|
||||
app.component("ArticleMasonry", ArticleMasonry);
|
||||
app.component("ButtonGroup", ButtonGroup);
|
||||
app.component("Footer", Footer);
|
||||
app.component("Header", Header);
|
||||
app.component("ImageViewer", ImageViewer);
|
||||
|
||||
@@ -260,10 +260,13 @@ if (isClient()) {
|
||||
<Header />
|
||||
<main id="article-content">
|
||||
<Content />
|
||||
<MaterialButton v-if="articleId" :text="'复制短链'" :color="'outlined'" @click="copyShortLink" />
|
||||
<ButtonGroup v-if="frontmatter?.external_links" :links="frontmatter.external_links" />
|
||||
<PrevNext />
|
||||
</main>
|
||||
<div id="article-beside">
|
||||
<MaterialButton v-if="articleId" :color="'text'" :icon="'content_copy'" @click="copyShortLink">
|
||||
复制短链
|
||||
</MaterialButton>
|
||||
<div class="post-info">
|
||||
<p class="date-publish" v-if="formattedPublishDate">发布于 {{ formattedPublishDate }}</p>
|
||||
<p class="date-update" :title="lastUpdatedRawTime">{{ formattedLastUpdated }}</p>
|
||||
|
||||
46
.vitepress/theme/styles/components/ButtonGroup.scss
Normal file
46
.vitepress/theme/styles/components/ButtonGroup.scss
Normal file
@@ -0,0 +1,46 @@
|
||||
@use "../mixin";
|
||||
|
||||
.ButtonGroup {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 2px;
|
||||
|
||||
position: relative;
|
||||
|
||||
.MaterialButton {
|
||||
&:nth-child(1n) {
|
||||
&.xs {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&.s {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
&.xs {
|
||||
border-radius: var(--md-sys-shape-corner-full) 20px 20px var(--md-sys-shape-corner-full);
|
||||
}
|
||||
|
||||
&.s {
|
||||
border-radius: var(--md-sys-shape-corner-full) 40px 40px var(--md-sys-shape-corner-full);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
&.xs {
|
||||
border-radius: 16px var(--md-sys-shape-corner-full) var(--md-sys-shape-corner-full) 20px;
|
||||
}
|
||||
|
||||
&.s {
|
||||
border-radius: 32px var(--md-sys-shape-corner-full) var(--md-sys-shape-corner-full) 40px;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
border-radius: var(--md-sys-shape-corner-full) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,13 @@ tags:
|
||||
- readme
|
||||
- osu!
|
||||
date: 2022-07-04T04:00:00Z
|
||||
download_links:
|
||||
- 直连下载: https://github.com/sendevia/AincradMix/releases/latest/download/AincradMix.osk
|
||||
external_links:
|
||||
- type: download
|
||||
label: 直连下载
|
||||
link: https://github.com/sendevia/AincradMix/releases/latest/download/AincradMix.osk
|
||||
- type: normal
|
||||
label: github
|
||||
link: https://github.com/sendevia/AincradMix
|
||||
---
|
||||
|
||||
::: tip 简介
|
||||
|
||||
Reference in New Issue
Block a user