Skip to content

Commit

Permalink
component: Card
Browse files Browse the repository at this point in the history
  • Loading branch information
jeannemas committed Jun 4, 2024
1 parent 5363e40 commit ee8ae4d
Show file tree
Hide file tree
Showing 19 changed files with 305 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/lib/components/calendar/CalendarRoot.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script context="module" lang="ts">
import '@internationalized/date';
import { Calendar as CalendarPrimitive } from 'bits-ui';
import type { SvelteHTMLElements } from 'svelte/elements';
import { writable } from 'svelte/store';
Expand Down
32 changes: 32 additions & 0 deletions src/lib/components/card/CardContent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import type { EmptyObject } from '$lib/utils/types.js';
import { rootContext } from './context.js';
/**
* The attributes of the content.
*/
Expand Down Expand Up @@ -33,11 +35,41 @@
type $$Slots = Slots;
$: attributes = $$restProps as Attributes;
const rootCtx = rootContext.get();
if (!rootCtx) {
throw new Error('Card.Content must be used within a Card.Root component.');
}
</script>

<!-- <style lang="postcss">
</style> -->

<!--
@component
The content of the card component.
Must be used within a `Card.Root` component.
### Attributes
Accepts the attributes of a `div` element.
### Events
None.
### Props
None.
### Slots
- `default` - The default slot.
-->

<div
{...attributes}
class="{contentStyles({
Expand Down
43 changes: 42 additions & 1 deletion src/lib/components/card/CardDescription.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import type { EmptyObject } from '$lib/utils/types.js';
import { headerContext } from './context.js';
/**
* The attributes of the description.
*/
Expand All @@ -23,7 +25,13 @@
* The styles of the description.
*/
export const descriptionStyles = tv({
base: ['text-sm text-muted-foreground'],
base: ['text-sm'],
variants: {
variant: {
danger: ['text-red-500'],
default: ['text-muted-foreground'],
},
},
});
</script>

Expand All @@ -33,15 +41,48 @@
type $$Slots = Slots;
$: attributes = $$restProps as Attributes;
const headerCtx = headerContext.get();
if (!headerCtx) {
throw new Error('Card.Description must be used within a Card.Header component.');
}
$: ({ variant } = $headerCtx!);
</script>

<!-- <style lang="postcss">
</style> -->

<!--
@component
The description of the card component.
Must be used within a `Card.Header` component.
### Attributes
Accepts the attributes of a `p` element.
### Events
None.
### Props
None.
### Slots
- `default` - The default slot.
-->

<p
{...attributes}
class="{descriptionStyles({
class: attributes.class,
variant,
})}"
>
<slot />
Expand Down
38 changes: 35 additions & 3 deletions src/lib/components/card/CardFooter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import type { EmptyObject } from '$lib/utils/types.js';
import { rootContext } from './context.js';
/**
* The attributes of the footer.
*/
export type Attributes = SvelteHTMLElements['div'];
export type Attributes = SvelteHTMLElements['footer'];
/**
* The props of the footer.
*/
Expand All @@ -33,16 +35,46 @@
type $$Slots = Slots;
$: attributes = $$restProps as Attributes;
const rootCtx = rootContext.get();
if (!rootCtx) {
throw new Error('Card.Content must be used within a Card.Root component.');
}
</script>

<!-- <style lang="postcss">
</style> -->

<div
<!--
@component
The footer of the card component.
Must be used within a `Card.Root` component.
### Attributes
Accepts the attributes of a `footer` element.
### Events
None.
### Props
None.
### Slots
- `default` - The default slot.
-->

<footer
{...attributes}
class="{footerStyles({
class: attributes.class,
})}"
>
<slot />
</div>
</footer>
46 changes: 43 additions & 3 deletions src/lib/components/card/CardHeader.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<script context="module" lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
import { writable } from 'svelte/store';
import { tv } from 'tailwind-variants';
import type { EmptyObject } from '$lib/utils/types.js';
import { headerContext, rootContext } from './context.js';
/**
* The attributes of the header.
*/
export type Attributes = SvelteHTMLElements['div'];
export type Attributes = SvelteHTMLElements['header'];
/**
* The props of the header.
*/
Expand All @@ -33,16 +36,53 @@
type $$Slots = Slots;
$: attributes = $$restProps as Attributes;
const rootCtx = rootContext.get();
if (!rootCtx) {
throw new Error('Card.Header must be used within a Card.Root component.');
}
const headerCtx = headerContext.set(writable());
$: headerCtx.update(($ctx) => ({
...$ctx,
...$rootCtx,
}));
</script>

<!-- <style lang="postcss">
</style> -->

<div
<!--
@component
The header of the card component.
Must be used within a `Card.Root` component.
### Attributes
Accepts the attributes of a `header` element.
### Events
None.
### Props
None.
### Slots
- `default` - The default slot.
-->

<header
{...attributes}
class="{headerStyles({
class: attributes.class,
})}"
>
<slot />
</div>
</header>
56 changes: 54 additions & 2 deletions src/lib/components/card/CardRoot.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<script context="module" lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
import { writable } from 'svelte/store';
import { tv, type VariantProps } from 'tailwind-variants';
import type { EmptyObject } from '$lib/utils/types.js';
import { rootContext } from './context.js';
/**
* The attributes of the root.
*/
Expand Down Expand Up @@ -40,8 +43,8 @@
},
variants: {
variant: {
danger: ['border-red-500 bg-red-50 text-red-500'],
default: ['border-border bg-card text-card-foreground'],
danger: ['border-red-500 bg-red-50'],
default: ['border-border bg-card'],
},
},
});
Expand All @@ -55,11 +58,60 @@
export let variant: Props['variant'] = rootStyles.defaultVariants.variant;
$: attributes = $$restProps as Attributes;
const rootCtx = rootContext.set(writable());
$: rootCtx.update(($ctx) => ({
...$ctx,
variant,
}));
</script>

<!-- <style lang="postcss">
</style> -->

<!--
@component
The root of the card component.
### Attributes
Accepts the attributes of a `div` element.
### Events
None.
### Props
- `variant` - The variant of the card.
### Slots
- `default` - The default slot.
### Components hierarchy
```html
<Card.Root>
<Card.Header>
<Card.Title />
<Card.Description />
</Card.Header>
<Card.Content>
...
</Card.Content>
<Card.Footer>
...
</Card.Footer>
</Card.Root>
```
-->

<div
{...attributes}
class="{rootStyles({
Expand Down
Loading

0 comments on commit ee8ae4d

Please sign in to comment.