@at-flux/astroflare 1.0.2 → 1.0.4

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.
Files changed (41) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +98 -14
  3. package/dist/chunk-pbuEa-1d.js +13 -0
  4. package/dist/core.cjs +162 -138
  5. package/dist/core.d.cts +59 -2
  6. package/dist/core.d.ts +59 -2
  7. package/dist/core.js +147 -16
  8. package/dist/forms/index.cjs +7 -130
  9. package/dist/forms/index.d.cts +2 -52
  10. package/dist/forms/index.d.ts +2 -52
  11. package/dist/forms/index.js +99 -14
  12. package/dist/{chunk-DRYHJSYC.js → forms-8uIdWmMD.cjs} +81 -53
  13. package/dist/index-Bk-K9aDQ.d.ts +44 -0
  14. package/dist/index-CcH_yXr-.d.cts +44 -0
  15. package/dist/index.cjs +20 -141
  16. package/dist/index.d.cts +3 -2
  17. package/dist/index.d.ts +3 -2
  18. package/dist/index.js +3 -17
  19. package/package.json +14 -8
  20. package/src/components/CollectionQuery.astro +107 -0
  21. package/src/components/ContactModalCta.astro +2 -0
  22. package/src/components/FilterPills.astro +164 -0
  23. package/src/components/IconButton.astro +5 -0
  24. package/src/components/InstagramProfileLink.astro +3 -0
  25. package/src/components/ListSummary.astro +63 -0
  26. package/src/components/MediaProtect.astro +41 -0
  27. package/src/components/Modal.astro +3 -0
  28. package/src/components/ModalTrigger.astro +2 -0
  29. package/src/components/Pager.astro +92 -0
  30. package/src/components/Section.astro +3 -0
  31. package/src/components/TagSummary.astro +71 -0
  32. package/src/components/ThemeToggle.astro +1 -0
  33. package/src/components/Tooltip.astro +70 -0
  34. package/src/components/collection-query-props.ts +45 -0
  35. package/src/runtime/collection-query.ts +156 -0
  36. package/src/runtime/media-protect.ts +70 -0
  37. package/src/styles/accessibility.css +1 -1
  38. package/src/styles/no-save.css +2 -2
  39. package/src/styles/prose.css +23 -11
  40. package/src/styles/scrollbar.css +10 -3
  41. package/dist/chunk-ALMPH3A2.js +0 -0
@@ -1,53 +1,56 @@
1
+ //#region \0rolldown/runtime.js
1
2
  var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
5
11
  };
6
-
7
- // src/forms/index.ts
8
- var forms_exports = {};
9
- __export(forms_exports, {
10
- composeEmailAddress: () => composeEmailAddress,
11
- generateFormResultHtml: () => generateFormResultHtml,
12
- generateFormSectionHtml: () => generateFormSectionHtml,
13
- renderEmailTemplate: () => renderEmailTemplate,
14
- sendEmail: () => sendEmail
12
+ //#endregion
13
+ let resend = require("resend");
14
+ //#region src/forms/index.ts
15
+ var forms_exports = /* @__PURE__ */ __exportAll({
16
+ composeEmailAddress: () => composeEmailAddress,
17
+ generateFormResultHtml: () => generateFormResultHtml,
18
+ generateFormSectionHtml: () => generateFormSectionHtml,
19
+ renderEmailTemplate: () => renderEmailTemplate,
20
+ sendEmail: () => sendEmail
15
21
  });
16
- import { Resend } from "resend";
17
22
  async function sendEmail(config, payload) {
18
- if (config.mock) {
19
- console.info("[astroflare:forms] Mock email payload", payload);
20
- return { id: "mock-email-id" };
21
- }
22
- const resend = new Resend(config.apiKey);
23
- const { data, error } = await resend.emails.send({
24
- from: payload.from,
25
- to: payload.to,
26
- subject: payload.subject,
27
- html: payload.html
28
- });
29
- if (error) {
30
- console.error("[astroflare:forms] Resend API error", error);
31
- throw new Error(`Failed to send email: ${error.message ?? "Unknown error"}`);
32
- }
33
- return data;
23
+ if (config.mock) {
24
+ console.info("[astroflare:forms] Mock email payload", payload);
25
+ return { id: "mock-email-id" };
26
+ }
27
+ const { data, error } = await new resend.Resend(config.apiKey).emails.send({
28
+ from: payload.from,
29
+ to: payload.to,
30
+ subject: payload.subject,
31
+ html: payload.html
32
+ });
33
+ if (error) {
34
+ console.error("[astroflare:forms] Resend API error", error);
35
+ throw new Error(`Failed to send email: ${error.message ?? "Unknown error"}`);
36
+ }
37
+ return data;
34
38
  }
35
39
  function composeEmailAddress(local, domain, tag) {
36
- const taggedLocal = tag ? `${local}+${tag}` : local;
37
- return `${taggedLocal}@${domain}`;
40
+ return `${tag ? `${local}+${tag}` : local}@${domain}`;
38
41
  }
39
42
  function generateFormSectionHtml(section) {
40
- const itemsHtml = section.items.map((item) => {
41
- const value = item.value ?? "";
42
- const isHtml = /<[^>]+>/.test(value);
43
- return `
43
+ const itemsHtml = section.items.map((item) => {
44
+ const value = item.value ?? "";
45
+ const isHtml = /<[^>]+>/.test(value);
46
+ return `
44
47
  <div style="margin-bottom:16px;">
45
48
  <p style="margin:0 0 4px;font-weight:600;color:#111827;">${item.key}</p>
46
49
  ${isHtml ? `<div style="margin:0;color:#111827;line-height:1.6;">${value || "Not specified"}</div>` : `<p style="margin:0;color:#111827;line-height:1.6;white-space:pre-wrap;">${value || "Not specified"}</p>`}
47
50
  </div>
48
51
  `;
49
- }).join("");
50
- return `
52
+ }).join("");
53
+ return `
51
54
  <section style="background:#f3f4f6;padding:16px;border-radius:8px;margin:16px 0;border:1px solid #e5e7eb;">
52
55
  <h3 style="margin:0 0 12px;color:#111827;font-size:16px;font-weight:600;">${section.title}</h3>
53
56
  <div style="color:#111827;">
@@ -57,14 +60,11 @@ function generateFormSectionHtml(section) {
57
60
  `;
58
61
  }
59
62
  function generateFormResultHtml(sections) {
60
- return sections.map(generateFormSectionHtml).join("\n");
63
+ return sections.map(generateFormSectionHtml).join("\n");
61
64
  }
62
65
  async function renderEmailTemplate(args) {
63
- const { title, contentHtml, brandName, footerText } = args;
64
- const footer = footerText ?? `This message was generated by the ${brandName ?? "site"} contact form on ${(/* @__PURE__ */ new Date()).toLocaleString(
65
- "en-GB"
66
- )}.`;
67
- return `<!DOCTYPE html>
66
+ const { title, contentHtml, brandName, footerText } = args;
67
+ return `<!DOCTYPE html>
68
68
  <html lang="en">
69
69
  <head>
70
70
  <meta charset="utf-8">
@@ -95,7 +95,7 @@ async function renderEmailTemplate(args) {
95
95
  <tr>
96
96
  <td style="padding:16px 24px;background:#f9fafb;border-top:1px solid #e5e7eb;">
97
97
  <p style="margin:0;color:#6b7280;font-size:12px;line-height:18px;">
98
- ${footer}
98
+ ${footerText ?? `This message was generated by the ${brandName ?? "site"} contact form on ${(/* @__PURE__ */ new Date()).toLocaleString("en-GB")}.`}
99
99
  </p>
100
100
  </td>
101
101
  </tr>
@@ -106,12 +106,40 @@ async function renderEmailTemplate(args) {
106
106
  </body>
107
107
  </html>`;
108
108
  }
109
-
110
- export {
111
- sendEmail,
112
- composeEmailAddress,
113
- generateFormSectionHtml,
114
- generateFormResultHtml,
115
- renderEmailTemplate,
116
- forms_exports
117
- };
109
+ //#endregion
110
+ Object.defineProperty(exports, "composeEmailAddress", {
111
+ enumerable: true,
112
+ get: function() {
113
+ return composeEmailAddress;
114
+ }
115
+ });
116
+ Object.defineProperty(exports, "forms_exports", {
117
+ enumerable: true,
118
+ get: function() {
119
+ return forms_exports;
120
+ }
121
+ });
122
+ Object.defineProperty(exports, "generateFormResultHtml", {
123
+ enumerable: true,
124
+ get: function() {
125
+ return generateFormResultHtml;
126
+ }
127
+ });
128
+ Object.defineProperty(exports, "generateFormSectionHtml", {
129
+ enumerable: true,
130
+ get: function() {
131
+ return generateFormSectionHtml;
132
+ }
133
+ });
134
+ Object.defineProperty(exports, "renderEmailTemplate", {
135
+ enumerable: true,
136
+ get: function() {
137
+ return renderEmailTemplate;
138
+ }
139
+ });
140
+ Object.defineProperty(exports, "sendEmail", {
141
+ enumerable: true,
142
+ get: function() {
143
+ return sendEmail;
144
+ }
145
+ });
@@ -0,0 +1,44 @@
1
+ import { CreateEmailResponseSuccess } from "resend";
2
+
3
+ //#region src/forms/index.d.ts
4
+ declare namespace index_d_exports {
5
+ export { EmailPayload, FormSection, ResendConfig, composeEmailAddress, generateFormResultHtml, generateFormSectionHtml, renderEmailTemplate, sendEmail };
6
+ }
7
+ interface ResendConfig {
8
+ /**
9
+ * Resend API key.
10
+ */
11
+ apiKey: string;
12
+ /**
13
+ * When true, do not send real email – log to console instead.
14
+ * Useful for local/dev environments.
15
+ */
16
+ mock?: boolean;
17
+ }
18
+ interface EmailPayload {
19
+ from: string;
20
+ to: string;
21
+ subject: string;
22
+ html: string;
23
+ }
24
+ declare function sendEmail(config: ResendConfig, payload: EmailPayload): Promise<CreateEmailResponseSuccess | {
25
+ id: string;
26
+ }>;
27
+ declare function composeEmailAddress(local: string, domain: string, tag?: string): string;
28
+ interface FormSection {
29
+ title: string;
30
+ items: {
31
+ key: string;
32
+ value: string;
33
+ }[];
34
+ }
35
+ declare function generateFormSectionHtml(section: FormSection): string;
36
+ declare function generateFormResultHtml(sections: FormSection[]): string;
37
+ declare function renderEmailTemplate(args: {
38
+ title: string;
39
+ contentHtml: string;
40
+ brandName?: string;
41
+ footerText?: string;
42
+ }): Promise<string>;
43
+ //#endregion
44
+ export { generateFormResultHtml as a, renderEmailTemplate as c, composeEmailAddress as i, sendEmail as l, FormSection as n, generateFormSectionHtml as o, ResendConfig as r, index_d_exports as s, EmailPayload as t };
@@ -0,0 +1,44 @@
1
+ import { CreateEmailResponseSuccess } from "resend";
2
+
3
+ //#region \0rolldown/runtime.js
4
+ declare namespace index_d_exports {
5
+ export { EmailPayload, FormSection, ResendConfig, composeEmailAddress, generateFormResultHtml, generateFormSectionHtml, renderEmailTemplate, sendEmail };
6
+ }
7
+ interface ResendConfig {
8
+ /**
9
+ * Resend API key.
10
+ */
11
+ apiKey: string;
12
+ /**
13
+ * When true, do not send real email – log to console instead.
14
+ * Useful for local/dev environments.
15
+ */
16
+ mock?: boolean;
17
+ }
18
+ interface EmailPayload {
19
+ from: string;
20
+ to: string;
21
+ subject: string;
22
+ html: string;
23
+ }
24
+ declare function sendEmail(config: ResendConfig, payload: EmailPayload): Promise<CreateEmailResponseSuccess | {
25
+ id: string;
26
+ }>;
27
+ declare function composeEmailAddress(local: string, domain: string, tag?: string): string;
28
+ interface FormSection {
29
+ title: string;
30
+ items: {
31
+ key: string;
32
+ value: string;
33
+ }[];
34
+ }
35
+ declare function generateFormSectionHtml(section: FormSection): string;
36
+ declare function generateFormResultHtml(sections: FormSection[]): string;
37
+ declare function renderEmailTemplate(args: {
38
+ title: string;
39
+ contentHtml: string;
40
+ brandName?: string;
41
+ footerText?: string;
42
+ }): Promise<string>;
43
+ //#endregion
44
+ export { generateFormResultHtml as a, renderEmailTemplate as c, composeEmailAddress as i, sendEmail as l, FormSection as n, generateFormSectionHtml as o, ResendConfig as r, index_d_exports as s, EmailPayload as t };
package/dist/index.cjs CHANGED
@@ -1,142 +1,21 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- composeEmailAddress: () => composeEmailAddress,
24
- forms: () => forms_exports,
25
- generateFormResultHtml: () => generateFormResultHtml,
26
- generateFormSectionHtml: () => generateFormSectionHtml,
27
- renderEmailTemplate: () => renderEmailTemplate,
28
- sendEmail: () => sendEmail
29
- });
30
- module.exports = __toCommonJS(index_exports);
31
-
32
- // src/forms/index.ts
33
- var forms_exports = {};
34
- __export(forms_exports, {
35
- composeEmailAddress: () => composeEmailAddress,
36
- generateFormResultHtml: () => generateFormResultHtml,
37
- generateFormSectionHtml: () => generateFormSectionHtml,
38
- renderEmailTemplate: () => renderEmailTemplate,
39
- sendEmail: () => sendEmail
40
- });
41
- var import_resend = require("resend");
42
- async function sendEmail(config, payload) {
43
- if (config.mock) {
44
- console.info("[astroflare:forms] Mock email payload", payload);
45
- return { id: "mock-email-id" };
46
- }
47
- const resend = new import_resend.Resend(config.apiKey);
48
- const { data, error } = await resend.emails.send({
49
- from: payload.from,
50
- to: payload.to,
51
- subject: payload.subject,
52
- html: payload.html
53
- });
54
- if (error) {
55
- console.error("[astroflare:forms] Resend API error", error);
56
- throw new Error(`Failed to send email: ${error.message ?? "Unknown error"}`);
57
- }
58
- return data;
59
- }
60
- function composeEmailAddress(local, domain, tag) {
61
- const taggedLocal = tag ? `${local}+${tag}` : local;
62
- return `${taggedLocal}@${domain}`;
63
- }
64
- function generateFormSectionHtml(section) {
65
- const itemsHtml = section.items.map((item) => {
66
- const value = item.value ?? "";
67
- const isHtml = /<[^>]+>/.test(value);
68
- return `
69
- <div style="margin-bottom:16px;">
70
- <p style="margin:0 0 4px;font-weight:600;color:#111827;">${item.key}</p>
71
- ${isHtml ? `<div style="margin:0;color:#111827;line-height:1.6;">${value || "Not specified"}</div>` : `<p style="margin:0;color:#111827;line-height:1.6;white-space:pre-wrap;">${value || "Not specified"}</p>`}
72
- </div>
73
- `;
74
- }).join("");
75
- return `
76
- <section style="background:#f3f4f6;padding:16px;border-radius:8px;margin:16px 0;border:1px solid #e5e7eb;">
77
- <h3 style="margin:0 0 12px;color:#111827;font-size:16px;font-weight:600;">${section.title}</h3>
78
- <div style="color:#111827;">
79
- ${itemsHtml}
80
- </div>
81
- </section>
82
- `;
83
- }
84
- function generateFormResultHtml(sections) {
85
- return sections.map(generateFormSectionHtml).join("\n");
86
- }
87
- async function renderEmailTemplate(args) {
88
- const { title, contentHtml, brandName, footerText } = args;
89
- const footer = footerText ?? `This message was generated by the ${brandName ?? "site"} contact form on ${(/* @__PURE__ */ new Date()).toLocaleString(
90
- "en-GB"
91
- )}.`;
92
- return `<!DOCTYPE html>
93
- <html lang="en">
94
- <head>
95
- <meta charset="utf-8">
96
- <meta name="viewport" content="width=device-width, initial-scale=1">
97
- <title>${title}</title>
98
- <meta http-equiv="x-ua-compatible" content="ie=edge">
99
- </head>
100
- <body style="margin:0;padding:0;background:#f3f4f6;color:#111827;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';">
101
- <table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background:#f3f4f6;">
102
- <tr>
103
- <td align="center" style="padding:24px;">
104
- <table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="max-width:720px;background:#ffffff;border-radius:12px;overflow:hidden;border:1px solid #e5e7eb;">
105
- <tr>
106
- <td style="padding:24px 24px 16px 24px;border-bottom:1px solid #e5e7eb;">
107
- <h1 style="margin:0 0 8px 0;font-size:20px;line-height:28px;color:#111827;letter-spacing:0.3px;">
108
- ${title}
109
- </h1>
110
- <p style="margin:0;font-size:13px;color:#6b7280;line-height:20px;">
111
- Contact form submission
112
- </p>
113
- </td>
114
- </tr>
115
- <tr>
116
- <td style="padding:24px;">
117
- ${contentHtml}
118
- </td>
119
- </tr>
120
- <tr>
121
- <td style="padding:16px 24px;background:#f9fafb;border-top:1px solid #e5e7eb;">
122
- <p style="margin:0;color:#6b7280;font-size:12px;line-height:18px;">
123
- ${footer}
124
- </p>
125
- </td>
126
- </tr>
127
- </table>
128
- </td>
129
- </tr>
130
- </table>
131
- </body>
132
- </html>`;
133
- }
134
- // Annotate the CommonJS export names for ESM import in node:
135
- 0 && (module.exports = {
136
- composeEmailAddress,
137
- forms,
138
- generateFormResultHtml,
139
- generateFormSectionHtml,
140
- renderEmailTemplate,
141
- sendEmail
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_forms = require("./forms-8uIdWmMD.cjs");
3
+ const require_core = require("./core.cjs");
4
+ exports.buildCollectionHref = require_core.buildCollectionHref;
5
+ exports.buildPageSequence = require_core.buildPageSequence;
6
+ exports.composeEmailAddress = require_forms.composeEmailAddress;
7
+ exports.formatDisplayDate = require_core.formatDisplayDate;
8
+ Object.defineProperty(exports, "forms", {
9
+ enumerable: true,
10
+ get: function() {
11
+ return require_forms.forms_exports;
12
+ }
142
13
  });
14
+ exports.generateFormResultHtml = require_forms.generateFormResultHtml;
15
+ exports.generateFormSectionHtml = require_forms.generateFormSectionHtml;
16
+ exports.getTagPalette = require_core.getTagPalette;
17
+ exports.matchesCollectionFilters = require_core.matchesCollectionFilters;
18
+ exports.paginateCollection = require_core.paginateCollection;
19
+ exports.parseCollectionQuery = require_core.parseCollectionQuery;
20
+ exports.renderEmailTemplate = require_forms.renderEmailTemplate;
21
+ exports.sendEmail = require_forms.sendEmail;
package/dist/index.d.cts CHANGED
@@ -1,2 +1,3 @@
1
- export { EmailPayload, FormSection, ResendConfig, composeEmailAddress, i as forms, generateFormResultHtml, generateFormSectionHtml, renderEmailTemplate, sendEmail } from './forms/index.cjs';
2
- import 'resend';
1
+ import { a as generateFormResultHtml, c as renderEmailTemplate, i as composeEmailAddress, l as sendEmail, n as FormSection, o as generateFormSectionHtml, r as ResendConfig, s as index_d_exports, t as EmailPayload } from "./index-CcH_yXr-.cjs";
2
+ import { CollectionQueryOptions, CollectionQueryState, DateFormatOptions, PaginationSlice, TagColorOptions, TagPalette, buildCollectionHref, buildPageSequence, formatDisplayDate, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery } from "./core.cjs";
3
+ export { CollectionQueryOptions, CollectionQueryState, DateFormatOptions, EmailPayload, FormSection, PaginationSlice, ResendConfig, TagColorOptions, TagPalette, buildCollectionHref, buildPageSequence, composeEmailAddress, formatDisplayDate, index_d_exports as forms, generateFormResultHtml, generateFormSectionHtml, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery, renderEmailTemplate, sendEmail };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { EmailPayload, FormSection, ResendConfig, composeEmailAddress, i as forms, generateFormResultHtml, generateFormSectionHtml, renderEmailTemplate, sendEmail } from './forms/index.js';
2
- import 'resend';
1
+ import { a as generateFormResultHtml, c as renderEmailTemplate, i as composeEmailAddress, l as sendEmail, n as FormSection, o as generateFormSectionHtml, r as ResendConfig, s as index_d_exports, t as EmailPayload } from "./index-Bk-K9aDQ.js";
2
+ import { CollectionQueryOptions, CollectionQueryState, DateFormatOptions, PaginationSlice, TagColorOptions, TagPalette, buildCollectionHref, buildPageSequence, formatDisplayDate, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery } from "./core.js";
3
+ export { CollectionQueryOptions, CollectionQueryState, DateFormatOptions, EmailPayload, FormSection, PaginationSlice, ResendConfig, TagColorOptions, TagPalette, buildCollectionHref, buildPageSequence, composeEmailAddress, formatDisplayDate, index_d_exports as forms, generateFormResultHtml, generateFormSectionHtml, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery, renderEmailTemplate, sendEmail };
package/dist/index.js CHANGED
@@ -1,17 +1,3 @@
1
- import "./chunk-ALMPH3A2.js";
2
- import {
3
- composeEmailAddress,
4
- forms_exports,
5
- generateFormResultHtml,
6
- generateFormSectionHtml,
7
- renderEmailTemplate,
8
- sendEmail
9
- } from "./chunk-DRYHJSYC.js";
10
- export {
11
- composeEmailAddress,
12
- forms_exports as forms,
13
- generateFormResultHtml,
14
- generateFormSectionHtml,
15
- renderEmailTemplate,
16
- sendEmail
17
- };
1
+ import { composeEmailAddress, generateFormResultHtml, generateFormSectionHtml, renderEmailTemplate, sendEmail, t as forms_exports } from "./forms/index.js";
2
+ import { buildCollectionHref, buildPageSequence, formatDisplayDate, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery } from "./core.js";
3
+ export { buildCollectionHref, buildPageSequence, composeEmailAddress, formatDisplayDate, forms_exports as forms, generateFormResultHtml, generateFormSectionHtml, getTagPalette, matchesCollectionFilters, paginateCollection, parseCollectionQuery, renderEmailTemplate, sendEmail };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@at-flux/astroflare",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "description": "Reusable headless components, styles, and utilities for Astro + Tailwind v4 + Cloudflare projects",
6
- "author": "Taylor Siviter <taylor@siviter.xyz>",
6
+ "author": "atflux <dev@atflux.uk>",
7
7
  "license": "MIT",
8
8
  "keywords": [
9
9
  "astro",
@@ -55,13 +55,15 @@
55
55
  "files": [
56
56
  "dist",
57
57
  "src/components",
58
+ "src/runtime",
58
59
  "src/styles",
59
60
  "scripts/link-local.mjs",
60
61
  "README.md"
61
62
  ],
62
63
  "devDependencies": {
64
+ "@astrojs/node": "^9.5.5",
63
65
  "jsdom": "^25.0.1",
64
- "tsup": "^8.0.0",
66
+ "tsdown": "^0.21.7",
65
67
  "typescript": "^5.0.0",
66
68
  "vitest": "^3.2.4"
67
69
  },
@@ -77,22 +79,26 @@
77
79
  }
78
80
  },
79
81
  "engines": {
80
- "node": ">=18"
82
+ "node": ">=20.19"
81
83
  },
82
84
  "repository": {
83
85
  "type": "git",
84
- "url": "git+https://github.com/at-flux/astroflare.git"
86
+ "url": "git+https://github.com/at-flux/astroflare.git",
87
+ "directory": "packages/astroflare"
85
88
  },
86
89
  "bugs": {
87
90
  "url": "https://github.com/at-flux/astroflare/issues"
88
91
  },
89
- "homepage": "https://github.com/at-flux/astroflare#readme",
92
+ "homepage": "https://github.com/at-flux/astroflare/tree/main/packages/astroflare",
90
93
  "publishConfig": {
91
94
  "access": "public"
92
95
  },
93
96
  "scripts": {
94
- "build": "tsup",
95
- "dev": "tsup --watch",
97
+ "build": "tsdown",
98
+ "dev": "tsdown --watch",
99
+ "styleguide:dev": "astro dev --root styleguide",
100
+ "styleguide:build": "astro build --root styleguide",
101
+ "styleguide:preview": "astro preview --root styleguide",
96
102
  "test": "vitest run",
97
103
  "test:watch": "vitest",
98
104
  "typecheck": "tsc --noEmit",
@@ -0,0 +1,107 @@
1
+ ---
2
+ import FilterPills from "./FilterPills.astro";
3
+ import Pager from "./Pager.astro";
4
+ import { buildCollectionHref, buildPageSequence } from "../collection-query";
5
+ import type { CollectionQueryProps, CollectionQueryServerProps } from "./collection-query-props";
6
+ type Props = CollectionQueryProps;
7
+
8
+ const {
9
+ useServer = false,
10
+ filters = [],
11
+ maxPageButtons = 7,
12
+ filtersClass = "mb-8",
13
+ pagerClass = "mt-6",
14
+ perPage = 9,
15
+ class: className = "",
16
+ } = Astro.props;
17
+
18
+ const serverProps = useServer
19
+ ? (Astro.props as CollectionQueryServerProps)
20
+ : null;
21
+ const pathname = serverProps?.pathname ?? "";
22
+ const query = serverProps?.query ?? { page: 1, size: 9, offset: 0, filters: {} };
23
+ const totalPages = serverProps?.totalPages ?? 1;
24
+ const currentPage = serverProps?.currentPage ?? 1;
25
+
26
+ const activeFilters = query.filters ?? {};
27
+ const allHref = buildCollectionHref(pathname, query, { filters: {}, page: 1, offset: 0 });
28
+ const serverFilterItems = filters.map((option) => {
29
+ const nextFilters = { ...activeFilters, [option.key]: option.value };
30
+ return {
31
+ value: `${option.key}:${option.value}`,
32
+ label: option.label ?? option.value,
33
+ href: buildCollectionHref(pathname, query, { filters: nextFilters, page: 1, offset: 0 }),
34
+ active: activeFilters[option.key] === option.value,
35
+ colorKey: option.value,
36
+ };
37
+ });
38
+ const clientFilterItems = filters.map((option) => ({
39
+ value: option.value,
40
+ label: option.label ?? option.value,
41
+ colorKey: option.value,
42
+ }));
43
+ const pagerItems = buildPageSequence(totalPages, currentPage, maxPageButtons).map((item) =>
44
+ item === "…"
45
+ ? { ellipsis: true as const }
46
+ : {
47
+ page: item,
48
+ href: buildCollectionHref(pathname, query, { page: item, offset: (item - 1) * query.size }),
49
+ active: item === currentPage,
50
+ },
51
+ );
52
+ ---
53
+
54
+ {useServer && (
55
+ <>
56
+ <slot
57
+ name="filters"
58
+ >
59
+ {serverFilterItems.length > 0 && (
60
+ <FilterPills
61
+ items={serverFilterItems}
62
+ allHref={allHref}
63
+ active={Object.keys(activeFilters).length === 0 ? "all" : "__filtered__"}
64
+ class={filtersClass}
65
+ />
66
+ )}
67
+ </slot>
68
+ <slot />
69
+ <slot name="pager">
70
+ <Pager items={pagerItems} class={pagerClass} />
71
+ </slot>
72
+ </>
73
+ )}
74
+
75
+ {!useServer && (
76
+ <collection-query
77
+ class={className}
78
+ data-af-query
79
+ data-per-page={String(perPage)}
80
+ data-max-page-buttons={String(maxPageButtons)}
81
+ >
82
+ <slot
83
+ name="filters"
84
+ >
85
+ {clientFilterItems.length > 0 && (
86
+ <FilterPills
87
+ items={clientFilterItems}
88
+ active="all"
89
+ class={filtersClass}
90
+ />
91
+ )}
92
+ </slot>
93
+ <slot />
94
+ <slot name="pager">
95
+ <Pager class={pagerClass} />
96
+ </slot>
97
+ </collection-query>
98
+ )}
99
+
100
+ {
101
+ !useServer && (
102
+ <script>
103
+ import { initCollectionQueryRoots } from "../runtime/collection-query";
104
+ initCollectionQueryRoots();
105
+ </script>
106
+ )
107
+ }
@@ -4,9 +4,11 @@ import ModalTrigger from './ModalTrigger.astro';
4
4
  interface Props {
5
5
  /** Target dialog id (must match `<dialog id="…">`). */
6
6
  modalId?: string;
7
+ /** Visible CTA text. */
7
8
  label: string;
8
9
  /** `solid` — primary pill; `text` — tertiary link style (e.g. inline in prose). */
9
10
  variant?: 'solid' | 'text';
11
+ /** Classes applied to the trigger host. */
10
12
  class?: string;
11
13
  }
12
14