feat:create component add vibentec config design page

This commit is contained in:
Nam Doan
2025-11-28 13:12:00 +07:00
parent 09b01f1d6b
commit 497c060756
12 changed files with 385 additions and 48 deletions
@@ -33,22 +33,23 @@ export default function VtDropdown({
{props.trigger.text} {props.trigger.isShowArrow && <ChevronDown />}
</DropdownMenu.Trigger>
<DropdownMenu.Content>
{props.items.map(
(
item: {
text: string
className?: string
href?: string
icon?: string
},
index: number
) => (
<DropdownMenu.Item
key={item.text + index}
className={item.className || ""}
>
{item.icon && (
<img
{props.items.length > 0 &&
props.items.map(
(
item: {
text: string
className?: string
href?: string
icon?: string
},
index: number
) => (
<DropdownMenu.Item
key={item.text + index}
className={item.className || ""}
>
{item.icon && (
<img
src={item.icon}
alt={item.text}
className="w-5 h-5 rounded-[50%] mr-3"
@@ -11,13 +11,13 @@ export default function BannerNav({ node, context }: { node: LayoutComponentDefi
return (
<nav className="content-container txt-xsmall-plus flex items-center justify-between w-full h-full text-small-regular">
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full">
{props.left && <DynamicLayoutRenderer nodes={props.left} context={context} />}
</div>
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full">
{props.center && <DynamicLayoutRenderer nodes={props.center} context={context} />}
</div>
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full justify-end">
{props.right && <DynamicLayoutRenderer nodes={props.right} context={context} />}
</div>
</nav>
@@ -1,11 +1,11 @@
import { IconButton } from "@medusajs/ui"
import { MagnifyingGlass, User, ShoppingBag } from "@medusajs/icons"
import { Button, IconButton } from "@medusajs/ui"
import { MagnifyingGlass, User, ShoppingBag, Heart } from "@medusajs/icons"
import {
LayoutComponentDefinition,
LayoutContext,
} from "@vibentec/component-map"
export default function VtIconButton({
export default function VtButton({
nodes,
context,
}: {
@@ -13,16 +13,29 @@ export default function VtIconButton({
context: LayoutContext
}) {
const props = nodes.config || {}
const variantsIcon = {
search: MagnifyingGlass,
const icons = {
search: MagnifyingGlass,
user: User,
cart: ShoppingBag
cart: ShoppingBag,
heart: Heart
}
if (!props.variant) return null
const Icon = variantsIcon[props.variant as keyof typeof variantsIcon]
const Icon = props.icon && icons[props.icon as keyof typeof icons]
return (
<IconButton className={props?.className ?? ""}>
<Icon />
</IconButton>
<>
{props?.icon && (
<IconButton className={props?.className ?? ""}>
<Icon />
{props?.label && (
<span className="mr-2 text-[#11314E]">{props.label}</span>
)}
</IconButton>
)}
{!props?.icon && (
<Button className={props?.className ?? ""}>
{props?.label && <span>{props.label}</span>}
</Button>
)}
</>
)
}
@@ -14,13 +14,13 @@ export default function VtNav({ nodes, context }: { nodes: LayoutComponentDefini
return (
<div className="relative mx-auto border-b duration-200 bg-white border-ui-border-base">
<nav className={clx("content-container txt-xsmall-plus flex items-center justify-between w-full h-full text-small-regular", props.className)}>
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full">
{props.left && <DynamicLayoutRenderer nodes={props.left} context={context} />}
</div>
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full">
{props.center && <DynamicLayoutRenderer nodes={props.center} context={context} />}
</div>
<div className="flex items-center gap-x-4">
<div className="flex items-center gap-x-4 w-full h-full justify-end">
{props.right && <DynamicLayoutRenderer nodes={props.right} context={context} />}
</div>
</nav>
@@ -0,0 +1,40 @@
import React from "react"
import { MagnifyingGlass } from "@medusajs/icons"
import {
LayoutComponentDefinition,
LayoutContext,
} from "@vibentec/component-map"
export default function VtSearchInput({
nodes,
context,
}: {
nodes: LayoutComponentDefinition
context: LayoutContext
}) {
const props = nodes.config || {}
const placeholder = props.placeholder ?? "Search"
const shortcut = props.shortcut ?? "⌘K"
return (
<div
className={
`flex items-center gap-3 w-full max-w-xl bg-white border border-grey-20 rounded-rounded shadow-sm px-4 py-2 ${
props?.className ?? ""
}`
}
>
<MagnifyingGlass className="text-[#11314E]" />
<input
type="search"
placeholder={placeholder}
className="flex-1 bg-transparent outline-none text-[#11314E] placeholder:text-[#11314E]"
/>
{shortcut && (
<span className="text-[#11314E] border border-grey-30 rounded-rounded px-2 py-0.5 text-sm">
{shortcut}
</span>
)}
</div>
)
}
+4 -2
View File
@@ -14,7 +14,8 @@ import VtLink from "@modules/layout/components/vt-linkbutton"
import VtSideMenu from "@modules/layout/components/vt-sidemenu"
import VtImage from "@modules/layout/templates/vt-image"
import VtDropdown from "@modules/layout/components/vt-dropdown"
import VtIconButton from "@modules/layout/templates/vt-icon-button"
import VtButton from "@modules/layout/templates/vt-icon-button"
import VtSearchInput from "@modules/layout/templates/vt-search-input"
type ComponentConfig = Record<string, any>;
@@ -56,7 +57,8 @@ export const componentMap: Record<string, ComponentRenderer> = {
Banner: nodesContextRenderer(Banner),
HomeButton: nodesContextRenderer(HomeButton),
AccountButton: nodesContextRenderer(AccountButton),
IconButton: nodesContextRenderer(VtIconButton),
Button: nodesContextRenderer(VtButton),
SearchInput: nodesContextRenderer(VtSearchInput),
VtCartButton: nodesContextRenderer(VtCartButton),
Link: nodesContextRenderer(VtLink),
Image: nodesContextRenderer(VtImage),
+1 -1
View File
@@ -2,7 +2,7 @@ import fs from "fs"
import path from "path"
import { jsonFileNames } from "./devJsonFileNames";
const fileName = jsonFileNames.namDrsquatch;
const fileName = jsonFileNames.namVibentec;
export async function loadDesignConfig() {
const filePath = path.join(process.cwd(), "config", fileName)
+1
View File
@@ -3,4 +3,5 @@ export const jsonFileNames = {
stePlayGround: "ste.playground.design.json",
nam3Bear: "nam.3bear.design.json",
namDrsquatch: "nam.drsquatch.design.json",
namVibentec: "nam.vibentec.design.json"
};