Skip to content

Commit

Permalink
feat(vue): add input and card (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
cschroeter authored Jul 15, 2024
1 parent 50397b3 commit eaf646c
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 6 deletions.
14 changes: 14 additions & 0 deletions components/vue/src/components/ui/primitives/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type AccordionVariantProps, card } from 'styled-system/recipes'
import type { Assign, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'

const { withProvider, withContext } = createStyleContext(card)

export interface RootProps extends Assign<HTMLStyledProps<'div'>, AccordionVariantProps> {}
export const Root = withProvider<RootProps>('div', 'root')

export const Header = withContext<HTMLStyledProps<'div'>>('div', 'header')
export const Body = withContext<HTMLStyledProps<'div'>>('div', 'body')
export const Footer = withContext<HTMLStyledProps<'div'>>('div', 'footer')
export const Title = withContext<HTMLStyledProps<'h3'>>('h3', 'title')
export const Description = withContext<HTMLStyledProps<'div'>>('div', 'description')
2 changes: 2 additions & 0 deletions components/vue/src/components/ui/primitives/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { Button, type ButtonProps } from './button'
export { Input, type InputProps } from './input'
export * as Card from './card'
6 changes: 6 additions & 0 deletions components/vue/src/components/ui/primitives/input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { styled } from 'styled-system/jsx'
import { input } from 'styled-system/recipes'
import type { ComponentProps } from 'styled-system/types'

export type InputProps = ComponentProps<typeof Input>
export const Input = styled('input', input)
17 changes: 14 additions & 3 deletions components/vue/src/lib/create-style-context.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { styled } from 'styled-system/jsx'
import type { ElementType } from 'styled-system/types'
import { type ComputedRef, computed, defineComponent, inject, provide } from 'vue'
import {
type ComputedRef,
type FunctionalComponent,
computed,
defineComponent,
inject,
provide,
} from 'vue'

type Props = Record<string, unknown>
type Recipe = {
Expand All @@ -14,7 +21,7 @@ export const createStyleContext = <R extends Recipe>(recipe: R) => {
const withProvider = <P,>(Component: ElementType, slot: Slot<R>) => {
const StyledComponent = styled(Component)

return defineComponent<P>({
const StyledSlotProvider = defineComponent<P>({
setup(props, { slots }) {
const splittedProps = computed(() => {
return recipe.splitVariantProps(props)
Expand All @@ -33,12 +40,14 @@ export const createStyleContext = <R extends Recipe>(recipe: R) => {
)
},
})

return StyledSlotProvider as unknown as FunctionalComponent<P>
}

const withContext = <P,>(Component: ElementType, slot: Slot<R>) => {
const StyledComponent = styled(Component)

return defineComponent<P>({
const StyledSlotComponent = defineComponent<P>({
setup(props, { slots }) {
const slotStyles = inject<ComputedRef<StyleContext<R>>>('styles')

Expand All @@ -49,6 +58,8 @@ export const createStyleContext = <R extends Recipe>(recipe: R) => {
)
},
})

return StyledSlotComponent as unknown as FunctionalComponent<P>
}

return { withProvider, withContext }
Expand Down
2 changes: 1 addition & 1 deletion components/vue/src/stories/button.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Button } from '~/components/ui'
<template>
<Story title="Button">
<Variant title="Basic">
<Button pt="2">Park UI</Button>
<Button>Park UI</Button>
</Variant>
</Story>
</template>
18 changes: 18 additions & 0 deletions components/vue/src/stories/card.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { Card } from '~/components/ui'
</script>

<template>
<Story title="Card">
<Variant title="Basic">
<Card.Root width="sm">
<Card.Header>
<Card.Title>Team Members</Card.Title>
<Card.Description>Add new members to your organisation.</Card.Description>
</Card.Header>
<Card.Body>Body</Card.Body>
<Card.Footer>Footer</Card.Footer>
</Card.Root>
</Variant>
</Story>
</template>
11 changes: 11 additions & 0 deletions components/vue/src/stories/input.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
import { Input } from '~/components/ui'
</script>

<template>
<Story title="Input">
<Variant title="Basic">
<Input id="name" placeholder="Your Name" />
</Variant>
</Story>
</template>
11 changes: 11 additions & 0 deletions website/public/registry/latest/vue/components/card.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "card",
"name": "Card",
"variants": [
{
"file": "primitives/card.tsx",
"content": "import { type AccordionVariantProps, card } from 'styled-system/recipes'\nimport type { Assign, HTMLStyledProps } from 'styled-system/types'\nimport { createStyleContext } from '~/lib/create-style-context'\n\nconst { withProvider, withContext } = createStyleContext(card)\n\nexport interface RootProps extends Assign<HTMLStyledProps<'div'>, AccordionVariantProps> {}\nexport const Root = withProvider<RootProps>('div', 'root')\n\nexport const Header = withContext<HTMLStyledProps<'div'>>('div', 'header')\nexport const Body = withContext<HTMLStyledProps<'div'>>('div', 'body')\nexport const Footer = withContext<HTMLStyledProps<'div'>>('div', 'footer')\nexport const Title = withContext<HTMLStyledProps<'h3'>>('h3', 'title')\nexport const Description = withContext<HTMLStyledProps<'div'>>('div', 'description')\n",
"exports": "export * as Card from './card'"
}
]
}
6 changes: 5 additions & 1 deletion website/public/registry/latest/vue/components/index.json
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
[{ "id": "button", "name": "Button" }]
[
{ "id": "button", "name": "Button" },
{ "id": "card", "name": "Card" },
{ "id": "input", "name": "Input" }
]
11 changes: 11 additions & 0 deletions website/public/registry/latest/vue/components/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "input",
"name": "Input",
"variants": [
{
"file": "primitives/input.tsx",
"content": "import { styled } from 'styled-system/jsx'\nimport { input } from 'styled-system/recipes'\nimport type { ComponentProps } from 'styled-system/types'\n\nexport type InputProps = ComponentProps<typeof Input>\nexport const Input = styled('input', input)\n",
"exports": "export { Input, type InputProps } from './input'"
}
]
}
2 changes: 1 addition & 1 deletion website/public/registry/latest/vue/helpers/index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"filename": "create-style-context.tsx",
"content": "import { styled } from 'styled-system/jsx'\nimport type { ElementType } from 'styled-system/types'\nimport { type ComputedRef, computed, defineComponent, inject, provide } from 'vue'\n\ntype Props = Record<string, unknown>\ntype Recipe = {\n (props?: Props): Props\n splitVariantProps: (props: Props) => [Props, Props]\n}\ntype Slot<R extends Recipe> = keyof ReturnType<R>\ntype StyleContext<R extends Recipe> = Record<Slot<R>, string>\n\nexport const createStyleContext = <R extends Recipe>(recipe: R) => {\n const withProvider = <P,>(Component: ElementType, slot: Slot<R>) => {\n const StyledComponent = styled(Component)\n\n return defineComponent<P>({\n setup(props, { slots }) {\n const splittedProps = computed(() => {\n return recipe.splitVariantProps(props)\n })\n\n const styles = computed(() => {\n const [variantProps] = splittedProps.value\n return recipe(variantProps) as StyleContext<R>\n })\n\n provide('styles', styles)\n return () => (\n <StyledComponent {...splittedProps.value[1]} class={styles.value[slot]}>\n {slots.default?.()}\n </StyledComponent>\n )\n },\n })\n }\n\n const withContext = <P,>(Component: ElementType, slot: Slot<R>) => {\n const StyledComponent = styled(Component)\n\n return defineComponent<P>({\n setup(props, { slots }) {\n const slotStyles = inject<ComputedRef<StyleContext<R>>>('styles')\n\n return () => (\n <StyledComponent {...props} class={slotStyles?.value?.[slot]}>\n {slots.default?.()}\n </StyledComponent>\n )\n },\n })\n }\n\n return { withProvider, withContext }\n}\n"
"content": "import { styled } from 'styled-system/jsx'\nimport type { ElementType } from 'styled-system/types'\nimport {\n type ComputedRef,\n type FunctionalComponent,\n computed,\n defineComponent,\n inject,\n provide,\n} from 'vue'\n\ntype Props = Record<string, unknown>\ntype Recipe = {\n (props?: Props): Props\n splitVariantProps: (props: Props) => [Props, Props]\n}\ntype Slot<R extends Recipe> = keyof ReturnType<R>\ntype StyleContext<R extends Recipe> = Record<Slot<R>, string>\n\nexport const createStyleContext = <R extends Recipe>(recipe: R) => {\n const withProvider = <P,>(Component: ElementType, slot: Slot<R>) => {\n const StyledComponent = styled(Component)\n\n const StyledSlotProvider = defineComponent<P>({\n setup(props, { slots }) {\n const splittedProps = computed(() => {\n return recipe.splitVariantProps(props)\n })\n\n const styles = computed(() => {\n const [variantProps] = splittedProps.value\n return recipe(variantProps) as StyleContext<R>\n })\n\n provide('styles', styles)\n return () => (\n <StyledComponent {...splittedProps.value[1]} class={styles.value[slot]}>\n {slots.default?.()}\n </StyledComponent>\n )\n },\n })\n\n return StyledSlotProvider as unknown as FunctionalComponent<P>\n }\n\n const withContext = <P,>(Component: ElementType, slot: Slot<R>) => {\n const StyledComponent = styled(Component)\n\n const StyledSlotComponent = defineComponent<P>({\n setup(props, { slots }) {\n const slotStyles = inject<ComputedRef<StyleContext<R>>>('styles')\n\n return () => (\n <StyledComponent {...props} class={slotStyles?.value?.[slot]}>\n {slots.default?.()}\n </StyledComponent>\n )\n },\n })\n\n return StyledSlotComponent as unknown as FunctionalComponent<P>\n }\n\n return { withProvider, withContext }\n}\n"
}
]

0 comments on commit eaf646c

Please sign in to comment.