feat: setup PandaCSS, ArkUI, ParkUI Preset and Lucide-React

feature/next-intl
RaviAnand Mohabir 3 weeks ago
parent 12820974c5
commit a69f2c6932

4
.gitignore vendored

@ -38,3 +38,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
## Panda
styled-system
styled-system-studio

@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"prepare": "panda codegen",
"dev": "next dev --turbo",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
@ -13,11 +14,13 @@
"format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx}\""
},
"dependencies": {
"@ark-ui/react": "^3.9.0",
"@payloadcms/db-mongodb": "3.0.0-beta.94",
"@payloadcms/next": "^3.0.0-beta.94",
"@payloadcms/richtext-lexical": "^3.0.0-beta.94",
"@payloadcms/translations": "^3.0.0-beta.94",
"graphql": "^16.9.0",
"lucide-react": "^0.436.0",
"next": "15.0.0-canary.132",
"payload": "^3.0.0-beta.94",
"react": "19.0.0-rc-eb3ad065-20240822",
@ -25,6 +28,8 @@
"sharp": "^0.33.5"
},
"devDependencies": {
"@pandacss/dev": "^0.45.1",
"@park-ui/panda-preset": "^0.42.0",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",

@ -0,0 +1,30 @@
import { createPreset } from "@park-ui/panda-preset";
import { defineConfig } from "@pandacss/dev";
export default defineConfig({
// Whether to use css reset
preflight: true,
presets: [
"@pandacss/preset-base",
createPreset({
accentColor: "red",
}),
],
// Where to look for your css declarations
include: ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"],
// Files to exclude
exclude: [],
// Useful for theme customization
theme: {
extend: {},
},
// The output directory for your css system
outdir: "styled-system",
jsxFramework: "react",
});

@ -0,0 +1,5 @@
{
"$schema": "https://park-ui.com/registry/latest/schema.json",
"jsFramework": "react",
"outputPath": "./src/components/ui"
}

@ -0,0 +1,5 @@
module.exports = {
plugins: {
'@pandacss/dev/postcss': {},
},
}

@ -1,3 +1,5 @@
@layer reset, base, tokens, recipes, utilities;
:root {
--background: #ffffff;
--foreground: #171717;

@ -0,0 +1,40 @@
import { forwardRef } from 'react'
import { Center, styled } from 'styled-system/jsx'
import { Spinner } from './spinner'
import { Button as StyledButton, type ButtonProps as StyledButtonProps } from './styled/button'
interface ButtonLoadingProps {
loading?: boolean
loadingText?: React.ReactNode
}
export interface ButtonProps extends StyledButtonProps, ButtonLoadingProps {}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
const { loading, disabled, loadingText, children, ...rest } = props
const trulyDisabled = loading || disabled
return (
<StyledButton disabled={trulyDisabled} ref={ref} {...rest}>
{loading && !loadingText ? (
<>
<ButtonSpinner />
<styled.span opacity={0}>{children}</styled.span>
</>
) : loadingText ? (
loadingText
) : (
children
)}
</StyledButton>
)
})
Button.displayName = 'Button'
const ButtonSpinner = () => (
<Center inline position="absolute" transform="translate(-50%, -50%)" top="50%" insetStart="50%">
<Spinner colorPalette="gray" />
</Center>
)

@ -0,0 +1,7 @@
import { ark } from '@ark-ui/react/factory'
import { styled } from 'styled-system/jsx'
import { button } from 'styled-system/recipes'
import type { ComponentProps } from 'styled-system/types'
export type ButtonProps = ComponentProps<typeof Button>
export const Button = styled(ark.button, button)

@ -0,0 +1,95 @@
import {
type ElementType,
type ForwardRefExoticComponent,
type PropsWithoutRef,
type RefAttributes,
createContext,
forwardRef,
useContext,
} from 'react'
import { cx } from 'styled-system/css'
import { type StyledComponent, isCssProperty, styled } from 'styled-system/jsx'
type Props = Record<string, unknown>
type Recipe = {
(props?: Props): Props
splitVariantProps: (props: Props) => [Props, Props]
}
type Slot<R extends Recipe> = keyof ReturnType<R>
type Options = { forwardProps?: string[] }
const shouldForwardProp = (prop: string, variantKeys: string[], options: Options = {}) =>
options.forwardProps?.includes(prop) || (!variantKeys.includes(prop) && !isCssProperty(prop))
export const createStyleContext = <R extends Recipe>(recipe: R) => {
const StyleContext = createContext<Record<Slot<R>, string> | null>(null)
const withRootProvider = <P extends {}>(Component: ElementType) => {
const StyledComponent = (props: P) => {
const [variantProps, otherProps] = recipe.splitVariantProps(props)
const slotStyles = recipe(variantProps) as Record<Slot<R>, string>
return (
<StyleContext.Provider value={slotStyles}>
<Component {...otherProps} />
</StyleContext.Provider>
)
}
return StyledComponent
}
const withProvider = <T, P extends { className?: string | undefined }>(
Component: ElementType,
slot: Slot<R>,
options?: Options,
): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>> => {
const StyledComponent = styled(
Component,
{},
{
shouldForwardProp: (prop, variantKeys) => shouldForwardProp(prop, variantKeys, options),
},
) as StyledComponent<ElementType>
const StyledSlotProvider = forwardRef<T, P>((props, ref) => {
const [variantProps, otherProps] = recipe.splitVariantProps(props)
const slotStyles = recipe(variantProps) as Record<Slot<R>, string>
return (
<StyleContext.Provider value={slotStyles}>
<StyledComponent
{...otherProps}
ref={ref}
className={cx(slotStyles?.[slot], props.className)}
/>
</StyleContext.Provider>
)
})
// @ts-expect-error
StyledSlotProvider.displayName = Component.displayName || Component.name
return StyledSlotProvider
}
const withContext = <T, P extends { className?: string | undefined }>(
Component: ElementType,
slot: Slot<R>,
): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>> => {
const StyledComponent = styled(Component)
const StyledSlotComponent = forwardRef<T, P>((props, ref) => {
const slotStyles = useContext(StyleContext)
return (
<StyledComponent {...props} ref={ref} className={cx(slotStyles?.[slot], props.className)} />
)
})
// @ts-expect-error
StyledSlotComponent.displayName = Component.displayName || Component.name
return StyledSlotComponent
}
return {
withRootProvider,
withProvider,
withContext,
}
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save