cschroeter / park-ui

Beautifully designed components built with Ark UI and Panda CSS that work with a variety of JS frameworks.
https://park-ui.com
MIT License
1.71k stars 75 forks source link

Revise Component API #144

Closed cschroeter closed 10 months ago

cschroeter commented 10 months ago

At the moment, each component snippet is declared as follows:

import { Avatar as ArkAvatar } from '@ark-ui/react/avatar'
import { styled, type HTMLStyledProps } from 'styled-system/jsx'
import { avatar } from 'styled-system/recipes'
import { createStyleContext } from '~/lib/create-style-context'

const { withProvider, withContext } = createStyleContext(avatar)

const Avatar = withProvider(styled(ArkAvatar.Root), 'root')
const AvatarFallback = withContext(styled(ArkAvatar.Fallback), 'fallback')
const AvatarImage = withContext(styled(ArkAvatar.Image), 'image')

const Root = Avatar
const Fallback = AvatarFallback
const Image = AvatarImage

export { Avatar, AvatarFallback, AvatarImage, Fallback, Image, Root }

These can then be used as follows:

import type { AvatarProps } from '~/components/ui/avatar'
import * as Avatar from '~/components/ui/avatar'

export const Demo = (props: AvatarProps) => {
  return (
    <Avatar.Root {...props}>
      <Avatar.Fallback>PA</Avatar.Fallback>
      <Avatar.Image src="https://i.pravatar.cc/300" alt="avatar" />
    </Avatar.Root>
  )
}

While this approach works well for complex components like DatePicker, ColorPicker, or components with a more open API design like Tabs, it can be somewhat cumbersome for smaller components such as Avatar, Switch, Checkbox, Pagination, etc.

Therefore, the goal for the next few iterations is to redesign these smaller components for use in a more encapsulated component design, like so:

export const Demo = (props: AvatarProps) => {
  return  <Avatar name='Segun Adebayo' src='https://bit.ly/sage-adebayo' />
}

The simplified snippet would look like this:

interface AvatarProps extends AvatarProps, AvatarVariantProps {
  name: string
  src: string
}

export const Avatar = (props: AvatarProps) => {
  const { name, src, ...rest } = props
  return (
    <ArkAvatar.Root {...rest}>
      <ArkAvatar.Fallback>{getInitials(name)}</ArkAvatar.Fallback>
      <ArkAvatar.Image src={src} alt={name} />
    </ArkAvatar.Root>
  )
}

Status

Component Status
Avatar
Checkbox
Number Input
Pagination
Pin Input
Rating Group
Slider
Switch
cschroeter commented 10 months ago

@kovsu I've added a list of components that we may wan tto add. Could be more.