dea*_*904 6 html css css-transitions reactjs tailwind-css
我想制作一个动画标签,例如:
\n
我正在使用 React 和 Tailwind。这是我的代码:
\nimport 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}\nRun Code Online (Sandbox Code Playgroud)\n但它看起来像:
\n
正如我translate-x-10在主题不是 时使用的那样light,因此文本也会移动。
我希望使 UI 与上面的 UI 完全相同,同时仍然使用实际选项卡的按钮。
\n最小 Codesandbox \xe2\x86\x92 https://codesandbox.io/s/mobx-theme-change-n1nvg?file=/src/App.tsx
\n我该怎么做?
\n事实证明,使用纯 Tailwind 就可以实现这一点。
\nmodule.exports = {\n theme: {\n extend: {\n translate: {\n 200: \'200%\',\n },\n },\n },\n}\nRun Code Online (Sandbox Code Playgroud)\nimport * 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})\nRun Code Online (Sandbox Code Playgroud)\nCodesandbox \xe2\x86\x92 https://codesandbox.io/s/mobx-theme-change-animated-18gc6?file=/src/App.tsx
\n我不知道为什么它不在 Codesandbox 上动画,但它在本地工作。也许是 Codesandbox 的错误:)
\n