diff --git a/apps/docs/src/pages/components/Playground.tsx b/apps/docs/src/pages/components/Playground.tsx index 4ba1a87564..ae868164b0 100644 --- a/apps/docs/src/pages/components/Playground.tsx +++ b/apps/docs/src/pages/components/Playground.tsx @@ -2,17 +2,23 @@ import React, { useCallback, useState } from "react"; import jsxToString from "react-element-to-jsx-string"; import { CodeEditor } from "react-live-runner"; import { classes } from "@docs/components/code/Live"; +import { css } from "@emotion/css"; import { useData } from "nextra/hooks"; // @ts-ignore import { themes } from "prism-react-renderer"; import { HvCheckBox, HvOption, + HvRadio, + HvRadioGroup, HvSelect, + HvSlider, } from "@hitachivantara/uikit-react-core"; +type ControlType = "radio" | "slider"; + type Control = { - type?: string; + type?: ControlType; defaultValue?: string; values?: string[]; }; @@ -37,7 +43,7 @@ const generateCode = ( .map(([key, value]) => typeof value === "boolean" && value ? key - : "boolean" && !value + : typeof value === "boolean" && !value ? "" : `${key}="${value}"`, ) @@ -45,8 +51,12 @@ const generateCode = ( .trim(); const componentPropsString = Object.entries(componentProps || {}) - .map(([key, value]) => `${key}="${value}"`) - .join(" "); + .map(([key, value]) => { + if (key === "style") return ""; + return typeof value === "boolean" && value ? key : `${key}="${value}"`; + }) + .join(" ") + .trim(); const childrenString = typeof children === "string" @@ -97,14 +107,82 @@ export const Playground = ({ (prop: string, control: Control) => { const propMeta = data?.meta.docgen.props[prop]; - if (!propMeta) return null; + // override control type + if (control.type) { + if (propMeta.type.name === "enum") { + if (control.type === "slider") { + const min = 1; + const max = propMeta.type.value.length; + + const formattedLabel = (label: React.ReactNode) => { + if (!label) return ""; + return propMeta.type.value[ + parseInt(label as string, 10) - 1 + ].value.replace(/"/g, ""); + }; + + return ( + p.value.replace(/"/g, "") === propsState[prop], + ) + 1 || + propMeta.type.value.findIndex( + (p: any) => + p.value.replace(/"/g, "") === control.defaultValue, + ) + 1, + ]} + formatMark={(label) => formattedLabel(label)} + formatTooltip={(label) => formattedLabel(label)} + onChange={(values) => { + handleSelectChange( + null, + prop, + propMeta.type.value[values[0] - 1]?.value.replace(/"/g, ""), + ); + }} + /> + ); + } + if (control.type === "radio") { + return ( + handleSelectChange(e, prop, v)} + classes={{ + root: css({ width: "100%" }), + }} + > + {propMeta.type.value.map((v: any) => { + const value = v.value.replace('"', "").replace('"', ""); + return ; + })} + + ); + } + } + } + // default control types if (propMeta.type.name === "enum") { return ( handleSelectChange(e, prop, value)} > @@ -149,13 +227,13 @@ export const Playground = ({ return ( <> -
-
+
+
{children?.props.children}
-
+
{Object.keys(controls || {}).map((prop) => { const control = controls[prop]; if (!control) return null; diff --git a/apps/docs/src/pages/components/_meta.ts b/apps/docs/src/pages/components/_meta.ts index 83e3ea699e..e0d6d4d2d7 100644 --- a/apps/docs/src/pages/components/_meta.ts +++ b/apps/docs/src/pages/components/_meta.ts @@ -5,5 +5,6 @@ export default { }, avatar: "Avatar", badge: "Badge", + banner: "Banner", button: "Button", }; diff --git a/apps/docs/src/pages/components/avatar.mdx b/apps/docs/src/pages/components/avatar.mdx index 9ecb408e25..4db57a129c 100644 --- a/apps/docs/src/pages/components/avatar.mdx +++ b/apps/docs/src/pages/components/avatar.mdx @@ -8,18 +8,9 @@ import Playground from "./Playground"; import { getComponentData } from "../../utils/utils"; export const getStaticProps = async ({ params }) => { - -const meta = await getComponentData("Avatar", "core", avatarClasses) - -return { -props: { -ssg: { -meta: meta, -}, -}, -} - -} + const meta = await getComponentData("Avatar", "core", avatarClasses); + return { props: { ssg: { meta: meta } } }; +}; @@ -32,9 +23,11 @@ meta: meta, componentName="HvAvatar" controls={{ size: { + type: "slider", defaultValue: "md", }, variant: { + type: "radio", defaultValue: "circular", }, }} diff --git a/apps/docs/src/pages/components/badge.mdx b/apps/docs/src/pages/components/badge.mdx index 5d5bb9ffcb..cda5ea8c88 100644 --- a/apps/docs/src/pages/components/badge.mdx +++ b/apps/docs/src/pages/components/badge.mdx @@ -6,24 +6,15 @@ import { Page } from "@docs/components/Page"; import { getComponentData } from "../../utils/utils"; export const getStaticProps = async ({ params }) => { - -const meta = await getComponentData("Badge", "core", badgeClasses) - -return { -props: { -ssg: { -meta: meta, -}, -}, -} - -} + const meta = await getComponentData("Badge", "core", badgeClasses); + return { props: { ssg: { meta: meta } } }; +}; -### With icon +### Icon Use the `icon` prop to specify a icon to use with the badge. @@ -50,7 +41,7 @@ Use the `maxCount` prop to specify the maximum value to be displayed. Above that ``` -### With text +### Text To display text with the badge you can use the `text` prop along with the `textVariant` prop to specify the typography variant to use. @@ -65,7 +56,7 @@ To display text with the badge you can use the `text` prop along with the `textV ``` -### With state +### Controlled count A badge sample using react hooks to set the number of events. diff --git a/apps/docs/src/pages/components/banner.mdx b/apps/docs/src/pages/components/banner.mdx new file mode 100644 index 0000000000..4ba956f558 --- /dev/null +++ b/apps/docs/src/pages/components/banner.mdx @@ -0,0 +1,125 @@ +import { css } from "@emotion/css"; +import { bannerClasses, HvBanner } from "@hitachivantara/uikit-react-core"; + +import { Description } from "@docs/components/Description"; +import { Page } from "@docs/components/Page"; + +import Playground from "./Playground"; + +import { getComponentData } from "../../utils/utils"; + +export const getStaticProps = async ({ params }) => { + const meta = await getComponentData("Banner", "core", bannerClasses); + return { props: { ssg: { meta: meta } } }; +}; + + + + + + + +### Aactions + +You can add a set of actions to the banner by specifying the `actions` prop. The `onAction` prop is a callback function that is called when an action is clicked. + +```jsx live + console.log("Clicked", action)} + style={{ position: "relative", top: 0 }} +/> +``` + +### Custom icons + +You can pass a custom icon to the banner by using the `customIcon` prop. + +```jsx live +} + style={{ position: "relative", top: 0 }} +/> +``` + +### Controlled + +Controlled banner. Click the buttons to display different banners. + +```jsx live +import { useState } from "react"; + +export default function Demo() { + const SimpleBanner = ({ + variant, + ...others + }: Omit) => { + const [open, setOpen] = useState(false); + + return ( + <> + setOpen(true)} + color="primary" + style={{ width: "150px", textTransform: "capitalize", margin: 10 }} + > + {variant} + + setOpen(false)} + offset={10} + variant={variant} + showIcon + actions={ + + Action + + } + bannerContentProps={{ + actionProps: { "aria-label": "Close the banner" }, + }} + {...others} + /> + + ); + }; + + return ( + <> + + + + + ); + +} +``` + + diff --git a/apps/docs/src/pages/components/button.mdx b/apps/docs/src/pages/components/button.mdx index 9b4fdd03d2..e095063e77 100644 --- a/apps/docs/src/pages/components/button.mdx +++ b/apps/docs/src/pages/components/button.mdx @@ -13,18 +13,9 @@ import Playground from "./Playground"; import { getComponentData } from "../../utils/utils"; export const getStaticProps = async ({ params }) => { - -const meta = await getComponentData("Button", "core", buttonClasses) - -return { -props: { -ssg: { -meta: meta, -}, -}, -} - -} + const meta = await getComponentData("Button", "core", buttonClasses); + return { props: { ssg: { meta: meta } } }; +}; @@ -40,9 +31,11 @@ meta: meta, defaultValue: "primary", }, size: { + type: "slider", defaultValue: "md", }, radius: { + type: "slider", defaultValue: "base", }, disabled: { @@ -69,7 +62,7 @@ meta: meta, ``` -### With icon +### Icon Use the `startIcon` or `endIcon` props to insert an icon on the button. You can also use an icon directly as a child of the `HvButton` component if you only want a clickable icon. In this case it might be useful