Commit 5b756a9b authored by Zhang Xiaojie's avatar Zhang Xiaojie

feat:Basic Btn, Shopping Card

parent d0d86dfc
......@@ -2,12 +2,15 @@
import { useI18n } from "vue-i18n";
import links from "@/data/links.json";
import ShoppingWrapper from "./components/src/Slg_Wrapper";
import { ShoppingCard as SC } from "./components/src/Slg_ShoppingCard/index.vue"
import Slg_BasicButton from "./components/src/Slg_BasicButton";
import HotCard from "./components/src/Slg_HotCard";
import Slg_ActionCard from "./components/src/Slg_ActionCard";
import recList from "./data/recList";
import { computed, onMounted, ref } from "vue";
import Slg_ShoppingCard from "./components/src/Slg_ShoppingCard/index.vue";
const { t } = useI18n();
const getImgURL = (src: string) => {
......@@ -48,15 +51,26 @@ const handleFav = () => {
<div class="slg-w-60">
<Slg_BasicButton />
</div>
</div> -->
</div>-->
<div style="width: 500px;">
<HotCard setBg imgURL="https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF" />
</div>
<div style="width: 266px;height: 266px;">
<HotCard
setBg
<div style="width: 600px;">
<Slg_ActionCard
imgURL="https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF"
header="名店潮品 限时五折"
content="Create a beautiful NFT products. Explore the best collection from various artist"
/>
</div>
<div style="width: 294px;">
<Slg_ShoppingCard
imgURL="https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF"
likes="1.3k"
:iconURL="getImgURL('ts')"
/>
</div>
<!-- <div class="w-8/12 mx-auto">
<ShoppingWrapper
:list="mappedList"
......
import Slg_ActionCard from "./index.vue";
import { App } from "vue";
Slg_ActionCard.install = (app: App) => {
app.component(Slg_ActionCard.name, Slg_ActionCard);
};
export default Slg_ActionCard;
<script lang="ts" setup>
import { computed } from 'vue'
import Slg_BasicButton from '../Slg_BasicButton/index.vue'
export interface ActionCard {
header: string
content: string
action?: boolean
imgURL?: string
bgColor?: string
reverse?: boolean
}
const props = withDefaults(defineProps<ActionCard>(), {
label: 'button',
reverse: false,
bgColor: '#D6C298'
})
const boxClassObj = computed(() => {
return props.reverse ? ' slg-flex-row-reverse slg-pr-4' : ' slg-flex-row slg-pl-4'
})
const boxStyleObj = computed(() => {
return {
backgroundColor: props.bgColor
}
})
interface Emits {
(e: 'click'): void
}
const emit = defineEmits<Emits>()
const handleClick = () => {
emit('click')
}
</script>
<template>
<div
class="slg-flex slg-items-center slg-justify-between"
:class="boxClassObj"
:style="boxStyleObj"
>
<div >
<div class="slg-text-mainGreen slg-text-2xl">{{ header ? header : 'header' }}</div>
<div
class="slg-text-gray-600 slg-text-xs slg-pt-3 slg-w-60"
>{{ content ? content : 'content' }}</div>
<div style="width:234px" class="slg-pt-8">
<Slg_BasicButton :label="props.label" @click="handleClick" height="L" />
</div>
</div>
<img v-if="imgURL" :src="imgURL" style="width:303.74px;height:225px;" />
</div>
</template>
<style>
@tailwind base;
@tailwind components;
@tailwind utilities;
</style>
\ No newline at end of file
<script setup lang="ts">
import { computed } from 'vue';
type Size = 'SM' | 'L'
type Pattern = 'PRIMARY' | 'SECOND' | 'ROUND' | 'BLUR'
......@@ -11,16 +10,18 @@ interface Slg_BasicButton {
labelColor?: string,
bgColor?: string,
borderColor?: string,
label?: string
label?: string,
roundCorner?: boolean
}
const props = withDefaults(defineProps<Slg_BasicButton>(), {
height: 'SM',
pattern: 'SECOND',
pattern: 'PRIMARY',
bgColor: 'rgba(247, 245, 230, 1)',
labelColor: '#2E2E22',
borderColor: '#2E2E22',
label: 'BUTTON'
label: 'BUTTON',
roundCorner: false
})
const btnStyleObj = computed(() => {
......@@ -39,19 +40,21 @@ const btnStyleObj = computed(() => {
})
const btnStyleClass = computed(() => ({
[`slg-button--${props.pattern}`]: true
[`slg-button--${props.pattern}`]: true,
'slg-rounded-2xl': props.roundCorner
}))
const labelStyleClass = computed(() => {
return props.height == 'SM' ? 'slg-text-xs my-2 slg-font-medium' : 'slg-text-sm my-3 slg-font-bold'
return props.height == 'SM' ? 'slg-text-xs slg-py-2 slg-font-medium' : 'slg-text-sm slg-py-3 slg-font-bold'
})
interface Emits {
(e: "click"): void;
(e: "click", value: Event): void;
}
const emit = defineEmits<Emits>()
const onClick = () => {
emit('click')
const onClick = (e: Event) => {
emit('click', e)
}
</script>
......@@ -59,7 +62,7 @@ const onClick = () => {
<template>
<button
class="slg-w-full slg-flex slg-justify-center slg-items-center"
:class="btnStyleClass"
:class="[btnStyleClass, , labelStyleClass]"
:style="btnStyleObj"
@click="onClick"
>
......@@ -67,9 +70,9 @@ const onClick = () => {
v-if="iconURL"
:src="iconURL"
class="slg-w-2 slg-h-2 slg-justify-center slg-items-center"
:class="pattern == 'ROUND' ? ' slg-h-6 slg-w-6' : ' slg-h-2 slg-w-2 slg-mr-3'"
:class="[pattern == 'ROUND' ? ' slg-h-6 slg-w-6' : ' slg-h-2 slg-w-2 slg-mr-3']"
/>
<span v-if="label" :style="{ color: labelColor }" :class="labelStyleClass">
<span v-if="label" :style="{ color: labelColor }">
{{
pattern == 'ROUND' && iconURL ?
'' :
......@@ -80,6 +83,10 @@ const onClick = () => {
</template>
<style>
@tailwind base;
@tailwind components;
@tailwind utilities;
.slg-button--PRIMARY {
background-color: white;
border-width: 1px;
......
......@@ -84,8 +84,12 @@ const onClick = () => {
v-if="imgURL"
class="slg-self-end"
:class="bgStyle"
src="https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF"
style="width: 300px;height:260px ;"
/>
</div>
</template>
\ No newline at end of file
</template>
<style scpoed>
@tailwind base;
@tailwind components;
@tailwind utilities;
</style>
\ No newline at end of file
<script setup lang="ts">
import { propsToAttrMap } from '@vue/shared';
import { computed } from 'vue';
import Slg_BasicButton from '../Slg_BasicButton';
export type itemStatus = "IN" | "SOLDOUT"
export type Pattern = "PRIMARY" | "LARGE"
export interface ShoppingCard {
itemName: string;
intro: string;
price: string,
itemName?: string;
intro?: string;
price?: string,
discount?: string,
likes: string,
status: itemStatus,
likes?: string,
status?: itemStatus,
imgURL: string,
iconURL: string,
cartURL: string,
iconURL?: string,
cartURL?: string,
showRTIcon?: boolean
secondaryColor?: string
pattern?: Pattern
}
......@@ -32,7 +33,9 @@ enum BTN_EVENT {
}
const props = withDefaults(defineProps<ShoppingCard>(), {
showRTIcon: true
showRTIcon: true,
status: 'IN',
pattern: 'PRIMARY'
});
const emit = defineEmits<Emits>();
......@@ -53,43 +56,36 @@ const secondaryColor = computed(() => {
<template>
<div>
<div class="bg-purple-200 relative" style="height: 346px;">
<img :src="imgURL" class="w-full h-full object-cover" />
<div class="slg-bg-purple-200 slg-relative">
<img :src="imgURL" class="slg-w-full slg-h-full slg-object-cover" />
<button
v-if="showRTIcon"
v-if="iconURL"
@click="handleClick($event, BTN_EVENT.BTN2)"
class="absolute flex items-center top-3 right-4 rounded-2xl bg-white bg-opacity-50 border-white text-red-400 py-3 px-4 text-xs"
class="slg-absolute slg-flex slg-items-center slg-top-3 slg-right-4 slg-rounded-2xl slg-bg-white slg-bg-opacity-50 slg-border-white slg-text-red-400 slg-py-3 slg-px-4 slg-text-xs"
>
<img :src="iconURL" class="w-4 h-4 pr-1" />
{{ likes }}
<img :src="iconURL" class="slg-w-4 slg-h-4 slg-pr-1" />
{{ likes ? likes : '' }}
</button>
</div>
<div>
<div class="text-sm font-bold pt-3 text-mainContent">
<div class="slg-text-sm slg-font-bold slg-pt-3 slg-text-mainContent">
<div v-if="status == 'IN'">{{ itemName }}</div>
<div v-else class="flex items-center">
<span class="text-xs pr-2" :style="{ color: secondaryColor }">已售罄</span>
<strike>{{ itemName }}</strike>
<div v-else class="slg-flex slg-items-center">
<span class="slg-text-xs slg-pr-2" :style="{ color: secondaryColor }">已售罄</span>
<strike>{{ itemName ? itemName : '' }}</strike>
</div>
</div>
<div class="text-xs pt-1 text-mainContent">{{ intro }}</div>
<div class="pt-2 pb-3 text-xs">
<div class="slg-text-xs slg-pt-1 slg-text-mainContent">{{ intro }}</div>
<div class="slg-pt-2 slg-pb-3 slg-text-xs">
<span
:class="discount ? 'font-semibold' : ' text-mainContent'"
:class="discount ? 'slg-font-semibold' : 'slg-text-mainContent'"
:style="discount ? { color: secondaryColor } : ''"
class="pr-2"
>{{ discount ? discount : price }}</span>
class="slg-pr-2"
>{{ discount ? discount : price ? price : '' }}</span>
<strike v-if="discount">{{ price }}</strike>
</div>
</div>
<button
type="button"
class="border w-full border-black text-xs py-2 flex items-center justify-center"
@click="handleClick($event, BTN_EVENT.BTN1)"
>
<img :src="cartURL" class="w-2 h-2 mr-3" />
加入购物车
</button>
<Slg_BasicButton label="加入购物车" @click="handleClick($event, BTN_EVENT.BTN1)" />
</div>
</template>
<style scpoed>
......
import { Story } from "@storybook/vue3";
import ShoppingWrapper from "../components/src/Slg_Wrapper";
// More on default export: https://storybook.js.org/docs/vue/writing-stories/introduction#default-export
export default {
title: "Example/ShoppingWrapper",
component: ShoppingWrapper,
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
argTypes: {
// list: Array<SC>
// header?: string
// iconLeft?: string
// iconRight?: string
// pattern?: Pattern
// colNumber?: number
// gapX?:string
pa: {
control: { type: "select" },
options: ["IN", "SOLDOUT"],
},
onClick: {},
},
};
// More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args
const Template: Story = (args) => ({
// Components used in your story `template` are defined in the `components` object
components: { ShoppingWrapper },
// The story's `args` need to be mapped into the template through the `setup()` method
setup() {
return { args };
},
// And then the `args` are bound to your component with `v-bind="args"`
template: '<ShoppingCard v-bind="args" />',
});
export const Normal = Template.bind({});
Normal.args = {
status: "IN",
itemName: "Sunburn Ointment",
intro: "All Natural Ingredients.",
price: "$99.99",
likes: "1.5k",
imgURL: "https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF",
iconURL: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQ4IDQ4Ij48dGl0bGU+aWxsdXN0cmF0aW9uL2RpcmVjdGlvbjwvdGl0bGU+PGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+PGcgaWQ9ImlsbHVzdHJhdGlvbi9kaXJlY3Rpb24iIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiPjxwYXRoIGlkPSJDb21iaW5lZC1TaGFwZSIgZmlsbD0iI0ZGRDQ3NiIgZD0iTTIzLjQ5MTcwMTUsMzMuNjAzMDY0MSBMMi45Mzg0MDI1OCwzMS40MzIxMDMzIEMyLjM4OTE3MzE2LDMxLjM3NDA5MDQgMS45OTA5NjM0NiwzMC44ODE4MjMzIDIuMDQ4OTc2MzEsMzAuMzMyNTkzOSBDMi4wNzQ3NTE1LDMwLjA4ODU3MDUgMi4xODkzNDg2MSwyOS44NjI1NDE5IDIuMzcwOTU3MjIsMjkuNjk3NTI2NSBMMzQuMjYwOTEwNSwwLjcyMTI4NTMyNSBDMzQuNjY5NjYxNCwwLjM0OTg4MTA0OSAzNS4zMDIxMDIyLDAuMzgwMTU2NDggMzUuNjczNTA2NCwwLjc4ODkwNzM5MyBDMzUuOTIzMjYyMSwxLjA2Mzc3NzMxIDM2LjAwMDExMzMsMS40NTQ0MjA5NiAzNS44NzMwOTAxLDEuODAzNDE0NDcgTDI0LjUzNjQzNTcsMzIuOTUwNjE2NCBDMjQuMzc5MzQ3MywzMy4zODIyMTMzIDIzLjk0ODQ1NjUsMzMuNjUxMzA5MiAyMy40OTE3MDE1LDMzLjYwMzA2NDEgWiIvPjxwYXRoIGlkPSJDb21iaW5lZC1TaGFwZS1Db3B5IiBmaWxsPSIjRkZDNDQ1IiBkPSJNMjQuMzE2MzU5NywzMy4yODgxMDI5IEMyNC4wMzA2NTc1LDMzLjAxMzg0NjIgMjMuOTMzNzI0NiwzMi41OTY4MjMyIDI0LjA2OTE3NiwzMi4yMjQ2NzM1IEwzNS4wOTE5MjMsMS45Mzk5MjUxIEMzNS4yMjY2MDc1LDEuNTY5ODgyNDMgMzUuNTY1OTI0OSwxLjMxMzMzNjEzIDM1Ljk1ODY2NjksMS4yODQ2MDk1NSBDMzYuNTA5NDgwMiwxLjI0NDMyMTA2IDM2Ljk4ODY2MjgsMS42NTgxODMxOCAzNy4wMjg5NTEzLDIuMjA4OTk2NDcgTDQwLjI0Mzc1NTcsNDYuMTYwOTI1NiBDNDAuMjY0NDM1NSw0Ni40NDM2NTQ2IDQwLjE2NDE0NDYsNDYuNzIxODc1MiAzOS45Njc4MjkzLDQ2LjkyNjM4MzMgQzM5LjU4NTM2NzIsNDcuMzI0ODA2NyAzOC45NTIzMzQ0LDQ3LjMzNzc0NTggMzguNTUzOTExMSw0Ni45NTUyODM3IEwyNC4zMTYzNTk3LDMzLjI4ODEwMjkgWiIvPjwvZz48L3N2Zz4=",
cartURL: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQ4IDQ4Ij48dGl0bGU+aWxsdXN0cmF0aW9uL2RpcmVjdGlvbjwvdGl0bGU+PGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+PGcgaWQ9ImlsbHVzdHJhdGlvbi9kaXJlY3Rpb24iIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiPjxwYXRoIGlkPSJDb21iaW5lZC1TaGFwZSIgZmlsbD0iI0ZGRDQ3NiIgZD0iTTIzLjQ5MTcwMTUsMzMuNjAzMDY0MSBMMi45Mzg0MDI1OCwzMS40MzIxMDMzIEMyLjM4OTE3MzE2LDMxLjM3NDA5MDQgMS45OTA5NjM0NiwzMC44ODE4MjMzIDIuMDQ4OTc2MzEsMzAuMzMyNTkzOSBDMi4wNzQ3NTE1LDMwLjA4ODU3MDUgMi4xODkzNDg2MSwyOS44NjI1NDE5IDIuMzcwOTU3MjIsMjkuNjk3NTI2NSBMMzQuMjYwOTEwNSwwLjcyMTI4NTMyNSBDMzQuNjY5NjYxNCwwLjM0OTg4MTA0OSAzNS4zMDIxMDIyLDAuMzgwMTU2NDggMzUuNjczNTA2NCwwLjc4ODkwNzM5MyBDMzUuOTIzMjYyMSwxLjA2Mzc3NzMxIDM2LjAwMDExMzMsMS40NTQ0MjA5NiAzNS44NzMwOTAxLDEuODAzNDE0NDcgTDI0LjUzNjQzNTcsMzIuOTUwNjE2NCBDMjQuMzc5MzQ3MywzMy4zODIyMTMzIDIzLjk0ODQ1NjUsMzMuNjUxMzA5MiAyMy40OTE3MDE1LDMzLjYwMzA2NDEgWiIvPjxwYXRoIGlkPSJDb21iaW5lZC1TaGFwZS1Db3B5IiBmaWxsPSIjRkZDNDQ1IiBkPSJNMjQuMzE2MzU5NywzMy4yODgxMDI5IEMyNC4wMzA2NTc1LDMzLjAxMzg0NjIgMjMuOTMzNzI0NiwzMi41OTY4MjMyIDI0LjA2OTE3NiwzMi4yMjQ2NzM1IEwzNS4wOTE5MjMsMS45Mzk5MjUxIEMzNS4yMjY2MDc1LDEuNTY5ODgyNDMgMzUuNTY1OTI0OSwxLjMxMzMzNjEzIDM1Ljk1ODY2NjksMS4yODQ2MDk1NSBDMzYuNTA5NDgwMiwxLjI0NDMyMTA2IDM2Ljk4ODY2MjgsMS42NTgxODMxOCAzNy4wMjg5NTEzLDIuMjA4OTk2NDcgTDQwLjI0Mzc1NTcsNDYuMTYwOTI1NiBDNDAuMjY0NDM1NSw0Ni40NDM2NTQ2IDQwLjE2NDE0NDYsNDYuNzIxODc1MiAzOS45Njc4MjkzLDQ2LjkyNjM4MzMgQzM5LjU4NTM2NzIsNDcuMzI0ODA2NyAzOC45NTIzMzQ0LDQ3LjMzNzc0NTggMzguNTUzOTExMSw0Ni45NTUyODM3IEwyNC4zMTYzNTk3LDMzLjI4ODEwMjkgWiIvPjwvZz48L3N2Zz4="
};
......@@ -10,7 +10,8 @@ module.exports = {
mainHeader:'#354E57',
mainContent:"#2E2E22",
gold:'#A67744',
lightGray:'#F7F7F7'
lightGray:'#F7F7F7',
mainGreen:'#354E57'
},
spacing:{
'body':'1087px'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment