emdash-plugin-avdeb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,131 @@
1
+ ---
2
+ /** A call-to-action link to an AVDEB page, carrying the site's referral code. */
3
+ import { avdebLink } from "../catalog.ts";
4
+ import type { Alignment, ButtonVariant } from "../constants.ts";
5
+ import type { ContextData } from "../payload.ts";
6
+ import { relFor } from "../view.ts";
7
+
8
+ interface Props {
9
+ context: ContextData | null;
10
+ href: string;
11
+ label: string;
12
+ variant?: ButtonVariant;
13
+ align?: Alignment;
14
+ class?: string;
15
+ }
16
+
17
+ const { context, href, label, variant = "solid", align = "start", class: className } = Astro.props;
18
+ const url = avdebLink(href, context?.ref ?? "");
19
+ const accent = context?.display.accentColor;
20
+ const newTab = context?.display.newTab ?? false;
21
+ ---
22
+
23
+ <p class:list={["avdeb-cta", `avdeb-cta--${align}`, className]} style={accent ? `--avdeb-accent:${accent}` : undefined}>
24
+ {
25
+ url ? (
26
+ <a class:list={["avdeb-btn", `avdeb-btn--${variant}`]} href={url} rel={relFor(url)} target={newTab ? "_blank" : undefined}>
27
+ <span>{label}</span>
28
+ <svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M3 8h9.5M8.5 4 12.5 8l-4 4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" /></svg>
29
+ </a>
30
+ ) : (
31
+ <span>{label}</span>
32
+ )
33
+ }
34
+ </p>
35
+
36
+ <style is:global>
37
+ :where(.avdeb-cta) {
38
+ --avdeb-accent: #3b6548;
39
+ --avdeb-accent-contrast: #fff;
40
+ display: flex;
41
+ margin-block: 1.75em;
42
+ }
43
+
44
+ :where(.avdeb-cta--center) {
45
+ justify-content: center;
46
+ }
47
+
48
+ :where(.avdeb-cta--end) {
49
+ justify-content: flex-end;
50
+ }
51
+
52
+ :where(.avdeb-btn) {
53
+ display: inline-flex;
54
+ align-items: center;
55
+ gap: 0.55em;
56
+ padding: 0.85em 1.4em;
57
+ border: 1.5px solid var(--avdeb-accent);
58
+ border-radius: 999px;
59
+ font: inherit;
60
+ font-weight: 600;
61
+ line-height: 1.1;
62
+ text-decoration: none;
63
+ transition:
64
+ transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
65
+ box-shadow 0.2s,
66
+ background-color 0.2s,
67
+ color 0.2s;
68
+ }
69
+
70
+ :where(.avdeb-btn svg) {
71
+ flex: none;
72
+ transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
73
+ }
74
+
75
+ :where(.avdeb-btn:hover) :where(svg) {
76
+ transform: translateX(3px);
77
+ }
78
+
79
+ :where(.avdeb-btn:dir(rtl)) :where(svg) {
80
+ scale: -1 1;
81
+ }
82
+
83
+ :where(.avdeb-btn:focus-visible) {
84
+ outline: 2px solid var(--avdeb-accent);
85
+ outline-offset: 3px;
86
+ }
87
+
88
+ :where(.avdeb-btn--solid) {
89
+ background: var(--avdeb-accent);
90
+ color: var(--avdeb-accent-contrast);
91
+ box-shadow: 0 10px 24px -12px var(--avdeb-accent);
92
+ }
93
+
94
+ :where(.avdeb-btn--solid:hover) {
95
+ transform: translateY(-1px);
96
+ box-shadow: 0 14px 30px -12px var(--avdeb-accent);
97
+ }
98
+
99
+ :where(.avdeb-btn--outline) {
100
+ background: transparent;
101
+ color: var(--avdeb-accent);
102
+ }
103
+
104
+ :where(.avdeb-btn--outline:hover) {
105
+ background: var(--avdeb-accent);
106
+ color: var(--avdeb-accent-contrast);
107
+ }
108
+
109
+ :where(.avdeb-btn--link) {
110
+ padding: 0;
111
+ border: 0;
112
+ border-radius: 0;
113
+ background: none;
114
+ color: var(--avdeb-accent);
115
+ }
116
+
117
+ :where(.avdeb-btn--link:hover) {
118
+ text-decoration: underline;
119
+ text-underline-offset: 0.2em;
120
+ }
121
+
122
+ @media (prefers-reduced-motion: reduce) {
123
+ :where(.avdeb-btn, .avdeb-btn svg) {
124
+ transition: none;
125
+ }
126
+
127
+ :where(.avdeb-btn:hover, .avdeb-btn:hover svg) {
128
+ transform: none;
129
+ }
130
+ }
131
+ </style>
@@ -0,0 +1,15 @@
1
+ ---
2
+ /** Portable Text renderer for `avdeb-button` blocks. */
3
+ import { buttonRequest } from "../blocks.ts";
4
+ import Button from "./Button.astro";
5
+ import { loadContext } from "./load.ts";
6
+
7
+ interface Props {
8
+ node: Record<string, unknown>;
9
+ }
10
+
11
+ const req = buttonRequest(Astro.props.node ?? {});
12
+ const context = await loadContext(Astro.locals, Astro.url);
13
+ ---
14
+
15
+ <Button context={context} href={req.href} label={req.label} variant={req.variant} align={req.align} />