(null)
- const handleCopyClick = () => {
- const textToCopy = lang === "json" ? JSON.stringify(content || children) : theCode.current.textContent
- navigator.clipboard.writeText(textToCopy)
+ const handleCopyClick = useCallback(() => {
+ const textToCopy = lang === "json" ? JSON.stringify(content || children) : theCode.current?.textContent
+ if (textToCopy) {
+ navigator.clipboard.writeText(textToCopy).catch(() => {
+ console.warn("Cannot copy text to clipboard")
+ })
+ }
setIsCopied(true)
- clearTimeout(timeoutRef.current) // clear any possibly existing Refs
- timeoutRef.current = setTimeout(() => setIsCopied(false), 1000)
- }
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current) // clear any possibly existing Refs
+ }
+ timeoutRef.current = window.setTimeout(() => setIsCopied(false), 1000)
+ }, [content, children, lang])
return (
- {content || children}
+ {(content || children) as React.ReactNode}
)}
@@ -170,21 +179,23 @@ export const CodeBlock = ({
)
}
-CodeBlock.propTypes = {
+type CodeBlockSize = "auto" | "small" | "medium" | "large"
+
+export interface CodeBlockProps {
/** The content to render. Will override children if passed. */
- content: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
+ content?: string | object
/** The children to render. Will be overridden by content prop if passed as well. */
- children: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),
+ children?: React.ReactNode | object
/** Pass at title to render. Will look like a single tab. */
- heading: PropTypes.string,
+ heading?: string
/** Set whether the code should wrap or not. Default is true. */
- wrap: PropTypes.bool,
+ wrap?: boolean
/** Set the size of the CodeBlock. Default is "auto" */
- size: PropTypes.oneOf(["auto", "small", "medium", "large"]),
+ size?: CodeBlockSize
/** Render a button to copy the code to the clipboard. Defaults to true */
- copy: PropTypes.bool,
+ copy?: boolean
/** Pass a lang prop. Passing "json" will render a fully-featured JsonView. Will also add a data-lang-attribute to the codeblock */
- lang: PropTypes.string,
+ lang?: string
/** Add a custom className to the wrapper of the CodeBlock */
- className: PropTypes.string,
+ className?: string
}
diff --git a/packages/ui-components/src/components/CodeBlock/CodeBlock.stories.js b/packages/ui-components/src/components/CodeBlock/CodeBlock.stories.tsx
similarity index 91%
rename from packages/ui-components/src/components/CodeBlock/CodeBlock.stories.js
rename to packages/ui-components/src/components/CodeBlock/CodeBlock.stories.tsx
index 5df9b1520..b684fc7e1 100644
--- a/packages/ui-components/src/components/CodeBlock/CodeBlock.stories.js
+++ b/packages/ui-components/src/components/CodeBlock/CodeBlock.stories.tsx
@@ -4,12 +4,11 @@
*/
import React from "react"
-import PropTypes from "prop-types"
-import { CodeBlock } from "./index.js"
-import { Tabs } from "../../deprecated_js/Tabs/index.js"
-import { TabList } from "../../deprecated_js/TabList/index.js"
-import { Tab } from "../../deprecated_js/Tab/index.js"
-import { TabPanel } from "../../deprecated_js/TabPanel/index.js"
+import { CodeBlock } from "."
+import { Tabs } from "../Tabs"
+import { TabList } from "../TabList"
+import { Tab } from "../Tab"
+import { TabPanel } from "../TabPanel"
const TabStory = {
args: {
@@ -32,7 +31,7 @@ export default {
},
}
-const TabsTemplate = ({ tabs, codeBlocks }) => (
+const TabsTemplate = ({ tabs, codeBlocks }: TabsTemplateProps) => (
{tabs.map((tab, t) => (
@@ -47,9 +46,9 @@ const TabsTemplate = ({ tabs, codeBlocks }) => (
)
-TabsTemplate.propTypes = {
- tabs: PropTypes.array,
- codeBlocks: PropTypes.array,
+interface TabsTemplateProps {
+ tabs: (typeof Tab)[]
+ codeBlocks: (typeof CodeBlock)[]
}
export const Default = {
diff --git a/packages/ui-components/src/components/CodeBlock/CodeBlock.test.js b/packages/ui-components/src/components/CodeBlock/CodeBlock.test.tsx
similarity index 85%
rename from packages/ui-components/src/components/CodeBlock/CodeBlock.test.js
rename to packages/ui-components/src/components/CodeBlock/CodeBlock.test.tsx
index 752b09782..05c65fee8 100644
--- a/packages/ui-components/src/components/CodeBlock/CodeBlock.test.js
+++ b/packages/ui-components/src/components/CodeBlock/CodeBlock.test.tsx
@@ -5,31 +5,31 @@
import * as React from "react"
import { render, screen } from "@testing-library/react"
-import { CodeBlock } from "./index"
+import { CodeBlock } from "."
describe("CodeBlock", () => {
- test("renders a CodeBlock with content as passed", async () => {
+ test("renders a CodeBlock with content as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("juno-code-block")
expect(screen.getByTestId("codeblock")).toHaveTextContent("some example code")
})
- test("renders a CodeBlock with children as passed", async () => {
+ test("renders a CodeBlock with children as passed", () => {
render({"some children here"})
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("juno-code-block")
expect(screen.getByTestId("codeblock")).toHaveTextContent("some children here")
})
- test("renders a CodeBlock with a lang attribute as passed", async () => {
+ test("renders a CodeBlock with a lang attribute as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("juno-code-block")
expect(screen.getByTestId("codeblock")).toHaveAttribute("data-lang", "javascript")
})
- test("renders a wrapping CodeBlock by default", async () => {
+ test("renders a wrapping CodeBlock by default", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("juno-code-block")
@@ -39,7 +39,7 @@ describe("CodeBlock", () => {
expect(document.querySelector("pre")).not.toHaveClass("jn-overflow-x-auto")
})
- test("renders a non-wrapping CodeBlock as passed", async () => {
+ test("renders a non-wrapping CodeBlock as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("juno-code-block")
@@ -49,7 +49,7 @@ describe("CodeBlock", () => {
expect(document.querySelector("pre")).toHaveClass("jn-overflow-x-auto")
})
- test("renders a CodeBlock without height restrictions by default", async () => {
+ test("renders a CodeBlock without height restrictions by default", () => {
render()
expect(document.querySelector("pre")).toBeInTheDocument()
expect(document.querySelector("pre")).not.toHaveClass("juno-codeblock-pre-small")
@@ -57,7 +57,7 @@ describe("CodeBlock", () => {
expect(document.querySelector("pre")).not.toHaveClass("juno-codeblock-pre-large")
})
- test("renders a small sized CodeBlock as passed", async () => {
+ test("renders a small sized CodeBlock as passed", () => {
render()
expect(document.querySelector("pre")).toBeInTheDocument()
expect(document.querySelector("pre")).toHaveClass("juno-codeblock-pre-small")
@@ -65,7 +65,7 @@ describe("CodeBlock", () => {
expect(document.querySelector("pre")).not.toHaveClass("juno-codeblock-pre-large")
})
- test("renders a medium sized CodeBlock as passed", async () => {
+ test("renders a medium sized CodeBlock as passed", () => {
render()
expect(document.querySelector("pre")).toBeInTheDocument()
expect(document.querySelector("pre")).not.toHaveClass("juno-codeblock-pre-small")
@@ -73,14 +73,14 @@ describe("CodeBlock", () => {
expect(document.querySelector("pre")).not.toHaveClass("juno-codeblock-pre-large")
})
- test("renders a heading as passed", async () => {
+ test("renders a heading as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(document.querySelector(".juno-codeblock-heading")).toBeInTheDocument()
expect(document.querySelector(".juno-codeblock-heading")).toHaveTextContent("Look, a CodeBlock!")
})
- test("renders a JSONView as passed", async () => {
+ test("renders a JSONView as passed", () => {
const testJson = {
someKey: "some value",
someOtherKey: 12,
@@ -92,7 +92,7 @@ describe("CodeBlock", () => {
expect(document.querySelector("[data-json-viewer]")).toBeInTheDocument()
})
- test("renders a JSONView as passed with children", async () => {
+ test("renders a JSONView as passed with children", () => {
const testObj = {
someKey: "some value",
someOtherKey: 12,
@@ -108,18 +108,18 @@ describe("CodeBlock", () => {
expect(document.querySelector("[data-json-viewer]")).toBeInTheDocument()
})
- test("renders a CodeBlock with a Copy button by default", async () => {
+ test("renders a CodeBlock with a Copy button by default", () => {
render()
expect(screen.getByRole("button", { name: "contentCopy" })).toBeInTheDocument()
})
- test("renders a CodeBlock with className as passed", async () => {
+ test("renders a CodeBlock with className as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveClass("my-class")
})
- test("renders a CodeBlock with all props as passed", async () => {
+ test("renders a CodeBlock with all props as passed", () => {
render()
expect(screen.getByTestId("codeblock")).toBeInTheDocument()
expect(screen.getByTestId("codeblock")).toHaveAttribute("data-lolol", "code-lang-js")
diff --git a/packages/ui-components/src/components/CodeBlock/index.js b/packages/ui-components/src/components/CodeBlock/index.ts
similarity index 71%
rename from packages/ui-components/src/components/CodeBlock/index.js
rename to packages/ui-components/src/components/CodeBlock/index.ts
index 70d649657..c3b9ee86c 100644
--- a/packages/ui-components/src/components/CodeBlock/index.js
+++ b/packages/ui-components/src/components/CodeBlock/index.ts
@@ -3,4 +3,4 @@
* SPDX-License-Identifier: Apache-2.0
*/
-export { CodeBlock } from "./CodeBlock.component.js"
+export { CodeBlock } from "./CodeBlock.component"
diff --git a/packages/ui-components/src/components/ComboBox/ComboBox.test.js b/packages/ui-components/src/components/ComboBox/ComboBox.test.js
index d165de214..26f85447e 100644
--- a/packages/ui-components/src/components/ComboBox/ComboBox.test.js
+++ b/packages/ui-components/src/components/ComboBox/ComboBox.test.js
@@ -7,7 +7,7 @@ import * as React from "react"
import { cleanup, render, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { ComboBox } from "./index"
-import { AppShellProvider } from "../AppShellProvider/index"
+import { AppShellProvider } from "../../deprecated_js/AppShellProvider/index"
import { ComboBoxOption } from "../ComboBoxOption/index"
const mockOnBlur = jest.fn()
diff --git a/packages/ui-components/src/components/ComboBoxOption/ComboBoxOption.test.js b/packages/ui-components/src/components/ComboBoxOption/ComboBoxOption.test.js
index 8aac13416..06e2cfc65 100644
--- a/packages/ui-components/src/components/ComboBoxOption/ComboBoxOption.test.js
+++ b/packages/ui-components/src/components/ComboBoxOption/ComboBoxOption.test.js
@@ -5,7 +5,7 @@
import * as React from "react"
import { cleanup, render, screen, waitFor } from "@testing-library/react"
-import { AppShellProvider } from "../AppShellProvider"
+import { AppShellProvider } from "../../deprecated_js/AppShellProvider"
import userEvent from "@testing-library/user-event"
import { ComboBox } from "../ComboBox/ComboBox.component"
import { ComboBoxOption } from "../ComboBoxOption/ComboBoxOption.component"
diff --git a/packages/ui-components/src/components/DateTimePicker/DateTimePicker.test.js b/packages/ui-components/src/components/DateTimePicker/DateTimePicker.test.js
index 0c5f91e98..c0bcef8da 100644
--- a/packages/ui-components/src/components/DateTimePicker/DateTimePicker.test.js
+++ b/packages/ui-components/src/components/DateTimePicker/DateTimePicker.test.js
@@ -7,7 +7,7 @@ import React from "react"
import { cleanup, render, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { DateTimePicker } from "./index"
-import { AppShellProvider } from "../AppShellProvider"
+import { AppShellProvider } from "../../deprecated_js/AppShellProvider"
const mockOnOpen = jest.fn()
const mockOnClear = jest.fn()
diff --git a/packages/ui-components/src/components/JsonViewer/JsonViewer.component.tsx b/packages/ui-components/src/components/JsonViewer/JsonViewer.component.tsx
index 921a5a91c..055fbfa23 100644
--- a/packages/ui-components/src/components/JsonViewer/JsonViewer.component.tsx
+++ b/packages/ui-components/src/components/JsonViewer/JsonViewer.component.tsx
@@ -410,7 +410,7 @@ type ThemeType = "dark" | "light"
export interface JsonViewerProps extends Omit, "data"> {
/** Pass a valid json. Required. */
// data: PropTypes.object.isRequired,
- data: object | object[]
+ data: string | object | object[]
/** pass a styles object */
style?: object
/** show toolbar */
diff --git a/packages/ui-components/src/components/StyleProvider/StyleProvider.component.tsx b/packages/ui-components/src/components/StyleProvider/StyleProvider.component.tsx
index 61b146393..66db9c1d2 100644
--- a/packages/ui-components/src/components/StyleProvider/StyleProvider.component.tsx
+++ b/packages/ui-components/src/components/StyleProvider/StyleProvider.component.tsx
@@ -29,7 +29,7 @@ export interface StyleContextProps {
const StylesContext = createContext(undefined)
const APP_BODY_CSS_CLASS_NAME = "juno-app-body"
-const DEFAULT_THEME_NAME = "theme-dark"
+export const DEFAULT_THEME_NAME = "theme-dark"
/**
* Component that inserts the ui styles and manages theming and styles.
@@ -149,7 +149,7 @@ export interface StyleProviderProps {
/** What element to render as a wrapper, respectively where to render the StyleProvider. */
stylesWrapper?: StyleProviderStylesWrapper
/** The name of the theme to render. */
- theme?: string
+ theme?: string | null
/** The mode of the shadowRoot. Only relevant when `stylesWrapper="shadowRoot"`. */
shadowRootMode?: ShadowRootMode
}
diff --git a/packages/ui-components/src/components/AppShellProvider/AppShellProvider.component.js b/packages/ui-components/src/deprecated_js/AppShellProvider/AppShellProvider.component.js
similarity index 94%
rename from packages/ui-components/src/components/AppShellProvider/AppShellProvider.component.js
rename to packages/ui-components/src/deprecated_js/AppShellProvider/AppShellProvider.component.js
index f86e0e05f..f275fbaae 100644
--- a/packages/ui-components/src/components/AppShellProvider/AppShellProvider.component.js
+++ b/packages/ui-components/src/deprecated_js/AppShellProvider/AppShellProvider.component.js
@@ -6,7 +6,7 @@
import React from "react"
import PropTypes from "prop-types"
-import { StyleProvider } from "../../deprecated_js/StyleProvider/StyleProvider.component"
+import { StyleProvider } from "../StyleProvider/StyleProvider.component"
import { ShadowRoot } from "../../deprecated_js/ShadowRoot/ShadowRoot.component"
import { PortalProvider } from "../../deprecated_js/PortalProvider/PortalProvider.component"
diff --git a/packages/ui-components/src/components/AppShellProvider/AppShellProvider.test.js b/packages/ui-components/src/deprecated_js/AppShellProvider/AppShellProvider.test.js
similarity index 100%
rename from packages/ui-components/src/components/AppShellProvider/AppShellProvider.test.js
rename to packages/ui-components/src/deprecated_js/AppShellProvider/AppShellProvider.test.js
diff --git a/packages/ui-components/src/deprecated_js/AppShellProvider/index.js b/packages/ui-components/src/deprecated_js/AppShellProvider/index.js
new file mode 100644
index 000000000..3af34f51c
--- /dev/null
+++ b/packages/ui-components/src/deprecated_js/AppShellProvider/index.js
@@ -0,0 +1,6 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { AppShellProvider } from "./AppShellProvider.component"
diff --git a/packages/ui-components/src/index.js b/packages/ui-components/src/index.js
index f83a13d6f..4b18cf042 100644
--- a/packages/ui-components/src/index.js
+++ b/packages/ui-components/src/index.js
@@ -7,7 +7,7 @@ import "./global.scss"
export { AppBody } from "./components/AppBody/index.js"
export { AppIntro } from "./components/AppIntro/index.js"
export { AppShell } from "./components/AppShell/index.js"
-export { AppShellProvider } from "./components/AppShellProvider/index.js"
+export { AppShellProvider } from "./deprecated_js/AppShellProvider/index"
export { Badge } from "./components/Badge"
export { Box } from "./components/Box"
export { Breadcrumb } from "./components/Breadcrumb"
@@ -18,7 +18,7 @@ export { Checkbox } from "./components/Checkbox/index"
export { CheckboxRow } from "./components/CheckboxRow/index.js"
export { CheckboxGroup } from "./components/CheckboxGroup/index.js"
export { Code } from "./components/Code/index.js"
-export { CodeBlock } from "./components/CodeBlock/index.js"
+export { CodeBlock } from "./components/CodeBlock/index"
export { ComboBox } from "./components/ComboBox/index.js"
export { ComboBoxOption } from "./components/ComboBoxOption/index.js"
export { ContentArea } from "./components/ContentArea/index.js"