From b37d9706e80375717f4d45d8068ec87e068dda88 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 15:40:24 +0200 Subject: [PATCH 01/14] feat: add switch in eol table --- .../EOL/EOLReleaseTable/TableBody.tsx | 92 ++++++++++++------- .../components/EOL/EOLReleaseTable/index.tsx | 27 +----- .../site/next-data/generators/releaseData.mjs | 2 +- packages/ui-components/package.json | 1 + .../src/Common/Switch/index.module.css | 59 ++++++++++++ .../src/Common/Switch/index.stories.tsx | 33 +++++++ .../ui-components/src/Common/Switch/index.tsx | 46 ++++++++++ pnpm-lock.yaml | 30 ++++++ 8 files changed, 235 insertions(+), 55 deletions(-) create mode 100644 packages/ui-components/src/Common/Switch/index.module.css create mode 100644 packages/ui-components/src/Common/Switch/index.stories.tsx create mode 100644 packages/ui-components/src/Common/Switch/index.tsx diff --git a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx b/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx index ee2fa061f37c7..5040e078ba211 100644 --- a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx @@ -1,5 +1,6 @@ 'use client'; +import Switch from '@node-core/ui-components/Common/Switch'; import { useTranslations } from 'next-intl'; import type { FC } from 'react'; import { Fragment, useState } from 'react'; @@ -23,45 +24,72 @@ const EOLReleaseTableBody: FC = ({ const t = useTranslations(); const [currentModal, setCurrentModal] = useState(); + const [hideNonLts, setHideNonLts] = useState(false); + + const filteredReleases = hideNonLts + ? eolReleases.filter(release => release.isLts) + : eolReleases; return ( - - {eolReleases.map(release => ( - + <> + setHideNonLts(!hideNonLts)} + /> + + - + + + + + + - + + {filteredReleases.map(release => ( + + + - + - - + + + + - open || setCurrentModal(undefined)} - /> - - ))} - + open || setCurrentModal(undefined)} + /> + + ))} + +
- v{release.major} {release.codename ? `(${release.codename})` : ''} - + {t('components.eolTable.version')} ( + {t('components.eolTable.codename')}) + {t('components.eolTable.lastUpdated')}{t('components.eolTable.vulnerabilities')}{t('components.eolTable.details')}
- -
+ v{release.major}{' '} + {release.codename ? `(${release.codename})` : ''} + - - + + - setCurrentModal(release.version)} - > - {t('components.downloadReleasesTable.details')} - -
+ + + setCurrentModal(release.version)} + > + {t('components.downloadReleasesTable.details')} + +
+ ); }; diff --git a/apps/site/components/EOL/EOLReleaseTable/index.tsx b/apps/site/components/EOL/EOLReleaseTable/index.tsx index d1e15f6dc37de..17e923b65b5ee 100644 --- a/apps/site/components/EOL/EOLReleaseTable/index.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/index.tsx @@ -1,11 +1,10 @@ -import { getTranslations } from 'next-intl/server'; import type { FC } from 'react'; import provideReleaseData from '#site/next-data/providers/releaseData'; import provideVulnerabilities from '#site/next-data/providers/vulnerabilities'; import { EOL_VERSION_IDENTIFIER } from '#site/next.constants.mjs'; -import EOLReleaseTableBody from './TableBody'; +import EOLReleaseTableInner from './TableBody'; const EOLReleaseTable: FC = async () => { const releaseData = await provideReleaseData(); @@ -15,27 +14,11 @@ const EOLReleaseTable: FC = async () => { release => release.status === EOL_VERSION_IDENTIFIER ); - const t = await getTranslations(); - return ( - - - - - - - - - - - -
- {t('components.eolTable.version')} ( - {t('components.eolTable.codename')}) - {t('components.eolTable.lastUpdated')}{t('components.eolTable.vulnerabilities')}{t('components.eolTable.details')}
+ ); }; diff --git a/apps/site/next-data/generators/releaseData.mjs b/apps/site/next-data/generators/releaseData.mjs index 9887cef858474..50b8399c9ba65 100644 --- a/apps/site/next-data/generators/releaseData.mjs +++ b/apps/site/next-data/generators/releaseData.mjs @@ -63,7 +63,7 @@ const generateReleaseData = async () => { version: latestVersion.semver.raw, versionWithPrefix: `v${latestVersion.semver.raw}`, codename: major.support.codename || '', - isLts: status.endsWith('LTS'), + isLts: support.ltsStart !== undefined, npm: latestVersion.dependencies.npm || '', v8: latestVersion.dependencies.v8, releaseDate: latestVersion.releaseDate, diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 0ea39b5f4abd0..738fdbac02b40 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -42,6 +42,7 @@ "@radix-ui/react-label": "~2.1.7", "@radix-ui/react-select": "~2.2.6", "@radix-ui/react-separator": "~1.1.7", + "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "~1.1.13", "@radix-ui/react-toast": "~1.2.15", "@radix-ui/react-tooltip": "~1.2.8", diff --git a/packages/ui-components/src/Common/Switch/index.module.css b/packages/ui-components/src/Common/Switch/index.module.css new file mode 100644 index 0000000000000..fa8416ea88586 --- /dev/null +++ b/packages/ui-components/src/Common/Switch/index.module.css @@ -0,0 +1,59 @@ +@reference "../../styles/index.css"; + +.switch { + @apply inline-flex + justify-end + gap-3; + + .label { + @apply cursor-pointer + select-none + text-sm + font-medium + text-neutral-800 + dark:text-neutral-200; + } + + .root { + @apply w-10.5 + relative + inline-flex + h-6 + cursor-pointer + items-center + rounded-full + bg-black + transition-colors + duration-100 + ease-out + focus:outline-none + focus-visible:ring-2 + focus-visible:ring-green-500 + focus-visible:ring-offset-2 + focus-visible:ring-offset-neutral-900 + dark:bg-neutral-700 + dark:focus-visible:ring-green-400; + } + + .root[data-state='checked'] { + @apply bg-green-600; + } + + .thumb { + @apply pointer-events-none + block + h-5 + w-5 + translate-x-0.5 + rounded-full + bg-white + ring-0 + transition-transform + duration-100 + ease-out; + } + + .thumb[data-state='checked'] { + @apply translate-x-5; + } +} diff --git a/packages/ui-components/src/Common/Switch/index.stories.tsx b/packages/ui-components/src/Common/Switch/index.stories.tsx new file mode 100644 index 0000000000000..cf32306b7c6bd --- /dev/null +++ b/packages/ui-components/src/Common/Switch/index.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta as MetaObj, StoryObj } from '@storybook/react'; +import { useState } from 'react'; + +import Switch from '#ui/Common/Switch'; + +type Story = StoryObj; +type Meta = MetaObj; + +export const Uncontrolled: Story = { + args: { + label: 'Enable Feature', + }, +}; + +export const Controlled: Story = { + args: { + label: 'Enable Feature', + }, + render: args => { + const [checked, setChecked] = useState(false); + + return ; + }, +}; + +export const WithoutLabel: Story = {}; + +export default { + component: Switch, + parameters: { + layout: 'centered', + }, +} as Meta; diff --git a/packages/ui-components/src/Common/Switch/index.tsx b/packages/ui-components/src/Common/Switch/index.tsx new file mode 100644 index 0000000000000..847d1775a2f45 --- /dev/null +++ b/packages/ui-components/src/Common/Switch/index.tsx @@ -0,0 +1,46 @@ +import * as SwitchPrimitive from '@radix-ui/react-switch'; +import classNames from 'classnames'; +import { FC, PropsWithChildren, useId } from 'react'; + +import styles from './index.module.css'; + +type SwitchProps = SwitchPrimitive.SwitchProps & { + label?: string; + checked?: boolean; + onCheckedChange?: (checked: boolean) => void; + thumbClassname?: string; +}; + +const Switch: FC> = ({ + label, + checked, + onCheckedChange, + className, + thumbClassname, + ...props +}) => { + const id = useId(); + + return ( +
+ {label && ( + + )} + + + +
+ ); +}; + +export default Switch; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a63808bd069f6..db64583c59c93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -483,6 +483,9 @@ importers: '@radix-ui/react-separator': specifier: ~1.1.7 version: 1.1.7(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-switch': + specifier: ^1.2.6 + version: 1.2.6(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-tabs': specifier: ~1.1.13 version: 1.1.13(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -2482,6 +2485,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tabs@1.1.13': resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} peerDependencies: @@ -11179,6 +11195,20 @@ snapshots: optionalDependencies: '@types/react': 19.2.0 + '@radix-ui/react-switch@1.2.6(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.0)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.0 + '@radix-ui/react-tabs@1.1.13(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/primitive': 1.1.3 From 680b0ca478cae757a9722b68b2dd02d9e6da8161 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 15:51:35 +0200 Subject: [PATCH 02/14] feat: translation keys --- apps/site/components/EOL/EOLReleaseTable/TableBody.tsx | 2 +- packages/i18n/src/locales/en.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx b/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx index 5040e078ba211..2b69b38724a79 100644 --- a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx @@ -33,7 +33,7 @@ const EOLReleaseTableBody: FC = ({ return ( <> setHideNonLts(!hideNonLts)} /> diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index 653bd8f5e775c..fba6167bcae98 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -214,7 +214,8 @@ "releaseDate": "Released at", "lastUpdated": "Last updated", "vulnerabilities": "Vulnerabilities", - "details": "Details" + "details": "Details", + "hideNonLts": "Hide non-LTS versions" }, "minorReleasesTable": { "version": "Version", From 6f7ab9828016dde593d4b0d9dd2317a56699bf53 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 16:34:22 +0200 Subject: [PATCH 03/14] refactor: client renaming --- .../EOL/EOLReleaseTable/{TableBody.tsx => TableClient.tsx} | 4 ++-- apps/site/components/EOL/EOLReleaseTable/index.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename apps/site/components/EOL/EOLReleaseTable/{TableBody.tsx => TableClient.tsx} (96%) diff --git a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx b/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx similarity index 96% rename from apps/site/components/EOL/EOLReleaseTable/TableBody.tsx rename to apps/site/components/EOL/EOLReleaseTable/TableClient.tsx index 2b69b38724a79..12be27be746d0 100644 --- a/apps/site/components/EOL/EOLReleaseTable/TableBody.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx @@ -17,7 +17,7 @@ type EOLReleaseTableBodyProps = { vulnerabilities: GroupedVulnerabilities; }; -const EOLReleaseTableBody: FC = ({ +const EOLReleaseTableClient: FC = ({ eolReleases, vulnerabilities, }) => { @@ -93,4 +93,4 @@ const EOLReleaseTableBody: FC = ({ ); }; -export default EOLReleaseTableBody; +export default EOLReleaseTableClient; diff --git a/apps/site/components/EOL/EOLReleaseTable/index.tsx b/apps/site/components/EOL/EOLReleaseTable/index.tsx index 17e923b65b5ee..c3315fa0588ee 100644 --- a/apps/site/components/EOL/EOLReleaseTable/index.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/index.tsx @@ -4,7 +4,7 @@ import provideReleaseData from '#site/next-data/providers/releaseData'; import provideVulnerabilities from '#site/next-data/providers/vulnerabilities'; import { EOL_VERSION_IDENTIFIER } from '#site/next.constants.mjs'; -import EOLReleaseTableInner from './TableBody'; +import EOLReleaseTableClient from './TableClient'; const EOLReleaseTable: FC = async () => { const releaseData = await provideReleaseData(); @@ -15,7 +15,7 @@ const EOLReleaseTable: FC = async () => { ); return ( - From bdf5ce96db4ce64f11d03b7e57e1f2159b803f89 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 18:59:32 +0200 Subject: [PATCH 04/14] fix: dont create arrow fn onCheckedChange --- apps/site/components/EOL/EOLReleaseTable/TableClient.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx b/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx index 12be27be746d0..fed81872c8d29 100644 --- a/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx +++ b/apps/site/components/EOL/EOLReleaseTable/TableClient.tsx @@ -35,7 +35,7 @@ const EOLReleaseTableClient: FC = ({ setHideNonLts(!hideNonLts)} + onCheckedChange={setHideNonLts} /> From aebe8305ebb4f317f25773ff82426f661cb6e6f6 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 19:00:45 +0200 Subject: [PATCH 05/14] chore: use tilde for version --- packages/ui-components/package.json | 2 +- pnpm-lock.yaml | 52 +++-------------------------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 738fdbac02b40..5eee9b85c9111 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -42,7 +42,7 @@ "@radix-ui/react-label": "~2.1.7", "@radix-ui/react-select": "~2.2.6", "@radix-ui/react-separator": "~1.1.7", - "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-switch": "~1.2.6", "@radix-ui/react-tabs": "~1.1.13", "@radix-ui/react-toast": "~1.2.15", "@radix-ui/react-tooltip": "~1.2.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db64583c59c93..782e206fc7dbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -173,7 +173,7 @@ importers: version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) postcss-calc: specifier: ~10.1.1 - version: 10.1.1(postcss@8.5.6) + version: 10.1.1(postcss@8.5.3) react: specifier: 'catalog:' version: 19.2.0 @@ -261,13 +261,13 @@ importers: version: 5.2.0(eslint@9.36.0(jiti@2.6.1)) global-jsdom: specifier: ^27.0.0 - version: 27.0.0(jsdom@27.0.0(postcss@8.5.6)) + version: 27.0.0(jsdom@27.0.0(postcss@8.5.3)) handlebars: specifier: 4.7.8 version: 4.7.8 jsdom: specifier: ^27.0.0 - version: 27.0.0(postcss@8.5.6) + version: 27.0.0(postcss@8.5.3) mdast-util-from-markdown: specifier: ^2.0.2 version: 2.0.2 @@ -484,7 +484,7 @@ importers: specifier: ~1.1.7 version: 1.1.7(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-switch': - specifier: ^1.2.6 + specifier: ~1.2.6 version: 1.2.6(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-tabs': specifier: ~1.1.13 @@ -9829,10 +9829,6 @@ snapshots: dependencies: postcss: 8.5.3 - '@csstools/css-syntax-patches-for-csstree@1.0.14(postcss@8.5.6)': - dependencies: - postcss: 8.5.6 - '@csstools/css-tokenizer@3.0.4': {} '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': @@ -13484,14 +13480,6 @@ snapshots: transitivePeerDependencies: - postcss - cssstyle@5.3.1(postcss@8.5.6): - dependencies: - '@asamuzakjp/css-color': 4.0.5 - '@csstools/css-syntax-patches-for-csstree': 1.0.14(postcss@8.5.6) - css-tree: 3.1.0 - transitivePeerDependencies: - - postcss - csstype@3.1.3: {} damerau-levenshtein@1.0.8: {} @@ -14670,10 +14658,6 @@ snapshots: dependencies: jsdom: 27.0.0(postcss@8.5.3) - global-jsdom@27.0.0(jsdom@27.0.0(postcss@8.5.6)): - dependencies: - jsdom: 27.0.0(postcss@8.5.6) - global-modules@2.0.0: dependencies: global-prefix: 3.0.0 @@ -15279,34 +15263,6 @@ snapshots: - supports-color - utf-8-validate - jsdom@27.0.0(postcss@8.5.6): - dependencies: - '@asamuzakjp/dom-selector': 6.6.1 - cssstyle: 5.3.1(postcss@8.5.6) - data-urls: 6.0.0 - decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - parse5: 7.3.0 - rrweb-cssom: 0.8.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 6.0.0 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 8.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 15.1.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - postcss - - supports-color - - utf-8-validate - jsesc@3.1.0: {} json-buffer@3.0.1: {} From 4502c6cc9ce4bdd7e12f15735844ddda16d93569 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Thu, 23 Oct 2025 19:10:09 +0200 Subject: [PATCH 06/14] refactor: rename prop --- packages/ui-components/src/Common/Switch/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui-components/src/Common/Switch/index.tsx b/packages/ui-components/src/Common/Switch/index.tsx index 847d1775a2f45..9cde39ff45e94 100644 --- a/packages/ui-components/src/Common/Switch/index.tsx +++ b/packages/ui-components/src/Common/Switch/index.tsx @@ -8,7 +8,7 @@ type SwitchProps = SwitchPrimitive.SwitchProps & { label?: string; checked?: boolean; onCheckedChange?: (checked: boolean) => void; - thumbClassname?: string; + thumbClassName?: string; }; const Switch: FC> = ({ @@ -16,7 +16,7 @@ const Switch: FC> = ({ checked, onCheckedChange, className, - thumbClassname, + thumbClassName, ...props }) => { const id = useId(); @@ -36,7 +36,7 @@ const Switch: FC> = ({ {...props} > From f530878450c63aee83ab09bbaa615bfe45105601 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Wed, 29 Oct 2025 06:29:48 -0500 Subject: [PATCH 07/14] fixes test, but does it? --- apps/site/next-data/generators/__tests__/releaseData.test.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/site/next-data/generators/__tests__/releaseData.test.mjs b/apps/site/next-data/generators/__tests__/releaseData.test.mjs index 43de9287c87b1..0591eefd46c6f 100644 --- a/apps/site/next-data/generators/__tests__/releaseData.test.mjs +++ b/apps/site/next-data/generators/__tests__/releaseData.test.mjs @@ -43,7 +43,7 @@ describe('generateReleaseData', () => { version: '14.0.0', versionWithPrefix: 'v14.0.0', codename: '', - isLts: false, + isLts: true, npm: '6.14.10', v8: '8.0.276.20', releaseDate: '2021-04-20', From 39eb665cb27a91d40d895a80cf7fe5a27566b292 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Wed, 29 Oct 2025 17:12:29 +0100 Subject: [PATCH 08/14] fix: add use client directive --- packages/ui-components/src/Common/Switch/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/ui-components/src/Common/Switch/index.tsx b/packages/ui-components/src/Common/Switch/index.tsx index 9cde39ff45e94..3a0b75cfd6917 100644 --- a/packages/ui-components/src/Common/Switch/index.tsx +++ b/packages/ui-components/src/Common/Switch/index.tsx @@ -1,3 +1,5 @@ +'use client'; + import * as SwitchPrimitive from '@radix-ui/react-switch'; import classNames from 'classnames'; import { FC, PropsWithChildren, useId } from 'react'; From fee09ef2671d0fc181543bce12369c7c758af002 Mon Sep 17 00:00:00 2001 From: Efe Date: Sat, 1 Nov 2025 11:12:28 +0100 Subject: [PATCH 09/14] fix: apply motion safe Co-authored-by: Caner Akdas Signed-off-by: Efe --- packages/ui-components/src/Common/Switch/index.module.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui-components/src/Common/Switch/index.module.css b/packages/ui-components/src/Common/Switch/index.module.css index fa8416ea88586..8ed39992f4d84 100644 --- a/packages/ui-components/src/Common/Switch/index.module.css +++ b/packages/ui-components/src/Common/Switch/index.module.css @@ -23,9 +23,9 @@ items-center rounded-full bg-black - transition-colors - duration-100 - ease-out + motion-safe:transition-colors + motion-safe:duration-100 + motion-safe:ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-green-500 From a0ae7e07d0164641dc3d10a365b59ce7d61ddd60 Mon Sep 17 00:00:00 2001 From: Efe Date: Sat, 1 Nov 2025 11:13:05 +0100 Subject: [PATCH 10/14] refactor: use size instead of w&h Co-authored-by: Caner Akdas Signed-off-by: Efe --- packages/ui-components/src/Common/Switch/index.module.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ui-components/src/Common/Switch/index.module.css b/packages/ui-components/src/Common/Switch/index.module.css index 8ed39992f4d84..1f58dd3c4f665 100644 --- a/packages/ui-components/src/Common/Switch/index.module.css +++ b/packages/ui-components/src/Common/Switch/index.module.css @@ -42,8 +42,7 @@ .thumb { @apply pointer-events-none block - h-5 - w-5 + size-5 translate-x-0.5 rounded-full bg-white From 8cbd84a388f416446e96cd8389941a3d63974d15 Mon Sep 17 00:00:00 2001 From: Efe Date: Sat, 1 Nov 2025 11:13:23 +0100 Subject: [PATCH 11/14] fix: use motion safe Co-authored-by: Caner Akdas Signed-off-by: Efe --- packages/ui-components/src/Common/Switch/index.module.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui-components/src/Common/Switch/index.module.css b/packages/ui-components/src/Common/Switch/index.module.css index 1f58dd3c4f665..6036b03ebe918 100644 --- a/packages/ui-components/src/Common/Switch/index.module.css +++ b/packages/ui-components/src/Common/Switch/index.module.css @@ -47,9 +47,9 @@ rounded-full bg-white ring-0 - transition-transform - duration-100 - ease-out; + motion-safe:transition-transform + motion-safe:duration-100 + motion-safe:ease-out; } .thumb[data-state='checked'] { From d73475e05abc89204864c101df429dc996ce0a01 Mon Sep 17 00:00:00 2001 From: Efe Date: Sat, 1 Nov 2025 11:18:16 +0100 Subject: [PATCH 12/14] refactor: use import type for types Co-authored-by: Caner Akdas Signed-off-by: Efe --- packages/ui-components/src/Common/Switch/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui-components/src/Common/Switch/index.tsx b/packages/ui-components/src/Common/Switch/index.tsx index 3a0b75cfd6917..5181b99c2fa4b 100644 --- a/packages/ui-components/src/Common/Switch/index.tsx +++ b/packages/ui-components/src/Common/Switch/index.tsx @@ -2,7 +2,8 @@ import * as SwitchPrimitive from '@radix-ui/react-switch'; import classNames from 'classnames'; -import { FC, PropsWithChildren, useId } from 'react'; +import { useId } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import styles from './index.module.css'; From ce14ae68b3a8f6700f4024100c55f3b8bd77704f Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Mon, 3 Nov 2025 18:55:32 +0100 Subject: [PATCH 13/14] fix: adjust focus visible ring offset --- .../ui-components/src/Common/Switch/index.module.css | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/ui-components/src/Common/Switch/index.module.css b/packages/ui-components/src/Common/Switch/index.module.css index 6036b03ebe918..7d0a33166540c 100644 --- a/packages/ui-components/src/Common/Switch/index.module.css +++ b/packages/ui-components/src/Common/Switch/index.module.css @@ -23,16 +23,17 @@ items-center rounded-full bg-black - motion-safe:transition-colors - motion-safe:duration-100 - motion-safe:ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-green-500 focus-visible:ring-offset-2 - focus-visible:ring-offset-neutral-900 + focus-visible:ring-offset-neutral-100 + motion-safe:transition-colors + motion-safe:duration-100 + motion-safe:ease-out dark:bg-neutral-700 - dark:focus-visible:ring-green-400; + dark:focus-visible:ring-green-400 + dark:focus-visible:ring-offset-neutral-900; } .root[data-state='checked'] { From 52fd77bfddbb4740fba1d7ace0e72ec16a92b837 Mon Sep 17 00:00:00 2001 From: Efe Karasakal Date: Mon, 3 Nov 2025 19:07:19 +0100 Subject: [PATCH 14/14] chore: update pnpm lock --- pnpm-lock.yaml | 56 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e94f7f65f57e8..724f9667cec5e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -483,6 +483,9 @@ importers: '@radix-ui/react-separator': specifier: ~1.1.7 version: 1.1.7(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-switch': + specifier: ~1.2.6 + version: 1.2.6(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-tabs': specifier: ~1.1.13 version: 1.1.13(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -2483,6 +2486,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tabs@1.1.13': resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} peerDependencies: @@ -11164,6 +11180,20 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 + '@radix-ui/react-switch@1.2.6(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.2)(react@19.2.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + '@radix-ui/react-tabs@1.1.13(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -13864,7 +13894,7 @@ snapshots: eslint: 9.36.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)))(eslint@9.36.0(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.36.0(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.36.0(jiti@2.6.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.36.0(jiti@2.6.1)) @@ -13901,7 +13931,7 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)))(eslint@9.36.0(jiti@2.6.1)) eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -13917,7 +13947,7 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)) eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -13944,6 +13974,17 @@ snapshots: - bluebird - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@2.6.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3) + eslint: 9.36.0(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)): dependencies: debug: 3.2.7 @@ -13954,6 +13995,7 @@ snapshots: eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color + optional: true eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)): dependencies: @@ -13973,7 +14015,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.36.0(jiti@2.6.1)))(eslint@9.36.0(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13984,7 +14026,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.36.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.36.0(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -14002,7 +14044,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.36.0(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -14024,6 +14066,8 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.45.0(eslint@9.36.0(jiti@2.6.1))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack