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 (
+
+ )
+}
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',