diff --git a/.vscode/settings.json b/.vscode/settings.json index a0ca001e..4b95a89c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "Checkmark", "csstools", "frontmatter", + "hljs", "Killa", "nextjs", "omni", diff --git a/docs/app/components/PageLayout.tsx b/docs/app/components/PageLayout.tsx index 0d4b46db..af4c3dd3 100644 --- a/docs/app/components/PageLayout.tsx +++ b/docs/app/components/PageLayout.tsx @@ -136,6 +136,7 @@ export function TabPageContentSections(
{props.children} diff --git a/docs/app/components/code-builder/builder-form.tsx b/docs/app/components/code-builder/builder-form.tsx new file mode 100644 index 00000000..99b74531 --- /dev/null +++ b/docs/app/components/code-builder/builder-form.tsx @@ -0,0 +1,103 @@ +'use client' + +import { vstack } from '@cerberus/styled-system/patterns' +import type { + BooleanResult, + BuilderResult, + EnumResult, + TextResult, +} from './helpers' +import { Field, Label, Show } from '@cerberus-design/react' +import { lazy, useCallback, type ChangeEvent } from 'react' +import { useCodeBuilder } from '@/app/context/code-builder' +import { css } from '@cerberus/styled-system/css' + +const Select = lazy(() => import('./builder-select')) +const Input = lazy(() => import('./builder-input')) +const Toggle = lazy(() => import('./builder-toggle')) + +interface BuilderFormProps { + api: Record +} + +export default function BuilderForm(props: BuilderFormProps) { + const { selectedProps, setSelectedProps } = useCodeBuilder() + + const handleInputChange = useCallback( + (e: ChangeEvent) => { + setSelectedProps(e.currentTarget.name, e.currentTarget.value) + }, + [setSelectedProps], + ) + + const handleSelectChange = useCallback( + (e: ChangeEvent) => { + setSelectedProps(e.currentTarget.name, e.currentTarget.value) + }, + [setSelectedProps], + ) + + const handleToggleChange = useCallback( + (e: ChangeEvent) => { + setSelectedProps(e.currentTarget.name, e.currentTarget.checked) + }, + [setSelectedProps], + ) + + return ( +
+ {Object.keys(props.api).map((key) => ( +
+ + + + + + + + + +
+ ))} +
+ ) +} diff --git a/docs/app/components/code-builder/builder-input.tsx b/docs/app/components/code-builder/builder-input.tsx new file mode 100644 index 00000000..0212841b --- /dev/null +++ b/docs/app/components/code-builder/builder-input.tsx @@ -0,0 +1,15 @@ +'use client' + +import { Input, type InputProps } from '@cerberus-design/react' +import type { TextResult } from './helpers' + +interface BuilderInputProps + extends Omit, + TextResult { + selectedValue: string +} + +export default function BuilderInput(props: BuilderInputProps) { + const { selectedValue, ...nativeProps } = props + return +} diff --git a/docs/app/components/code-builder/builder-layout.tsx b/docs/app/components/code-builder/builder-layout.tsx new file mode 100644 index 00000000..8fde6129 --- /dev/null +++ b/docs/app/components/code-builder/builder-layout.tsx @@ -0,0 +1,87 @@ +import { Show } from '@cerberus-design/react' +import { css, cx } from '@cerberus/styled-system/css' +import { cq, hstack, vstack } from '@cerberus/styled-system/patterns' +import { type PropsWithChildren } from 'react' +import BuilderSidebar from './builder-sidebar' +import type { BuilderResult } from './helpers' +import BuilderForm from './builder-form' +import BuilderSnippet from './builder-snippet' + +interface CodeBuilderProps { + api: Record + code?: string +} + +export default function BuilderLayout( + props: PropsWithChildren, +) { + return ( +
+
+
+ {props.children} +
+ + +

+ Preview Playground +

+ + +
+
+ + +
+ +
+
+
+ ) +} diff --git a/docs/app/components/code-builder/builder-select.tsx b/docs/app/components/code-builder/builder-select.tsx new file mode 100644 index 00000000..1e81d4b6 --- /dev/null +++ b/docs/app/components/code-builder/builder-select.tsx @@ -0,0 +1,35 @@ +import { type SelectHTMLAttributes } from 'react' +import type { EnumResult } from './helpers' +import { css } from '@cerberus/styled-system/css' +import { focusStates } from '@cerberus-design/panda-preset' + +type BuilderSelectProps = Omit & + SelectHTMLAttributes & { + options: string[] + } + +export default function BuilderSelect(props: BuilderSelectProps) { + const { options, ...nativeProps } = props + return ( + + ) +} diff --git a/docs/app/components/code-builder/builder-sidebar.tsx b/docs/app/components/code-builder/builder-sidebar.tsx new file mode 100644 index 00000000..2347c180 --- /dev/null +++ b/docs/app/components/code-builder/builder-sidebar.tsx @@ -0,0 +1,41 @@ +import { css, cx } from '@cerberus/styled-system/css' +import { scrollable } from '@cerberus/styled-system/patterns' +import type { PropsWithChildren } from 'react' + +interface BuilderSidebarProps {} + +export default function BuilderSidebar( + props: PropsWithChildren, +) { + return ( +
+
{props.children}
+
+ ) +} diff --git a/docs/app/components/code-builder/builder-snippet.tsx b/docs/app/components/code-builder/builder-snippet.tsx new file mode 100644 index 00000000..bea0a45c --- /dev/null +++ b/docs/app/components/code-builder/builder-snippet.tsx @@ -0,0 +1,48 @@ +'use client' + +import SyntaxHighlighter from 'react-syntax-highlighter' +import { nightOwl } from 'react-syntax-highlighter/dist/esm/styles/hljs' +import { useCodeBuilder } from '@/app/context/code-builder' +import { useMemo, type PropsWithChildren } from 'react' +import { css } from '@cerberus/styled-system/css' + +interface BuilderSnippetProps { + code: string +} + +export default function BuilderSnippet( + props: PropsWithChildren, +) { + const { selectedProps } = useCodeBuilder() + const code = useMemo(() => { + return props.code.replace(/{{([^}]+)}}/g, (_, key): string => { + if (key === 'text') { + return (selectedProps[key as keyof typeof selectedProps] || + 'Add Text') as string + } + if (key === 'disabled') { + return `{${selectedProps[key as keyof typeof selectedProps] || 'false'}}` + } + return `"${selectedProps[key as keyof typeof selectedProps] || 'false'}"` + }) + }, [props.code, selectedProps]) + + return ( + + {code} + + ) +} diff --git a/docs/app/components/code-builder/builder-toggle.tsx b/docs/app/components/code-builder/builder-toggle.tsx new file mode 100644 index 00000000..295e4da3 --- /dev/null +++ b/docs/app/components/code-builder/builder-toggle.tsx @@ -0,0 +1,25 @@ +'use client' + +import { Toggle, useToggle, type ToggleProps } from '@cerberus-design/react' +import type { BooleanResult } from './helpers' + +interface BuilderToggleProps + extends Omit, + BooleanResult {} + +export default function BuilderToggle(props: BuilderToggleProps) { + const { onChange, ...nativeProps } = props + const { checked, handleChange } = useToggle({ + checked: nativeProps.value ? nativeProps.name : '', + onChange, + }) + + return ( + + ) +} diff --git a/docs/app/components/code-builder/code-builder.tsx b/docs/app/components/code-builder/code-builder.tsx new file mode 100644 index 00000000..52d74e7a --- /dev/null +++ b/docs/app/components/code-builder/code-builder.tsx @@ -0,0 +1,21 @@ +import { type PropsWithChildren } from 'react' +import CodeBuilderProvider from '../../context/code-builder' +import type { BuilderResult } from './helpers' +import BuilderLayout from './builder-layout' + +interface CodeBuilderProps { + api: Record + code?: string +} + +export default function CodeBuilder( + props: PropsWithChildren, +) { + return ( + + + {props.children} + + + ) +} diff --git a/docs/app/components/code-builder/helpers.ts b/docs/app/components/code-builder/helpers.ts new file mode 100644 index 00000000..2a51316d --- /dev/null +++ b/docs/app/components/code-builder/helpers.ts @@ -0,0 +1,49 @@ +export interface EnumResult { + name: string + type: 'enum' + value: string[] +} + +function Enum(name: string, value: string[]): EnumResult { + return { + name, + type: 'enum', + value, + } +} + +export interface TextResult { + name: string + type: 'text' + value: string +} + +function Text(name: string, value: string): TextResult { + return { + name, + type: 'text', + value, + } +} + +export interface BooleanResult { + name: string + type: 'boolean' + value: boolean +} + +function Boolean(name: string, value: boolean): BooleanResult { + return { + name, + type: 'boolean', + value, + } +} + +export type BuilderResult = EnumResult | TextResult | BooleanResult + +export const builder = { + Boolean, + Enum, + Text, +} diff --git a/docs/app/context/code-builder.tsx b/docs/app/context/code-builder.tsx new file mode 100644 index 00000000..e079e694 --- /dev/null +++ b/docs/app/context/code-builder.tsx @@ -0,0 +1,76 @@ +'use client' + +import { + createContext, + useCallback, + useContext, + useMemo, + useState, + type PropsWithChildren, +} from 'react' +import type { BuilderResult } from '../components/code-builder/helpers' + +function getInitialAPIValues(api: Record, key: string) { + const result = api[key] + switch (result.type) { + case 'enum': + return result.value[0] + case 'text': + return result.value + case 'boolean': + return false + } +} + +interface CodeBuilderContextValue { + selectedProps: Record + setSelectedProps: (key: string, value: boolean | string) => void +} + +const CodeBuilderContext = createContext(null) + +interface CodeBuilderProviderProps { + api: Record +} + +export default function CodeBuilderProvider( + props: PropsWithChildren, +) { + const [selectedProps, setSelectedProps] = useState< + Record + >(() => { + return Object.keys(props.api).reduce( + (acc, key) => ({ ...acc, [key]: getInitialAPIValues(props.api, key) }), + {}, + ) + }) + + const handleChange = useCallback( + (key: string, value: boolean | string) => { + setSelectedProps((prev) => ({ + ...prev, + [key]: value, + })) + }, + [setSelectedProps], + ) + + const value = useMemo( + () => ({ selectedProps, setSelectedProps: handleChange }), + [selectedProps, handleChange], + ) + + return ( + + {props.children} + + ) +} + +export function useCodeBuilder() { + const context = useContext(CodeBuilderContext) + if (!context) { + throw new Error('useCodeBuilder must be used within a CodeBuilderProvider') + } + return context +} diff --git a/docs/app/global.d.ts b/docs/app/global.d.ts index 998ac6a8..d3e53dd3 100644 --- a/docs/app/global.d.ts +++ b/docs/app/global.d.ts @@ -1,4 +1,6 @@ declare module 'color-space' +declare module 'react-syntax-highlighter' +declare module 'react-syntax-highlighter/dist/esm/styles/hljs' declare module '*.mdx' { let MDXComponent: (props: any) => JSX.Element diff --git a/docs/app/react/button/components/button-preview.tsx b/docs/app/react/button/components/button-preview.tsx index bac49f97..c12f7c32 100644 --- a/docs/app/react/button/components/button-preview.tsx +++ b/docs/app/react/button/components/button-preview.tsx @@ -1,7 +1,9 @@ +'use client' + +import { Fragment } from 'react' import { Button } from '@cerberus-design/react' import { ArrowDownRight } from '@cerberus-design/icons' import { css } from '@cerberus/styled-system/css' -import { Fragment } from 'react' import { grid, gridItem } from '@cerberus/styled-system/patterns' export function BasicButtonPreview() { diff --git a/docs/app/react/button/components/live-playground.tsx b/docs/app/react/button/components/live-playground.tsx new file mode 100644 index 00000000..50aa94c7 --- /dev/null +++ b/docs/app/react/button/components/live-playground.tsx @@ -0,0 +1,71 @@ +'use client' + +import CodeBuilder from '@/app/components/code-builder/code-builder' +import { builder } from '@/app/components/code-builder/helpers' +import { useCodeBuilder } from '@/app/context/code-builder' +import { Button } from '@cerberus-design/react' + +const api = { + palette: builder.Enum('palette', ['action', 'secondaryAction', 'danger']), + usage: builder.Enum('usage', ['filled', 'outlined', 'text']), + shape: builder.Enum('shape', ['sharp', 'rounded']), + text: builder.Text('name', 'Button'), + disabled: builder.Boolean('disabled', false), +} + +export function LivePlayground() { + return ( + + + + ) +} + +export function LivePlaygroundWithCode() { + return ( + + {{text}} + + ) +}`} + > + + + ) +} + +export function ButtonPreview() { + const { selectedProps } = useCodeBuilder() + switch (selectedProps.palette) { + case 'secondaryAction': + return ( + + ) + case 'danger': + return ( + + ) + + default: + return ( + + ) + } +} diff --git a/docs/app/react/button/dev.mdx b/docs/app/react/button/dev.mdx index c461b54f..079c34fa 100644 --- a/docs/app/react/button/dev.mdx +++ b/docs/app/react/button/dev.mdx @@ -6,14 +6,13 @@ recipe: 'button.ts' import CodePreview from '@/app/components/CodePreview' import { - BasicButtonPreview, - DangerButtonPreview, - OutlineButtonPreview, - TextButtonPreview, - RoundedButtonPreview, + // DEPRECATED WithIconButtonPreview, CustomButtonPreview, } from '@/app/react/button/components/button-preview' +import { + LivePlaygroundWithCode, +} from '@/app/react/button/components/live-playground' ```ts import { Button } from '@cerberus-design/react' @@ -23,65 +22,7 @@ import { Button } from '@cerberus-design/react' You can mix and match all of the examples to create the button style of your choosing. -### Default - -}> -```tsx title="button.tsx" -import { Button } from '@cerberus-design/react' - -function BasicButton() { - return -} -``` - - -### Danger - -}> -```tsx title="button.tsx" -import { Button } from '@cerberus-design/react' - -function DangerButton() { - -} -``` - - -### Outlined - -}> -```tsx title="button.tsx" -import { Button } from '@cerberus-design/react' - -function OutlinedButton() { - return -} -``` - - -### Text - -}> -```tsx title="button.tsx" -import { Button } from '@cerberus-design/react' - -function TextButton() { - return -} -``` - - -### Rounded - -}> -```tsx title="button.tsx" -import { Button } from '@cerberus-design/react' - -function RoundedButton() { - return -} -``` - + ### With Icon @@ -132,7 +73,7 @@ function CustomButton() { ```ts showLineNumbers=false export interface ButtonProps extends ButtonHTMLAttributes { - palette?: 'action' | 'danger' + palette?: 'action' | 'secondaryAction' | 'danger' usage?: 'filled' | 'outlined' | 'text' shape?: 'sharp' | 'rounded' } diff --git a/docs/app/react/button/overview.mdx b/docs/app/react/button/overview.mdx index 4d4e355b..e9cf81ac 100644 --- a/docs/app/react/button/overview.mdx +++ b/docs/app/react/button/overview.mdx @@ -7,8 +7,11 @@ a11y: 'touch-target' import CodePreview from '@/app/components/CodePreview' import OverviewList from '@/app/components/OverviewList' import { - OverviewButtonPreview + OverviewButtonPreview, } from '@/app/react/button/components/button-preview' +import { + LivePlayground, +} from '@/app/react/button/components/live-playground' } /> + ## Resources diff --git a/docs/package.json b/docs/package.json index 8f4a25cd..cf137768 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,6 +17,7 @@ "next": "14.2.7", "react": "^18", "react-dom": "^18", + "react-syntax-highlighter": "^15.5.0", "remove": "^0.1.5" }, "devDependencies": { diff --git a/packages/panda-preset/src/recipes/button.ts b/packages/panda-preset/src/recipes/button.ts index 383addf8..91652834 100644 --- a/packages/panda-preset/src/recipes/button.ts +++ b/packages/panda-preset/src/recipes/button.ts @@ -59,6 +59,18 @@ export const button: RecipeConfig = defineRecipe({ }, }, + compoundVariants: [ + { + palette: 'danger', + usage: 'filled', + css: { + _hover: { + color: 'colorPalette.text.inverse', + }, + }, + }, + ], + defaultVariants: { palette: 'action', usage: 'filled', diff --git a/packages/panda-preset/src/recipes/shared/button.base.ts b/packages/panda-preset/src/recipes/shared/button.base.ts index e9579460..41cb073b 100644 --- a/packages/panda-preset/src/recipes/shared/button.base.ts +++ b/packages/panda-preset/src/recipes/shared/button.base.ts @@ -41,7 +41,6 @@ export const nonTextStates = { } export const textUsage = { - colorPalette: 'secondaryAction', bgColor: 'transparent', border: 'none', color: textInitial, @@ -50,6 +49,7 @@ export const textUsage = { transitionTimingFunction: 'ease-in-out', _hover: { bgColor: 'colorPalette.ghost.hover', + color: 'colorPalette.text.200', }, _active: { bgColor: 'colorPalette.ghost.active', @@ -87,10 +87,4 @@ export const outlinedUsage = { export const buttonPalettes = { ...actionPalettes, ...statePalettes, - danger: { - ...statePalettes.danger, - _hover: { - color: 'danger.text.inverse', - }, - }, } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb65fefc..7b215fad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,6 +103,9 @@ importers: react-dom: specifier: ^18 version: 18.3.1(react@18.3.1) + react-syntax-highlighter: + specifier: ^15.5.0 + version: 15.5.0(react@18.3.1) remove: specifier: ^0.1.5 version: 0.1.5 @@ -1684,9 +1687,6 @@ packages: '@types/eslint@8.56.10': resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -1699,6 +1699,9 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -2313,12 +2316,21 @@ packages: character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} @@ -2386,6 +2398,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -2904,6 +2919,9 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} @@ -3167,6 +3185,9 @@ packages: hast-util-is-element@3.0.0: resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} @@ -3197,12 +3218,18 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + hastscript@8.0.0: resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} hastscript@9.0.0: resolution: {integrity: sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==} + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -3262,9 +3289,15 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} @@ -3314,6 +3347,9 @@ packages: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -3344,6 +3380,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} @@ -3730,6 +3769,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + lru-cache@10.2.0: resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} engines: {node: 14 || >=16.14} @@ -4157,6 +4199,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} @@ -4398,6 +4443,14 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + + prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -4405,6 +4458,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} @@ -4439,6 +4495,11 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-syntax-highlighter@15.5.0: + resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} + peerDependencies: + react: '>= 0.14.0' + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -4459,6 +4520,9 @@ packages: resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} engines: {node: '>= 0.4'} + refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -4676,6 +4740,9 @@ packages: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -5182,6 +5249,10 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -6781,7 +6852,7 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: - '@types/eslint': 9.6.1 + '@types/eslint': 8.56.10 '@types/estree': 1.0.5 '@types/eslint@8.56.10': @@ -6789,11 +6860,6 @@ snapshots: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.5 - '@types/json-schema': 7.0.15 - '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.5 @@ -6814,6 +6880,10 @@ snapshots: '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.10 + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.2 @@ -7581,10 +7651,16 @@ snapshots: character-entities-html4@2.1.0: {} + character-entities-legacy@1.1.4: {} + character-entities-legacy@3.0.0: {} + character-entities@1.2.4: {} + character-entities@2.0.2: {} + character-reference-invalid@1.1.4: {} + character-reference-invalid@2.0.1: {} chokidar@3.6.0: @@ -7646,6 +7722,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@1.0.8: {} + comma-separated-tokens@2.0.3: {} commander@11.1.0: {} @@ -8466,6 +8544,10 @@ snapshots: dependencies: reusify: 1.0.4 + fault@1.0.4: + dependencies: + format: 0.2.2 + fault@2.0.1: dependencies: format: 0.2.2 @@ -8753,6 +8835,8 @@ snapshots: dependencies: '@types/hast': 3.0.4 + hast-util-parse-selector@2.2.5: {} + hast-util-parse-selector@4.0.0: dependencies: '@types/hast': 3.0.4 @@ -8873,6 +8957,14 @@ snapshots: dependencies: '@types/hast': 3.0.4 + hastscript@6.0.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + hastscript@8.0.0: dependencies: '@types/hast': 3.0.4 @@ -8889,6 +8981,8 @@ snapshots: property-information: 6.5.0 space-separated-tokens: 2.0.2 + highlight.js@10.7.3: {} + hookable@5.5.3: {} html-void-elements@3.0.0: {} @@ -8931,8 +9025,15 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + is-alphabetical@1.0.4: {} + is-alphabetical@2.0.1: {} + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + is-alphanumerical@2.0.1: dependencies: is-alphabetical: 2.0.1 @@ -8987,6 +9088,8 @@ snapshots: dependencies: has-tostringtag: 1.0.2 + is-decimal@1.0.4: {} + is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -9011,6 +9114,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@1.0.4: {} + is-hexadecimal@2.0.1: {} is-interactive@1.0.0: {} @@ -9348,6 +9453,11 @@ snapshots: dependencies: js-tokens: 4.0.0 + lowlight@1.20.0: + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + lru-cache@10.2.0: {} lru-cache@10.4.3: {} @@ -10067,6 +10177,15 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + parse-entities@4.0.1: dependencies: '@types/unist': 2.0.10 @@ -10328,6 +10447,10 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + prismjs@1.27.0: {} + + prismjs@1.29.0: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -10339,6 +10462,10 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + property-information@6.5.0: {} proxy-from-env@1.1.0: {} @@ -10367,6 +10494,15 @@ snapshots: react-is@17.0.2: {} + react-syntax-highlighter@15.5.0(react@18.3.1): + dependencies: + '@babel/runtime': 7.24.5 + highlight.js: 10.7.3 + lowlight: 1.20.0 + prismjs: 1.29.0 + react: 18.3.1 + refractor: 3.6.0 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -10399,6 +10535,12 @@ snapshots: globalthis: 1.0.3 which-builtin-type: 1.1.3 + refractor@3.6.0: + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + regenerator-runtime@0.14.1: {} regexp.prototype.flags@1.5.2: @@ -10710,6 +10852,8 @@ snapshots: dependencies: whatwg-url: 7.1.0 + space-separated-tokens@1.1.5: {} + space-separated-tokens@2.0.2: {} sprintf-js@1.0.3: {} @@ -11312,6 +11456,8 @@ snapshots: wrappy@1.0.2: {} + xtend@4.0.2: {} + yallist@3.1.1: {} yallist@4.0.0: {} diff --git a/tests/panda-preset/recipes/button.test.ts b/tests/panda-preset/recipes/button.test.ts index a2cc2cb9..b66e48fb 100644 --- a/tests/panda-preset/recipes/button.test.ts +++ b/tests/panda-preset/recipes/button.test.ts @@ -80,7 +80,6 @@ describe('button recipe', () => { test('should have a text usage variant', () => { expect(button.variants?.usage.text).toMatchObject({ - colorPalette: 'secondaryAction', color: initialText, bgColor: 'transparent', border: 'none', @@ -89,6 +88,7 @@ describe('button recipe', () => { transitionTimingFunction: 'ease-in-out', _hover: { bgColor: 'colorPalette.ghost.hover', + color: 'colorPalette.text.200', }, _active: { bgColor: 'colorPalette.ghost.active', @@ -153,6 +153,20 @@ describe('button recipe', () => { }) }) + test('should have a compound variant', () => { + expect(button.compoundVariants).toMatchObject([ + { + palette: 'danger', + usage: 'filled', + css: { + _hover: { + color: 'colorPalette.text.inverse', + }, + }, + }, + ]) + }) + test('should have default variants', () => { expect(button.defaultVariants).toMatchObject({ palette: 'action', diff --git a/tests/panda-preset/recipes/iconButton.test.ts b/tests/panda-preset/recipes/iconButton.test.ts index 08bb3bf3..ab29384b 100644 --- a/tests/panda-preset/recipes/iconButton.test.ts +++ b/tests/panda-preset/recipes/iconButton.test.ts @@ -82,7 +82,6 @@ describe('iconButton recipe', () => { test('should have a text usage variant', () => { expect(iconButton.variants?.usage.text).toMatchObject({ - colorPalette: 'secondaryAction', color: initialText, bgColor: 'transparent', border: 'none', @@ -91,6 +90,7 @@ describe('iconButton recipe', () => { transitionTimingFunction: 'ease-in-out', _hover: { bgColor: 'colorPalette.ghost.hover', + color: 'colorPalette.text.200', }, _active: { bgColor: 'colorPalette.ghost.active',