diff --git a/src/renderer/components/+namespaces/namespace-select.scss b/src/renderer/components/+namespaces/namespace-select.scss index 33293a6d7a..afdd917494 100644 --- a/src/renderer/components/+namespaces/namespace-select.scss +++ b/src/renderer/components/+namespaces/namespace-select.scss @@ -9,16 +9,6 @@ height: var(--font-size); position: absolute; z-index: 20; - - &.front { - left: 0px; - background: linear-gradient(to right, var(--contentColor) 0px, transparent); - } - - &.back { - right: 0px; - background: linear-gradient(to left, var(--contentColor) 0px, transparent); - } } .NamespaceSelect { diff --git a/src/renderer/components/+namespaces/namespace-select.tsx b/src/renderer/components/+namespaces/namespace-select.tsx index d398f91f0a..fd523ef34d 100644 --- a/src/renderer/components/+namespaces/namespace-select.tsx +++ b/src/renderer/components/+namespaces/namespace-select.tsx @@ -1,14 +1,19 @@ import "./namespace-select.scss"; -import React from "react"; -import { computed } from "mobx"; +import Color from "color"; +import { computed, observable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; -import { Select, SelectOption, SelectProps } from "../select"; -import { cssNames } from "../../utils"; -import { Icon } from "../icon"; -import { namespaceStore } from "./namespace.store"; +import React from "react"; +import { findDOMNode } from "react-dom"; +import { components, SelectComponentsConfig, ValueContainerProps } from "react-select"; + import { kubeWatchApi } from "../../api/kube-watch-api"; -import { components, ValueContainerProps } from "react-select"; +import { ThemeStore } from "../../theme.store"; +import { cssNames } from "../../utils"; +import { computeStackingColor } from "../../utils/color"; +import { Icon } from "../icon"; +import { Select, SelectOption, SelectProps } from "../select"; +import { namespaceStore } from "./namespace.store"; interface Props extends SelectProps { showIcons?: boolean; @@ -19,35 +24,70 @@ interface Props extends SelectProps { const defaultProps: Partial = { showIcons: true, - showClusterOption: false, + components: {}, + customizeOptions: (options) => options, }; -function GradientValueContainer({children, ...rest}: ValueContainerProps) { - return ( - -
- {children} -
- - ); +function getGVCStyle(position: "front" | "back", backgroundColor: Color): React.CSSProperties { + const placement = position === "front" ? "left" : "right"; + const direction = position === "front" ? "to right" : "to left"; + + return { + [placement]: "0px", + background: `linear-gradient(${direction}, ${backgroundColor.rgb().toString()} 0px, transparent)`, + }; +} + +function getGVC(trueBackgroundColour: Color): React.FunctionComponent { + return function ({children, ...rest}: ValueContainerProps) { + return ( + +
+ {children} +
+ + ); + }; } @observer export class NamespaceSelect extends React.Component { static defaultProps = defaultProps as object; + @observable ValueContainer?: React.ComponentClass> | React.FunctionComponent; componentDidMount() { + // eslint-disable-next-line react/no-find-dom-node + const elem = findDOMNode(this) as HTMLElement; + + this.ValueContainer = getGVC(computeStackingColor(elem, "backgroundColor")); + disposeOnUnmount(this, [ kubeWatchApi.subscribeStores([namespaceStore], { preload: true, loadOnce: true, // skip reloading namespaces on every render / page visit - }) + }), + ThemeStore.getInstance().onThemeApplied(() => { + this.ValueContainer = getGVC(computeStackingColor(elem, "backgroundColor")); + }), ]); } + @computed get components(): SelectComponentsConfig { + if (!this.ValueContainer) { + return this.props.components; + } + + const { components: { ValueContainer, ...components } } = this.props; + + return { + ...components, + ValueContainer: this.ValueContainer, + }; + } + @computed.struct get options(): SelectOption[] { const { customizeOptions, showClusterOption, showAllNamespacesOption } = this.props; - let options: SelectOption[] = namespaceStore.items.map(ns => ({ value: ns.getName() })); + const options: SelectOption[] = namespaceStore.items.map(ns => ({ value: ns.getName() })); if (showAllNamespacesOption) { options.unshift({ label: "All Namespaces", value: "" }); @@ -55,11 +95,7 @@ export class NamespaceSelect extends React.Component { options.unshift({ label: "Cluster", value: "" }); } - if (customizeOptions) { - options = customizeOptions(options); - } - - return options; + return customizeOptions(options); } formatOptionLabel = (option: SelectOption) => { @@ -75,9 +111,7 @@ export class NamespaceSelect extends React.Component { }; render() { - const { className, showIcons, customizeOptions, components = {}, ...selectProps } = this.props; - - components.ValueContainer ??= GradientValueContainer; + const { className, showIcons, customizeOptions, components, ...selectProps } = this.props; return (