diff --git a/src/internal/hooks/use-base-component/__tests__/init-themes.test.tsx b/src/internal/hooks/use-base-component/__tests__/init-themes.test.tsx new file mode 100644 index 0000000000..63b497c43b --- /dev/null +++ b/src/internal/hooks/use-base-component/__tests__/init-themes.test.tsx @@ -0,0 +1,54 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; +import { render } from '@testing-library/react'; + +import useBaseComponent, { + clearThemesInitialized, + InternalBaseComponentProps, +} from '../../../../../lib/components/internal/hooks/use-base-component'; + +const awsuiGlobalFlagsSymbol = Symbol.for('awsui-global-flags'); + +jest.mock('../../../../../lib/components/internal/environment', () => ({ + ALWAYS_VISUAL_REFRESH: true, + PACKAGE_SOURCE: 'components', + PACKAGE_VERSION: '3.0.0', + THEME: 'console', +})); + +function InternalDemo({ __internalRootRef }: InternalBaseComponentProps) { + return
Demo
; +} + +function Demo() { + const baseComponentProps = useBaseComponent('DemoComponent'); + return ; +} + +describe('useBaseComponent initThemes with ALWAYS_VISUAL_REFRESH=true', () => { + afterEach(() => { + clearThemesInitialized(); + document.body.classList.remove('awsui-one-theme'); + document.body.classList.remove('awsui-visual-refresh'); + delete (window as any)[awsuiGlobalFlagsSymbol]; + }); + + test('should add awsui-one-theme class when oneTheme flag is set', () => { + (window as any)[awsuiGlobalFlagsSymbol] = { oneTheme: true }; + render(); + expect(document.body).toHaveClass('awsui-one-theme'); + }); + + test('should not add awsui-visual-refresh class', () => { + (window as any)[awsuiGlobalFlagsSymbol] = { oneTheme: true }; + render(); + expect(document.body).not.toHaveClass('awsui-visual-refresh'); + }); + + test('should not add any theme class when no flag is set', () => { + render(); + expect(document.body).not.toHaveClass('awsui-one-theme'); + expect(document.body).not.toHaveClass('awsui-visual-refresh'); + }); +}); diff --git a/src/internal/hooks/use-base-component/index.ts b/src/internal/hooks/use-base-component/index.ts index a549ddc347..a2fff153b0 100644 --- a/src/internal/hooks/use-base-component/index.ts +++ b/src/internal/hooks/use-base-component/index.ts @@ -4,13 +4,14 @@ import React from 'react'; import { ComponentConfiguration, + initThemes, useComponentMetadata, useComponentMetrics, useFocusVisible, } from '@cloudscape-design/component-toolkit/internal'; import { AnalyticsMetadata } from '../../../types/analytics'; -import { PACKAGE_SOURCE, PACKAGE_VERSION, THEME } from '../../environment'; +import { ALWAYS_VISUAL_REFRESH, PACKAGE_SOURCE, PACKAGE_VERSION, THEME } from '../../environment'; import { getVisualTheme } from '../../utils/get-visual-theme'; import { useVisualRefresh } from '../use-visual-mode'; import { useMissingStylesCheck } from './styles-check'; @@ -28,11 +29,24 @@ export interface InternalBaseComponentProps { * attached to the (internal) component's root DOM node. The hook takes care of attaching the metadata to this * root DOM node and emits the telemetry for this component. */ + +let themesInitialized = false; + +/** for testing only */ +export function clearThemesInitialized() { + themesInitialized = false; +} + export default function useBaseComponent( componentName: string, config?: ComponentConfiguration, analyticsMetadata?: AnalyticsMetadata ) { + if (!themesInitialized) { + initThemes({ skipVisualRefresh: ALWAYS_VISUAL_REFRESH }); + themesInitialized = true; + } + const isVisualRefresh = useVisualRefresh(); const theme = getVisualTheme(THEME, isVisualRefresh); useComponentMetrics(componentName, { packageSource: PACKAGE_SOURCE, packageVersion: PACKAGE_VERSION, theme }, config);