diff --git a/packages/library/src/components/index.ts b/packages/library/src/components/index.ts
index d75a3c1..fb22734 100644
--- a/packages/library/src/components/index.ts
+++ b/packages/library/src/components/index.ts
@@ -9,3 +9,4 @@ export { Badge, badgeVariants } from './ui/badge'
export { Checkbox } from './ui/checkbox'
export { CheckboxGroup } from './ui/checkbox-group'
export { RadioGroup, RadioGroupItem } from './ui/radio-group'
+export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction } from './ui/card'
diff --git a/packages/library/src/components/ui/card/Card.vue b/packages/library/src/components/ui/card/Card.vue
new file mode 100644
index 0000000..a5be5a5
--- /dev/null
+++ b/packages/library/src/components/ui/card/Card.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardAction.vue b/packages/library/src/components/ui/card/CardAction.vue
new file mode 100644
index 0000000..c91638b
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardAction.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardContent.vue b/packages/library/src/components/ui/card/CardContent.vue
new file mode 100644
index 0000000..9421851
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardContent.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardDescription.vue b/packages/library/src/components/ui/card/CardDescription.vue
new file mode 100644
index 0000000..1641f9e
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardDescription.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardFooter.vue b/packages/library/src/components/ui/card/CardFooter.vue
new file mode 100644
index 0000000..46bf012
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardFooter.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardHeader.vue b/packages/library/src/components/ui/card/CardHeader.vue
new file mode 100644
index 0000000..ef3f9a0
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardHeader.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/CardTitle.vue b/packages/library/src/components/ui/card/CardTitle.vue
new file mode 100644
index 0000000..eb55649
--- /dev/null
+++ b/packages/library/src/components/ui/card/CardTitle.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/library/src/components/ui/card/index.ts b/packages/library/src/components/ui/card/index.ts
new file mode 100644
index 0000000..1627758
--- /dev/null
+++ b/packages/library/src/components/ui/card/index.ts
@@ -0,0 +1,7 @@
+export { default as Card } from "./Card.vue"
+export { default as CardAction } from "./CardAction.vue"
+export { default as CardContent } from "./CardContent.vue"
+export { default as CardDescription } from "./CardDescription.vue"
+export { default as CardFooter } from "./CardFooter.vue"
+export { default as CardHeader } from "./CardHeader.vue"
+export { default as CardTitle } from "./CardTitle.vue"
diff --git a/packages/library/src/index.ts b/packages/library/src/index.ts
index 0a51792..ad818d1 100644
--- a/packages/library/src/index.ts
+++ b/packages/library/src/index.ts
@@ -19,6 +19,12 @@ export {
Switch,
Select,
Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+ CardAction,
Dialog,
Message,
Badge,
diff --git a/packages/library/src/lib/index.ts b/packages/library/src/lib/index.ts
index 4efbb97..78bb977 100644
--- a/packages/library/src/lib/index.ts
+++ b/packages/library/src/lib/index.ts
@@ -1,7 +1,6 @@
import type { App } from 'vue'
import {
Select as PrimeSelect,
- Card as PrimeCard,
Dialog as PrimeDialog,
Message as PrimeMessage,
} from 'primevue'
@@ -19,6 +18,13 @@ import {
CheckboxGroup,
RadioGroup,
RadioGroupItem,
+ Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+ CardAction,
} from '../components'
export {
@@ -33,6 +39,13 @@ export {
CheckboxGroup,
RadioGroup,
RadioGroupItem,
+ Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+ CardAction,
}
/**
@@ -89,15 +102,6 @@ const nychthemeron: ThemeLibrary = {
'optionLabel',
'emptyMessage',
]),
- Card: ptThemeable(PrimeCard, 'card', [
- 'header',
- 'body',
- 'caption',
- 'title',
- 'subtitle',
- 'content',
- 'footer',
- ]),
Dialog: ptThemeable(PrimeDialog, 'dialog', [
'mask',
'header',
@@ -121,7 +125,6 @@ const _engine = new ThemeEngine(nychthemeron)
export const LoadingIcon = _engine.getComponent('LoadingIcon')
export const Select: typeof PrimeSelect = _engine.getComponent('Select')
-export const Card: typeof PrimeCard = _engine.getComponent('Card')
export const Dialog: typeof PrimeDialog = _engine.getComponent('Dialog')
export const Message: typeof PrimeMessage = _engine.getComponent('Message')
@@ -136,7 +139,13 @@ export const createNychthemeron = (): {
RadioGroupItem: typeof RadioGroupItem
Switch: typeof Switch
Select: typeof PrimeSelect
- Card: typeof PrimeCard
+ Card: typeof Card
+ CardHeader: typeof CardHeader
+ CardTitle: typeof CardTitle
+ CardDescription: typeof CardDescription
+ CardContent: typeof CardContent
+ CardFooter: typeof CardFooter
+ CardAction: typeof CardAction
Dialog: typeof PrimeDialog
Message: typeof PrimeMessage
Badge: typeof Badge
@@ -153,6 +162,12 @@ export const createNychthemeron = (): {
Switch,
Select,
Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+ CardAction,
Dialog,
Message,
Badge,
@@ -168,6 +183,12 @@ export const createNychthemeron = (): {
app.component('NychSwitch', Switch)
app.component('NychSelect', Select)
app.component('NychCard', Card)
+ app.component('NychCardHeader', CardHeader)
+ app.component('NychCardTitle', CardTitle)
+ app.component('NychCardDescription', CardDescription)
+ app.component('NychCardContent', CardContent)
+ app.component('NychCardFooter', CardFooter)
+ app.component('NychCardAction', CardAction)
app.component('NychDialog', Dialog)
app.component('NychMessage', Message)
app.component('NychBadge', Badge)
diff --git a/packages/library/tests/Card.spec.ts b/packages/library/tests/Card.spec.ts
new file mode 100644
index 0000000..c51fb16
--- /dev/null
+++ b/packages/library/tests/Card.spec.ts
@@ -0,0 +1,32 @@
+import { describe, it, expect } from 'vitest'
+import { h } from 'vue'
+import { mount } from '@vue/test-utils'
+import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '../src/lib'
+
+describe('Card', () => {
+ it('renders header, title, description, content, and footer together', () => {
+ const wrapper = mount(Card, {
+ slots: {
+ default: () => [
+ h(CardHeader, undefined, {
+ default: () => [
+ h(CardTitle, undefined, { default: () => 'Elysium' }),
+ h(CardDescription, undefined, { default: () => 'The blessed fields' }),
+ ],
+ }),
+ h(CardContent, undefined, { default: () => 'A resting place for the virtuous.' }),
+ h(CardFooter, undefined, { default: () => 'Enter' }),
+ ],
+ },
+ })
+ expect(wrapper.text()).toContain('Elysium')
+ expect(wrapper.text()).toContain('The blessed fields')
+ expect(wrapper.text()).toContain('A resting place for the virtuous.')
+ expect(wrapper.text()).toContain('Enter')
+ })
+
+ it('exposes a data-slot attribute for styling hooks', () => {
+ const wrapper = mount(Card)
+ expect(wrapper.attributes('data-slot')).toBe('card')
+ })
+})
diff --git a/packages/library/tests/lib.spec.ts b/packages/library/tests/lib.spec.ts
index 4a523c5..6080c56 100644
--- a/packages/library/tests/lib.spec.ts
+++ b/packages/library/tests/lib.spec.ts
@@ -4,7 +4,6 @@ import {
createNychthemeron,
LoadingIcon,
Select,
- Card,
Dialog,
Message,
} from '../src/index'
@@ -64,7 +63,6 @@ describe('LoadingIcon', () => {
describe('themed pt components', () => {
const cases = [
{ name: 'Select', component: Select, base: 'nych-select' },
- { name: 'Card', component: Card, base: 'nych-card' },
{ name: 'Dialog', component: Dialog, base: 'nych-dialog' },
{ name: 'Message', component: Message, base: 'nych-message' },
]
diff --git a/packages/playground/stories/Card.stories.ts b/packages/playground/stories/Card.stories.ts
index e005029..21d9c02 100644
--- a/packages/playground/stories/Card.stories.ts
+++ b/packages/playground/stories/Card.stories.ts
@@ -1,6 +1,15 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'
-import { Card as NychCard, Button as NychButton, Badge as NychBadge } from '@nychthemeron/library'
+import {
+ Card as NychCard,
+ CardHeader as NychCardHeader,
+ CardTitle as NychCardTitle,
+ CardDescription as NychCardDescription,
+ CardContent as NychCardContent,
+ CardFooter as NychCardFooter,
+ Button as NychButton,
+ Badge as NychBadge,
+} from '@nychthemeron/library'
const meta = {
title: 'Components/Card',
@@ -16,15 +25,17 @@ type Story = StoryObj
export const Default: Story = {
render: () => ({
- components: { NychCard },
+ components: { NychCard, NychCardHeader, NychCardTitle, NychCardDescription, NychCardContent },
template: `
- Elysium
- The blessed fields
-
+
+ Elysium
+ The blessed fields
+
+
A resting place reserved for the heroic and the virtuous, where the
air is mild and the laurel never wilts.
-
+
`,
}),
@@ -32,19 +43,29 @@ export const Default: Story = {
export const WithFooter: Story = {
render: () => ({
- components: { NychCard, NychButton },
+ components: {
+ NychCard,
+ NychCardHeader,
+ NychCardTitle,
+ NychCardDescription,
+ NychCardContent,
+ NychCardFooter,
+ NychButton,
+ },
template: `
- Passage of the Styx
- One obol required
-
+
+ Passage of the Styx
+ One obol required
+
+
Charon ferries the souls of the dead across the river that divides
the world of the living from the world of the dead.
-
-
-
-
-
+
+
+ Pay the toll
+ Turn back
+
`,
}),
@@ -52,21 +73,19 @@ export const WithFooter: Story = {
export const WithHeaderAndTag: Story = {
render: () => ({
- components: { NychCard, NychBadge },
+ components: { NychCard, NychCardHeader, NychCardTitle, NychCardContent, NychBadge },
template: `
-
-
-
-
-
+
+
+
Oracle of Delphi Sacred
-
-
-
+
+
+
Seekers travelled from across the Aegean to hear the Pythia speak the
will of Apollo in riddling verse.
-
+
`,
}),