- Show minimap}
- control={
- editorConfiguration.minimap.enabled = checked}
- />
- }
- />
+ editorConfiguration.minimap.enabled = !editorConfiguration.minimap.enabled}
+ >
+ Show minimap
+
Position
diff --git a/src/renderer/components/+preferences/kubectl-binaries.tsx b/src/renderer/components/+preferences/kubectl-binaries.tsx
index bffc69e3c0..13a0299ee3 100644
--- a/src/renderer/components/+preferences/kubectl-binaries.tsx
+++ b/src/renderer/components/+preferences/kubectl-binaries.tsx
@@ -26,7 +26,7 @@ import { getDefaultKubectlDownloadPath, UserStore } from "../../../common/user-s
import { observer } from "mobx-react";
import { bundledKubectlPath } from "../../../main/kubectl";
import { SelectOption, Select } from "../select";
-import { FormSwitch, Switcher } from "../switch";
+import { Switch } from "../switch";
import { packageMirrors } from "../../../common/user-store/preferences-helpers";
export const KubectlBinaries = observer(() => {
@@ -48,16 +48,12 @@ export const KubectlBinaries = observer(() => {
<>
- userStore.downloadKubectlBinaries = v.target.checked}
- name="kubectl-download"
- />
- }
- label="Download kubectl binaries matching the Kubernetes cluster version"
- />
+ userStore.downloadKubectlBinaries = !userStore.downloadKubectlBinaries}
+ >
+ Download kubectl binaries matching the Kubernetes cluster version
+
diff --git a/src/renderer/components/+preferences/proxy.tsx b/src/renderer/components/+preferences/proxy.tsx
index b85bd5e0e1..f25c1fbc9b 100644
--- a/src/renderer/components/+preferences/proxy.tsx
+++ b/src/renderer/components/+preferences/proxy.tsx
@@ -24,10 +24,11 @@ import React from "react";
import { UserStore } from "../../../common/user-store";
import { Input } from "../input";
import { SubTitle } from "../layout/sub-title";
-import { FormSwitch, Switcher } from "../switch";
+import { Switch } from "../switch";
export const LensProxy = observer(() => {
const [proxy, setProxy] = React.useState(UserStore.getInstance().httpsProxy || "");
+ const store = UserStore.getInstance();
return (
@@ -50,16 +51,9 @@ export const LensProxy = observer(() => {
- UserStore.getInstance().allowUntrustedCAs = v.target.checked}
- name="startup"
- />
- }
- label="Allow untrusted Certificate Authorities"
- />
+ store.allowUntrustedCAs = !store.allowUntrustedCAs}>
+ Allow untrusted Certificate Authorities
+
This will make Lens to trust ANY certificate authority without any validations.{" "}
Needed with some corporate proxies that do certificate re-writing.{" "}
diff --git a/src/renderer/components/switch/__tests__/switch.test.tsx b/src/renderer/components/switch/__tests__/switch.test.tsx
new file mode 100644
index 0000000000..d5187e1417
--- /dev/null
+++ b/src/renderer/components/switch/__tests__/switch.test.tsx
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import React from "react";
+import { fireEvent, render } from "@testing-library/react";
+import "@testing-library/jest-dom/extend-expect";
+import { Switch } from "..";
+
+describe("", () => {
+ it("renders w/o errors", () => {
+ const { container } = render();
+
+ expect(container).toBeInstanceOf(HTMLElement);
+ });
+
+ it("render label text", () => {
+ const { getByLabelText } = render(Test label);
+
+ expect(getByLabelText("Test label")).toBeTruthy();
+ });
+
+ it("passes disabled and checked attributes to input", () => {
+ const { container } = render();
+ const checkbox = container.querySelector("input[type=checkbox]");
+
+ expect(checkbox).toHaveAttribute("disabled");
+ expect(checkbox).toHaveAttribute("checked");
+ });
+
+ it("onClick event fired", () => {
+ const onClick = jest.fn();
+ const { getByTestId } = render();
+ const switcher = getByTestId("switch");
+
+ fireEvent.click(switcher);
+
+ expect(onClick).toHaveBeenCalled();
+ });
+
+ it("onClick event not fired for disabled item", () => {
+ const onClick = jest.fn();
+ const { getByTestId } = render();
+ const switcher = getByTestId("switch");
+
+ fireEvent.click(switcher);
+
+ expect(onClick).not.toHaveBeenCalled();
+ });
+});
diff --git a/src/renderer/components/switch/form-switcher.tsx b/src/renderer/components/switch/form-switcher.tsx
index 14df95f676..6499fb0b0f 100644
--- a/src/renderer/components/switch/form-switcher.tsx
+++ b/src/renderer/components/switch/form-switcher.tsx
@@ -35,6 +35,9 @@ const useStyles = makeStyles({
},
});
+/**
+ * @deprecated Use instead from "../switch.tsx".
+ */
export function FormSwitch(props: FormControlLabelProps) {
const classes = useStyles();
diff --git a/src/renderer/components/switch/index.ts b/src/renderer/components/switch/index.ts
index 60d44f3324..6987ce5b38 100644
--- a/src/renderer/components/switch/index.ts
+++ b/src/renderer/components/switch/index.ts
@@ -21,3 +21,4 @@
export * from "./switcher";
export * from "./form-switcher";
+export * from "./switch";
diff --git a/src/renderer/components/switch/switch.module.scss b/src/renderer/components/switch/switch.module.scss
new file mode 100644
index 0000000000..b890919c61
--- /dev/null
+++ b/src/renderer/components/switch/switch.module.scss
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+.Switch {
+ --thumb-size: 2rem;
+ --thumb-color: hsl(0 0% 100%);
+ --thumb-color-highlight: hsl(0 0% 100% / 25%);
+
+ --track-size: calc(var(--thumb-size) * 2);
+ --track-padding: 2px;
+ --track-color-inactive: hsl(80 0% 35%);
+ --track-color-active: hsl(110, 60%, 60%);
+
+ --thumb-position: 0%;
+ --thumb-transition-duration: .25s;
+
+ --hover-highlight-size: 0;
+
+ display: flex;
+ align-items: center;
+ gap: 2ch;
+ justify-content: space-between;
+ cursor: pointer;
+ user-select: none;
+ color: var(--textColorAccent);
+ font-weight: 500;
+
+ & > input {
+ padding: var(--track-padding);
+ background: var(--track-color-inactive);
+ inline-size: var(--track-size);
+ block-size: var(--thumb-size);
+ border-radius: var(--track-size);
+
+ appearance: none;
+ pointer-events: none;
+ border: none;
+ outline-offset: 5px;
+ box-sizing: content-box;
+
+ flex-shrink: 0;
+ display: grid;
+ align-items: center;
+ grid: [track] 1fr / [track] 1fr;
+
+ transition: background-color .25s ease;
+
+ &::before {
+ content: "";
+ cursor: pointer;
+ pointer-events: auto;
+ grid-area: track;
+ inline-size: var(--thumb-size);
+ block-size: var(--thumb-size);
+ background: var(--thumb-color);
+ box-shadow: 0 0 0 var(--hover-highlight-size) var(--thumb-color-highlight);
+ border-radius: 50%;
+ transform: translateX(var(--thumb-position));
+ transition:
+ transform var(--thumb-transition-duration) ease,
+ box-shadow .25s ease;
+ }
+
+ &:not(:disabled):hover::before {
+ --hover-highlight-size: .5rem;
+ }
+
+ &:checked {
+ background: var(--track-color-active);
+ --thumb-position: 100%;
+ }
+
+ &:disabled {
+ --track-color-inactive: hsl(80 0% 30%);
+ --thumb-color: transparent;
+
+ &::before {
+ cursor: not-allowed;
+ box-shadow: inset 0 0 0 2px hsl(0 0% 0% / 40%);
+ }
+ }
+
+ &:focus-visible {
+ box-shadow: 0 0 0 2px var(--blue);
+ }
+ }
+
+ &.disabled {
+ cursor: not-allowed;
+ }
+}
+
+@include theme-light {
+ .Switch {
+ --thumb-color-highlight: hsl(0 0% 0% / 25%);
+
+ & > input {
+ &:disabled {
+ --track-color-inactive: hsl(80 0% 80%);
+ }
+ }
+ }
+}
diff --git a/src/renderer/components/switch/switch.tsx b/src/renderer/components/switch/switch.tsx
new file mode 100644
index 0000000000..7bf5f2b3be
--- /dev/null
+++ b/src/renderer/components/switch/switch.tsx
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2021 OpenLens Authors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import styles from "./switch.module.scss";
+
+import React, { ChangeEvent, HTMLProps } from "react";
+import { cssNames } from "../../utils";
+
+interface Props extends Omit, "onChange"> {
+ onChange?: (checked: boolean, event: ChangeEvent) => void;
+}
+
+export function Switch({ children, disabled, onChange, ...props }: Props) {
+ return (
+
+ );
+}
diff --git a/src/renderer/components/switch/switcher.tsx b/src/renderer/components/switch/switcher.tsx
index 749e5134c9..136175e394 100644
--- a/src/renderer/components/switch/switcher.tsx
+++ b/src/renderer/components/switch/switcher.tsx
@@ -31,6 +31,9 @@ interface Props extends SwitchProps {
classes: Styles;
}
+/**
+ * @deprecated Use instead from "../switch.tsx".
+ */
export const Switcher = withStyles((theme: Theme) =>
createStyles({
root: {