在 Tailwind CSS 中制作动画选项卡?

dea*_*904 6 html css css-transitions reactjs tailwind-css

我想制作一个动画标签,例如:

\n

动画标签顺风

\n

我正在使用 React 和 Tailwind。这是我的代码:

\n
import React from \'react\'\nimport clsx from \'clsx\'\n\nexport const Modal = () => {\n  const [theme, setTheme] = React.useState<\'light\' | \'dark\' | \'system\'>(\'light\')\n  return (\n    <div className="flex mx-2 mt-2 rounded-md bg-blue-gray-100">\n      <div\n        className={clsx(\'flex-1 py-1 my-2 ml-2 text-center rounded-md\', {\n          \'bg-white\': theme === \'light\',\n          \'transition duration-1000 ease-out transform translate-x-10\':\n            theme !== \'light\',\n        })}\n      >\n        <button\n          className={clsx(\n            \'w-full text-sm cursor-pointer select-none focus:outline-none\',\n            {\n              \'font-bold text-blue-gray-900\': theme === \'light\',\n              \'text-blue-gray-600\': theme !== \'light\',\n            }\n          )}\n          onClick={() => {\n            setTheme(\'light\')\n          }}\n        >\n          Light\n        </button>\n      </div>\n      <div\n        className={clsx(\'flex-1 py-1 my-2 ml-2 text-center rounded-md\', {\n          \'bg-white\': theme === \'dark\',\n        })}\n      >\n        <button\n          className={clsx(\n            \'w-full text-sm cursor-pointer select-none focus:outline-none\',\n            {\n              \'font-bold text-blue-gray-900\': theme === \'dark\',\n              \'text-blue-gray-600\': theme !== \'dark\',\n            }\n          )}\n          onClick={() => {\n            setTheme(\'dark\')\n          }}\n        >\n          Dark\n        </button>\n      </div>\n      <div\n        className={clsx(\'flex-1 py-1 my-2 mr-2 text-center rounded-md\', {\n          \'bg-white\': theme === \'system\',\n        })}\n      >\n        <button\n          className={clsx(\n            \'w-full text-sm cursor-pointer select-none focus:outline-none\',\n            {\n              \'font-bold text-blue-gray-900\': theme === \'system\',\n              \'text-blue-gray-600\': theme !== \'system\',\n            }\n          )}\n          onClick={() => {\n            setTheme(\'system\')\n          }}\n        >\n          System\n        </button>\n      </div>\n    </div>\n  )\n}\n
Run Code Online (Sandbox Code Playgroud)\n

但它看起来像:

\n

我的顺风动画标签尝试

\n

正如我translate-x-10在主题不是 时使用的那样light,因此文本也会移动。

\n

我希望使 UI 与上面的 UI 完全相同,同时仍然使用实际选项卡的按钮。

\n

最小 Codesandbox \xe2\x86\x92 https://codesandbox.io/s/mobx-theme-change-n1nvg?file=/src/App.tsx

\n

我该怎么做?

\n

dea*_*904 2

事实证明,使用纯 Tailwind 就可以实现这一点。

\n

tailwind.config.js

\n
module.exports = {\n    theme: {\n        extend: {\n            translate: {\n                200: \'200%\',\n            },\n        },\n    },\n}\n
Run Code Online (Sandbox Code Playgroud)\n

应用程序.tsx

\n
import * as React from "react"\nimport { observer } from "mobx-react"\nimport clsx from "clsx"\n\nimport { useStore } from "./context"\n\nconst AppTheme = observer(() => {\n    const {\n        theme: { app },\n        updateTheme,\n    } = useStore()\n\n    return (\n        <>\n            <div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">\n                <div className="mt-2">\n                    <h4 className="text-xl font-bold text-gray-800">Background</h4>\n                </div>\n            </div>\n\n            <div className="relative mx-2 mt-2 rounded-md bg-gray-100">\n                <div\n                    id="slider"\n                    className={clsx(\n                        "absolute inset-y-0 w-1/3 h-full px-4 py-1 transition-transform transform",\n                        {\n                            "translate-x-0": app === "light",\n                            "translate-x-full": app === "dark",\n                            "translate-x-200": app === "system",\n                        },\n                    )}\n                    style={\n                        app === "system"\n                            ? {\n                                    transform: "translateX(200%)", // if you added `translate-x-200` to `tailwind.config.js` then you can remove the `style` tag completely\n                              }\n                            : {}\n                    }\n                >\n                    <div\n                        className={clsx(\n                            "w-full h-full bg-white rounded-md",\n                            {\n                                active: app === "light",\n                                "bg-gray-600": app === "dark",\n                            },\n                            {\n                                // needs to be separate object otherwise dark/light & system keys overlap resulting in a visual bug\n                                ["bg-gray-600"]: app === "system",\n                            },\n                        )}\n                    ></div>\n                </div>\n                <div className="relative flex w-full h-full">\n                    <button\n                        tabIndex={0}\n                        className={clsx(\n                            "py-1 my-2 ml-2 w-1/3 text-sm cursor-pointer select-none focus:outline-none",\n                            {\n                                active: app === "light",\n                                "font-bold text--gray-900": app === "light",\n                                "text--gray-600": app !== "light",\n                            },\n                        )}\n                        onKeyUp={(event: React.KeyboardEvent<HTMLElement>) => {\n                            if (event.key === "Tab")\n                                updateTheme({\n                                    app: "light",\n                                })\n                        }}\n                        onClick={() => {\n                            updateTheme({\n                                app: "light",\n                            })\n                        }}\n                    >\n                        Light\n                    </button>\n                    <button\n                        tabIndex={0}\n                        className={clsx(\n                            "py-1 my-2 ml-2 w-1/3 text-sm cursor-pointer select-none focus:outline-none",\n                            {\n                                active: app === "dark",\n                                "font-bold text-white": app === "dark",\n                                "text--gray-600": app !== "dark",\n                            },\n                        )}\n                        onKeyUp={(event: React.KeyboardEvent<HTMLElement>) => {\n                            if (event.key === "Tab")\n                                updateTheme({\n                                    app: "dark",\n                                })\n                        }}\n                        onClick={() => {\n                            updateTheme({\n                                app: "dark",\n                            })\n                        }}\n                    >\n                        Dark\n                    </button>\n                    <button\n                        tabIndex={0}\n                        className={clsx(\n                            "py-1 my-2 ml-2 w-1/3 text-sm cursor-pointer select-none focus:outline-none",\n                            {\n                                active: app === "system",\n                                "font-bold text-white": app === "system",\n                                "text--gray-600": app !== "system",\n                            },\n                        )}\n                        onKeyUp={(event: React.KeyboardEvent<HTMLElement>) => {\n                            if (event.key === "Tab")\n                                updateTheme({\n                                    app: "system",\n                                })\n                        }}\n                        onClick={() => {\n                            updateTheme({\n                                app: "system",\n                            })\n                        }}\n                    >\n                        System\n                    </button>\n                </div>\n            </div>\n        </>\n    )\n})\n\nexport default observer(function App() {\n    return <AppTheme />\n})\n
Run Code Online (Sandbox Code Playgroud)\n

Codesandbox \xe2\x86\x92 https://codesandbox.io/s/mobx-theme-change-animated-18gc6?file=/src/App.tsx

\n

我不知道为什么它不在 Codesandbox 上动画,但它在本地工作。也许是 Codesandbox 的错误:)

\n