diff --git a/.changeset/fair-knives-protect.md b/.changeset/fair-knives-protect.md new file mode 100644 index 000000000..353932cad --- /dev/null +++ b/.changeset/fair-knives-protect.md @@ -0,0 +1,5 @@ +--- +"@4design/for-ui": minor +--- + +refactor(Button): MUI剥がし diff --git a/package-lock.json b/package-lock.json index 39c876e1f..1e68edcf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "npm-run-all2": "6.1.2", "prettier": "3.2.5", "turbo": "1.11.2", - "typescript": "5.1.6" + "typescript": "5.4.5" }, "engines": { "node": ">=14.0.0", @@ -5771,11 +5771,14 @@ } }, "node_modules/@storybook/builder-webpack4/node_modules/watchpack/chokidar2": { - "version": "0.0.1", + "version": "2.0.0", "dev": true, "optional": true, "dependencies": { "chokidar": "^2.1.8" + }, + "engines": { + "node": "<8.10.0" } }, "node_modules/@storybook/builder-webpack4/node_modules/webpack": { @@ -28469,9 +28472,9 @@ } }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -30636,7 +30639,7 @@ "react-hook-form": "7.45.4", "react-icons": "4.10.1", "tailwindcss": "3.4.3", - "typescript": "5.1.6", + "typescript": "5.4.5", "vite": "3.2.5", "vitest": "0.33.0", "webpack": "5.88.2", @@ -33004,7 +33007,7 @@ "react-transition-group": "4.4.5", "tailwind-merge": "1.14.0", "tailwindcss": "3.4.3", - "typescript": "5.1.6", + "typescript": "5.4.5", "vite": "3.2.5", "vitest": "0.33.0", "webpack": "5.88.2", @@ -53942,9 +53945,9 @@ } }, "typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==" + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==" }, "ufo": { "version": "1.1.2", diff --git a/package.json b/package.json index 3a5315aca..8c84465db 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "npm-run-all2": "6.1.2", "prettier": "3.2.5", "turbo": "1.11.2", - "typescript": "5.1.6" + "typescript": "5.4.5" }, "volta": { "node": "16.20.2" diff --git a/packages/for-ui/package.json b/packages/for-ui/package.json index 4dec3b8df..160fbfad5 100644 --- a/packages/for-ui/package.json +++ b/packages/for-ui/package.json @@ -95,7 +95,7 @@ "react-hook-form": "7.45.4", "react-icons": "4.10.1", "tailwindcss": "3.4.3", - "typescript": "5.1.6", + "typescript": "5.4.5", "vite": "3.2.5", "vitest": "0.33.0", "webpack": "5.88.2", diff --git a/packages/for-ui/src/button/Button.test.tsx b/packages/for-ui/src/button/Button.test.tsx index e8b308d23..3d9e20d8f 100644 --- a/packages/for-ui/src/button/Button.test.tsx +++ b/packages/for-ui/src/button/Button.test.tsx @@ -1,3 +1,4 @@ +import { FC, ReactNode } from 'react'; import { MdOutlineCheck } from 'react-icons/md'; import { describe, expect, it } from 'vitest'; import { render, screen } from '@testing-library/react'; @@ -93,3 +94,16 @@ describe('Button', () => { expect(element).toBeInTheDocument(); }); }); + +describe('Type', () => { + it('is semantically correct for React component using as props', async () => { + const Link: FC<{ to: string; children?: ReactNode }> = ({ to, children }) => {children}; + render( + , + ); + const element = await screen.findByRole('link', { name: 'test' }); + expect(element).toBeInTheDocument(); + }); +}); diff --git a/packages/for-ui/src/button/Button.tsx b/packages/for-ui/src/button/Button.tsx index bd1f965eb..2b9e21155 100644 --- a/packages/for-ui/src/button/Button.tsx +++ b/packages/for-ui/src/button/Button.tsx @@ -1,6 +1,4 @@ -import { Children, ElementType, forwardRef, MouseEvent, MouseEventHandler, ReactNode, useMemo } from 'react'; -import MuiButton, { ButtonUnstyledProps as MuiButtonProps } from '@mui/base/ButtonUnstyled'; -import { LoadingButtonProps } from '@mui/lab/LoadingButton'; +import { Children, ElementType, forwardRef, ReactNode, useMemo } from 'react'; import { Loader } from '../loader'; import { ComponentPropsWithAs, Element, Ref } from '../system/componentType'; import { fsx } from '../system/fsx'; @@ -10,7 +8,7 @@ import { walkChildren } from '../system/walkChildren'; type Child = Exclude> | string; export type ButtonProps = ComponentPropsWithAs< - Omit, 'href' | 'children' | 'onClick'> & { + { /** * 種類を指定 * @@ -57,48 +55,6 @@ export type ButtonProps = ComponentPropsWithA disabled?: boolean; - /** - * 先頭に表示するアイコンを指定 - * - * @deprecated childrenを使用してください - * ``` - * - * ``` - */ - startIcon?: ReactNode; - - /** - * 末尾に表示するアイコンを指定 - * - * @deprecated childrenを使用してください - * ``` - * - * ``` - */ - endIcon?: ReactNode; - - /** - * 読み込み中のアイコンを表示する場所を指定 - * - * @deprecated デザインの仕様変更に伴い表示位置は固定になりました - */ - loadingPosition?: LoadingButtonProps['loadingPosition']; - - /** - * colorを指定する場合に指定 - * - * @deprecated intention propsを使ってください - */ - color?: 'primary' | 'secondary' | 'default'; - - onClick?: MouseEventHandler; - className?: string; }, As @@ -130,56 +86,41 @@ export const Button: ButtonComponent = forwardRef( { as, variant = 'outlined', - intention: passedIntention = 'subtle', + intention = 'subtle', size = 'large', loading = false, - startIcon, - endIcon, - color, children, className, + disabled, onClick, ...rest }: ButtonProps, ref?: Ref, ): Element => { - const component = as || 'button'; + const Component = as || 'button'; const childTexts = useMemo(() => Children.map(children, extractText) || [], [children]); const structure: Structure = useMemo(() => { - if ((childTexts.at(0) && !childTexts.at(-1)) || (endIcon && children)) { + if (childTexts.at(0) && !childTexts.at(-1)) { return 'text-icon'; } - if ((!childTexts.at(0) && childTexts.at(-1)) || (startIcon && children)) { + if (!childTexts.at(0) && childTexts.at(-1)) { return 'icon-text'; } - if (!childTexts.at(0) || (startIcon && !children)) { + if (!childTexts.at(0)) { return 'icon'; } return 'text'; - }, [startIcon, endIcon, children, childTexts]); - - // Legacy support for color props - // If not needed, rename the passedIntention to intention. - - const intention = color - ? ( - { - primary: 'primary', - secondary: 'secondary', - default: 'primary', - } as const - )[color] - : passedIntention; + }, [childTexts]); return ( - - component={component} + )} - onClick={(e: MouseEvent) => { + {...rest} + onClick={(e) => { if (loading) { return; } onClick?.(e); }} > - {startIcon} {children} - {endIcon} {loading && (
)} - +
); }, ); diff --git a/packages/for-ui/src/system/componentType.ts b/packages/for-ui/src/system/componentType.ts index 906c7dda2..3fba3b656 100644 --- a/packages/for-ui/src/system/componentType.ts +++ b/packages/for-ui/src/system/componentType.ts @@ -15,7 +15,7 @@ export type AsProps = { export type ComponentPropsWithAs = AsProps & Props & RefProps & - PreservedOmit, keyof (Props & AsProps & RefProps)>; + NoInfer, keyof (Props & AsProps & RefProps)>>; export type ElementTypeToHTMLElement = Element extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[Element]