From 90fee47da548253d3879c9a82d73d74541de3595 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 13:20:32 -0600 Subject: [PATCH 01/11] fix: prevent Go back button from exceeding content width on DemoConnectGuard --- src/components/RenderConnectStep.js | 8 +++++++- src/views/demoConnectGuard/DemoConnectGuard.module.css | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/RenderConnectStep.js b/src/components/RenderConnectStep.js index 14a81fd81e..66616862b5 100644 --- a/src/components/RenderConnectStep.js +++ b/src/components/RenderConnectStep.js @@ -107,7 +107,13 @@ const RenderConnectStep = (props) => { !selectedInstitution?.is_demo if (shouldShowDemoConnectGuard) { - return + return ( +
+
+ +
+
+ ) } let connectStepView = null diff --git a/src/views/demoConnectGuard/DemoConnectGuard.module.css b/src/views/demoConnectGuard/DemoConnectGuard.module.css index 239452b150..1ba0b408ac 100644 --- a/src/views/demoConnectGuard/DemoConnectGuard.module.css +++ b/src/views/demoConnectGuard/DemoConnectGuard.module.css @@ -1,7 +1,6 @@ .container { display: flex; flex-direction: column; - align-items: center; justify-content: center; text-align: center; padding-top: 20px; From e52196561b6d5473792bbcbddf006156e77cf7f8 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:02:31 -0600 Subject: [PATCH 02/11] feat: No longer allow @kyper components --- .eslintrc.cjs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 155237eb84..ce8322476c 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -30,12 +30,8 @@ module.exports = { { paths: [ { - name: '@kyper/input', - message: "Please import from 'src/privacy/input instead'.", - }, - { - name: '@kyper/textarea', - message: "Please import from 'src/privacy/input instead'.", + name: '@kyper/*', + message: 'Kyper has been retired. Please use MXUI instead.', }, { name: '@mui/material/TextField', From 44abf6862c0ae0d64e7a4bd9b02578b310d960ad Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:04:15 -0600 Subject: [PATCH 03/11] Remove unused @mx-cartographer/kyper-mui --- package-lock.json | 273 ---------------------------------------------- package.json | 1 - 2 files changed, 274 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fa72a9786..07e668198d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "vite-plugin-dts": "^4.5.4" }, "devDependencies": { - "@mx-cartographer/kyper-mui": "^2.2.0-alpha1", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", @@ -1958,20 +1957,6 @@ } } }, - "node_modules/@mui/types": { - "version": "7.2.24", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", - "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", - "dev": true, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/utils": { "version": "7.3.11", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.11.tgz", @@ -2330,252 +2315,6 @@ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@mx-cartographer/kyper-mui": { - "version": "2.2.0-alpha1", - "resolved": "https://registry.npmjs.org/@mx-cartographer/kyper-mui/-/kyper-mui-2.2.0-alpha1.tgz", - "integrity": "sha512-wHi2w5uX/1V31oou6nNZQb5PskrNHbbxrGflTo9ogzneU3l9vD/pROagVa62HU4CU9icxWaBfTJJUtNKm+VASw==", - "dev": true, - "dependencies": { - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.14.8", - "@mui/material": "^5.14.8", - "@mxenabled/cssinjs": "^0.6.0", - "@mxenabled/design-tokens": "^1.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "peerDependencies": { - "@emotion/react": "^11", - "@emotion/styled": "^11", - "@mui/icons-material": "^5", - "@mui/material": "^5", - "@mxenabled/design-tokens": "^1", - "react": "^18", - "react-dom": "^18" - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/core-downloads-tracker": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", - "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/icons-material": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.18.0.tgz", - "integrity": "sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/material": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", - "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.18.0", - "@mui/system": "^5.18.0", - "@mui/types": "~7.2.15", - "@mui/utils": "^5.17.1", - "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^19.0.0", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/material/node_modules/@mui/system": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", - "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.17.1", - "@mui/styled-engine": "^5.18.0", - "@mui/types": "~7.2.15", - "@mui/utils": "^5.17.1", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/material/node_modules/@mui/system/node_modules/@mui/private-theming": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz", - "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.17.1", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/material/node_modules/@mui/system/node_modules/@mui/styled-engine": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", - "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.13.5", - "@emotion/serialize": "^1.3.3", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mx-cartographer/kyper-mui/node_modules/@mui/material/node_modules/@mui/utils": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz", - "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/types": "~7.2.15", - "@types/prop-types": "^15.7.12", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^19.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mxenabled/cssinjs": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@mxenabled/cssinjs/-/cssinjs-0.6.0.tgz", - "integrity": "sha512-pj4/+iqyEGS1zg4i7jo7jLX+tS9h1YA5W1vLfUipuLWbxzEmoI6K2JvfhP1jT3eKTOJE3MTH+K53/t9KDyUu3Q==", - "dev": true, - "dependencies": { - "free-style": "^4.1.0", - "insert-css": "^2.0.0" - } - }, "node_modules/@mxenabled/design-tokens": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@mxenabled/design-tokens/-/design-tokens-1.0.3.tgz", @@ -8065,12 +7804,6 @@ "node": ">= 6" } }, - "node_modules/free-style": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/free-style/-/free-style-4.1.0.tgz", - "integrity": "sha512-Irv8vaifjszJimKa+6lcax5bEIpMb1oQ7N6zLFQK3ovCnYDPsy1M5DiuHV1mDSYvEFtQ2/mu37kn+UEooeJ6Ww==", - "dev": true - }, "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -9063,12 +8796,6 @@ "node": ">=8" } }, - "node_modules/insert-css": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", - "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==", - "dev": true - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", diff --git a/package.json b/package.json index 1d36c30359..8adac54ecd 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "vite-plugin-dts": "^4.5.4" }, "devDependencies": { - "@mx-cartographer/kyper-mui": "^2.2.0-alpha1", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", From a5b6dffd01830416038f3c999fa6ddb5bbd0a649 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:06:17 -0600 Subject: [PATCH 04/11] Remove kyper types file --- typings/kyper.d.ts | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 typings/kyper.d.ts diff --git a/typings/kyper.d.ts b/typings/kyper.d.ts deleted file mode 100644 index 5fc53d65bd..0000000000 --- a/typings/kyper.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare module '@kyper/textarea' -declare module '@kyper/input' -declare module '@kyper/icon/Accounts' -declare module '@kyper/icon/PiggyBankOutline' -declare module '@kyper/icon/Document' -declare module '@kyper/icon/CreditCard' -declare module '@kyper/icon/Dollar' -declare module '@kyper/icon/Growth' -declare module '@kyper/icon/Image' -declare module '@kyper/icon/Health' -declare module '@kyper/hooks' From 03d465b8acd443340243a470fb205653ca607697 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:22:05 -0600 Subject: [PATCH 05/11] Converted ViewTitle to typescript, css modules, and Stack for layout --- src/components/ViewTitle-test.tsx | 51 +++++++++++++++++++ .../{ViewTitle.js => ViewTitle.tsx} | 19 ++++--- 2 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 src/components/ViewTitle-test.tsx rename src/components/{ViewTitle.js => ViewTitle.tsx} (57%) diff --git a/src/components/ViewTitle-test.tsx b/src/components/ViewTitle-test.tsx new file mode 100644 index 0000000000..e234ca4152 --- /dev/null +++ b/src/components/ViewTitle-test.tsx @@ -0,0 +1,51 @@ +import React from 'react' +import { describe, it, expect } from 'vitest' +import { render, screen } from 'src/utilities/testingLibrary' +import { ViewTitle } from 'src/components/ViewTitle' +import { ReadableStatuses } from 'src/const/Statuses' + +describe('ViewTitle', () => { + it('renders the title text', () => { + render() + + const title = screen.getByTestId('title-text') + expect(title).toBeInTheDocument() + expect(title).toHaveTextContent('Account Details') + }) + + it('renders the title as an h1 heading', () => { + render() + + expect(screen.getByRole('heading', { level: 1, name: 'Account Details' })).toBeInTheDocument() + }) + + it('renders the error icon when connectionStatus is DEGRADED', () => { + const { container } = render( + , + ) + + expect(container.querySelector('svg')).toBeInTheDocument() + }) + + it('renders the error icon when connectionStatus is REJECTED', () => { + const { container } = render( + , + ) + + expect(container.querySelector('svg')).toBeInTheDocument() + }) + + it('does not render the error icon when connectionStatus is CONNECTED', () => { + const { container } = render( + , + ) + + expect(container.querySelector('svg')).not.toBeInTheDocument() + }) + + it('does not render the error icon when connectionStatus is not provided', () => { + const { container } = render() + + expect(container.querySelector('svg')).not.toBeInTheDocument() + }) +}) diff --git a/src/components/ViewTitle.js b/src/components/ViewTitle.tsx similarity index 57% rename from src/components/ViewTitle.js rename to src/components/ViewTitle.tsx index 4e780c9dce..921c6a22db 100644 --- a/src/components/ViewTitle.js +++ b/src/components/ViewTitle.tsx @@ -3,15 +3,16 @@ import PropTypes from 'prop-types' import { Stack } from '@mui/material' import { Icon, Text } from '@mxenabled/mxui' -import { useTokens } from 'src/context/LegacyTokenProvider' -import { InfoFilled } from '@kyper/icon/InfoFilled' import { ReadableStatuses } from 'src/const/Statuses' import styles from 'src/components/ViewTitle.module.css' -export const ViewTitle = ({ connectionStatus, title }) => { - const tokens = useTokens() +type ViewTitleProps = { + connectionStatus?: number + title: string +} +export const ViewTitle = ({ connectionStatus, title }: ViewTitleProps) => { return ( { {title} - {connectionStatus === ReadableStatuses.DEGRADED && ( - - )} - {connectionStatus === ReadableStatuses.REJECTED && ( - - )} + {connectionStatus && + [ReadableStatuses.DEGRADED, ReadableStatuses.REJECTED].includes(connectionStatus) && ( + + )} ) } From 3af474c6bafca1c7f04d283642a257baad3eeb22 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:23:47 -0600 Subject: [PATCH 06/11] Converted OAuthDefault to css modules, Stack for layout, and Kyper icons to MXUI --- src/views/oauth/OAuthDefault.js | 34 ++++++++----------------- src/views/oauth/OAuthDefault.module.css | 7 +++++ 2 files changed, 17 insertions(+), 24 deletions(-) create mode 100644 src/views/oauth/OAuthDefault.module.css diff --git a/src/views/oauth/OAuthDefault.js b/src/views/oauth/OAuthDefault.js index 91c36d5be3..19f56d950f 100644 --- a/src/views/oauth/OAuthDefault.js +++ b/src/views/oauth/OAuthDefault.js @@ -3,11 +3,11 @@ import PropTypes from 'prop-types' import { useSelector } from 'react-redux' import { sha256 } from 'js-sha256' -import { useTokens } from 'src/context/LegacyTokenProvider' -import { Export } from '@kyper/icon/Export' import { Button } from '@mui/material' +import Stack from '@mui/material/Stack' import { __ } from 'src/utilities/Intl' +import styles from './OAuthDefault.module.css' import { InstitutionBlock } from 'src/components/InstitutionBlock' import { SlideDown } from 'src/components/SlideDown' @@ -21,6 +21,7 @@ import useAnalyticsEvent from 'src/hooks/useAnalyticsEvent' import { AnalyticEvents, PageviewInfo } from 'src/const/Analytics' import { useApi } from 'src/context/ApiContext' import { PredirectInstructions } from 'src/views/oauth/experiments/PredirectInstructions' +import { Icon } from '@mxenabled/mxui' export const OAuthDefault = (props) => { // Experiment code - Remove after experiment is over @@ -43,11 +44,9 @@ export const OAuthDefault = (props) => { ) const isOauthLoading = useSelector((state) => state.connect.isOauthLoading) const oauthURL = useSelector((state) => state.connect.oauthURL) - const tokens = useTokens() - const styles = getStyles(tokens) return ( -
+ {hasPredirectInstructions ? ( <> @@ -86,6 +85,7 @@ export const OAuthDefault = (props) => { -
+ ) } @@ -120,18 +121,3 @@ OAuthDefault.propTypes = { selectedInstructionalData: PropTypes.object.isRequired, setIsLeavingUrl: PropTypes.func.isRequired, } - -const getStyles = (tokens) => ({ - primaryButton: { - display: 'flex', - marginTop: tokens.Spacing.XLarge, - }, - neutralButton: { - marginTop: tokens.Spacing.XSmall, - }, - export: { - marginLeft: tokens.Spacing.XSmall, - display: 'flex', - alignItems: 'center', - }, -}) diff --git a/src/views/oauth/OAuthDefault.module.css b/src/views/oauth/OAuthDefault.module.css new file mode 100644 index 0000000000..43856f66d7 --- /dev/null +++ b/src/views/oauth/OAuthDefault.module.css @@ -0,0 +1,7 @@ +primaryButton { + margin-top: var(--spacing-1); +} +icon { + display: flex; + align-items: center; +} From 6f6a989e4b38578eceb791e5de5f7b296c3c84da Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:29:16 -0600 Subject: [PATCH 07/11] Removed reference of Kyper from dev comments --- src/privacy/components.js | 2 +- src/privacy/input.ts | 4 ++-- src/utilities/Intl.jsx | 4 ++-- src/views/credentials/Credentials.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/privacy/components.js b/src/privacy/components.js index 86a74e788b..4895bb354f 100644 --- a/src/privacy/components.js +++ b/src/privacy/components.js @@ -1,7 +1,7 @@ import { Text } from '@mxenabled/mxui' import { withProtection } from 'src/privacy/withProtection' -// Add security to Kyper Components +// Add security to Components export const ProtectedText = withProtection(Text) export { ProtectedText as Text } diff --git a/src/privacy/input.ts b/src/privacy/input.ts index 44722d2aa3..96767d75a7 100644 --- a/src/privacy/input.ts +++ b/src/privacy/input.ts @@ -1,11 +1,11 @@ -// This is the ONLY file that @kyper related inputs should be directly imported +// This is the ONLY file that @mxnabled/mxui and mui related inputs should be directly imported import { SelectionBox } from '@mxenabled/mxui' import { withProtection } from 'src/privacy/withProtection' import { TextField } from '@mxenabled/mxui' /* - Add security to Kyper Inputs by wrapping them in a Higher Order Component that + Add security to Inputs by wrapping them in a Higher Order Component that handles security, and then re-export the same-named component for consumers Example code snippets: diff --git a/src/utilities/Intl.jsx b/src/utilities/Intl.jsx index f7d095720c..d3d3183ccd 100644 --- a/src/utilities/Intl.jsx +++ b/src/utilities/Intl.jsx @@ -68,8 +68,8 @@ Usage: {__(`This is a *custom bold* statement.`)} - // Shorthand for working with Kyper's Text component: - import { Text } from '@kyper/text' + // Shorthand for working with mxui's Text component: + import { Text } from '@mxui/text' {__(`This is a *custom bold* statement.`)} diff --git a/src/views/credentials/Credentials.js b/src/views/credentials/Credentials.js index 61db540dfd..ad6285792a 100644 --- a/src/views/credentials/Credentials.js +++ b/src/views/credentials/Credentials.js @@ -224,7 +224,7 @@ export const Credentials = React.forwardRef( handleTextInputChange(e) } - // When working inside a form with a kyper/password input + // When working inside a form with a password input // When pressing enter it wants to toggle the hide/show button // This is a way to manually check for ENTER and attempt the submit fn const handlePasswordEnterChange = (e) => { From 4f7e4597fa6786a4c1e4d20f25dd4fb010ed9c68 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 15:38:45 -0600 Subject: [PATCH 08/11] Updated to include no longer using Kyper --- .claude/skills/adr-review/reference/adr-checklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/adr-review/reference/adr-checklist.md b/.claude/skills/adr-review/reference/adr-checklist.md index 0afbfbaefe..9d8568bc56 100644 --- a/.claude/skills/adr-review/reference/adr-checklist.md +++ b/.claude/skills/adr-review/reference/adr-checklist.md @@ -45,7 +45,7 @@ Check added/changed `.tsx`/`.jsx`/`.css` code: `direction` instead. Flag ` Date: Thu, 24 Sep 2026 16:02:09 -0600 Subject: [PATCH 09/11] Create local usePrevious hook instead of Kyper usePrevious --- package-lock.json | 12 ------- package.json | 1 - src/Connect.tsx | 2 +- src/hooks/usePrevious-test.tsx | 63 ++++++++++++++++++++++++++++++++++ src/hooks/usePrevious.tsx | 16 +++++++++ 5 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 src/hooks/usePrevious-test.tsx create mode 100644 src/hooks/usePrevious.tsx diff --git a/package-lock.json b/package-lock.json index 07e668198d..4cb6561537 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@kyper/hooks": "^1.3.0", "@kyper/icon": "^1.22.0", "@mui/icons-material": "^7.3.9", "@mui/material": "^7.3.9", @@ -1608,17 +1607,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@kyper/hooks": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@kyper/hooks/-/hooks-1.3.0.tgz", - "integrity": "sha512-HCeeX2oTlWkwLjIyGdtlyAdxtuDe8yBi842yTr1SHwd8nvCIA3O8QFo/0/uj9xxey/IYXbMdaLLEESsU5UPAkQ==", - "license": "MIT", - "peerDependencies": { - "prop-types": "^15.7.2", - "react": "^16.14.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/@kyper/icon": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/@kyper/icon/-/icon-1.22.0.tgz", diff --git a/package.json b/package.json index 8adac54ecd..f5cc34e1bc 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@kyper/hooks": "^1.3.0", "@kyper/icon": "^1.22.0", "@mui/icons-material": "^7.3.9", "@mui/material": "^7.3.9", diff --git a/src/Connect.tsx b/src/Connect.tsx index c8da3b8ace..f50dc31567 100644 --- a/src/Connect.tsx +++ b/src/Connect.tsx @@ -7,7 +7,7 @@ import _toLower from 'lodash/toLower' import { Message, sha256 } from 'js-sha256' // import 'posthog-js/dist/recorder-v2' // Added for security requirements to use PostHog Session Recording import { TokenContext } from 'src/context/LegacyTokenProvider' -import { usePrevious } from '@kyper/hooks' +import { usePrevious } from 'src/hooks/usePrevious' import * as connectActions from 'src/redux/actions/Connect' import { setWidgetVersion } from 'src/redux/actions/App' diff --git a/src/hooks/usePrevious-test.tsx b/src/hooks/usePrevious-test.tsx new file mode 100644 index 0000000000..73c8180b1f --- /dev/null +++ b/src/hooks/usePrevious-test.tsx @@ -0,0 +1,63 @@ +import { renderHook } from '@testing-library/react' +import { usePrevious } from './usePrevious' + +describe('usePrevious', () => { + it('should return null on the initial render', () => { + const { result } = renderHook(() => usePrevious('first')) + + expect(result.current).toBe(null) + }) + + it('should return the previous value after the value changes', () => { + const { result, rerender } = renderHook(({ value }) => usePrevious(value), { + initialProps: { value: 'first' }, + }) + + expect(result.current).toBe(null) + + rerender({ value: 'second' }) + expect(result.current).toBe('first') + + rerender({ value: 'third' }) + expect(result.current).toBe('second') + }) + + it('should reflect the latest committed value when re-rendered with the same value', () => { + const { result, rerender } = renderHook(({ value }) => usePrevious(value), { + initialProps: { value: 'first' }, + }) + + rerender({ value: 'second' }) + expect(result.current).toBe('first') + + // The effect from the prior render already committed 'second' to the ref, + // so a same-value re-render reads 'second' even though the effect is skipped + rerender({ value: 'second' }) + expect(result.current).toBe('second') + }) + + it('should work with non-string values', () => { + const { result, rerender } = renderHook(({ value }) => usePrevious(value), { + initialProps: { value: 0 }, + }) + + expect(result.current).toBe(null) + + rerender({ value: 1 }) + expect(result.current).toBe(0) + + rerender({ value: 2 }) + expect(result.current).toBe(1) + }) + + it('should track previous values for objects', () => { + const firstObj = { id: 1 } + const secondObj = { id: 2 } + const { result, rerender } = renderHook(({ value }) => usePrevious(value), { + initialProps: { value: firstObj }, + }) + + rerender({ value: secondObj }) + expect(result.current).toBe(firstObj) + }) +}) diff --git a/src/hooks/usePrevious.tsx b/src/hooks/usePrevious.tsx new file mode 100644 index 0000000000..6fd48c6550 --- /dev/null +++ b/src/hooks/usePrevious.tsx @@ -0,0 +1,16 @@ +import { useEffect, useRef } from 'react' + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const usePrevious = (value: any): any => { + // The ref object is a generic container whose current property is mutable + // and can hold any value, similar to an instance property on a class + const ref = useRef(null) + + // Store current value in ref + useEffect(() => { + ref.current = value + }, [value]) // Only re-run if value changes + + // Return previous value (happens before update in useEffect above) + return ref.current +} From 9183e9cf45def329dff178bac10e3e7c14cac7f3 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 16:06:06 -0600 Subject: [PATCH 10/11] v2.41.0 changes --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 016cd849a4..545d70bbec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## v.2.41.0 + +### Removed + +- `@kyper/hooks` and `@mx-cartographer/kyper-mui` dependencies. +- Kyper type definitions (`typings/kyper.d.ts`). +- ESLint rule now disallows importing `@kyper` components. + +### Updated + +- `OAuthDefault` converted to CSS modules, `Stack` for layout, and MXUI icons. +- `ViewTitle` converted to TypeScript, CSS modules, and `Stack` for layout. + +### Added + +- Local `usePrevious` hook to replace the Kyper `usePrevious` hook. + +### Fixed + +- Prevent the Go back button from exceeding content width on `DemoConnectGuard`. + ## v.0.15.5 ### Fixed From 34317897d16f73b9a11b3bbf172029a769f3d279 Mon Sep 17 00:00:00 2001 From: Jameson Date: Thu, 24 Sep 2026 16:22:49 -0600 Subject: [PATCH 11/11] Added missing cssinjs package --- package-lock.json | 23 +++++++++++++++++++++++ package.json | 1 + 2 files changed, 24 insertions(+) diff --git a/package-lock.json b/package-lock.json index 4cb6561537..c318221919 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@kyper/icon": "^1.22.0", "@mui/icons-material": "^7.3.9", "@mui/material": "^7.3.9", + "@mxenabled/cssinjs": "^0.6.0", "@mxenabled/design-tokens": "^1.0.3", "@mxenabled/mxui": "^2.10.0", "@reduxjs/toolkit": "^2.2.7", @@ -2303,6 +2304,16 @@ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/@mxenabled/cssinjs": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@mxenabled/cssinjs/-/cssinjs-0.6.0.tgz", + "integrity": "sha512-pj4/+iqyEGS1zg4i7jo7jLX+tS9h1YA5W1vLfUipuLWbxzEmoI6K2JvfhP1jT3eKTOJE3MTH+K53/t9KDyUu3Q==", + "license": "MIT", + "dependencies": { + "free-style": "^4.1.0", + "insert-css": "^2.0.0" + } + }, "node_modules/@mxenabled/design-tokens": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@mxenabled/design-tokens/-/design-tokens-1.0.3.tgz", @@ -7792,6 +7803,12 @@ "node": ">= 6" } }, + "node_modules/free-style": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/free-style/-/free-style-4.1.0.tgz", + "integrity": "sha512-Irv8vaifjszJimKa+6lcax5bEIpMb1oQ7N6zLFQK3ovCnYDPsy1M5DiuHV1mDSYvEFtQ2/mu37kn+UEooeJ6Ww==", + "license": "MIT" + }, "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -8784,6 +8801,12 @@ "node": ">=8" } }, + "node_modules/insert-css": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", + "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==", + "license": "MIT" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", diff --git a/package.json b/package.json index f5cc34e1bc..e8c1b88a10 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@kyper/icon": "^1.22.0", "@mui/icons-material": "^7.3.9", "@mui/material": "^7.3.9", + "@mxenabled/cssinjs": "^0.6.0", "@mxenabled/design-tokens": "^1.0.3", "@mxenabled/mxui": "^2.10.0", "@reduxjs/toolkit": "^2.2.7",