mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Theme] fix theme$
usage when used with useObservable
(#220141)
## Summary
When using `theme$` with
[`useObservable`](ad33f76dff/src/useObservable.ts (L10-L21)
)
passing custom default `theme`, the resulting `theme` can be wrong.
Take for example this code...
```ts
import useObservable from 'react-use/lib/useObservable';
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, {
darkMode: false,
name: 'amsterdam',
});
```
In such case `kibanaTheme.theme$` has the correct value but the
`useObservable` returns the default/initial value immediately, so the
default is always applied then updated, requiring 2 renderings just to
update to the correct theme.
The simplest approach to fix this is just to pass the
`kibanaTheme.getTheme()` as the default when using with `useObservable`.
```ts
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, kibanaTheme.getTheme());
```
---
Ideally, in the future we have a commonly shared way to access the theme
in react via a `useKibanaTheme` hook or a better/more consistent API for
`useEuiTheme`.
### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Edgar Santos <edgar.santos@elastic.co>
This commit is contained in:
parent
fdf3ef7ffc
commit
12b7429afe
81 changed files with 212 additions and 376 deletions
|
@ -25,7 +25,6 @@ const buildTableContext = (dataView: DataView, rows: DataTableRecord[]): DataTab
|
|||
getRowByIndex: jest.fn((index) => rows[index]),
|
||||
onFilter: jest.fn(),
|
||||
dataView,
|
||||
isDarkMode: false,
|
||||
selectedDocsState: buildSelectedDocsState([]),
|
||||
pageIndex: 0,
|
||||
pageSize: 10,
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { of } from 'rxjs';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import './data_table.scss';
|
||||
import type { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import {
|
||||
|
@ -99,7 +97,6 @@ import {
|
|||
import { useSorting } from '../hooks/use_sorting';
|
||||
|
||||
const CONTROL_COLUMN_IDS_DEFAULT = [SELECT_ROW, OPEN_DETAILS];
|
||||
const THEME_DEFAULT = { darkMode: false };
|
||||
const VIRTUALIZATION_OPTIONS: EuiDataGridProps['virtualizationOptions'] = {
|
||||
// Allowing some additional rows to be rendered outside
|
||||
// the view minimizes pop-in when scrolling quickly
|
||||
|
@ -520,7 +517,6 @@ export const UnifiedDataTable = ({
|
|||
}: UnifiedDataTableProps) => {
|
||||
const { fieldFormats, toastNotifications, dataViewFieldEditor, uiSettings, storage, data } =
|
||||
services;
|
||||
const { darkMode } = useObservable(services.theme?.theme$ ?? of(THEME_DEFAULT), THEME_DEFAULT);
|
||||
const dataGridRef = useRef<EuiDataGridRefProps>(null);
|
||||
const [isFilterActive, setIsFilterActive] = useState(false);
|
||||
const [isCompareActive, setIsCompareActive] = useState(false);
|
||||
|
@ -686,7 +682,6 @@ export const UnifiedDataTable = ({
|
|||
getRowByIndex: (index: number) => displayedRows[index],
|
||||
onFilter,
|
||||
dataView,
|
||||
isDarkMode: darkMode,
|
||||
selectedDocsState,
|
||||
valueToStringConverter,
|
||||
componentsTourSteps,
|
||||
|
@ -696,7 +691,6 @@ export const UnifiedDataTable = ({
|
|||
}),
|
||||
[
|
||||
componentsTourSteps,
|
||||
darkMode,
|
||||
dataView,
|
||||
isPlainRecord,
|
||||
isPaginationEnabled,
|
||||
|
|
|
@ -20,7 +20,6 @@ export interface DataTableContext {
|
|||
getRowByIndex: (index: number) => DataTableRecord | undefined;
|
||||
onFilter?: DocViewFilterFn;
|
||||
dataView: DataView;
|
||||
isDarkMode: boolean;
|
||||
selectedDocsState: UseSelectedDocsState;
|
||||
valueToStringConverter: ValueToStringConverter;
|
||||
componentsTourSteps?: Record<string, string>;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { of } from 'rxjs';
|
||||
import { shallow } from 'enzyme';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
|
@ -51,9 +50,6 @@ const mockServices = {
|
|||
fieldFormats: {
|
||||
getDefaultInstance: jest.fn(() => ({ convert: (value: unknown) => (value ? value : '-') })),
|
||||
},
|
||||
theme: {
|
||||
theme$: of({ darkMode: false }),
|
||||
},
|
||||
};
|
||||
|
||||
const rowsSource: EsHitRecord[] = [
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export { useDarkMode } from './use_dark_mode';
|
||||
export { useKibanaIsDarkMode } from './use_kibana_is_dark_mode';
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { useEuiTheme, COLOR_MODES_STANDARD } from '@elastic/eui';
|
||||
|
||||
/**
|
||||
* A **temporary** hook to simplify getting `isDarkMode` from eui context
|
||||
*
|
||||
* TODO: Replace with hook directly from eui
|
||||
* See https://github.com/elastic/eui/issues/8693
|
||||
*/
|
||||
export const useKibanaIsDarkMode = (): boolean => {
|
||||
const { colorMode } = useEuiTheme();
|
||||
|
||||
return colorMode === COLOR_MODES_STANDARD.dark;
|
||||
};
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
export { KibanaThemeProvider, type KibanaThemeProviderProps } from './theme_provider';
|
||||
export { wrapWithTheme } from './with_theme';
|
||||
export { useKibanaIsDarkMode } from './hooks';
|
||||
|
||||
// Re-exporting from @kbn/react-kibana-context-common for convenience to consumers.
|
||||
export { defaultTheme, type KibanaTheme } from '@kbn/react-kibana-context-common';
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
import { snakeCase } from 'lodash';
|
||||
import React, { FC, useState, useEffect, useMemo } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import {
|
||||
EuiCard,
|
||||
EuiFlexGroup,
|
||||
|
@ -36,6 +35,7 @@ import {
|
|||
RedirectAppLinksContainer as RedirectAppLinks,
|
||||
RedirectAppLinksKibanaProvider,
|
||||
} from '@kbn/shared-ux-link-redirect-app';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { FetchResult } from '@kbn/newsfeed-plugin/public';
|
||||
import {
|
||||
FeatureCatalogueEntry,
|
||||
|
@ -66,20 +66,11 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
|
|||
const [hasDataView, setHasDataView] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const { services } = useKibana<CoreStart & AppPluginStartDependencies>();
|
||||
const {
|
||||
http,
|
||||
docLinks,
|
||||
dataViews,
|
||||
share,
|
||||
application,
|
||||
chrome,
|
||||
dataViewEditor,
|
||||
customBranding,
|
||||
theme,
|
||||
} = services;
|
||||
const { http, docLinks, dataViews, share, application, chrome, dataViewEditor, customBranding } =
|
||||
services;
|
||||
const addBasePath = http.basePath.prepend;
|
||||
const currentTheme = useObservable(theme.theme$, { darkMode: false, name: 'amsterdam' });
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const minBreakpointM = useEuiMinBreakpoint('m');
|
||||
|
||||
// Home does not have a locator implemented, so hard-code it here.
|
||||
|
@ -152,9 +143,7 @@ export const Overview: FC<Props> = ({ newsFetchResult, solutions, features }) =>
|
|||
trackUiMetric(METRIC_TYPE.CLICK, `app_card_${appId}`);
|
||||
}}
|
||||
image={addBasePath(
|
||||
`/plugins/${PLUGIN_ID}/assets/kibana_${appId}_${
|
||||
currentTheme.darkMode ? 'dark' : 'light'
|
||||
}.svg`
|
||||
`/plugins/${PLUGIN_ID}/assets/kibana_${appId}_${isDarkMode ? 'dark' : 'light'}.svg`
|
||||
)}
|
||||
title={app.title}
|
||||
titleElement="h3"
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/core-application-browser-mocks",
|
||||
"@kbn/core-http-browser-mocks",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
|
@ -43,6 +43,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { DatatableColumn } from '@kbn/expressions-plugin/public';
|
||||
import { IconChartHeatmap } from '@kbn/chart-icons';
|
||||
import { getOverridesFor } from '@kbn/chart-expressions-common';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { HeatmapRenderProps, FilterEvent, BrushEvent } from '../../common';
|
||||
import {
|
||||
applyPaletteParams,
|
||||
|
@ -156,7 +157,7 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
|
|||
overrides,
|
||||
}) => {
|
||||
const chartRef = useRef<Chart>(null);
|
||||
const isDarkTheme = chartsThemeService.useDarkMode();
|
||||
const isDarkTheme = useKibanaIsDarkMode();
|
||||
// legacy heatmap legend is handled by the uiState
|
||||
const [showLegend, setShowLegend] = useState<boolean>(() => {
|
||||
const bwcLegendStateDefault = args.legend.isVisible ?? true;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/transpose-utils",
|
||||
"@kbn/ebt-tools",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -43,6 +43,7 @@ import type { FieldFormat } from '@kbn/field-formats-plugin/common';
|
|||
import { getOverridesFor } from '@kbn/chart-expressions-common';
|
||||
import { useKbnPalettes } from '@kbn/palettes';
|
||||
import { useAppFixedViewport } from '@kbn/core-rendering-browser';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { consolidateMetricColumns } from '../../common/utils';
|
||||
import { DEFAULT_PERCENT_DECIMALS } from '../../common/constants';
|
||||
import {
|
||||
|
@ -303,7 +304,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => {
|
|||
},
|
||||
});
|
||||
|
||||
const isDarkMode = props.chartsThemeService.useDarkMode();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const layers = useMemo(
|
||||
() =>
|
||||
getLayers(
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"@kbn/core-rendering-browser",
|
||||
"@kbn/palettes",
|
||||
"@kbn/ebt-tools",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
extractVisualizationType,
|
||||
} from '@kbn/chart-expressions-common';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { ExpressionTagcloudRendererDependencies } from '../plugin';
|
||||
import { TagcloudRendererConfig } from '../../common/types';
|
||||
import { EXPRESSION_NAME } from '../../common';
|
||||
|
@ -98,12 +99,6 @@ export const tagcloudRenderer: (
|
|||
handlers.event(chartSizeEvent);
|
||||
|
||||
const palettesRegistry = await plugins.charts.palettes.getPalettes();
|
||||
let isDarkMode = false;
|
||||
plugins.charts.theme.darkModeEnabled$
|
||||
.subscribe((val) => {
|
||||
isDarkMode = val.darkMode;
|
||||
})
|
||||
.unsubscribe();
|
||||
|
||||
performanceTracker.mark(PERFORMANCE_TRACKER_MARKS.RENDER_START);
|
||||
|
||||
|
@ -125,7 +120,7 @@ export const tagcloudRenderer: (
|
|||
fireEvent={handlers.event}
|
||||
syncColors={config.syncColors}
|
||||
overrides={config.overrides}
|
||||
isDarkMode={isDarkMode}
|
||||
isDarkMode={useKibanaIsDarkMode()}
|
||||
/>
|
||||
</VisualizationContainer>
|
||||
)}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"@kbn/palettes",
|
||||
"@kbn/charts-theme",
|
||||
"@kbn/ebt-tools",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -58,6 +58,7 @@ import {
|
|||
import { PersistedState } from '@kbn/visualizations-plugin/public';
|
||||
import { getOverridesFor, ChartSizeSpec } from '@kbn/chart-expressions-common';
|
||||
import { useAppFixedViewport } from '@kbn/core-rendering-browser';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { AlertRuleFromVisUIActionData } from '@kbn/alerts-ui-shared';
|
||||
import type {
|
||||
FilterEvent,
|
||||
|
@ -237,7 +238,7 @@ export function XYChart({
|
|||
|
||||
const chartRef = useRef<Chart>(null);
|
||||
const chartBaseTheme = chartsThemeService.useChartsBaseTheme();
|
||||
const darkMode = chartsThemeService.useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const palettes = useKbnPalettes();
|
||||
const appFixedViewport = useAppFixedViewport();
|
||||
const filteredLayers = getFilteredLayers(layers);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"@kbn/alerts-ui-shared",
|
||||
"@kbn/ui-actions-browser",
|
||||
"@kbn/ebt-tools",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -23,7 +23,11 @@ export class ThemeService {
|
|||
/** An observable of the current charts base theme */
|
||||
public chartsBaseTheme$ = this._chartsBaseTheme$.asObservable();
|
||||
|
||||
/** An observable boolean for dark mode of kibana */
|
||||
/**
|
||||
* An observable boolean for dark mode of kibana
|
||||
*
|
||||
* @deprecated use `useKibanaIsDarkMode`
|
||||
*/
|
||||
public get darkModeEnabled$(): Observable<CoreTheme> {
|
||||
if (!this.theme$) {
|
||||
throw new Error('ThemeService not initialized');
|
||||
|
@ -32,7 +36,11 @@ export class ThemeService {
|
|||
return this.theme$;
|
||||
}
|
||||
|
||||
/** A React hook for consuming the dark mode value */
|
||||
/**
|
||||
* A React hook for consuming the dark mode value
|
||||
*
|
||||
* @deprecated use `useKibanaIsDarkMode`
|
||||
*/
|
||||
public useDarkMode = (): boolean => {
|
||||
const [value, update] = useState(false);
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiButton,
|
||||
|
@ -20,6 +19,7 @@ import {
|
|||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
import useMountedState from 'react-use/lib/useMountedState';
|
||||
import { useDashboardApi } from '../../../dashboard_api/use_dashboard_api';
|
||||
|
@ -36,7 +36,7 @@ export function DashboardEmptyScreen() {
|
|||
const isMounted = useMountedState();
|
||||
const dashboardApi = useDashboardApi();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const isDarkTheme = useObservable(coreServices.theme.theme$)?.darkMode;
|
||||
const isDarkTheme = useKibanaIsDarkMode();
|
||||
const viewMode = useStateFromPublishingSubject(dashboardApi.viewMode$);
|
||||
const isEditMode = useMemo(() => {
|
||||
return viewMode === 'edit';
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
"@kbn/ui-actions-browser",
|
||||
"@kbn/esql-types",
|
||||
"@kbn/saved-objects-tagging-plugin",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/std"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
|
|
|
@ -8,17 +8,16 @@
|
|||
*/
|
||||
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { ApplicationStart, CoreTheme, NotificationsStart } from '@kbn/core/public';
|
||||
import { ApplicationStart, NotificationsStart } from '@kbn/core/public';
|
||||
import type { GuideState, GuideStep as GuideStepStatus } from '@kbn/guided-onboarding';
|
||||
|
||||
import type { GuideId, GuideConfig, StepConfig } from '@kbn/guided-onboarding';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { GuidedOnboardingApi } from '../types';
|
||||
|
||||
import type { PluginState } from '../../common';
|
||||
|
@ -33,7 +32,6 @@ interface GuidePanelProps {
|
|||
api: GuidedOnboardingApi;
|
||||
application: ApplicationStart;
|
||||
notifications: NotificationsStart;
|
||||
theme$: Observable<CoreTheme>;
|
||||
}
|
||||
|
||||
const getProgress = (state?: GuideState): number => {
|
||||
|
@ -48,15 +46,16 @@ const getProgress = (state?: GuideState): number => {
|
|||
return 0;
|
||||
};
|
||||
|
||||
export const GuidePanel = ({ api, application, notifications, theme$ }: GuidePanelProps) => {
|
||||
export const GuidePanel = ({ api, application, notifications }: GuidePanelProps) => {
|
||||
const euiThemeContext = useEuiTheme();
|
||||
const euiTheme = euiThemeContext.euiTheme;
|
||||
const isDarkTheme = useKibanaIsDarkMode();
|
||||
|
||||
const [isGuideOpen, setIsGuideOpen] = useState(false);
|
||||
const [isQuitGuideModalOpen, setIsQuitGuideModalOpen] = useState(false);
|
||||
const [pluginState, setPluginState] = useState<PluginState | undefined>(undefined);
|
||||
const [guideConfig, setGuideConfig] = useState<GuideConfig | undefined>(undefined);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const { darkMode: isDarkTheme } = useObservable(theme$, { darkMode: false, name: 'amsterdam' });
|
||||
|
||||
const styles = getGuidePanelStyles({ euiThemeContext, isDarkTheme });
|
||||
|
||||
|
|
|
@ -86,15 +86,9 @@ export class GuidedOnboardingPlugin
|
|||
application: ApplicationStart;
|
||||
notifications: NotificationsStart;
|
||||
}) {
|
||||
const { theme } = startServices;
|
||||
ReactDOM.render(
|
||||
<KibanaRenderContextProvider {...startServices}>
|
||||
<GuidePanel
|
||||
api={api}
|
||||
application={application}
|
||||
notifications={notifications}
|
||||
theme$={theme.theme$}
|
||||
/>
|
||||
<GuidePanel api={api} application={application} notifications={notifications} />
|
||||
</KibanaRenderContextProvider>,
|
||||
targetDomElement
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"@kbn/config-schema",
|
||||
"@kbn/features-plugin",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -17,7 +17,7 @@ import React from 'react';
|
|||
import { EuiCard, EuiButton, EuiButtonEmpty, UseEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { getServices } from '../../kibana_services';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
interface Props {
|
||||
urlBasePath: string;
|
||||
|
@ -26,8 +26,9 @@ interface Props {
|
|||
}
|
||||
|
||||
export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) {
|
||||
const IS_DARK_THEME = getServices().theme.getTheme().darkMode;
|
||||
const cardGraphicFile = !IS_DARK_THEME
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
const cardGraphicFile = !isDarkMode
|
||||
? 'illustration_integrations_lightmode.png'
|
||||
: 'illustration_integrations_darkmode.png';
|
||||
const cardGraphicURL = `${urlBasePath}/plugins/home/assets/common/${cardGraphicFile}`;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/core-http-browser",
|
||||
"@kbn/deeplinks-observability",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { useDarkMode } from './use_dark_mode';
|
||||
import { createKibanaReactContext } from '../context';
|
||||
import { KibanaServices } from '../context/types';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { CoreTheme } from '@kbn/core/public';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
|
||||
describe('useDarkMode', () => {
|
||||
let container: HTMLDivElement | null;
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.removeChild(container!);
|
||||
container = null;
|
||||
});
|
||||
|
||||
const TestConsumer: React.FC = () => {
|
||||
const darkMode = useDarkMode();
|
||||
return <div>{String(darkMode)}</div>;
|
||||
};
|
||||
|
||||
const mock = (): [KibanaServices, BehaviorSubject<CoreTheme>] => {
|
||||
const core = coreMock.createStart();
|
||||
const subject = new BehaviorSubject<CoreTheme>({ darkMode: false, name: 'amsterdam' });
|
||||
core.theme.theme$ = subject.asObservable();
|
||||
|
||||
return [core, subject];
|
||||
};
|
||||
|
||||
test('returns the value from the theme', () => {
|
||||
const [core] = mock();
|
||||
const { Provider } = createKibanaReactContext(core);
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider>
|
||||
<TestConsumer />
|
||||
</Provider>,
|
||||
container
|
||||
);
|
||||
|
||||
const div = container!.querySelector('div');
|
||||
expect(div!.textContent).toBe('false');
|
||||
});
|
||||
|
||||
test('value changes if the theme changes', () => {
|
||||
const [core, subject] = mock();
|
||||
const { Provider } = createKibanaReactContext(core);
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider>
|
||||
<TestConsumer />
|
||||
</Provider>,
|
||||
container
|
||||
);
|
||||
|
||||
let div = container!.querySelector('div');
|
||||
expect(div!.textContent).toBe('false');
|
||||
|
||||
act(() => {
|
||||
subject.next({ darkMode: true, name: 'amsterdam' });
|
||||
});
|
||||
|
||||
div = container!.querySelector('div');
|
||||
expect(div!.textContent).toBe('true');
|
||||
});
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { useKibana } from '../context';
|
||||
|
||||
export const useDarkMode = (defaultValue?: boolean): boolean => {
|
||||
const {
|
||||
services: { theme },
|
||||
} = useKibana();
|
||||
|
||||
if (!theme) {
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
throw new TypeError('theme service not available in kibana-react context.');
|
||||
}
|
||||
|
||||
const currentTheme = useObservable(theme.theme$, theme.getTheme());
|
||||
return currentTheme.darkMode;
|
||||
};
|
|
@ -31,8 +31,6 @@ export {
|
|||
useGlobalUiSetting$,
|
||||
} from './ui_settings';
|
||||
|
||||
export { useDarkMode } from './dark_mode';
|
||||
|
||||
export { useExecutionContext } from './use_execution_context';
|
||||
|
||||
export { reactRouterNavigate, reactRouterOnClickHandler } from './react_router_navigate';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Observable } from 'rxjs';
|
||||
import { of, type Observable } from 'rxjs';
|
||||
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import type { MountPoint } from '@kbn/core/public';
|
||||
|
@ -24,7 +24,7 @@ import { toMountPoint as _toMountPoint } from '@kbn/react-kibana-mount';
|
|||
// dark mode is applied correctly. This code is for compatibility purposes,
|
||||
// and will be removed when the deprecated usages are removed.
|
||||
const themeStart: ThemeServiceStart = {
|
||||
theme$: new Observable((subscriber) => subscriber.next(defaultTheme)),
|
||||
theme$: of(defaultTheme),
|
||||
getTheme: () => defaultTheme,
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import { Router, Routes, Route } from '@kbn/shared-ux-router';
|
|||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { css } from '@emotion/css';
|
||||
|
@ -23,11 +22,15 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
|||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
import type { FleetConfigType, FleetStartServices } from '../../plugin';
|
||||
|
||||
import { PackageInstallProvider } from '../integrations/hooks';
|
||||
import { SpaceSettingsContextProvider } from '../../hooks/use_space_settings_context';
|
||||
|
||||
import { ErrorLayout, PermissionsError } from '../../layouts/error';
|
||||
|
||||
import { type FleetStatusProviderProps, useAuthz, useFleetStatus, useFlyoutContext } from './hooks';
|
||||
|
||||
import {
|
||||
|
@ -60,7 +63,6 @@ import { EnrollmentTokenListPage } from './sections/agents/enrollment_token_list
|
|||
import { UninstallTokenListPage } from './sections/agents/uninstall_token_list_page';
|
||||
import { SettingsApp } from './sections/settings';
|
||||
import { DebugPage } from './sections/debug';
|
||||
import { ErrorLayout, PermissionsError } from '../../layouts/error';
|
||||
|
||||
const FEEDBACK_URL = 'https://ela.st/fleet-feedback';
|
||||
|
||||
|
@ -199,8 +201,7 @@ export const FleetAppContext: React.FC<{
|
|||
fleetStatus,
|
||||
}) => {
|
||||
const XXL_BREAKPOINT = 1600;
|
||||
const darkModeObservable = useObservable(startServices.theme.theme$);
|
||||
const isDarkMode = darkModeObservable && darkModeObservable.darkMode;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
return (
|
||||
<KibanaRenderContextProvider
|
||||
|
|
|
@ -28,7 +28,7 @@ import type { Pagination } from '../../../../hooks';
|
|||
import { useAgentVersion } from '../../../../hooks';
|
||||
import { useLink, useAuthz } from '../../../../hooks';
|
||||
|
||||
import { AgentPolicySummaryLine } from '../../../../components';
|
||||
import { AgentPolicySummaryLine } from '../../../../../../components';
|
||||
import { Tags } from '../../components/tags';
|
||||
import type { AgentMetrics } from '../../../../../../../common/types';
|
||||
import { formatAgentCPU, formatAgentMemory } from '../../services/agent_metrics';
|
||||
|
|
|
@ -17,7 +17,7 @@ import { sendGetAgents, sendGetAgentStatus } from '../../../hooks';
|
|||
import { AgentListPage } from '.';
|
||||
|
||||
jest.mock('../../../../integrations/hooks/use_confirm_force_install', () => ({
|
||||
useConfirmForceInstall: () => <>confirmForceInstall</>,
|
||||
useConfirmForceInstall: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('./hooks/use_missing_encryption_key_callout', () => ({
|
||||
|
@ -195,6 +195,8 @@ describe('agent_list_page', () => {
|
|||
totalInactive: 0,
|
||||
},
|
||||
});
|
||||
jest.useFakeTimers({ legacyFakeTimers: true });
|
||||
|
||||
({ utils } = renderAgentList());
|
||||
|
||||
await waitFor(() => {
|
||||
|
@ -212,6 +214,10 @@ describe('agent_list_page', () => {
|
|||
utils.getByText('All agents selected');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should not set selection mode when agent selection changed automatically', async () => {
|
||||
act(() => {
|
||||
jest.runOnlyPendingTimers();
|
||||
|
|
|
@ -13,12 +13,13 @@ import { Redirect, useRouteMatch } from 'react-router-dom';
|
|||
import { Router, Routes, Route } from '@kbn/shared-ux-router';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
import type { FleetConfigType, FleetStartServices } from '../../plugin';
|
||||
|
||||
import {
|
||||
|
@ -33,6 +34,8 @@ import { SpaceSettingsContextProvider } from '../../hooks/use_space_settings_con
|
|||
|
||||
import { FleetServerFlyout } from '../fleet/components';
|
||||
|
||||
import { ErrorLayout, PermissionsError } from '../../layouts/error';
|
||||
|
||||
import { AgentPolicyContextProvider, useFlyoutContext } from './hooks';
|
||||
import { FLEET_ROUTING_PATHS, INTEGRATIONS_ROUTING_PATHS, pagePathGetters } from './constants';
|
||||
|
||||
|
@ -40,12 +43,11 @@ import type { UIExtensionsStorage } from './types';
|
|||
|
||||
import { EPMApp } from './sections/epm';
|
||||
|
||||
import { ErrorLayout, PermissionsError } from '../../layouts/error';
|
||||
|
||||
import { PackageInstallProvider, UIExtensionsContext, FlyoutContextProvider } from './hooks';
|
||||
import { IntegrationsHeader } from './components/header';
|
||||
import { AgentEnrollmentFlyout } from './components';
|
||||
import { ReadOnlyContextProvider } from './hooks/use_read_only_context';
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
const EmptyContext = () => <></>;
|
||||
|
@ -78,8 +80,7 @@ export const IntegrationsAppContext: React.FC<{
|
|||
fleetStatus,
|
||||
}) => {
|
||||
const XXL_BREAKPOINT = 1600;
|
||||
const darkModeObservable = useObservable(startServices.theme.theme$);
|
||||
const isDarkMode = darkModeObservable && darkModeObservable.darkMode;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
const CloudContext = startServices.cloud?.CloudContextProvider || EmptyContext;
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import { COLOR_MODES_STANDARD, EuiCallOut, EuiSpacer, EuiToolTip, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiCallOut, EuiSpacer, EuiToolTip, useEuiTheme } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
import { installationStatuses } from '../../../../../../common/constants';
|
||||
import type { EpmPackageInstallStatus } from '../../../../../../common/types';
|
||||
|
||||
|
@ -90,8 +92,8 @@ const getCalloutText = ({
|
|||
|
||||
const useInstallationStatusStyles = (): InstallationStatusStylesProps &
|
||||
CompressedInstallationStylesProps => {
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
return React.useMemo(
|
||||
() => ({
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
"@kbn/zod-helpers",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/fields-metadata-plugin",
|
||||
"@kbn/test-jest-helpers",
|
||||
"@kbn/core-saved-objects-utils-server",
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { toExpression } from '@kbn/interpreter';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { KibanaExecutionContext } from '@kbn/core-execution-context-common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
|
@ -497,10 +497,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
|
|||
}
|
||||
}, [suggestionForDraggedField, dispatchLens]);
|
||||
|
||||
const IS_DARK_THEME: boolean = useObservable(core.theme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
}).darkMode;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
const renderDragDropPrompt = () => {
|
||||
if (chartSizeSpec) {
|
||||
|
@ -580,7 +577,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
|
|||
<img
|
||||
aria-hidden={true}
|
||||
css={promptIllustrationStyle}
|
||||
src={IS_DARK_THEME ? applyChangesIllustrationDark : applyChangesIllustrationLight}
|
||||
src={isDarkMode ? applyChangesIllustrationDark : applyChangesIllustrationLight}
|
||||
alt={applyChangesString}
|
||||
/>
|
||||
<h2>
|
||||
|
|
|
@ -690,7 +690,7 @@ describe('DatatableComponent', () => {
|
|||
|
||||
renderDatatableComponent();
|
||||
|
||||
expect(getCellColorFn).toBeCalledTimes(3); // 3 initial renders of table
|
||||
expect(getCellColorFn).toBeCalledTimes(2); // 2 initial renders of table
|
||||
});
|
||||
|
||||
test('caches getCellColorFn by columnId with transpose columns', () => {
|
||||
|
@ -717,7 +717,7 @@ describe('DatatableComponent', () => {
|
|||
},
|
||||
});
|
||||
|
||||
expect(getCellColorFn).toBeCalledTimes(3); // 3 initial renders of table
|
||||
expect(getCellColorFn).toBeCalledTimes(2); // 2 initial renders of table
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -29,13 +29,12 @@ import {
|
|||
import { CustomPaletteState, EmptyPlaceholder } from '@kbn/charts-plugin/public';
|
||||
import { ClickTriggerEvent } from '@kbn/charts-plugin/public';
|
||||
import { IconChartDatatable } from '@kbn/chart-icons';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { getOriginalId } from '@kbn/transpose-utils';
|
||||
import { CoreTheme } from '@kbn/core/public';
|
||||
import { getKbnPalettes } from '@kbn/palettes';
|
||||
import { useKbnPalettes } from '@kbn/palettes';
|
||||
import type { IFieldFormat } from '@kbn/field-formats-plugin/common';
|
||||
import { getColorCategories, getLegacyColorCategories } from '@kbn/chart-expressions-common';
|
||||
import { css } from '@emotion/react';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme/hooks';
|
||||
import type { LensTableRowContextMenuEvent } from '../../../types';
|
||||
import { RowHeightMode } from '../../../../common/types';
|
||||
import { LensGridDirection } from '../../../../common/expressions';
|
||||
|
@ -82,11 +81,8 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
|
|||
const dataGridRef = useRef<EuiDataGridRefProps>(null);
|
||||
|
||||
const isInteractive = props.interactive;
|
||||
const theme = useObservable<CoreTheme>(props.theme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
});
|
||||
const palettes = getKbnPalettes(theme);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const palettes = useKbnPalettes();
|
||||
|
||||
const [columnConfig, setColumnConfig] = useState({
|
||||
columns: props.args.columns,
|
||||
|
@ -423,7 +419,7 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
|
|||
palettes,
|
||||
data,
|
||||
colorByTerms,
|
||||
theme.darkMode,
|
||||
isDarkMode,
|
||||
syncColors,
|
||||
palette,
|
||||
colorMapping
|
||||
|
@ -437,14 +433,14 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
|
|||
formatters,
|
||||
columnConfig,
|
||||
DataContext,
|
||||
theme.darkMode,
|
||||
isDarkMode,
|
||||
getCellColor,
|
||||
props.args.fitRowToContent
|
||||
);
|
||||
}, [
|
||||
formatters,
|
||||
columnConfig,
|
||||
theme.darkMode,
|
||||
isDarkMode,
|
||||
props.args.fitRowToContent,
|
||||
props.paletteService,
|
||||
palettes,
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
|
||||
import { Ast } from '@kbn/interpreter';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreTheme, ThemeServiceStart } from '@kbn/core/public';
|
||||
import { ThemeServiceStart } from '@kbn/core/public';
|
||||
import {
|
||||
PaletteRegistry,
|
||||
CUSTOM_PALETTE,
|
||||
|
@ -23,9 +23,9 @@ import { IconChartDatatable } from '@kbn/chart-icons';
|
|||
import { getOriginalId } from '@kbn/transpose-utils';
|
||||
import { LayerTypes } from '@kbn/expression-xy-plugin/public';
|
||||
import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/common';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { getSortingCriteria } from '@kbn/sort-predicates';
|
||||
import { getKbnPalettes } from '@kbn/palettes';
|
||||
import { getKbnPalettes, useKbnPalettes } from '@kbn/palettes';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { FormBasedPersistedState } from '../../datasources/form_based/types';
|
||||
import type {
|
||||
SuggestionRequest,
|
||||
|
@ -493,16 +493,13 @@ export const getDatatableVisualization = ({
|
|||
};
|
||||
},
|
||||
DimensionEditorComponent(props) {
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
});
|
||||
const palettes = getKbnPalettes(theme);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const palettes = useKbnPalettes();
|
||||
|
||||
return (
|
||||
<TableDimensionEditor
|
||||
{...props}
|
||||
isDarkMode={theme.darkMode}
|
||||
isDarkMode={isDarkMode}
|
||||
palettes={palettes}
|
||||
paletteService={paletteService}
|
||||
formatFactory={formatFactory}
|
||||
|
|
|
@ -505,10 +505,7 @@ export const getPieVisualization = ({
|
|||
};
|
||||
},
|
||||
DimensionEditorComponent(props) {
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
});
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, kibanaTheme.getTheme());
|
||||
const palettes = getKbnPalettes(theme);
|
||||
return (
|
||||
<DimensionEditor
|
||||
|
|
|
@ -305,10 +305,7 @@ export const getTagcloudVisualization = ({
|
|||
},
|
||||
|
||||
DimensionEditorComponent(props) {
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
});
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, kibanaTheme.getTheme());
|
||||
const palettes = getKbnPalettes(theme);
|
||||
|
||||
if (props.groupId === TAG_GROUP_ID) {
|
||||
|
|
|
@ -754,10 +754,7 @@ export const getXyVisualization = ({
|
|||
paletteService,
|
||||
};
|
||||
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, {
|
||||
darkMode: false,
|
||||
name: 'amsterdam',
|
||||
});
|
||||
const theme = useObservable<CoreTheme>(kibanaTheme.theme$, kibanaTheme.getTheme());
|
||||
const palettes = getKbnPalettes(theme);
|
||||
const layer = props.state.layers.find((l) => l.layerId === props.layerId)!;
|
||||
const dimensionEditor = isReferenceLayer(layer) ? (
|
||||
|
|
|
@ -120,6 +120,7 @@
|
|||
"@kbn/core-capabilities-common",
|
||||
"@kbn/presentation-panel-plugin",
|
||||
"@kbn/esql-types",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/fields-metadata-plugin",
|
||||
"@kbn/response-ops-rule-form",
|
||||
"@kbn/alerts-ui-shared",
|
||||
|
|
|
@ -41,7 +41,8 @@ import type { KibanaFeature } from '@kbn/features-plugin/common';
|
|||
import type { FeaturesPluginStart } from '@kbn/features-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { reactRouterNavigate, useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
import type { Cluster } from '@kbn/remote-clusters-plugin/public';
|
||||
import { REMOTE_CLUSTERS_PATH } from '@kbn/remote-clusters-plugin/public';
|
||||
|
@ -339,7 +340,7 @@ export const EditRolePage: FunctionComponent<Props> = ({
|
|||
cloudOrgUrl,
|
||||
...startServices
|
||||
}) => {
|
||||
const isDarkMode = useDarkMode();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
if (!dataViews) {
|
||||
// The dataViews plugin is technically marked as an optional dependency because we don't need to pull it in for Anonymous pages (such
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"@kbn/core-elasticsearch-server",
|
||||
"@kbn/core-http-server-utils",
|
||||
"@kbn/core-user-profile-browser-mocks",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { EuiEmptyPrompt, EuiImage, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiEmptyPrompt, EuiImage } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { dashboardsDark, dashboardsLight } from '@kbn/shared-svg';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
interface Props {
|
||||
actions: React.ReactNode;
|
||||
}
|
||||
|
||||
export function EmptyDashboards({ actions }: Props) {
|
||||
const { colorMode } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -22,11 +23,7 @@ export function EmptyDashboards({ actions }: Props) {
|
|||
hasShadow={false}
|
||||
hasBorder={false}
|
||||
icon={
|
||||
<EuiImage
|
||||
size="fullWidth"
|
||||
src={colorMode === 'DARK' ? dashboardsDark : dashboardsLight}
|
||||
alt=""
|
||||
/>
|
||||
<EuiImage size="fullWidth" src={isDarkMode ? dashboardsDark : dashboardsLight} alt="" />
|
||||
}
|
||||
title={
|
||||
<h2>
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSkeletonText, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSkeletonText } from '@elastic/eui';
|
||||
import type { CloudProvider } from '@kbn/custom-icons';
|
||||
import { getAgentIcon, getCloudProviderIcon } from '@kbn/custom-icons';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { get } from 'lodash';
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import {
|
||||
CLOUD_AVAILABILITY_ZONE,
|
||||
CLOUD_INSTANCE_ID,
|
||||
|
@ -89,7 +90,7 @@ const cloudDetailsKeys = [
|
|||
];
|
||||
|
||||
export function InstanceDetails({ serviceName, serviceNodeName, kuery }: Props) {
|
||||
const { colorMode } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const history = useHistory();
|
||||
|
||||
const { data, status } = useInstanceDetailsFetcher({
|
||||
|
@ -133,7 +134,6 @@ export function InstanceDetails({ serviceName, serviceNodeName, kuery }: Props)
|
|||
|
||||
const containerType = data.kubernetes?.pod?.name ? 'Kubernetes' : 'Docker';
|
||||
|
||||
const isDarkMode = colorMode === 'DARK';
|
||||
return (
|
||||
<EuiFlexGroup direction="column" responsive={false}>
|
||||
<EuiFlexItem>
|
||||
|
|
|
@ -31,6 +31,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer, useEuiTheme } from '@ela
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import type { ReactElement } from 'react';
|
||||
import React from 'react';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useChartThemes } from '@kbn/observability-shared-plugin/public';
|
||||
import { isExpectedBoundsComparison } from '../time_comparison/get_comparison_options';
|
||||
|
@ -77,7 +78,8 @@ export function TimeseriesChart({
|
|||
}: TimeseriesChartProps) {
|
||||
const history = useHistory();
|
||||
const { chartRef, updatePointerEvent } = useChartPointerEventContext();
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const chartThemes = useChartThemes();
|
||||
const anomalyChartTimeseries = getChartAnomalyTimeseries({
|
||||
anomalyTimeseries,
|
||||
|
@ -117,7 +119,6 @@ export function TimeseriesChart({
|
|||
}
|
||||
: undefined;
|
||||
|
||||
const isDarkMode = colorMode === 'DARK';
|
||||
const endZoneColor = isDarkMode ? euiTheme.colors.lightShade : euiTheme.colors.darkShade;
|
||||
const endZoneRectAnnotationStyle: Partial<RectAnnotationStyle> = {
|
||||
stroke: endZoneColor,
|
||||
|
@ -152,7 +153,7 @@ export function TimeseriesChart({
|
|||
alignItems="center"
|
||||
responsive={false}
|
||||
gutterSize="xs"
|
||||
style={{ fontWeight: 'normal' }}
|
||||
css={{ fontWeight: 'normal' }}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="iInCircle" />
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { CloudProvider } from '@kbn/custom-icons';
|
||||
import { getAgentIcon, getCloudProviderIcon, getServerlessIcon } from '@kbn/custom-icons';
|
||||
import type { ReactChild } from 'react';
|
||||
|
@ -75,11 +76,9 @@ export interface PopoverItem {
|
|||
}
|
||||
|
||||
export function ServiceIcons({ start, end, serviceName, environment }: Props) {
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const [selectedIconPopover, setSelectedIconPopover] = useState<Icons | null>();
|
||||
|
||||
const { colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === 'DARK';
|
||||
|
||||
const { data: icons, status: iconsFetchStatus } = useFetcher(
|
||||
(callApmApi) => {
|
||||
if (serviceName && start && end) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import type { Storage } from '@kbn/kibana-utils-plugin/public';
|
|||
import { NavigationWarningPromptProvider } from '@kbn/observability-shared-plugin/public';
|
||||
import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme/hooks';
|
||||
import {
|
||||
type KibanaEnvContext,
|
||||
useKibanaContextForPluginProvider,
|
||||
|
@ -23,7 +24,6 @@ import {
|
|||
import type { InfraClientStartDeps, InfraClientStartExports } from '../types';
|
||||
import { HeaderActionMenuProvider } from '../containers/header_action_menu_provider';
|
||||
import { TriggersActionsProvider } from '../containers/triggers_actions_context';
|
||||
import { useIsDarkMode } from '../hooks/use_is_dark_mode';
|
||||
|
||||
export const CommonInfraProviders: FC<
|
||||
PropsWithChildren<{
|
||||
|
@ -34,7 +34,7 @@ export const CommonInfraProviders: FC<
|
|||
theme$: AppMountParameters['theme$'];
|
||||
}>
|
||||
> = ({ children, triggersActionsUI, setHeaderActionMenu, appName, storage, theme$ }) => {
|
||||
const darkMode = useIsDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
|
||||
return (
|
||||
<TriggersActionsProvider triggersActionsUI={triggersActionsUI}>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { merge } from 'rxjs';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiCallOut, EuiLink, useEuiTheme } from '@elastic/eui';
|
||||
|
@ -21,6 +21,7 @@ import {
|
|||
import { initializeUnsavedChanges } from '@kbn/presentation-containers';
|
||||
import { LogStream } from '@kbn/logs-shared-plugin/public';
|
||||
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import type { Query } from '@kbn/es-query';
|
||||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
|
@ -73,6 +74,7 @@ export function getLogStreamEmbeddableFactory(services: Services) {
|
|||
return {
|
||||
api,
|
||||
Component: () => {
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const { filters, query, timeRange } = useFetchContext(api);
|
||||
const { startTimestamp, endTimestamp } = useMemo(() => {
|
||||
return {
|
||||
|
@ -81,14 +83,6 @@ export function getLogStreamEmbeddableFactory(services: Services) {
|
|||
};
|
||||
}, [timeRange]);
|
||||
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
useEffect(() => {
|
||||
const subscription = services.coreStart.theme.theme$.subscribe((theme) => {
|
||||
setDarkMode(theme.darkMode);
|
||||
});
|
||||
return () => subscription.unsubscribe();
|
||||
}, []);
|
||||
|
||||
return !startTimestamp || !endTimestamp ? null : (
|
||||
<LogStreamEmbeddableProviders
|
||||
core={services.coreStart}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { CoreTheme } from '@kbn/core/public';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { of } from 'rxjs';
|
||||
import { useKibanaContextForPlugin } from './use_kibana';
|
||||
|
||||
const themeDefault: CoreTheme = { darkMode: false, name: 'amsterdam' };
|
||||
|
||||
export const useIsDarkMode = () => {
|
||||
const { services } = useKibanaContextForPlugin();
|
||||
const { darkMode } = useObservable(services.theme?.theme$ ?? of(themeDefault), themeDefault);
|
||||
|
||||
return darkMode;
|
||||
};
|
|
@ -17,7 +17,7 @@ import {
|
|||
import styled from 'styled-components';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { euiLightVars, euiDarkVars } from '@kbn/ui-theme';
|
||||
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { getCoreVitalTooltipMessage, Thresholds } from './core_vital_item';
|
||||
import {
|
||||
LEGEND_NEEDS_IMPROVEMENT_LABEL,
|
||||
|
@ -50,7 +50,7 @@ interface Props {
|
|||
}
|
||||
|
||||
export function PaletteLegends({ ranks, title, onItemHover, thresholds, isCls }: Props) {
|
||||
const darkMode = useDarkMode(false);
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const palette = euiPaletteForStatus(3);
|
||||
const labels = [LEGEND_GOOD_LABEL, LEGEND_NEEDS_IMPROVEMENT_LABEL, LEGEND_POOR_LABEL];
|
||||
|
||||
|
|
|
@ -17,13 +17,14 @@ import type { AppMountParameters } from '@kbn/core/public';
|
|||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { CellActionsProvider } from '@kbn/cell-actions';
|
||||
import { NavigationProvider } from '@kbn/security-solution-navigation';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { UpsellingProvider } from '../common/components/upselling_provider';
|
||||
import { ManageUserInfo } from '../detections/components/user_info';
|
||||
import { APP_NAME } from '../../common/constants';
|
||||
import { ErrorToastDispatcher } from '../common/components/error_toast_dispatcher';
|
||||
import { MlCapabilitiesProvider } from '../common/components/ml/permissions/ml_capabilities_provider';
|
||||
import { GlobalToaster, ManageGlobalToaster } from '../common/components/toasters';
|
||||
import { KibanaContextProvider, useKibana, useDarkMode } from '../common/lib/kibana';
|
||||
import { KibanaContextProvider, useKibana } from '../common/lib/kibana';
|
||||
import type { State } from '../common/store';
|
||||
import type { StartServices } from '../types';
|
||||
import { PageRouter } from './routes';
|
||||
|
@ -47,7 +48,7 @@ const StartAppComponent: FC<StartAppComponent> = ({ children, history, store, th
|
|||
upselling,
|
||||
} = services;
|
||||
|
||||
const darkMode = useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
|
||||
return (
|
||||
<KibanaRenderContextProvider {...services}>
|
||||
|
|
|
@ -19,7 +19,7 @@ import type { GenerationInterval } from '@kbn/elastic-assistant-common';
|
|||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { InfoPopoverBody } from '../info_popover_body';
|
||||
import { getTimerPrefix } from './last_times_popover/helpers';
|
||||
import * as i18n from '../translations';
|
||||
|
@ -42,8 +42,7 @@ const CountdownComponent: React.FC<Props> = ({
|
|||
}) => {
|
||||
// theming:
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useMemo(() => theme.getTheme().darkMode === true, [theme]);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
// popover state:
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
|
|
|
@ -9,10 +9,10 @@ import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiText, useEuiTheme } from '@elas
|
|||
import { css } from '@emotion/react';
|
||||
import type { GenerationInterval } from '@kbn/elastic-assistant-common';
|
||||
import moment from 'moment';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { PreferenceFormattedDate } from '../../../../../../common/components/formatted_date';
|
||||
import { useKibana } from '../../../../../../common/lib/kibana';
|
||||
import { MAX_SECONDS_BADGE_WIDTH } from '../helpers';
|
||||
import * as i18n from '../translations';
|
||||
|
||||
|
@ -22,8 +22,7 @@ interface Props {
|
|||
|
||||
const GenerationTimingComponent: React.FC<Props> = ({ interval }) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useMemo(() => theme.getTheme().darkMode === true, [theme]);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
return (
|
||||
<EuiFlexGroup alignItems="center" data-test-subj="generationTiming" gutterSize="none">
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import type { GenerationInterval } from '@kbn/elastic-assistant-common';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
import { useKibana } from '../../../../../common/lib/kibana';
|
||||
import { GenerationTiming } from './generation_timing';
|
||||
import { useKibanaFeatureFlags } from '../../../use_kibana_feature_flags';
|
||||
import * as i18n from './translations';
|
||||
|
@ -25,8 +25,7 @@ const LastTimesPopoverComponent: React.FC<Props> = ({
|
|||
successfulGenerations,
|
||||
}) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useMemo(() => theme.getTheme().darkMode === true, [theme]);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const { attackDiscoveryAlertsEnabled } = useKibanaFeatureFlags();
|
||||
|
||||
const calculatedBy = attackDiscoveryAlertsEnabled
|
||||
|
|
|
@ -18,7 +18,7 @@ import { css } from '@emotion/react';
|
|||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import type { GenerationInterval } from '@kbn/elastic-assistant-common';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { Countdown } from './countdown';
|
||||
import { LoadingMessages } from './loading_messages';
|
||||
import * as i18n from './translations';
|
||||
|
@ -69,7 +69,7 @@ const LoadingCalloutComponent: React.FC<Props> = ({
|
|||
successfulGenerations,
|
||||
}) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const { attackDiscoveryAlertsEnabled } = useKibanaFeatureFlags();
|
||||
|
||||
const isTerminalState = useMemo(() => getIsTerminalState(status), [status]);
|
||||
|
@ -122,8 +122,6 @@ const LoadingCalloutComponent: React.FC<Props> = ({
|
|||
]
|
||||
);
|
||||
|
||||
const isDarkMode = useMemo(() => theme.getTheme().darkMode === true, [theme]);
|
||||
|
||||
const backgroundColor = useMemo(() => {
|
||||
const defaultBackgroundColor = isDarkMode ? BACKGROUND_COLOR_DARK : BACKGROUND_COLOR_LIGHT;
|
||||
const successBackgroundColor = euiTheme.colors.backgroundBaseSuccess;
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiPopoverTitle, EuiText } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import type { GenerationInterval } from '@kbn/elastic-assistant-common';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
|
||||
import { LastTimesPopover } from '../countdown/last_times_popover';
|
||||
import {
|
||||
|
@ -33,8 +33,7 @@ const InfoPopoverBodyComponent: React.FC<Props> = ({
|
|||
connectorIntervals,
|
||||
successfulGenerations,
|
||||
}) => {
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useMemo(() => theme.getTheme().darkMode === true, [theme]);
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const { attackDiscoveryAlertsEnabled } = useKibanaFeatureFlags();
|
||||
const averageIntervalSeconds = useMemo(() => {
|
||||
if (attackDiscoveryAlertsEnabled) {
|
||||
|
|
|
@ -12,7 +12,8 @@ import { DEFAULT_ATTACK_DISCOVERY_MAX_ALERTS } from '@kbn/elastic-assistant';
|
|||
import React, { useMemo } from 'react';
|
||||
|
||||
import { getAttackDiscoveryLoadingMessage } from '@kbn/elastic-assistant-common';
|
||||
import { useDateFormat, useKibana } from '../../../../common/lib/kibana';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useDateFormat } from '../../../../common/lib/kibana';
|
||||
import { getCanceledResultMessage } from './get_canceled_result_message';
|
||||
import { getFormattedDate } from './get_formatted_time';
|
||||
import { getIsTerminalState } from '../get_is_terminal_state';
|
||||
|
@ -49,7 +50,7 @@ const LoadingMessagesComponent: React.FC<Props> = ({
|
|||
start,
|
||||
status,
|
||||
}) => {
|
||||
const { theme } = useKibana().services;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const dateFormat = useDateFormat();
|
||||
|
||||
const formattedStart = useMemo(
|
||||
|
@ -76,8 +77,6 @@ const LoadingMessagesComponent: React.FC<Props> = ({
|
|||
localStorageAttackDiscoveryMaxAlerts,
|
||||
});
|
||||
|
||||
const isDarkMode = theme.getTheme().darkMode === true;
|
||||
|
||||
const isTerminalState = useMemo(() => getIsTerminalState(status), [status]);
|
||||
|
||||
const progressMessage = useMemo(
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
import React, { type PropsWithChildren } from 'react';
|
||||
import { css, type CSSInterpolation } from '@emotion/css';
|
||||
import { EuiText, useEuiTheme, COLOR_MODES_STANDARD, type EuiTextProps } from '@elastic/eui';
|
||||
import { EuiText, useEuiTheme, type EuiTextProps } from '@elastic/eui';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
export interface PanelTextProps extends PropsWithChildren<EuiTextProps> {
|
||||
subdued?: true;
|
||||
|
@ -15,8 +16,8 @@ export interface PanelTextProps extends PropsWithChildren<EuiTextProps> {
|
|||
}
|
||||
export const PanelText = React.memo<PanelTextProps>(
|
||||
({ children, subdued, semiBold, cursive, ...props }) => {
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
let color;
|
||||
if (subdued && !isDarkMode) {
|
||||
|
|
|
@ -85,9 +85,6 @@ export const useKibana = jest.fn().mockReturnValue({
|
|||
});
|
||||
export const useUiSetting = jest.fn(createUseUiSettingMock());
|
||||
export const useUiSetting$ = jest.fn(createUseUiSetting$Mock());
|
||||
export const useDarkMode = jest
|
||||
.fn()
|
||||
.mockImplementation((defaultValue?: boolean) => defaultValue ?? false);
|
||||
export const useHttp = jest.fn().mockReturnValue(createStartServicesMock().http);
|
||||
export const useTimeZone = jest.fn();
|
||||
export const useDateFormat = jest.fn().mockReturnValue('MMM D, YYYY @ HH:mm:ss.SSS');
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
useKibana,
|
||||
useUiSetting,
|
||||
useUiSetting$,
|
||||
useDarkMode,
|
||||
withKibana,
|
||||
} from '@kbn/kibana-react-plugin/public';
|
||||
import type { ApmBase } from '@elastic/apm-rum';
|
||||
|
@ -24,6 +23,5 @@ export {
|
|||
useTypedKibana as useKibana,
|
||||
useUiSetting,
|
||||
useUiSetting$,
|
||||
useDarkMode,
|
||||
withKibana,
|
||||
};
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { euiLightVars as lightTheme, euiDarkVars as darkTheme } from '@kbn/ui-theme';
|
||||
|
||||
import { useDarkMode } from '../kibana';
|
||||
|
||||
export const useEuiTheme = () => {
|
||||
const darkMode = useDarkMode();
|
||||
return darkMode ? darkTheme : lightTheme;
|
||||
};
|
|
@ -10,7 +10,7 @@ import React, { memo, useMemo } from 'react';
|
|||
import { Provider } from 'react-redux';
|
||||
import { Router } from '@kbn/shared-ux-router';
|
||||
import type { History } from 'history';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { Store } from 'redux';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
|
@ -37,9 +37,7 @@ export const AppRootProvider = memo<{
|
|||
queryClient: QueryClient;
|
||||
children: ReactNode | ReactNode[];
|
||||
}>(({ store, history, coreStart, depsStart, queryClient, startServices, children }) => {
|
||||
const { theme: themeStart } = coreStart;
|
||||
const theme = useObservable(themeStart.theme$, themeStart.getTheme());
|
||||
const isDarkMode = theme.darkMode;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const services = useMemo(() => {
|
||||
return {
|
||||
...depsStart,
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiAvatar, EuiIcon } from '@elastic/eui';
|
||||
import { EuiAvatar, EuiIcon, useEuiTheme } from '@elastic/eui';
|
||||
import React, { memo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { useEuiTheme } from '../../../../common/lib/theme/use_eui_theme';
|
||||
import type { RuleStatusType } from '../../../common/types';
|
||||
|
||||
export interface RuleStatusIconProps {
|
||||
|
@ -27,12 +26,16 @@ const RuleStatusIconStyled = styled.div`
|
|||
`;
|
||||
|
||||
const RuleStatusIconComponent: React.FC<RuleStatusIconProps> = ({ name, type }) => {
|
||||
const theme = useEuiTheme();
|
||||
const color = type === 'passive' ? theme.euiColorLightestShade : theme.euiColorPrimary;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const color =
|
||||
type === 'passive' ? euiTheme.colors.backgroundBaseDisabled : euiTheme.colors.primary;
|
||||
return (
|
||||
<RuleStatusIconStyled>
|
||||
<EuiAvatar color={color} name={type === 'valid' ? '' : name} size="l" aria-label={name} />
|
||||
{type === 'valid' ? <EuiIcon type="check" color={theme.euiColorEmptyShade} size="l" /> : null}
|
||||
{type === 'valid' ? (
|
||||
<EuiIcon type="check" color={euiTheme.colors.backgroundBasePlain} size="l" />
|
||||
) : null}
|
||||
</RuleStatusIconStyled>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-theme';
|
||||
import React from 'react';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { DescriptionList } from '../../../../../common/utility_types';
|
||||
import { useDarkMode } from '../../../../common/lib/kibana';
|
||||
import type {
|
||||
FlowTargetSourceDest,
|
||||
NetworkDetailsStrategyResponse,
|
||||
|
@ -79,7 +79,7 @@ export const IpOverview = React.memo<IpOverviewProps>(
|
|||
}) => {
|
||||
const capabilities = useMlCapabilities();
|
||||
const userPermissions = hasMlUserPermissions(capabilities);
|
||||
const darkMode = useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const typeData = data[flowTarget];
|
||||
const column: DescriptionList[] = [
|
||||
{
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
|
||||
import React, { type PropsWithChildren } from 'react';
|
||||
import { EuiText, useEuiTheme, COLOR_MODES_STANDARD, type EuiTextProps } from '@elastic/eui';
|
||||
import { EuiText, type EuiTextProps } from '@elastic/eui';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
export type CardSubduedTextProps = PropsWithChildren<EuiTextProps>;
|
||||
export const CardSubduedText = React.memo<CardSubduedTextProps>(({ children, ...props }) => {
|
||||
const { colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
return (
|
||||
<EuiText {...props} color={isDarkMode ? 'text' : 'subdued'}>
|
||||
{children}
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { COLOR_MODES_STANDARD, useEuiTheme } from '@elastic/eui';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
export const HEIGHT_ANIMATION_DURATION = 250;
|
||||
|
||||
export const useCardPanelStyles = () => {
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const successBackgroundColor = euiTheme.colors.backgroundBaseSuccess;
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const darkModeStyles = useDarkPanelStyles(isDarkMode);
|
||||
|
||||
return css`
|
||||
|
|
|
@ -13,9 +13,9 @@ import type { OnboardingCardId } from '../../constants';
|
|||
import { TestProviders } from '../../../common/mock/test_providers';
|
||||
|
||||
const mockUseDarkMode = jest.fn(() => false);
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => ({
|
||||
...jest.requireActual('@kbn/kibana-react-plugin/public'),
|
||||
useDarkMode: () => mockUseDarkMode(),
|
||||
jest.mock('@kbn/react-kibana-context-theme', () => ({
|
||||
...jest.requireActual('@kbn/react-kibana-context-theme'),
|
||||
useKibanaIsDarkMode: () => mockUseDarkMode(),
|
||||
}));
|
||||
|
||||
jest.mock('@elastic/eui', () => ({
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import classnames from 'classnames';
|
||||
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import type { OnboardingCardId } from '../../constants';
|
||||
import type { CheckCompleteResult, CardBadge } from '../../types';
|
||||
import { CARD_COMPLETE_BADGE, EXPAND_CARD_BUTTON_LABEL } from './translations';
|
||||
|
@ -55,7 +55,7 @@ export const OnboardingCardPanel = React.memo<PropsWithChildren<OnboardingCardPa
|
|||
'onboardingCardPanel-expanded': isExpanded,
|
||||
'onboardingCardPanel-completed': isComplete,
|
||||
});
|
||||
const isDarkMode = useDarkMode();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
const iconType = useMemo(
|
||||
() => (iconDark && isDarkMode ? iconDark : icon),
|
||||
[isDarkMode, iconDark, icon]
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { COLOR_MODES_STANDARD, useEuiTheme } from '@elastic/eui';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
|
||||
export const useCardStyles = () => {
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
return css`
|
||||
min-width: 315px;
|
||||
|
|
|
@ -6,16 +6,9 @@
|
|||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
COLOR_MODES_STANDARD,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiImage,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useCurrentUser } from '../../../common/lib/kibana/hooks';
|
||||
import { OnboardingHeaderTopicSelector } from './onboarding_header_topic_selector';
|
||||
import { useOnboardingHeaderStyles } from './onboarding_header.styles';
|
||||
|
@ -30,8 +23,7 @@ import { useKibana } from '../../../common/lib/kibana';
|
|||
|
||||
export const OnboardingHeader = React.memo(() => {
|
||||
const currentUser = useCurrentUser();
|
||||
const { colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
|
||||
const styles = useOnboardingHeaderStyles();
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th
|
|||
import { getOr } from 'lodash/fp';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_header_title';
|
||||
import { useGlobalTime } from '../../../common/containers/use_global_time';
|
||||
import { useQueryInspector } from '../../../common/components/page/manage_query';
|
||||
|
@ -18,7 +19,6 @@ import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score
|
|||
import { buildHostNamesFilter, type HostItem } from '../../../../common/search_strategy';
|
||||
import { EntityType } from '../../../../common/entity_analytics/types';
|
||||
import type { DescriptionList } from '../../../../common/utility_types';
|
||||
import { useDarkMode } from '../../../common/lib/kibana';
|
||||
import { getEmptyTagValue } from '../../../common/components/empty_value';
|
||||
import { hostIdRenderer } from '../../../timelines/components/field_renderers/field_renderers';
|
||||
import { DefaultFieldRenderer } from '../../../timelines/components/field_renderers/default_renderer';
|
||||
|
@ -85,7 +85,7 @@ export const HostOverview = React.memo<HostSummaryProps>(
|
|||
}) => {
|
||||
const capabilities = useMlCapabilities();
|
||||
const userPermissions = hasMlUserPermissions(capabilities);
|
||||
const darkMode = useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const filterQuery = useMemo(
|
||||
() => (hostName ? buildHostNamesFilter([hostName]) : undefined),
|
||||
[hostName]
|
||||
|
|
|
@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th
|
|||
import { getOr } from 'lodash/fp';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { buildUserNamesFilter } from '../../../../common/search_strategy';
|
||||
import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_header_title';
|
||||
import { useGlobalTime } from '../../../common/containers/use_global_time';
|
||||
|
@ -18,7 +19,6 @@ import { useQueryInspector } from '../../../common/components/page/manage_query'
|
|||
import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score';
|
||||
import { EntityType } from '../../../../common/entity_analytics/types';
|
||||
import type { DescriptionList } from '../../../../common/utility_types';
|
||||
import { useDarkMode } from '../../../common/lib/kibana';
|
||||
import { getEmptyTagValue } from '../../../common/components/empty_value';
|
||||
import { DefaultFieldRenderer } from '../../../timelines/components/field_renderers/default_renderer';
|
||||
import {
|
||||
|
@ -86,7 +86,7 @@ export const UserOverview = React.memo<UserSummaryProps>(
|
|||
}) => {
|
||||
const capabilities = useMlCapabilities();
|
||||
const userPermissions = hasMlUserPermissions(capabilities);
|
||||
const darkMode = useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
const filterQuery = useMemo(
|
||||
() => (userName ? buildUserNamesFilter([userName]) : undefined),
|
||||
[userName]
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React, { memo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useSymbolIDs } from './use_symbol_ids';
|
||||
import { usePaintServerIDs } from './use_paint_server_ids';
|
||||
|
||||
|
@ -435,7 +435,7 @@ const SymbolsAndShapes = memo(({ id, isDarkMode }: { id: string; isDarkMode: boo
|
|||
*/
|
||||
// eslint-disable-next-line react/display-name
|
||||
export const SymbolDefinitions = memo(({ id }: { id: string }) => {
|
||||
const isDarkMode = useDarkMode();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
return (
|
||||
<HiddenSVG>
|
||||
<defs>
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { EuiIcon, type EuiIconProps } from '@elastic/eui';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import SiemMigrationsIconSVG from './siem_migrations.svg';
|
||||
import SiemMigrationsIconDarkSVG from './siem_migrations_dark.svg';
|
||||
|
||||
export const SiemMigrationsIcon = React.memo<Omit<EuiIconProps, 'type'>>((props) => {
|
||||
const isDark = useDarkMode();
|
||||
const isDark = useKibanaIsDarkMode();
|
||||
if (isDark) {
|
||||
return <EuiIcon type={SiemMigrationsIconDarkSVG} {...props} />;
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ import {
|
|||
EuiBadge,
|
||||
type EuiBasicTableColumn,
|
||||
useEuiTheme,
|
||||
COLOR_MODES_STANDARD,
|
||||
} from '@elastic/eui';
|
||||
import { Chart, BarSeries, Settings, ScaleType } from '@elastic/charts';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { SecurityPageName } from '@kbn/security-solution-navigation';
|
||||
import { AssistantIcon } from '@kbn/ai-assistant-icon';
|
||||
import { useElasticChartsTheme } from '@kbn/charts-theme';
|
||||
|
@ -52,8 +52,8 @@ const headerStyle = css`
|
|||
`;
|
||||
|
||||
const useCompleteBadgeStyles = () => {
|
||||
const { euiTheme, colorMode } = useEuiTheme();
|
||||
const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const isDarkMode = useKibanaIsDarkMode();
|
||||
return css`
|
||||
background-color: ${isDarkMode
|
||||
? euiTheme.colors.success
|
||||
|
|
|
@ -249,5 +249,6 @@
|
|||
"@kbn/actions-types",
|
||||
"@kbn/triggers-actions-ui-types",
|
||||
"@kbn/unified-histogram",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiDataGridCellValueElementProps } from '@elastic/eui';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { euiDarkVars as themeDark, euiLightVars as themeLight } from '@kbn/ui-theme';
|
||||
import { useDarkMode } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
|
||||
import { useStyles } from './styles';
|
||||
import { Indicator } from '../../../../../common/types/indicator';
|
||||
import { IndicatorFieldValue } from '../common/field_value';
|
||||
|
@ -25,7 +25,7 @@ export const cellRendererFactory = (from: number) => {
|
|||
throw new Error('this can only be used inside indicators table');
|
||||
}
|
||||
|
||||
const darkMode = useDarkMode();
|
||||
const darkMode = useKibanaIsDarkMode();
|
||||
|
||||
const { indicators, expanded } = indicatorsTableContext;
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/search-types",
|
||||
"@kbn/response-ops-alerts-fields-browser",
|
||||
"@kbn/charts-theme"
|
||||
"@kbn/charts-theme",
|
||||
"@kbn/react-kibana-context-theme"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue