This commit is contained in:
2026-03-23 03:30:31 +08:00
parent 5c6d8c6b92
commit ef6fe2e16c
6 changed files with 55 additions and 120 deletions

View File

@@ -1,51 +1,16 @@
import { Button, DownloadSvg } from "@defgov/ui"; import { Button, DownloadSvg } from "@defgov/ui";
import { OuterWrap } from "../common/OuterWrap"; import { OuterWrap } from "../common/OuterWrap";
import { useState } from "react";
import { InnerWrap } from "../common/InnerWrap"; import { InnerWrap } from "../common/InnerWrap";
export const ButtonGallery = () => { export const ButtonGallery = () => {
const [loading, setLoading] = useState(false);
return ( return (
<OuterWrap> <OuterWrap>
<InnerWrap> <InnerWrap>
<Button size="xs" iconSvg={<DownloadSvg />}> <Button variant="filled" icon={<DownloadSvg />}>
Ag
</Button>
<Button size="xs" iconSvg={<DownloadSvg />} iconOnly={true}>
Buttun Buttun
</Button> </Button>
<Button size="sm" iconSvg={<DownloadSvg />}>
Buttun
</Button>
<Button size="sm" iconSvg={<DownloadSvg />} iconOnly={true}>
Buttun
</Button>
<Button size="md" iconSvg={<DownloadSvg />}>
Buttun
</Button>
<Button size="md" iconSvg={<DownloadSvg />} iconOnly={true}>
Buttun
</Button>
<Button size="lg" iconSvg={<DownloadSvg />}>
Buttun
</Button>
<Button size="lg" iconSvg={<DownloadSvg />} iconOnly={true}>
Buttun
</Button>
</InnerWrap>
<InnerWrap>
<Button variant="filled">Buttun</Button>
<Button variant="outline">Buttun</Button> <Button variant="outline">Buttun</Button>
<Button variant="subtle">Buttun</Button> <Button variant="subtle">Buttun</Button>
<Button
isLoading={loading}
onClick={() => {
setLoading(!loading);
}}
>
Buttun
</Button>
</InnerWrap> </InnerWrap>
</OuterWrap> </OuterWrap>
); );

View File

@@ -115,7 +115,7 @@ function generateIndexFile(dirPath: string): void {
// 生成索引文件内容(模板字符串格式化) // 生成索引文件内容(模板字符串格式化)
const indexContent = ` const indexContent = `
import './index.scss'; import './index.css';
${exportStatements.join("\n")} ${exportStatements.join("\n")}
`; `;

View File

@@ -1,3 +1,4 @@
import { mergeProps } from "@base-ui/react";
import * as React from "react"; import * as React from "react";
import { cn } from "tailwind-variants"; import { cn } from "tailwind-variants";
@@ -6,43 +7,25 @@ export interface SlotProps extends React.HTMLAttributes<HTMLElement> {
} }
export const Slot = React.forwardRef<HTMLElement, SlotProps>( export const Slot = React.forwardRef<HTMLElement, SlotProps>(
( ({ children, className: externalClassName, ...restProps }, ref) => {
{ if (!React.isValidElement(children)) {
children, return null;
onClick: externalOnClick, }
style: styleProp,
className: classNameProp,
...props
},
ref,
) => {
if (!React.isValidElement(children)) return null;
const child = children as React.ReactElement<Record<string, unknown>>; const child = children as React.ReactElement<Record<string, unknown>>;
const childProps = child.props || {};
const mergedClassName = cn(child.props.className as string, classNameProp); const mergedClassName = cn(
childProps.className as string | undefined,
externalClassName,
);
const mergedStyle = { const otherMergedProps = mergeProps(childProps, restProps);
...(child.props.style ?? {}),
...(styleProp ?? {}),
} as React.CSSProperties;
const childOnClick = child.props.onClick as
| ((e: React.MouseEvent<HTMLElement>) => void)
| undefined;
const mergedOnClick = (e: React.MouseEvent<HTMLElement>) => {
childOnClick?.(e);
externalOnClick?.(e);
};
return React.cloneElement(child, { return React.cloneElement(child, {
...child.props, ...otherMergedProps,
...props,
ref,
style: mergedStyle,
className: mergedClassName, className: mergedClassName,
onClick: mergedOnClick, ref,
}); });
}, },
); );

View File

@@ -6,6 +6,7 @@ import { itemRootRecipe } from "@/styles/recipe/ItemRoot.recipe";
import { variantRecipe } from "@/styles/recipe/variant.recipe"; import { variantRecipe } from "@/styles/recipe/variant.recipe";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { inlineRootRecipe } from "@/styles/recipe/IinlineRoot.recipe"; import { inlineRootRecipe } from "@/styles/recipe/IinlineRoot.recipe";
import { Slot } from "@/common/Slot";
type ButtonProps = CommonProps & { type ButtonProps = CommonProps & {
size?: "md" | "lg" | "xl"; size?: "md" | "lg" | "xl";
@@ -26,7 +27,7 @@ export const Button = (props: ButtonProps) => {
disabled, disabled,
icon, icon,
iconOnly, iconOnly,
hideIcon, hideIcon = false,
} = props; } = props;
const buttonCls = cn( const buttonCls = cn(
@@ -39,6 +40,12 @@ export const Button = (props: ButtonProps) => {
return ( return (
<BUI.Button className={buttonCls} disabled={loading || disabled}> <BUI.Button className={buttonCls} disabled={loading || disabled}>
{!hideIcon &&
(iconOnly ? (
<span className={iconCls}></span>
) : (
<Slot className={iconCls}>{icon}</Slot>
))}
{children} {children}
</BUI.Button> </BUI.Button>
); );

View File

@@ -3,12 +3,10 @@
@import './styles/theme/theme-variant.css'; @import './styles/theme/theme-variant.css';
@import './styles/utility/brand.css'; @import './styles/utility/brand.css';
@import './styles/utility/gap.css'; @import './styles/utility/gap.css';
@import './styles/utility/height-inline.css';
@import './styles/utility/height.css'; @import './styles/utility/height.css';
@import './styles/utility/loading.css'; @import './styles/utility/loading.css';
@import './styles/utility/margin-right.css'; @import './styles/utility/margin.css';
@import './styles/utility/padding.css'; @import './styles/utility/padding.css';
@import './styles/utility/skin.css'; @import './styles/utility/skin.css';
@import './styles/utility/variant.css'; @import './styles/utility/variant.css';
@import './styles/utility/width-inline.css';
@import './styles/utility/width.css'; @import './styles/utility/width.css';

View File

@@ -1,52 +1,34 @@
import './index.scss'; import './index.css';
export * from './assets/svg/CheckIndicatorOutlineSvg.tsx'; export * from './assets/svg/CheckIndicatorOutlineSvg';
export * from './assets/svg/CheckIndicatorSvg.tsx'; export * from './assets/svg/CheckIndicatorSvg';
export * from './assets/svg/ChevronRightSvg.tsx'; export * from './assets/svg/ChevronRightSvg';
export * from './assets/svg/CutSvg.tsx'; export * from './assets/svg/CutSvg';
export * from './assets/svg/DownloadSvg.tsx'; export * from './assets/svg/DownloadSvg';
export * from './assets/svg/FileSvg.tsx'; export * from './assets/svg/FileSvg';
export * from './assets/svg/KeySvg.tsx'; export * from './assets/svg/KeySvg';
export * from './assets/svg/MoonSvg.tsx'; export * from './assets/svg/MoonSvg';
export * from './assets/svg/PasteSvg.tsx'; export * from './assets/svg/PasteSvg';
export * from './assets/svg/RadioIndicatorOutlineSvg.tsx'; export * from './assets/svg/RadioIndicatorOutlineSvg';
export * from './assets/svg/RadioIndicatorSvg.tsx'; export * from './assets/svg/RadioIndicatorSvg';
export * from './assets/svg/SearchSvg.tsx'; export * from './assets/svg/SearchSvg';
export * from './assets/svg/SettingSvg.tsx'; export * from './assets/svg/SettingSvg';
export * from './assets/svg/SpinnerSvg.tsx'; export * from './assets/svg/SpinnerSvg';
export * from './assets/svg/SunSvg.tsx'; export * from './assets/svg/SunSvg';
export * from './assets/svg/UserSvg.tsx'; export * from './assets/svg/UserSvg';
export * from './assets/svg/VolumeHighSvg.tsx'; export * from './assets/svg/VolumeHighSvg';
export * from './assets/svg/VolumeLowSvg.tsx'; export * from './assets/svg/VolumeLowSvg';
export * from './assets/svg/VolumeMediumSvg.tsx'; export * from './assets/svg/VolumeMediumSvg';
export * from './assets/svg/VolumeMuteSvg.tsx'; export * from './assets/svg/VolumeMuteSvg';
export * from './common/CommonProps.ts'; export * from './common/Box';
export * from './common/Box.tsx'; export * from './common/CommonProps';
export * from './lv1-fundamental/Slot/Slot.tsx'; export * from './common/Slot';
export * from './common/ThemeProvider/ThemeContext.ts'; export * from './common/ThemeProvider/ThemeContext';
export * from './common/ThemeProvider/ThemeProvider.tsx'; export * from './common/ThemeProvider/ThemeProvider';
export * from './common/ThemeProvider/useThemeContext.ts'; export * from './common/ThemeProvider/useThemeContext';
export * from './lv2-sized/Root/RootInline.recipe'; export * from './component/button/Button';
export * from './lv2-sized/Root/RootInline.ts'; export * from './styles/recipe/IinlineRoot.recipe';
export * from './styles/recipe/ItemRoot.recipe.ts'; export * from './styles/recipe/ItemRoot.recipe';
export * from './lv2-sized/ItemRoot/ItemRoot.tsx'; export * from './styles/recipe/variant.recipe';
export * from './lv2-sized/Section/Section.recipe.ts';
export * from './lv2-sized/Section/Section.tsx';
export * from './lv3-partial/Icon/Icon.recipe.ts';
export * from './lv3-partial/Icon/Icon.tsx';
export * from './lv3-partial/Indicator/Indicator.recipe.ts';
export * from './lv3-partial/Indicator/Indicator.tsx';
export * from './lv3-partial/Label/Label.style.ts';
export * from './lv3-partial/Label/Label.tsx';
export * from './lv3-partial/Tooltip/Tooltip.tsx';
export * from './lv4-normal/Button/Button.recipe.ts';
export * from './lv4-normal/Button/Button.tsx';
export * from './lv4-normal/Checkbox/Checkbox.recipe.ts';
export * from './lv4-normal/Checkbox/Checkbox.tsx';
export * from './lv4-normal/Radio/Radio.recipe.ts';
export * from './lv4-normal/Radio/Radio.tsx';
export * from './lv4-normal/Radio/RadioGroup.recipe.ts';
export * from './lv4-normal/Radio/RadioGroup.tsx';
export * from './lv4-normal/Radio/RadioGroupContext.ts';