From c8bc6045a94cc1bd8f232c8cd56e2729ddfba9ed Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Fri, 8 Nov 2024 16:34:33 +0530 Subject: [PATCH 1/8] fix: next js latest version test action fix --- .github/workflows/next-latest.yml | 85 ++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 68bd7f0d2..5c714e545 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -2,11 +2,11 @@ name: Next.js Latest on: push: - branches: [ main, master ] + branches: [main, master] pull_request: - branches: [ main, master ] + branches: [main, master] schedule: - - cron: '0 0 * * *' # Run daily at midnight UTC + - cron: '0 0 * * *' # Run daily at midnight UTC jobs: check-next-version: @@ -19,6 +19,8 @@ jobs: run: | LATEST=$(npm view next version) CURRENT=$(cat .next-version 2>/dev/null || echo "") + echo "Latest version: $LATEST" + echo "Current version: $CURRENT" if [ "$LATEST" != "$CURRENT" ]; then echo "should_run=true" >> $GITHUB_OUTPUT echo "latest_version=$LATEST" >> $GITHUB_OUTPUT @@ -34,31 +36,45 @@ jobs: name: Next.js latest steps: - uses: actions/checkout@v3 + - name: Use Node.js uses: actions/setup-node@v3 with: node-version: '18' + + - name: Print Environment Info + run: | + node -v + npm -v + cat .next-version || echo ".next-version file not found" + - name: Create Next.js project run: | npx create-next-app@latest test-app --typescript --eslint --tailwind --app --src-dir --use-npm --no-experimental-app cd test-app - - name: Install gluestack-ui + + - name: Install Gluestack UI working-directory: test-app run: | npx gluestack-ui init --template-only --projectType nextjs npx gluestack-ui add --all + - name: Rename original next.config file working-directory: test-app run: mv next.config.ts next.config.original.ts + - name: Create new next.config file working-directory: test-app run: | cat < next.config.ts import originalConfig from './next.config.original.ts'; - /** @type {import('next').NextConfig} */ const nextConfig = { ...originalConfig, + webpack(config) { + config.resolve.alias['react-native'] = 'react-native-web'; + return config; + }, typescript: { ignoreBuildErrors: true, }, @@ -66,6 +82,7 @@ jobs: export default nextConfig; EOT + - name: Add Button component working-directory: test-app run: | @@ -88,6 +105,7 @@ jobs: ) } EOT + - name: Build Next.js app working-directory: test-app env: @@ -95,45 +113,50 @@ jobs: run: | echo "{ \"extends\": \"next/core-web-vitals\", \"rules\": {} }" > .eslintrc.json npm run build -- --no-lint + - name: Start Next.js app working-directory: test-app - run: npm run start & sleep 10 + run: | + npm run start & + sleep 20 + + - name: Fetch and Log Server Response + run: | + curl -s http://localhost:3000 || echo "Failed to reach the server" + curl -s http://localhost:3000 > server_response.html + cat server_response.html + - name: Check if button is rendered run: | - if curl -s http://localhost:3000 | grep -q "Hello World!"; then - echo "Button found on the page" - exit 0 - else - echo "Button not found on the page" - exit 1 - fi + RESPONSE=$(curl -s http://localhost:3000) + echo "$RESPONSE" | grep -q "Hello World!" && echo "Button found" || (echo "Button not found" && exit 1) notify: needs: test-next-latest if: always() && github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - - name: Slack Notification - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - text: 'Next.js Latest Test: ${{ job.status }}' - fields: repo,commit,action,eventName - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + - name: Slack Notification + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + text: 'Next.js Latest Test: ${{ job.status }}' + fields: repo,commit,action,eventName + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} update-version: needs: test-next-latest if: ${{ needs.check-next-version.outputs.should_run == 'true' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Update Next.js version file - run: | - echo ${{ needs.check-next-version.outputs.latest_version }} > .next-version - git config user.name github-actions - git config user.email github-actions@github.com - git add .next-version - git commit -m "Update Next.js version to ${{ needs.check-next-version.outputs.latest_version }}" - git push + - uses: actions/checkout@v3 + - name: Update Next.js version file + run: | + echo ${{ needs.check-next-version.outputs.latest_version }} > .next-version + git config user.name github-actions + git config user.email github-actions@github.com + git add .next-version + git commit -m "Update Next.js version to ${{ needs.check-next-version.outputs.latest_version }}" + git push From a4f796f3e734616d4bef4fdd586cfa457b1f7615 Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Fri, 8 Nov 2024 16:49:52 +0530 Subject: [PATCH 2/8] fix: cleared babel issues & rn-css working --- .github/workflows/next-latest.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 5c714e545..2873ea3dc 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -71,8 +71,18 @@ jobs: const nextConfig = { ...originalConfig, - webpack(config) { + webpack(config, { isServer }) { config.resolve.alias['react-native'] = 'react-native-web'; + + // Add support for JSX and ensure React Native CSS works + if (!isServer) { + config.module.rules.push({ + test: /\.(js|jsx|ts|tsx)$/, + use: ['babel-loader'], + exclude: /node_modules/, + }); + } + return config; }, typescript: { @@ -106,6 +116,13 @@ jobs: } EOT + - name: Install dependencies and clean cache + working-directory: test-app + run: | + npm install + # Clean npm cache to avoid potential issues with older versions + npm cache clean --force + - name: Build Next.js app working-directory: test-app env: From 2b5e9d395f70698f6c338bb16754716855a80473 Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 16:35:47 +0530 Subject: [PATCH 3/8] fix: added patches for next js 15 --- .github/workflows/next-latest.yml | 963 +++++++++++++++++++++++++++++- 1 file changed, 937 insertions(+), 26 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 2873ea3dc..7e39034e7 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -1,4 +1,4 @@ -name: Next.js Latest +name: Next.js Latest with Gluestack UI on: push: @@ -33,7 +33,7 @@ jobs: needs: check-next-version if: ${{ needs.check-next-version.outputs.should_run == 'true' || github.event_name == 'push' || github.event_name == 'pull_request' }} runs-on: ubuntu-latest - name: Next.js latest + name: Next.js latest with Gluestack UI steps: - uses: actions/checkout@v3 @@ -67,32 +67,930 @@ jobs: working-directory: test-app run: | cat < next.config.ts - import originalConfig from './next.config.original.ts'; - - const nextConfig = { - ...originalConfig, - webpack(config, { isServer }) { - config.resolve.alias['react-native'] = 'react-native-web'; - - // Add support for JSX and ensure React Native CSS works - if (!isServer) { - config.module.rules.push({ - test: /\.(js|jsx|ts|tsx)$/, - use: ['babel-loader'], - exclude: /node_modules/, + import { withGluestackUI } from "@gluestack/ui-next-adapter"; + const nextConfig = { + transpilePackages: ["nativewind", "react-native-css-interop"], + }; + export default withGluestackUI(nextConfig); + EOT + - name: Copy data to src/app/registry.tsx + working-directory: test-app + run: | + cat < src/app/registry.tsx + "use client"; + import React, { useRef, useState } from "react"; + import { useServerInsertedHTML } from "next/navigation"; + import { StyleRegistry, createStyleRegistry } from "styled-jsx"; + // @ts-ignore + import { AppRegistry } from "react-native-web"; + import { flush } from "@gluestack-ui/nativewind-utils/flush"; + + export default function StyledJsxRegistry({ + children, + }: { + children: React.ReactNode; + }) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [jsxStyleRegistry] = useState(() => createStyleRegistry()); + const isServerInserted = useRef(false); + + useServerInsertedHTML(() => { + AppRegistry.registerComponent("Main", () => "main"); + const { getStyleElement } = AppRegistry.getApplication("Main"); + if (!isServerInserted.current) { + isServerInserted.current = true; + const styles = [getStyleElement(), jsxStyleRegistry.styles(), flush()]; + jsxStyleRegistry.flush(); + return <>{styles}; + } + }); + + return {children}; + } + EOT + - name: Copy data to components/ui/gluestack-ui-provider/index.web.tsx + working-directory: test-app + run: | + cat < components/ui/gluestack-ui-provider/index.web.tsx + + "use client"; + import React, { useEffect, useLayoutEffect } from "react"; + import { config } from "./config"; + import { OverlayProvider } from "@gluestack-ui/overlay"; + import { ToastProvider } from "@gluestack-ui/toast"; + import { setFlushStyles } from "@gluestack-ui/nativewind-utils/flush"; + import { script } from "./script"; + + const variableStyleTagId = "nativewind-style"; + const createStyle = (styleTagId: string) => { + const style = document.createElement("style"); + style.id = styleTagId; + style.appendChild(document.createTextNode("")); + return style; + }; + + export const useSafeLayoutEffect = + typeof window !== "undefined" ? useLayoutEffect : useEffect; + + export function GluestackUIProvider({ + mode = "light", + ...props + }: { + mode?: "light" | "dark" | "system"; + children?: React.ReactNode; + }) { + let cssVariablesWithMode = `/* empty */` + Object.keys(config).forEach((configKey) => { + cssVariablesWithMode += + configKey === "dark" ? `\n .dark {\n ` : `\n:root {\n`; + const cssVariables = Object.keys( + config[configKey as keyof typeof config] + ).reduce((acc: string, curr: string) => { + acc += `${curr}:${config[configKey as keyof typeof config][curr]}; `; + return acc; + }, ""); + cssVariablesWithMode += `${cssVariables} \n}`; }); - } - return config; - }, - typescript: { - ignoreBuildErrors: true, - }, - }; + setFlushStyles(cssVariablesWithMode); + + const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => { + script(e.matches ? "dark" : "light"); + }, []); + + useSafeLayoutEffect(() => { + if (mode !== "system") { + const documentElement = document.documentElement; + if (documentElement) { + documentElement.classList.add(mode); + documentElement.classList.remove(mode === "light" ? "dark" : "light"); + documentElement.style.colorScheme = mode; + } + } + }, [mode]); + + useSafeLayoutEffect(() => { + if (mode !== "system") return; + const media = window.matchMedia("(prefers-color-scheme: dark)"); + + media.addListener(handleMediaQuery); - export default nextConfig; + return () => media.removeListener(handleMediaQuery); + }, [handleMediaQuery]); + + useSafeLayoutEffect(() => { + if (typeof window !== "undefined") { + const documentElement = document.documentElement; + if (documentElement) { + const head = documentElement.querySelector("head"); + let style = head?.querySelector(`[id='${variableStyleTagId}']`); + if (!style) { + style = createStyle(variableStyleTagId); + style.innerHTML = cssVariablesWithMode; + if (head) head.appendChild(style); + } + } + } + }, []); + + return ( + <> + + {props.children} + + + ); + } EOT + - name: Create patches folder + working-directory: test-app + run: | + mkdir -p patches + - name: Create react-native-web patch file + working-directory: test-app/patches + run: | + cat < react-native-web+0.19.13.patch + diff --git a/node_modules/react-native-web/dist/cjs/exports/AppRegistry/renderApplication.js b/node_modules/react-native-web/dist/cjs/exports/AppRegistry/renderApplication.js + index 0c0cb2f..83fd94b 100644 + --- a/node_modules/react-native-web/dist/cjs/exports/AppRegistry/renderApplication.js + +++ b/node_modules/react-native-web/dist/cjs/exports/AppRegistry/renderApplication.js + @@ -1,6 +1,5 @@ + "use strict"; + + -var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; + var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; + exports.__esModule = true; + exports.default = renderApplication; + @@ -8,7 +7,7 @@ exports.getApplication = getApplication; + var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + var _AppContainer = _interopRequireDefault(require("./AppContainer")); + var _invariant = _interopRequireDefault(require("fbjs/lib/invariant")); + -var _render = _interopRequireWildcard(require("../render")); + +var _render = require("../render"); + var _StyleSheet = _interopRequireDefault(require("../StyleSheet")); + var _react = _interopRequireDefault(require("react")); + /** + @@ -24,9 +23,8 @@ var _react = _interopRequireDefault(require("react")); + function renderApplication(RootComponent, WrapperComponent, callback, options) { + var shouldHydrate = options.hydrate, + initialProps = options.initialProps, + - mode = options.mode, + rootTag = options.rootTag; + - var renderFn = shouldHydrate ? mode === 'concurrent' ? _render.hydrate : _render.hydrateLegacy : mode === 'concurrent' ? _render.render : _render.default; + + var renderFn = shouldHydrate ? _render.hydrate : _render.render; + (0, _invariant.default)(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); + return renderFn(/*#__PURE__*/_react.default.createElement(_AppContainer.default, { + WrapperComponent: WrapperComponent, + diff --git a/node_modules/react-native-web/dist/cjs/exports/render/index.js b/node_modules/react-native-web/dist/cjs/exports/render/index.js + index b41ee11..18d9b2f 100644 + --- a/node_modules/react-native-web/dist/cjs/exports/render/index.js + +++ b/node_modules/react-native-web/dist/cjs/exports/render/index.js + @@ -10,15 +10,10 @@ + + 'use client'; + + -var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; + exports.__esModule = true; + -exports.default = renderLegacy; + +exports.default = render; + exports.hydrate = hydrate; + -exports.hydrateLegacy = hydrateLegacy; + -exports.render = render; + -var _reactDom = require("react-dom"); + var _client = require("react-dom/client"); + -var _unmountComponentAtNode = _interopRequireDefault(require("../unmountComponentAtNode")); + var _dom = require("../StyleSheet/dom"); + function hydrate(element, root) { + (0, _dom.createSheet)(root); + @@ -30,21 +25,3 @@ function render(element, root) { + reactRoot.render(element); + return reactRoot; + } + \ No newline at end of file + -function hydrateLegacy(element, root, callback) { + - (0, _dom.createSheet)(root); + - (0, _reactDom.hydrate)(element, root, callback); + - return { + - unmount: function unmount() { + - return (0, _unmountComponentAtNode.default)(root); + - } + - }; + -} + -function renderLegacy(element, root, callback) { + - (0, _dom.createSheet)(root); + - (0, _reactDom.render)(element, root, callback); + - return { + - unmount: function unmount() { + - return (0, _unmountComponentAtNode.default)(root); + - } + - }; + -} + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/cjs/exports/unmountComponentAtNode/index.js b/node_modules/react-native-web/dist/cjs/exports/unmountComponentAtNode/index.js + index 3ea3964..e740204 100644 + --- a/node_modules/react-native-web/dist/cjs/exports/unmountComponentAtNode/index.js + +++ b/node_modules/react-native-web/dist/cjs/exports/unmountComponentAtNode/index.js + @@ -1,8 +1,7 @@ + "use strict"; + + exports.__esModule = true; + -exports.default = void 0; + -var _reactDom = require("react-dom"); + +exports.default = unmountComponentAtNode; + /** + * Copyright (c) Nicolas Gallagher. + * + @@ -11,5 +10,9 @@ var _reactDom = require("react-dom"); + * + * + */ + -var _default = exports.default = _reactDom.unmountComponentAtNode; + + + +function unmountComponentAtNode(rootTag) { + + rootTag.unmount(); + + return true; + +} + module.exports = exports.default; + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js b/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js + index b53dff6..c56c1dc 100644 + --- a/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js + +++ b/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js + @@ -11,15 +11,14 @@ import _extends from "@babel/runtime/helpers/extends"; + + import AppContainer from './AppContainer'; + import invariant from 'fbjs/lib/invariant'; + -import renderLegacy, { hydrateLegacy, render, hydrate } from '../render'; + +import { render, hydrate } from '../render'; + import StyleSheet from '../StyleSheet'; + import React from 'react'; + export default function renderApplication(RootComponent, WrapperComponent, callback, options) { + var shouldHydrate = options.hydrate, + initialProps = options.initialProps, + - mode = options.mode, + rootTag = options.rootTag; + - var renderFn = shouldHydrate ? mode === 'concurrent' ? hydrate : hydrateLegacy : mode === 'concurrent' ? render : renderLegacy; + + var renderFn = shouldHydrate ? hydrate : render; + invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); + return renderFn(/*#__PURE__*/React.createElement(AppContainer, { + WrapperComponent: WrapperComponent, + diff --git a/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js.flow b/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js.flow + index b9df2af..2b671ba 100644 + --- a/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js.flow + +++ b/node_modules/react-native-web/dist/exports/AppRegistry/renderApplication.js.flow + @@ -11,7 +11,7 @@ + import type { ComponentType, Node } from 'react'; + import AppContainer from './AppContainer'; + import invariant from 'fbjs/lib/invariant'; + -import renderLegacy, { hydrateLegacy, render, hydrate } from '../render'; + +import { render, hydrate } from '../render'; + import StyleSheet from '../StyleSheet'; + import React from 'react'; + export type Application = { + @@ -20,7 +20,6 @@ export type Application = { + declare export default function renderApplication(RootComponent: ComponentType, WrapperComponent?: ?ComponentType<*>, callback?: () => void, options: { + hydrate: boolean, + initialProps: Props, + - mode: 'concurrent' | 'legacy', + rootTag: any, + }): Application; + declare export function getApplication(RootComponent: ComponentType, initialProps: Object, WrapperComponent?: ?ComponentType<*>): {| + diff --git a/node_modules/react-native-web/dist/exports/render/index.js b/node_modules/react-native-web/dist/exports/render/index.js + index aa91a2a..8f9a14d 100644 + --- a/node_modules/react-native-web/dist/exports/render/index.js + +++ b/node_modules/react-native-web/dist/exports/render/index.js + @@ -9,35 +9,15 @@ + + 'use client'; + + -import { hydrate as domLegacyHydrate, render as domLegacyRender } from 'react-dom'; + import { createRoot as domCreateRoot, hydrateRoot as domHydrateRoot } from 'react-dom/client'; + -import unmountComponentAtNode from '../unmountComponentAtNode'; + import { createSheet } from '../StyleSheet/dom'; + export function hydrate(element, root) { + createSheet(root); + return domHydrateRoot(root, element); + } + -export function render(element, root) { + +export default function render(element, root) { + createSheet(root); + var reactRoot = domCreateRoot(root); + reactRoot.render(element); + return reactRoot; + } + \ No newline at end of file + -export function hydrateLegacy(element, root, callback) { + - createSheet(root); + - domLegacyHydrate(element, root, callback); + - return { + - unmount: function unmount() { + - return unmountComponentAtNode(root); + - } + - }; + -} + -export default function renderLegacy(element, root, callback) { + - createSheet(root); + - domLegacyRender(element, root, callback); + - return { + - unmount: function unmount() { + - return unmountComponentAtNode(root); + - } + - }; + -} + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/exports/render/index.js.flow b/node_modules/react-native-web/dist/exports/render/index.js.flow + index 1bd771e..729d57d 100644 + --- a/node_modules/react-native-web/dist/exports/render/index.js.flow + +++ b/node_modules/react-native-web/dist/exports/render/index.js.flow + @@ -9,11 +9,7 @@ + + 'use client'; + + -import { hydrate as domLegacyHydrate, render as domLegacyRender } from 'react-dom'; + import { createRoot as domCreateRoot, hydrateRoot as domHydrateRoot } from 'react-dom/client'; + -import unmountComponentAtNode from '../unmountComponentAtNode'; + import { createSheet } from '../StyleSheet/dom'; + declare export function hydrate(element: any, root: any): any; + -declare export function render(element: any, root: any): any; + -declare export function hydrateLegacy(element: any, root: any, callback: any): any; + -declare export default function renderLegacy(element: any, root: any, callback: any): any; + \ No newline at end of file + +declare export default function render(element: any, root: any): any; + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js b/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js + index 925051c..cea4dee 100644 + --- a/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js + +++ b/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js + @@ -7,5 +7,7 @@ + * + */ + + -import { unmountComponentAtNode } from 'react-dom'; + -export default unmountComponentAtNode; + \ No newline at end of file + +export default function unmountComponentAtNode(rootTag) { + + rootTag.unmount(); + + return true; + +} + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js.flow b/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js.flow + index b950090..90ec151 100644 + --- a/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js.flow + +++ b/node_modules/react-native-web/dist/exports/unmountComponentAtNode/index.js.flow + @@ -6,6 +6,4 @@ + * + * @noflow + */ + - + -import { unmountComponentAtNode } from 'react-dom'; + -export default unmountComponentAtNode; + \ No newline at end of file + +declare export default function unmountComponentAtNode(rootTag: any): any; + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.js.flow b/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.js.flow + new file mode 100644 + index 0000000..9eb6144 + --- /dev/null + +++ b/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.js.flow + @@ -0,0 +1,191 @@ + +/** + + * Copyright (c) Meta Platforms, Inc. and affiliates. + + * + + * This source code is licensed under the MIT license found in the + + * LICENSE file in the root directory of this source tree. + + * + + * @flow strict-local + + */ + + + +import * as React from 'react'; + +import { act, render } from '@testing-library/react'; + +import { createEventTarget } from 'dom-event-testing-library'; + +import { addEventListener } from '..'; + +describe('addEventListener', () => { + + describe('addEventListener()', () => { + + test('event dispatched on target', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('event dispatched on parent', () => { + + const listener = jest.fn(); + + const listenerCapture = jest.fn(); + + const targetRef = React.createRef(); + + const parentRef = React.createRef(); + + declare function Component(): any; + + render(); + + const parent = createEventTarget(parentRef.current); + + act(() => { + + parent.click(); + + }); + + expect(listener).toBeCalledTimes(0); + + expect(listenerCapture).toBeCalledTimes(0); + + }); + + test('event dispatched on child', () => { + + const log = []; + + const listener = jest.fn(() => { + + log.push('bubble'); + + }); + + const listenerCapture = jest.fn(() => { + + log.push('capture'); + + }); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(1); + + expect(listener).toBeCalledTimes(1); + + expect(log).toEqual(['capture', 'bubble']); + + }); + + test('event dispatched on text node', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const text = createEventTarget(childRef.current.firstChild); + + act(() => { + + text.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listener can be attached to document', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listener can be attached to window ', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('custom event dispatched on target', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + act(() => { + + const event = new CustomEvent('magic-event', { + + bubbles: true + + }); + + targetRef.current.dispatchEvent(event); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listeners can be set on multiple targets simultaneously', () => { + + const log = []; + + const targetRef = React.createRef(); + + const parentRef = React.createRef(); + + const childRef = React.createRef(); + + const listener = jest.fn(e => { + + log.push(['bubble', e.currentTarget.id]); + + }); + + const listenerCapture = jest.fn(e => { + + log.push(['capture', e.currentTarget.id]); + + }); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(2); + + expect(listener).toBeCalledTimes(2); + + expect(log).toEqual([['capture', 'parent'], ['capture', 'target'], ['bubble', 'target'], ['bubble', 'parent']]); + + }); + + test('listeners are specific to each event handle', () => { + + const log = []; + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + const listener = jest.fn(e => { + + log.push(['bubble', 'target']); + + }); + + const listenerAlt = jest.fn(e => { + + log.push(['bubble', 'target-alt']); + + }); + + const listenerCapture = jest.fn(e => { + + log.push(['capture', 'target']); + + }); + + const listenerCaptureAlt = jest.fn(e => { + + log.push(['capture', 'target-alt']); + + }); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(1); + + expect(listenerCaptureAlt).toBeCalledTimes(1); + + expect(listener).toBeCalledTimes(1); + + expect(listenerAlt).toBeCalledTimes(1); + + expect(log).toEqual([['capture', 'target'], ['capture', 'target-alt'], ['bubble', 'target'], ['bubble', 'target-alt']]); + + }); + + }); + + describe('stopPropagation and stopImmediatePropagation', () => { + + test('stopPropagation works as expected', () => { + + const childListener = jest.fn(e => { + + e.stopPropagation(); + + }); + + const targetListener = jest.fn(); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(childListener).toBeCalledTimes(1); + + expect(targetListener).toBeCalledTimes(0); + + }); + + test('stopImmediatePropagation works as expected', () => { + + const firstListener = jest.fn(e => { + + e.stopImmediatePropagation(); + + }); + + const secondListener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(firstListener).toBeCalledTimes(1); + + expect(secondListener).toBeCalledTimes(0); + + }); + + }); + +}); + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.node.js.flow b/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.node.js.flow + new file mode 100644 + index 0000000..c1805b7 + --- /dev/null + +++ b/node_modules/react-native-web/dist/modules/addEventListener/__tests__/index-test.node.js.flow + @@ -0,0 +1,21 @@ + +/** + + * Copyright (c) Meta Platforms, Inc. and affiliates. + + * + + * This source code is licensed under the MIT license found in the + + * LICENSE file in the root directory of this source tree. + + * + + * @flow strict-local + + */ + + + +import * as React from 'react'; + +import * as ReactDOMServer from 'react-dom/server'; + +import { addEventListener } from '..'; + +describe('addEventListener', () => { + + test('can render correctly using ReactDOMServer', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + const output = ReactDOMServer.renderToString(); + + expect(output).toBe('
'); + + }); + +}); + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/modules/useEvent/__tests__/index-test.js.flow b/node_modules/react-native-web/dist/modules/useEvent/__tests__/index-test.js.flow + new file mode 100644 + index 0000000..9b57364 + --- /dev/null + +++ b/node_modules/react-native-web/dist/modules/useEvent/__tests__/index-test.js.flow + @@ -0,0 +1,247 @@ + +/** + + * Copyright (c) Meta Platforms, Inc. and affiliates. + + * + + * This source code is licensed under the MIT license found in the + + * LICENSE file in the root directory of this source tree. + + * + + * @flow strict-local + + */ + + + +import * as React from 'react'; + +import { act, render } from '@testing-library/react'; + +import { createEventTarget } from 'dom-event-testing-library'; + +import useEvent from '..'; + +describe('use-event', () => { + + describe('setListener()', () => { + + test('event dispatched on target', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('event dispatched on parent', () => { + + const listener = jest.fn(); + + const listenerCapture = jest.fn(); + + const targetRef = React.createRef(); + + const parentRef = React.createRef(); + + declare function Component(): any; + + render(); + + const parent = createEventTarget(parentRef.current); + + act(() => { + + parent.click(); + + }); + + expect(listener).toBeCalledTimes(0); + + expect(listenerCapture).toBeCalledTimes(0); + + }); + + test('event dispatched on child', () => { + + const log = []; + + const listener = jest.fn(() => { + + log.push('bubble'); + + }); + + const listenerCapture = jest.fn(() => { + + log.push('capture'); + + }); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(1); + + expect(listener).toBeCalledTimes(1); + + expect(log).toEqual(['capture', 'bubble']); + + }); + + test('event dispatched on text node', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const text = createEventTarget(childRef.current.firstChild); + + act(() => { + + text.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listener can be attached to document ', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listener can be attached to window ', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listener is replaceable', () => { + + const listener = jest.fn(); + + const listenerAlt = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + const { + + rerender + + } = render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + rerender(); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + expect(listenerAlt).toBeCalledTimes(1); + + }); + + test('listener is removed when value is null', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(arg0: any): any; + + const { + + unmount + + } = render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(1); + + + + // this should unset the listener + + unmount(); + + listener.mockClear(); + + act(() => { + + target.click(); + + }); + + expect(listener).toBeCalledTimes(0); + + }); + + test('custom event dispatched on target', () => { + + const listener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + act(() => { + + const event = new CustomEvent('magic-event', { + + bubbles: true + + }); + + targetRef.current.dispatchEvent(event); + + }); + + expect(listener).toBeCalledTimes(1); + + }); + + test('listeners can be set on multiple targets simultaneously', () => { + + const log = []; + + const targetRef = React.createRef(); + + const parentRef = React.createRef(); + + const childRef = React.createRef(); + + const listener = jest.fn(e => { + + log.push(['bubble', e.currentTarget.id]); + + }); + + const listenerCapture = jest.fn(e => { + + log.push(['capture', e.currentTarget.id]); + + }); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(2); + + expect(listener).toBeCalledTimes(2); + + expect(log).toEqual([['capture', 'parent'], ['capture', 'target'], ['bubble', 'target'], ['bubble', 'parent']]); + + }); + + test('listeners are specific to each event handle', () => { + + const log = []; + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + const listener = jest.fn(e => { + + log.push(['bubble', 'target']); + + }); + + const listenerAlt = jest.fn(e => { + + log.push(['bubble', 'target-alt']); + + }); + + const listenerCapture = jest.fn(e => { + + log.push(['capture', 'target']); + + }); + + const listenerCaptureAlt = jest.fn(e => { + + log.push(['capture', 'target-alt']); + + }); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(listenerCapture).toBeCalledTimes(1); + + expect(listenerCaptureAlt).toBeCalledTimes(1); + + expect(listener).toBeCalledTimes(1); + + expect(listenerAlt).toBeCalledTimes(1); + + expect(log).toEqual([['capture', 'target'], ['capture', 'target-alt'], ['bubble', 'target'], ['bubble', 'target-alt']]); + + }); + + }); + + describe('cleanup', () => { + + test('removes all listeners for given event type from targets', () => { + + const clickListener = jest.fn(); + + declare function Component(): any; + + const { + + unmount + + } = render(); + + unmount(); + + const target = createEventTarget(document); + + act(() => { + + target.click(); + + }); + + expect(clickListener).toBeCalledTimes(0); + + }); + + }); + + describe('stopPropagation and stopImmediatePropagation', () => { + + test('stopPropagation works as expected', () => { + + const childListener = jest.fn(e => { + + e.stopPropagation(); + + }); + + const targetListener = jest.fn(); + + const targetRef = React.createRef(); + + const childRef = React.createRef(); + + declare function Component(): any; + + render(); + + const child = createEventTarget(childRef.current); + + act(() => { + + child.click(); + + }); + + expect(childListener).toBeCalledTimes(1); + + expect(targetListener).toBeCalledTimes(0); + + }); + + test('stopImmediatePropagation works as expected', () => { + + const firstListener = jest.fn(e => { + + e.stopImmediatePropagation(); + + }); + + const secondListener = jest.fn(); + + const targetRef = React.createRef(); + + declare function Component(): any; + + render(); + + const target = createEventTarget(targetRef.current); + + act(() => { + + target.click(); + + }); + + expect(firstListener).toBeCalledTimes(1); + + expect(secondListener).toBeCalledTimes(0); + + }); + + }); + +}); + \ No newline at end of file + diff --git a/node_modules/react-native-web/dist/modules/useStable/__tests__/index-test.js.flow b/node_modules/react-native-web/dist/modules/useStable/__tests__/index-test.js.flow + new file mode 100644 + index 0000000..49edfc6 + --- /dev/null + +++ b/node_modules/react-native-web/dist/modules/useStable/__tests__/index-test.js.flow + @@ -0,0 +1,54 @@ + +/** + + * Copyright (c) Meta Platforms, Inc. and affiliates. + + * + + * This source code is licensed under the MIT license found in the + + * LICENSE file in the root directory of this source tree. + + * + + * @flow + + */ + + + +import * as React from 'react'; + +import { render } from '@testing-library/react'; + +import useStable from '..'; + +describe('useStable', () => { + + let spy = {}; + + declare var TestComponent: (arg0: any) => React.Node; + + beforeEach(() => { + + spy = {}; + + }); + + test('correctly sets the initial value', () => { + + declare var initialValueCallback: () => any; + + render(); + + expect(spy.value).toBe(5); + + }); + + test('does not change the value', () => { + + let counter = 0; + + declare var initialValueCallback: () => any; + + const { + + rerender + + } = render(); + + expect(spy.value).toBe(0); + + rerender(); + + expect(spy.value).toBe(0); + + }); + + test('only calls the callback once', () => { + + let counter = 0; + + declare var initialValueCallback: () => any; + + const { + + rerender + + } = render(); + + expect(counter).toBe(1); + + rerender(); + + expect(counter).toBe(1); + + }); + + test('does not change the value if the callback initially returns null', () => { + + let counter = 0; + + declare var initialValueCallback: () => any; + + const { + + rerender + + } = render(); + + expect(spy.value).toBe(null); + + rerender(); + + expect(spy.value).toBe(null); + + }); + +}); + \ No newline at end of file + EOT - name: Add Button component working-directory: test-app run: | @@ -103,8 +1001,7 @@ jobs: ButtonSpinner, ButtonIcon, ButtonGroup, - } from "@/components/ui/button" - + } from "@/components/ui/button"; export default function Home() { return (
@@ -112,10 +1009,24 @@ jobs: Hello World!
- ) + ); } EOT + - name: Add postinstall script to package.json + working-directory: test-app + run: | + jq '.scripts.postinstall = "patch-package"' package.json > tmp.$$.json && mv tmp.$$.json package.json + + - name: Run postinstall to apply patches + working-directory: test-app + run: npm run postinstall + + - name: Install Babel dependencies + working-directory: test-app + run: | + npm install @babel/preset-react babel-loader --save-dev + - name: Install dependencies and clean cache working-directory: test-app run: | From a268310dd244d9b6083f3c435959e8713814e68e Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 16:51:22 +0530 Subject: [PATCH 4/8] fix: added String.raw for literals --- .github/workflows/next-latest.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 7e39034e7..8628c93db 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -140,17 +140,17 @@ jobs: mode?: "light" | "dark" | "system"; children?: React.ReactNode; }) { - let cssVariablesWithMode = `/* empty */` + let cssVariablesWithMode = String.raw`/* empty */` Object.keys(config).forEach((configKey) => { cssVariablesWithMode += - configKey === "dark" ? `\n .dark {\n ` : `\n:root {\n`; + configKey === "dark" ? String.raw`\n .dark {\n ` : String.raw`\n:root {\n`; const cssVariables = Object.keys( config[configKey as keyof typeof config] ).reduce((acc: string, curr: string) => { - acc += `${curr}:${config[configKey as keyof typeof config][curr]}; `; + acc += String.raw`${curr}:${config[configKey as keyof typeof config][curr]}; `; return acc; }, ""); - cssVariablesWithMode += `${cssVariables} \n}`; + cssVariablesWithMode += String.raw`${cssVariables} \n}`; }); setFlushStyles(cssVariablesWithMode); @@ -184,7 +184,7 @@ jobs: const documentElement = document.documentElement; if (documentElement) { const head = documentElement.querySelector("head"); - let style = head?.querySelector(`[id='${variableStyleTagId}']`); + let style = head?.querySelector(String.raw`[id='${variableStyleTagId}']`); if (!style) { style = createStyle(variableStyleTagId); style.innerHTML = cssVariablesWithMode; From 5521dd5e9716f6c0a5d3418d38074a56f22a926b Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 17:03:19 +0530 Subject: [PATCH 5/8] fix: removed raw strings --- .github/workflows/next-latest.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 8628c93db..a2b78914f 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -140,17 +140,17 @@ jobs: mode?: "light" | "dark" | "system"; children?: React.ReactNode; }) { - let cssVariablesWithMode = String.raw`/* empty */` + let cssVariablesWithMode = "" Object.keys(config).forEach((configKey) => { cssVariablesWithMode += - configKey === "dark" ? String.raw`\n .dark {\n ` : String.raw`\n:root {\n`; + configKey === "dark" ? "\n .dark {\n" : "\n:root {\n"; const cssVariables = Object.keys( config[configKey as keyof typeof config] ).reduce((acc: string, curr: string) => { - acc += String.raw`${curr}:${config[configKey as keyof typeof config][curr]}; `; + acc += ${{curr}}:${{config[configKey as keyof typeof config][curr]}};; return acc; }, ""); - cssVariablesWithMode += String.raw`${cssVariables} \n}`; + cssVariablesWithMode += ${{cssVariables}}}; }); setFlushStyles(cssVariablesWithMode); @@ -184,7 +184,7 @@ jobs: const documentElement = document.documentElement; if (documentElement) { const head = documentElement.querySelector("head"); - let style = head?.querySelector(String.raw`[id='${variableStyleTagId}']`); + let style = head?.querySelector([id=${{variableStyleTagId}}]); if (!style) { style = createStyle(variableStyleTagId); style.innerHTML = cssVariablesWithMode; From 213eefda19a11ef23c317f805a39cf9fcded92b0 Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 17:25:04 +0530 Subject: [PATCH 6/8] fix: added name change --- .github/workflows/next-latest.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index a2b78914f..44709e88a 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -1,4 +1,4 @@ -name: Next.js Latest with Gluestack UI +name: Next.js Latest on: push: @@ -33,7 +33,7 @@ jobs: needs: check-next-version if: ${{ needs.check-next-version.outputs.should_run == 'true' || github.event_name == 'push' || github.event_name == 'pull_request' }} runs-on: ubuntu-latest - name: Next.js latest with Gluestack UI + name: Next.js latest steps: - uses: actions/checkout@v3 From f319ca0719d3e3513d947822d40caffef3c9bfa8 Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 18:32:56 +0530 Subject: [PATCH 7/8] fix: removed template literals from provider --- .github/workflows/next-latest.yml | 157 +++++++++++++++--------------- 1 file changed, 80 insertions(+), 77 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index 44709e88a..a58a6da1d 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -70,6 +70,9 @@ jobs: import { withGluestackUI } from "@gluestack/ui-next-adapter"; const nextConfig = { transpilePackages: ["nativewind", "react-native-css-interop"], + typescript: { + ignoreBuildErrors: true, + }, }; export default withGluestackUI(nextConfig); EOT @@ -113,96 +116,96 @@ jobs: working-directory: test-app run: | cat < components/ui/gluestack-ui-provider/index.web.tsx - - "use client"; - import React, { useEffect, useLayoutEffect } from "react"; - import { config } from "./config"; - import { OverlayProvider } from "@gluestack-ui/overlay"; - import { ToastProvider } from "@gluestack-ui/toast"; - import { setFlushStyles } from "@gluestack-ui/nativewind-utils/flush"; - import { script } from "./script"; + + "use client"; + import React, { useEffect, useLayoutEffect } from "react"; + import { config } from "./config"; + import { OverlayProvider } from "@gluestack-ui/overlay"; + import { ToastProvider } from "@gluestack-ui/toast"; + import { setFlushStyles } from "@gluestack-ui/nativewind-utils/flush"; + import { script } from "./script"; - const variableStyleTagId = "nativewind-style"; - const createStyle = (styleTagId: string) => { - const style = document.createElement("style"); - style.id = styleTagId; - style.appendChild(document.createTextNode("")); - return style; - }; + const variableStyleTagId = "nativewind-style"; + const createStyle = (styleTagId: string) => { + const style = document.createElement("style"); + style.id = styleTagId; + style.appendChild(document.createTextNode("")); + return style; + }; - export const useSafeLayoutEffect = - typeof window !== "undefined" ? useLayoutEffect : useEffect; + export const useSafeLayoutEffect = + typeof window !== "undefined" ? useLayoutEffect : useEffect; - export function GluestackUIProvider({ - mode = "light", - ...props - }: { - mode?: "light" | "dark" | "system"; - children?: React.ReactNode; - }) { - let cssVariablesWithMode = "" - Object.keys(config).forEach((configKey) => { - cssVariablesWithMode += - configKey === "dark" ? "\n .dark {\n" : "\n:root {\n"; - const cssVariables = Object.keys( - config[configKey as keyof typeof config] - ).reduce((acc: string, curr: string) => { - acc += ${{curr}}:${{config[configKey as keyof typeof config][curr]}};; - return acc; - }, ""); - cssVariablesWithMode += ${{cssVariables}}}; - }); + export function GluestackUIProvider({ + mode = "light", + ...props + }: { + mode?: "light" | "dark" | "system"; + children?: React.ReactNode; + }) { + let cssVariablesWithMode = ""; + Object.keys(config).forEach((configKey) => { + cssVariablesWithMode += configKey === "dark" ? ".dark {" : ":root {"; + const cssVariables = Object.keys( + config[configKey as keyof typeof config] + ).reduce((acc: string, curr: string) => { + acc += curr + ":" + config[configKey as keyof typeof config][curr]; + return acc; + }, ""); + cssVariablesWithMode += cssVariables+ "\n}"; + }); - setFlushStyles(cssVariablesWithMode); + setFlushStyles(cssVariablesWithMode); - const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => { - script(e.matches ? "dark" : "light"); - }, []); + const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => { + script(e.matches ? "dark" : "light"); + }, []); - useSafeLayoutEffect(() => { - if (mode !== "system") { - const documentElement = document.documentElement; - if (documentElement) { - documentElement.classList.add(mode); - documentElement.classList.remove(mode === "light" ? "dark" : "light"); - documentElement.style.colorScheme = mode; - } - } - }, [mode]); + useSafeLayoutEffect(() => { + if (mode !== "system") { + const documentElement = document.documentElement; + if (documentElement) { + documentElement.classList.add(mode); + documentElement.classList.remove(mode === "light" ? "dark" : "light"); + documentElement.style.colorScheme = mode; + } + } + }, [mode]); - useSafeLayoutEffect(() => { - if (mode !== "system") return; - const media = window.matchMedia("(prefers-color-scheme: dark)"); + useSafeLayoutEffect(() => { + if (mode !== "system") return; + const media = window.matchMedia("(prefers-color-scheme: dark)"); - media.addListener(handleMediaQuery); + media.addListener(handleMediaQuery); - return () => media.removeListener(handleMediaQuery); - }, [handleMediaQuery]); + return () => media.removeListener(handleMediaQuery); + }, [handleMediaQuery]); - useSafeLayoutEffect(() => { - if (typeof window !== "undefined") { - const documentElement = document.documentElement; - if (documentElement) { - const head = documentElement.querySelector("head"); - let style = head?.querySelector([id=${{variableStyleTagId}}]); - if (!style) { - style = createStyle(variableStyleTagId); - style.innerHTML = cssVariablesWithMode; - if (head) head.appendChild(style); - } - } + useSafeLayoutEffect(() => { + if (typeof window !== "undefined") { + const documentElement = document.documentElement; + if (documentElement) { + const head = documentElement.querySelector("head"); + let style = head?.querySelector("[id="+variableStyleTagId+"]"); + if (!style) { + style = createStyle(variableStyleTagId); + style.innerHTML = cssVariablesWithMode; + if (head) head.appendChild(style); } - }, []); - - return ( - <> - - {props.children} - - - ); + } } + }, []); + + return ( + <> + + {props.children} + + + ); + } EOT + - name: Create patches folder working-directory: test-app run: | From 577896141451813c32bb80e4c648fc536a3b8c53 Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Tue, 12 Nov 2024 18:45:56 +0530 Subject: [PATCH 8/8] fix: removed update version test --- .github/workflows/next-latest.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/next-latest.yml b/.github/workflows/next-latest.yml index a58a6da1d..4c4f6275f 100644 --- a/.github/workflows/next-latest.yml +++ b/.github/workflows/next-latest.yml @@ -1076,18 +1076,3 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - - update-version: - needs: test-next-latest - if: ${{ needs.check-next-version.outputs.should_run == 'true' }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Update Next.js version file - run: | - echo ${{ needs.check-next-version.outputs.latest_version }} > .next-version - git config user.name github-actions - git config user.email github-actions@github.com - git add .next-version - git commit -m "Update Next.js version to ${{ needs.check-next-version.outputs.latest_version }}" - git push