-
Notifications
You must be signed in to change notification settings - Fork 357
Expand file tree
/
Copy pathcallout.tsx
More file actions
116 lines (108 loc) · 2.88 KB
/
callout.tsx
File metadata and controls
116 lines (108 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { Icon } from "solid-heroicons";
import { mergeProps, type JSX, Show, untrack } from "solid-js";
import {
lightBulb,
exclamationTriangle,
xCircle,
puzzlePiece,
bookOpen,
} from "solid-heroicons/solid";
const styles = {
note: {
container:
"bg-emerald-500/20 border-emerald-500 dark:border-emerald-400 dark:bg-emerald-800/20 dark:border-emerald-900",
title: "text-emerald-900 dark:text-emerald-300",
},
tip: {
container:
"bg-violet-800/20 border-violet-900 dark:border-violet-400 dark:bg-violet-800/10 dark:border-violet-900",
title: "text-violet-900 dark:text-violet-300",
},
advanced: {
container:
"bg-blue-400/20 border-blue-600 dark:border-blue-400 dark:bg-blue-400/20 dark:border-blue-600",
title: "text-blue-700 dark:text-blue-300",
},
caution: {
container:
"bg-amber-400/30 border-amber-600 dark:border-amber-400 dark:bg-amber-400/20 dark:border-amber-600",
title: "text-amber-900 dark:text-amber-400",
},
danger: {
container:
"bg-red-400/30 border-red-600 dark:border-red-400 dark:bg-red-400/20 dark:border-red-600",
title: "text-red-900 dark:text-red-400",
},
};
const icons = {
note: (props: { class?: string }) => (
<Icon
aria-hidden="true"
path={bookOpen}
class={`${props.class} fill-emerald-800 dark:fill-emerald-300`}
/>
),
tip: (props: { class?: string }) => (
<Icon
aria-hidden="true"
path={lightBulb}
class={`${props.class} fill-violet-900 dark:fill-violet-300`}
/>
),
advanced: (props: { class?: string }) => (
<Icon
aria-hidden="true"
path={puzzlePiece}
class={`${props.class} fill-blue-700 dark:fill-blue-300`}
/>
),
caution: (props: { class?: string }) => (
<Icon
aria-hidden="true"
path={exclamationTriangle}
class={`${props.class} fill-amber-500 dark:fill-amber-400`}
/>
),
danger: (props: { class?: string }) => (
<Icon
aria-hidden="true"
path={xCircle}
class={`${props.class} fill-red-500 dark:fill-red-400`}
/>
),
};
type CalloutType = keyof typeof styles;
export type CalloutProps = {
title?: string;
children: JSX.Element;
type?: CalloutType;
};
export function Callout(props: CalloutProps) {
const mergedProps = mergeProps({ type: "note" as CalloutType }, props);
const iconType = untrack(() => mergedProps.type);
const IconComponent = icons[iconType];
return (
<div
class={`my-6 flex w-full rounded-3xl border p-4 ${
styles[mergedProps.type].container
}`}
>
<IconComponent class="mt-1 h-6 w-8 flex-none" />
<div class={`m-0 w-full px-4 pb-1 ${styles[mergedProps.type].title}`}>
<Show
when={props.title}
fallback={
<span class="text-xl font-semibold capitalize">
{props.type || "Note"}
</span>
}
>
<span class="text-xl font-semibold">{mergedProps.title}</span>
</Show>
<div class="prose pr-7 dark:prose-invert [&>*:first-child]:mt-1">
{mergedProps.children}
</div>
</div>
</div>
);
}