navne-default-ad 1.0.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.
package/AUDIT.md ADDED
@@ -0,0 +1,25 @@
1
+ # Implementation audit
2
+
3
+ Audit date: 2026-09-04. No consumer was changed.
4
+
5
+ ## Implementations found
6
+
7
+ 1. `adBuilder/gobuild-ads-app/app/ad/template/defaultAd/components/defaultAdView.tsx`: fixed Schoolbook published/PDF renderer, fed by a Strapi adapter and coupled to a Zustand ceremony store.
8
+ 2. `adBuilder/gobuild-ads-app/app/pages/default/DefaultView.tsx`: interactive builder variant. It duplicates the layout but adds Zustand state, focus placeholders, dirty-state tracking, responsive height measurement, and builder callbacks.
9
+ 3. `obituries/digital-obituaries-app/app/components/defaultAd/Index.tsx`: publication viewer for obituary and thank-you ads. It supports Strapi-controlled typography/templates, local date conversion, SVG icons, and React state for height.
10
+
11
+ The API/backend contains preview URL generation but no additional React renderer. The thank-you layout is a conditional branch in the same two renderers, not a separate component.
12
+
13
+ ## Relevant differences and decisions
14
+
15
+ - React/Next: builder uses React 18 + Next 14; viewer uses React 19 + Next 15. The package supports both React majors and contains no Next imports.
16
+ - Data: the source shapes differ (`briefText` vs `briefIntroduction`, ceremony code vs label/object, numeric/string layout values). The package uses grouped, normalized data and exported adapters/types rather than leaking Strapi data.
17
+ - Typography: builder is fixed at 10/14pt Schoolbook; viewer has dynamic Strapi template values and Raleway/Athelas defaults. Both are represented by `DefaultAdStyle`, two presets, and `styleFromLegacyTemplate`.
18
+ - Styling: both implementations rely on Tailwind arbitrary classes, which are unsafe in an installed package. The package ships prefixed plain CSS and inline numeric styles.
19
+ - Fonts: both apps use `next/font/google` for Raleway and external `tk-athelas`/`tk-schoolbook` classes; no font assets exist locally. Consumers supply licensed fonts through `--default-ad-font-primary` and `--default-ad-font-secondary`, or `fontFamily` settings.
20
+ - Icons: SVG markup and dimensions previously come from Strapi. `DefaultAdIcon` carries those values; no app-relative asset URL is used. Markup must be trusted/sanitized before it reaches the renderer.
21
+ - Business logic: Zustand, focus/dirty state, ResizeObserver height estimation, API/Strapi lookup, PDF controls, navigation, pricing, and saving remain outside the package. `mode` adds semantic metadata and builder placeholder behavior only.
22
+ - Dates: differing source converters are supported with injectable formatters; simple stable defaults are included.
23
+ - SSR: rendering is pure and uses no `window`, `document`, hook, store, or environment variable.
24
+
25
+ The fixed AdBuilder published renderer is the visual baseline for `classicDefaultAdStyle`; the viewer's richer typography is retained as `publicationDefaultAdStyle` plus the legacy-template adapter.
package/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2026. All rights reserved.
2
+
3
+ This package is private and unlicensed until the owner selects a publication license.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # gobuild-default-ad
2
+
3
+ Framework-neutral React renderer for obituary and thank-you advertisements. This package is the future shared rendering layer; it does not fetch, save, price, navigate, or read application stores.
4
+
5
+ ## Install and use
6
+
7
+ ```bash
8
+ npm install gobuild-default-ad
9
+ ```
10
+
11
+ React 18/19 and React DOM 18/19 are peer dependencies and are never bundled.
12
+
13
+ ```tsx
14
+ import { DefaultAd, classicDefaultAdStyle, type DefaultAdData } from "gobuild-default-ad";
15
+ import "gobuild-default-ad/styles.css";
16
+
17
+ const data: DefaultAdData = {
18
+ type: "obituaries",
19
+ contact: {
20
+ firstName: "Anna",
21
+ lastName: "Jensen",
22
+ birthDate: "1940-01-02",
23
+ deathDate: "2026-08-30",
24
+ showBirthDate: true,
25
+ showDeathDate: true,
26
+ },
27
+ text: { intro: "Til minde om", deceased: "Elsket og savnet" },
28
+ };
29
+
30
+ export function Ad() {
31
+ return <DefaultAd data={data} style={{ ...classicDefaultAdStyle, columnsMm: 86 }} />;
32
+ }
33
+ ```
34
+
35
+ Importing the component also references its CSS, but the explicit stylesheet import is recommended for predictable framework ordering. No Tailwind content configuration is needed.
36
+
37
+ ## Public API
38
+
39
+ - `DefaultAd`: pure, SSR-safe renderer.
40
+ - `DefaultAdProps`: data, style, mode, formatter, placeholder, and standard `div` props.
41
+ - `DefaultAdData`, `DefaultAdContact`, `DefaultAdTextFields`, `DefaultAdIcon`: normalized input model.
42
+ - `DefaultAdStyle`, `DefaultAdTypography`, `DefaultAdSpacing`: layout and template controls.
43
+ - `classicDefaultAdStyle`: current fixed AdBuilder look.
44
+ - `publicationDefaultAdStyle`: current publication viewer defaults.
45
+ - `styleFromLegacyTemplate`: converts existing Strapi template numeric/font fields.
46
+
47
+ The consumer should map its API/store model to `DefaultAdData`. SVG markup is rendered as supplied and therefore must come from a trusted or sanitized source.
48
+
49
+ ### Fonts
50
+
51
+ Font files are not present in the source apps and are not redistributed. Load the same licensed fonts in the consumer, then set:
52
+
53
+ ```css
54
+ :root {
55
+ --default-ad-font-primary: Schoolbook, Georgia, serif;
56
+ --default-ad-font-secondary: Athelas, Georgia, serif;
57
+ }
58
+ ```
59
+
60
+ Alternatively pass `style.typography.fontFamily` and `secondaryFontFamily`.
61
+
62
+ ### Dates
63
+
64
+ Use `formatters.date`, `formatters.funeralDate`, and `formatters.lowercaseFirst` to preserve app-specific locale and UTC behavior. Defaults have no locale/runtime dependency.
65
+
66
+ ## Compatibility
67
+
68
+ - React/React DOM: `>=18 <20` peer dependencies.
69
+ - TypeScript: declarations are included.
70
+ - Next.js 14/15, Webpack, Turbopack: ESM and CommonJS exports; no Next API, alias, store, environment variable, or browser-only render dependency.
71
+ - SSR and Client Components: supported. The component itself needs no hook and no `use client` directive.
72
+ - CSS: package-owned, prefixed CSS; no Tailwind scan of `node_modules` required.
73
+
74
+ ## Build, test, and package
75
+
76
+ ```bash
77
+ npm install
78
+ npm run typecheck
79
+ npm test
80
+ npm run build
81
+ npm pack
82
+ ```
83
+
84
+ To test the tarball without publishing:
85
+
86
+ ```bash
87
+ npm install /absolute/path/to/gobuild-default-ad-0.1.0.tgz
88
+ ```
89
+
90
+ Import it in a temporary consumer and run that consumer's build. Do not migrate production components until the separate migration step.
91
+
92
+ ## Before publishing
93
+
94
+ Review `package.json` (especially `name`, scope, version, license, repository, and `publishConfig`), `README.md`, `AUDIT.md`, all exported types, and the output of `npm pack --dry-run`. Change the neutral package name to the final owned NPM scope if applicable. Publication is intentionally manual.
package/dist/index.cjs ADDED
@@ -0,0 +1,282 @@
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
+ DefaultAd: () => DefaultAd,
24
+ classicDefaultAdStyle: () => classicDefaultAdStyle,
25
+ publicationDefaultAdStyle: () => publicationDefaultAdStyle,
26
+ styleFromLegacyTemplate: () => styleFromLegacyTemplate
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/presets.ts
31
+ var classicDefaultAdStyle = {
32
+ columnsMm: 86,
33
+ heightMm: null,
34
+ paddingMm: 4,
35
+ horizontalPaddingMm: 2,
36
+ border: false,
37
+ borderWidthPt: 1.4,
38
+ typography: {
39
+ fontFamily: "var(--default-ad-font-primary, Schoolbook, Georgia, serif)",
40
+ secondaryFontFamily: "var(--default-ad-font-secondary, Schoolbook, Georgia, serif)",
41
+ introSize: 10,
42
+ introLeading: 12,
43
+ titleSize: 10,
44
+ titleLeading: 12,
45
+ nameSize: 14,
46
+ nameLeading: 16.8,
47
+ dateSize: 10,
48
+ longDateSize: 10,
49
+ dateLeading: 12,
50
+ bodySize: 10,
51
+ bodyLeading: 12,
52
+ memorialSize: 10,
53
+ memorialLeading: 12,
54
+ senderSize: 10,
55
+ senderLeading: 12
56
+ },
57
+ spacing: {
58
+ iconToText: 11,
59
+ introToTitle: 8,
60
+ textToName: 5.6,
61
+ dateTop: 5.6,
62
+ deceasedTop: 6,
63
+ memorialTop: 6,
64
+ senderTop: 8,
65
+ ceremonyTop: 8,
66
+ thanksTop: 7,
67
+ donationTop: 7,
68
+ sectionGapMm: 0
69
+ }
70
+ };
71
+ var publicationDefaultAdStyle = {
72
+ ...classicDefaultAdStyle,
73
+ typography: {
74
+ ...classicDefaultAdStyle.typography,
75
+ fontFamily: "var(--default-ad-font-primary, Raleway, Arial, sans-serif)",
76
+ secondaryFontFamily: "var(--default-ad-font-secondary, Athelas, Georgia, serif)",
77
+ introSize: 11,
78
+ introLeading: 13,
79
+ titleSize: 11,
80
+ titleLeading: 13,
81
+ nameSize: 17,
82
+ nameLeading: 15,
83
+ dateSize: 11.5,
84
+ longDateSize: 11,
85
+ bodySize: 12,
86
+ bodyLeading: 13,
87
+ memorialSize: 12,
88
+ memorialLeading: 13,
89
+ senderSize: 13,
90
+ senderLeading: 13
91
+ },
92
+ spacing: { ...classicDefaultAdStyle.spacing, sectionGapMm: 2 }
93
+ };
94
+ function styleFromLegacyTemplate(template) {
95
+ if (!template) return publicationDefaultAdStyle;
96
+ return {
97
+ ...publicationDefaultAdStyle,
98
+ typography: {
99
+ ...publicationDefaultAdStyle.typography,
100
+ fontFamily: template.font1 || publicationDefaultAdStyle.typography?.fontFamily,
101
+ secondaryFontFamily: template.font2 || publicationDefaultAdStyle.typography?.secondaryFontFamily,
102
+ introSize: template.introSize,
103
+ introLeading: template.introLeading,
104
+ titleSize: template.titleSize,
105
+ titleLeading: template.titleLeading,
106
+ nameSize: template.fullnameSize,
107
+ nameLeading: template.fullnameLeading
108
+ },
109
+ spacing: {
110
+ ...publicationDefaultAdStyle.spacing,
111
+ iconToText: template.textToIcon,
112
+ introToTitle: template.titleToText,
113
+ textToName: template.fullnameToText,
114
+ dateTop: template.datesTextMT,
115
+ deceasedTop: template.deceasedTextMT,
116
+ memorialTop: template.memorialTextMT,
117
+ senderTop: template.senderTextMT,
118
+ ceremonyTop: template.ceremonyTextMT,
119
+ thanksTop: template.thanksTextMT,
120
+ donationTop: template.donationTextMT
121
+ }
122
+ };
123
+ }
124
+
125
+ // src/utils.ts
126
+ var defaultFormatters = {
127
+ date(value) {
128
+ const match = value.match(/^(\d{4})-(\d{2})-(\d{2})/);
129
+ return match ? `${match[3]}.${match[2]}.${match[1]}` : value;
130
+ },
131
+ funeralDate(value, hideYear) {
132
+ if (!hideYear) return value;
133
+ return value.replace(/([.\/-])\d{4}(?=\D|$)/, "");
134
+ },
135
+ lowercaseFirst(value) {
136
+ return value ? value.charAt(0).toLocaleLowerCase() + value.slice(1) : value;
137
+ }
138
+ };
139
+ function mergeDefined(base, overrides) {
140
+ if (!overrides) return { ...base };
141
+ return Object.fromEntries(
142
+ Object.entries({ ...base, ...overrides }).filter(([, value]) => value !== void 0)
143
+ );
144
+ }
145
+ function decodeSvgMarkup(value) {
146
+ return value.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#(?:0*39|x0*27);/gi, "'").replace(/&amp;/g, "&");
147
+ }
148
+
149
+ // src/DefaultAd.tsx
150
+ var import_jsx_runtime = require("react/jsx-runtime");
151
+ function textStyle(size, leading, marginTop) {
152
+ return { fontSize: `${size}pt`, lineHeight: `${leading}pt`, marginTop: `${marginTop}pt` };
153
+ }
154
+ function Text({ children, className = "", style }) {
155
+ if (children === null || children === void 0 || children === "") return null;
156
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `gda-text ${className}`, style, children });
157
+ }
158
+ function DefaultAd({
159
+ data,
160
+ style,
161
+ mode = "published",
162
+ formatters,
163
+ showEmptyNamePlaceholder = mode === "builder",
164
+ emptyNamePlaceholder = "Fornavn Efternavn",
165
+ className = "",
166
+ rootStyle,
167
+ ...htmlProps
168
+ }) {
169
+ const typography = mergeDefined(
170
+ classicDefaultAdStyle.typography,
171
+ style?.typography
172
+ );
173
+ const spacing = mergeDefined(
174
+ classicDefaultAdStyle.spacing,
175
+ style?.spacing
176
+ );
177
+ const layout = mergeDefined(classicDefaultAdStyle, style);
178
+ const fmt = { ...defaultFormatters, ...formatters };
179
+ const { contact, text, icon, type } = data;
180
+ const hasName = Boolean(contact.firstName || contact.lastName);
181
+ const first = type === "thanks" ? text.thanksIntro : text.intro;
182
+ const second = type === "thanks" ? text.briefIntroduction : text.title;
183
+ const firstMargin = first && icon ? spacing.iconToText : 0;
184
+ const secondMargin = second ? first ? spacing.introToTitle : icon ? spacing.iconToText : 0 : 0;
185
+ const nameMargin = hasName ? first || second ? spacing.textToName : icon ? spacing.iconToText : 0 : 0;
186
+ const isSingleColumn = Number(layout.columnsMm) === 41;
187
+ const ceremonyCode = contact.ceremony?.code;
188
+ const ceremonyLabel = contact.ceremony?.label ?? ceremonyCode;
189
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
190
+ "div",
191
+ {
192
+ ...htmlProps,
193
+ "data-default-ad": "",
194
+ "data-ad-content": "",
195
+ "data-ad-ready": "true",
196
+ "data-mode": mode,
197
+ className: `gda-root ${className}`.trim(),
198
+ style: {
199
+ width: `${layout.columnsMm}mm`,
200
+ minWidth: `${layout.columnsMm}mm`,
201
+ ...layout.heightMm != null ? { height: `${layout.heightMm}mm` } : {},
202
+ padding: `${layout.paddingMm}mm ${layout.horizontalPaddingMm}mm`,
203
+ border: layout.border ? `${layout.borderWidthPt}pt solid black` : 0,
204
+ gap: `${spacing.sectionGapMm}mm`,
205
+ fontFamily: typography.fontFamily,
206
+ ...rootStyle
207
+ },
208
+ children: [
209
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "gda-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
210
+ "svg",
211
+ {
212
+ className: icon.className,
213
+ xmlns: "http://www.w3.org/2000/svg",
214
+ width: Number(icon.width) + 16,
215
+ height: Number(icon.height) + 16,
216
+ viewBox: icon.viewBox,
217
+ role: icon.title ? "img" : void 0,
218
+ "aria-hidden": icon.title ? void 0 : true,
219
+ children: [
220
+ icon.title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("title", { children: icon.title }) : null,
221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { dangerouslySetInnerHTML: { __html: decodeSvgMarkup(icon.svg) } })
222
+ ]
223
+ }
224
+ ) }) : null,
225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
226
+ Text,
227
+ {
228
+ className: type === "thanks" ? "gda-bold" : "",
229
+ style: textStyle(type === "thanks" ? 14 : typography.introSize, typography.introLeading, firstMargin),
230
+ children: type === "thanks" && first ? first : type === "obituaries" ? first : null
231
+ }
232
+ ),
233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { style: textStyle(typography.titleSize, typography.titleLeading, secondMargin), children: type === "thanks" && second ? fmt.lowercaseFirst(second) : type === "obituaries" ? second : null }),
234
+ hasName ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { className: "gda-bold gda-secondary-font", style: textStyle(typography.nameSize, typography.nameLeading, nameMargin), children: [contact.firstName, contact.lastName].filter(Boolean).join(" ") }) : showEmptyNamePlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "gda-placeholder", children: emptyNamePlaceholder }) : null,
235
+ contact.showBirthDate && contact.birthDate || contact.showDeathDate && contact.deathDate ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
236
+ "div",
237
+ {
238
+ className: `gda-dates ${isSingleColumn ? "gda-dates-single" : ""}`,
239
+ style: { marginTop: `${spacing.dateTop}pt`, lineHeight: `${typography.dateLeading}pt` },
240
+ children: [
241
+ contact.showBirthDate && contact.birthDate ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { fontSize: `${fmt.date(contact.birthDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }, children: [
242
+ "\u273B ",
243
+ fmt.date(contact.birthDate)
244
+ ] }) : null,
245
+ contact.showDeathDate && contact.deathDate ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { fontSize: `${fmt.date(contact.deathDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }, children: [
246
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "gda-death-cross", "aria-label": "died", children: "\u271D" }),
247
+ " ",
248
+ fmt.date(contact.deathDate)
249
+ ] }) : null
250
+ ]
251
+ }
252
+ ) : null,
253
+ type === "obituaries" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop), children: text.deceased }) : null,
254
+ type === "thanks" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop), children: text.ceremony ? fmt.lowercaseFirst(text.ceremony) : null }) : null,
255
+ type === "thanks" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop), children: text.message }) : null,
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { className: "gda-italic", style: textStyle(typography.memorialSize, typography.memorialLeading, spacing.memorialTop), children: text.memorial }),
257
+ text.sender ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { className: `${type === "obituaries" ? "gda-bold " : ""}gda-secondary-font`, style: textStyle(typography.senderSize, typography.senderLeading, spacing.senderTop), children: text.sender }) : null,
258
+ type === "obituaries" && ceremonyCode !== "NoCeremony" && (contact.showChurch || contact.showFuneralDate) && (contact.church || contact.funeralDate) ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "gda-text", style: textStyle(typography.bodySize, typography.bodyLeading, spacing.ceremonyTop), children: [
259
+ contact.showChurch && contact.church ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: contact.church.length > 15 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
260
+ ceremonyLabel,
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
262
+ contact.church
263
+ ] }) : `${ceremonyLabel ?? ""} ${contact.church}`.trim() }) : null,
264
+ contact.showFuneralDate && contact.funeralDate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: fmt.funeralDate(contact.funeralDate, Boolean(contact.hideFuneralYear)) }) : null
265
+ ] }) : null,
266
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop), children: text.thanks }),
267
+ text.donation ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
268
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "gda-divider", style: { marginTop: `${spacing.donationTop}pt` } }),
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { className: "gda-donation", style: textStyle(typography.bodySize, typography.bodyLeading, spacing.donationTop), children: text.donation })
270
+ ] }) : null
271
+ ]
272
+ }
273
+ );
274
+ }
275
+ // Annotate the CommonJS export names for ESM import in node:
276
+ 0 && (module.exports = {
277
+ DefaultAd,
278
+ classicDefaultAdStyle,
279
+ publicationDefaultAdStyle,
280
+ styleFromLegacyTemplate
281
+ });
282
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/presets.ts","../src/utils.ts","../src/DefaultAd.tsx"],"sourcesContent":["export { DefaultAd } from \"./DefaultAd\";\nexport { classicDefaultAdStyle, publicationDefaultAdStyle, styleFromLegacyTemplate } from \"./presets\";\nexport type {\n DefaultAdContact,\n DefaultAdData,\n DefaultAdFormatters,\n DefaultAdIcon,\n DefaultAdMode,\n DefaultAdProps,\n DefaultAdSpacing,\n DefaultAdStyle,\n DefaultAdTextFields,\n DefaultAdType,\n DefaultAdTypography,\n LegacyAdTemplate,\n} from \"./types\";\n","import type { DefaultAdStyle, LegacyAdTemplate } from \"./types\";\n\nexport const classicDefaultAdStyle: Readonly<DefaultAdStyle> = {\n columnsMm: 86,\n heightMm: null,\n paddingMm: 4,\n horizontalPaddingMm: 2,\n border: false,\n borderWidthPt: 1.4,\n typography: {\n fontFamily: \"var(--default-ad-font-primary, Schoolbook, Georgia, serif)\",\n secondaryFontFamily: \"var(--default-ad-font-secondary, Schoolbook, Georgia, serif)\",\n introSize: 10,\n introLeading: 12,\n titleSize: 10,\n titleLeading: 12,\n nameSize: 14,\n nameLeading: 16.8,\n dateSize: 10,\n longDateSize: 10,\n dateLeading: 12,\n bodySize: 10,\n bodyLeading: 12,\n memorialSize: 10,\n memorialLeading: 12,\n senderSize: 10,\n senderLeading: 12,\n },\n spacing: {\n iconToText: 11,\n introToTitle: 8,\n textToName: 5.6,\n dateTop: 5.6,\n deceasedTop: 6,\n memorialTop: 6,\n senderTop: 8,\n ceremonyTop: 8,\n thanksTop: 7,\n donationTop: 7,\n sectionGapMm: 0,\n },\n};\n\nexport const publicationDefaultAdStyle: Readonly<DefaultAdStyle> = {\n ...classicDefaultAdStyle,\n typography: {\n ...classicDefaultAdStyle.typography,\n fontFamily: \"var(--default-ad-font-primary, Raleway, Arial, sans-serif)\",\n secondaryFontFamily: \"var(--default-ad-font-secondary, Athelas, Georgia, serif)\",\n introSize: 11,\n introLeading: 13,\n titleSize: 11,\n titleLeading: 13,\n nameSize: 17,\n nameLeading: 15,\n dateSize: 11.5,\n longDateSize: 11,\n bodySize: 12,\n bodyLeading: 13,\n memorialSize: 12,\n memorialLeading: 13,\n senderSize: 13,\n senderLeading: 13,\n },\n spacing: { ...classicDefaultAdStyle.spacing, sectionGapMm: 2 },\n};\n\nexport function styleFromLegacyTemplate(template?: LegacyAdTemplate | null): DefaultAdStyle {\n if (!template) return publicationDefaultAdStyle;\n return {\n ...publicationDefaultAdStyle,\n typography: {\n ...publicationDefaultAdStyle.typography,\n fontFamily: template.font1 || publicationDefaultAdStyle.typography?.fontFamily,\n secondaryFontFamily: template.font2 || publicationDefaultAdStyle.typography?.secondaryFontFamily,\n introSize: template.introSize,\n introLeading: template.introLeading,\n titleSize: template.titleSize,\n titleLeading: template.titleLeading,\n nameSize: template.fullnameSize,\n nameLeading: template.fullnameLeading,\n },\n spacing: {\n ...publicationDefaultAdStyle.spacing,\n iconToText: template.textToIcon,\n introToTitle: template.titleToText,\n textToName: template.fullnameToText,\n dateTop: template.datesTextMT,\n deceasedTop: template.deceasedTextMT,\n memorialTop: template.memorialTextMT,\n senderTop: template.senderTextMT,\n ceremonyTop: template.ceremonyTextMT,\n thanksTop: template.thanksTextMT,\n donationTop: template.donationTextMT,\n },\n };\n}\n","import type { DefaultAdFormatters } from \"./types\";\n\nexport const defaultFormatters: Required<DefaultAdFormatters> = {\n date(value) {\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n return match ? `${match[3]}.${match[2]}.${match[1]}` : value;\n },\n funeralDate(value, hideYear) {\n if (!hideYear) return value;\n return value.replace(/([.\\/-])\\d{4}(?=\\D|$)/, \"\");\n },\n lowercaseFirst(value) {\n return value ? value.charAt(0).toLocaleLowerCase() + value.slice(1) : value;\n },\n};\n\nexport function mergeDefined<T extends object>(base: T, overrides?: Partial<T>): T {\n if (!overrides) return { ...base };\n return Object.fromEntries(\n Object.entries({ ...base, ...overrides }).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport function decodeSvgMarkup(value: string): string {\n return value\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#(?:0*39|x0*27);/gi, \"'\")\n .replace(/&amp;/g, \"&\");\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport { classicDefaultAdStyle } from \"./presets\";\nimport type { DefaultAdProps, DefaultAdSpacing, DefaultAdTypography } from \"./types\";\nimport { decodeSvgMarkup, defaultFormatters, mergeDefined } from \"./utils\";\nimport \"./styles.css\";\n\nfunction textStyle(size: number, leading: number, marginTop: number): CSSProperties {\n return { fontSize: `${size}pt`, lineHeight: `${leading}pt`, marginTop: `${marginTop}pt` };\n}\n\nfunction Text({ children, className = \"\", style }: { children?: ReactNode; className?: string; style: CSSProperties }) {\n if (children === null || children === undefined || children === \"\") return null;\n return <div className={`gda-text ${className}`} style={style}>{children}</div>;\n}\n\nexport function DefaultAd({\n data,\n style,\n mode = \"published\",\n formatters,\n showEmptyNamePlaceholder = mode === \"builder\",\n emptyNamePlaceholder = \"Fornavn Efternavn\",\n className = \"\",\n rootStyle,\n ...htmlProps\n}: DefaultAdProps) {\n const typography = mergeDefined(\n classicDefaultAdStyle.typography as Required<DefaultAdTypography>,\n style?.typography,\n );\n const spacing = mergeDefined(\n classicDefaultAdStyle.spacing as Required<DefaultAdSpacing>,\n style?.spacing,\n );\n const layout = mergeDefined(classicDefaultAdStyle, style);\n const fmt = { ...defaultFormatters, ...formatters };\n const { contact, text, icon, type } = data;\n const hasName = Boolean(contact.firstName || contact.lastName);\n const first = type === \"thanks\" ? text.thanksIntro : text.intro;\n const second = type === \"thanks\" ? text.briefIntroduction : text.title;\n const firstMargin = first && icon ? spacing.iconToText : 0;\n const secondMargin = second ? (first ? spacing.introToTitle : icon ? spacing.iconToText : 0) : 0;\n const nameMargin = hasName ? (first || second ? spacing.textToName : icon ? spacing.iconToText : 0) : 0;\n const isSingleColumn = Number(layout.columnsMm) === 41;\n const ceremonyCode = contact.ceremony?.code;\n const ceremonyLabel = contact.ceremony?.label ?? ceremonyCode;\n\n return (\n <div\n {...htmlProps}\n data-default-ad=\"\"\n data-ad-content=\"\"\n data-ad-ready=\"true\"\n data-mode={mode}\n className={`gda-root ${className}`.trim()}\n style={{\n width: `${layout.columnsMm}mm`,\n minWidth: `${layout.columnsMm}mm`,\n ...(layout.heightMm != null ? { height: `${layout.heightMm}mm` } : {}),\n padding: `${layout.paddingMm}mm ${layout.horizontalPaddingMm}mm`,\n border: layout.border ? `${layout.borderWidthPt}pt solid black` : 0,\n gap: `${spacing.sectionGapMm}mm`,\n fontFamily: typography.fontFamily,\n ...rootStyle,\n }}\n >\n {icon ? (\n <div className=\"gda-icon\">\n <svg className={icon.className} xmlns=\"http://www.w3.org/2000/svg\"\n width={Number(icon.width) + 16} height={Number(icon.height) + 16}\n viewBox={icon.viewBox} role={icon.title ? \"img\" : undefined} aria-hidden={icon.title ? undefined : true}>\n {icon.title ? <title>{icon.title}</title> : null}\n <g dangerouslySetInnerHTML={{ __html: decodeSvgMarkup(icon.svg) }} />\n </svg>\n </div>\n ) : null}\n\n <Text className={type === \"thanks\" ? \"gda-bold\" : \"\"}\n style={textStyle(type === \"thanks\" ? 14 : typography.introSize, typography.introLeading, firstMargin)}>\n {type === \"thanks\" && first ? first : type === \"obituaries\" ? first : null}\n </Text>\n <Text style={textStyle(typography.titleSize, typography.titleLeading, secondMargin)}>\n {type === \"thanks\" && second ? fmt.lowercaseFirst(second) : type === \"obituaries\" ? second : null}\n </Text>\n\n {hasName ? (\n <Text className=\"gda-bold gda-secondary-font\" style={textStyle(typography.nameSize, typography.nameLeading, nameMargin)}>\n {[contact.firstName, contact.lastName].filter(Boolean).join(\" \")}\n </Text>\n ) : showEmptyNamePlaceholder ? <div className=\"gda-placeholder\">{emptyNamePlaceholder}</div> : null}\n\n {(contact.showBirthDate && contact.birthDate) || (contact.showDeathDate && contact.deathDate) ? (\n <div className={`gda-dates ${isSingleColumn ? \"gda-dates-single\" : \"\"}`}\n style={{ marginTop: `${spacing.dateTop}pt`, lineHeight: `${typography.dateLeading}pt` }}>\n {contact.showBirthDate && contact.birthDate ? (\n <span style={{ fontSize: `${fmt.date(contact.birthDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }}>\n &#10043; {fmt.date(contact.birthDate)}\n </span>\n ) : null}\n {contact.showDeathDate && contact.deathDate ? (\n <span style={{ fontSize: `${fmt.date(contact.deathDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }}>\n <span className=\"gda-death-cross\" aria-label=\"died\">✝</span> {fmt.date(contact.deathDate)}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {type === \"obituaries\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop)}>{text.deceased}</Text> : null}\n {type === \"thanks\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop)}>{text.ceremony ? fmt.lowercaseFirst(text.ceremony) : null}</Text> : null}\n {type === \"thanks\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop)}>{text.message}</Text> : null}\n <Text className=\"gda-italic\" style={textStyle(typography.memorialSize, typography.memorialLeading, spacing.memorialTop)}>{text.memorial}</Text>\n {text.sender ? <Text className={`${type === \"obituaries\" ? \"gda-bold \" : \"\"}gda-secondary-font`} style={textStyle(typography.senderSize, typography.senderLeading, spacing.senderTop)}>{text.sender}</Text> : null}\n\n {type === \"obituaries\" && ceremonyCode !== \"NoCeremony\" && (contact.showChurch || contact.showFuneralDate) && (contact.church || contact.funeralDate) ? (\n <div className=\"gda-text\" style={textStyle(typography.bodySize, typography.bodyLeading, spacing.ceremonyTop)}>\n {contact.showChurch && contact.church ? <div>{contact.church.length > 15 ? <>{ceremonyLabel}<br />{contact.church}</> : `${ceremonyLabel ?? \"\"} ${contact.church}`.trim()}</div> : null}\n {contact.showFuneralDate && contact.funeralDate ? <div>{fmt.funeralDate(contact.funeralDate, Boolean(contact.hideFuneralYear))}</div> : null}\n </div>\n ) : null}\n\n <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop)}>{text.thanks}</Text>\n {text.donation ? <><div className=\"gda-divider\" style={{ marginTop: `${spacing.donationTop}pt` }} /><Text className=\"gda-donation\" style={textStyle(typography.bodySize, typography.bodyLeading, spacing.donationTop)}>{text.donation}</Text></> : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/dist/index.css ADDED
@@ -0,0 +1,69 @@
1
+ /* src/styles.css */
2
+ .gda-root {
3
+ box-sizing: border-box;
4
+ display: flex;
5
+ flex-direction: column;
6
+ flex-shrink: 0;
7
+ overflow: hidden;
8
+ color: #000;
9
+ background: #fff;
10
+ stroke: #000;
11
+ text-align: center;
12
+ box-shadow: 0 0 30px -10px rgb(0 0 0 / 30%);
13
+ transition: all 700ms;
14
+ }
15
+ .gda-root *,
16
+ .gda-root *::before,
17
+ .gda-root *::after {
18
+ box-sizing: border-box;
19
+ }
20
+ .gda-text {
21
+ font-weight: 400;
22
+ white-space: pre-line;
23
+ overflow-wrap: break-word;
24
+ text-wrap: balance;
25
+ }
26
+ .gda-bold {
27
+ font-weight: 700;
28
+ }
29
+ .gda-italic {
30
+ font-style: italic;
31
+ }
32
+ .gda-secondary-font {
33
+ font-family: var(--default-ad-font-secondary, inherit);
34
+ }
35
+ .gda-icon {
36
+ display: flex;
37
+ justify-content: center;
38
+ line-height: 0;
39
+ }
40
+ .gda-dates {
41
+ display: flex;
42
+ width: 100%;
43
+ flex-flow: row nowrap;
44
+ justify-content: center;
45
+ gap: 4mm;
46
+ font-weight: 400;
47
+ white-space: nowrap;
48
+ }
49
+ .gda-dates-single {
50
+ flex-direction: column;
51
+ gap: 0;
52
+ }
53
+ .gda-death-cross {
54
+ font-family: Georgia, serif;
55
+ }
56
+ .gda-divider {
57
+ width: 3rem;
58
+ margin-right: auto;
59
+ margin-left: auto;
60
+ border-top: 1.4pt solid #000;
61
+ }
62
+ .gda-donation {
63
+ margin-right: 19pt;
64
+ margin-left: 19pt;
65
+ }
66
+ .gda-placeholder {
67
+ opacity: .25;
68
+ }
69
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles.css"],"sourcesContent":[".gda-root {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n overflow: hidden;\n color: #000;\n background: #fff;\n stroke: #000;\n text-align: center;\n box-shadow: 0 0 30px -10px rgb(0 0 0 / 30%);\n transition: all 700ms;\n}\n.gda-root *, .gda-root *::before, .gda-root *::after { box-sizing: border-box; }\n.gda-text { font-weight: 400; white-space: pre-line; overflow-wrap: break-word; text-wrap: balance; }\n.gda-bold { font-weight: 700; }\n.gda-italic { font-style: italic; }\n.gda-secondary-font { font-family: var(--default-ad-font-secondary, inherit); }\n.gda-icon { display: flex; justify-content: center; line-height: 0; }\n.gda-dates { display: flex; width: 100%; flex-flow: row nowrap; justify-content: center; gap: 4mm; font-weight: 400; white-space: nowrap; }\n.gda-dates-single { flex-direction: column; gap: 0; }\n.gda-death-cross { font-family: Georgia, serif; }\n.gda-divider { width: 3rem; margin-right: auto; margin-left: auto; border-top: 1.4pt solid #000; }\n.gda-donation { margin-right: 19pt; margin-left: 19pt; }\n.gda-placeholder { opacity: .25; }\n"],"mappings":";AAAA,CAAC;AACC,cAAY;AACZ,WAAS;AACT,kBAAgB;AAChB,eAAa;AACb,YAAU;AACV,SAAO;AACP,cAAY;AACZ,UAAQ;AACR,cAAY;AACZ,cAAY,EAAE,EAAE,KAAK,MAAM,IAAI,EAAE,EAAE,EAAE,EAAE;AACvC,cAAY,IAAI;AAClB;AACA,CAbC,SAaS;AAAG,CAbZ,SAasB,CAAC;AAAU,CAbjC,SAa2C,CAAC;AAAU,cAAY;AAAY;AAC/E,CAAC;AAAW,eAAa;AAAK,eAAa;AAAU,iBAAe;AAAY,aAAW;AAAS;AACpG,CAAC;AAAW,eAAa;AAAK;AAC9B,CAAC;AAAa,cAAY;AAAQ;AAClC,CAAC;AAAqB,eAAa,IAAI,2BAA2B,EAAE;AAAU;AAC9E,CAAC;AAAW,WAAS;AAAM,mBAAiB;AAAQ,eAAa;AAAG;AACpE,CAAC;AAAY,WAAS;AAAM,SAAO;AAAM,aAAW,IAAI;AAAQ,mBAAiB;AAAQ,OAAK;AAAK,eAAa;AAAK,eAAa;AAAQ;AAC1I,CAAC;AAAmB,kBAAgB;AAAQ,OAAK;AAAG;AACpD,CAAC;AAAkB,eAAa,OAAO,EAAE;AAAO;AAChD,CAAC;AAAc,SAAO;AAAM,gBAAc;AAAM,eAAa;AAAM,cAAY,MAAM,MAAM;AAAM;AACjG,CAAC;AAAe,gBAAc;AAAM,eAAa;AAAM;AACvD,CAAC;AAAkB,WAAS;AAAK;","names":[]}
@@ -0,0 +1,137 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ type DefaultAdType = "obituaries" | "thanks";
5
+ type DefaultAdMode = "builder" | "preview" | "published";
6
+ interface DefaultAdIcon {
7
+ /** SVG child markup (for example, one or more path elements). Only use trusted markup. */
8
+ svg: string;
9
+ viewBox: string;
10
+ width: number | string;
11
+ height: number | string;
12
+ className?: string;
13
+ title?: string;
14
+ }
15
+ interface DefaultAdContact {
16
+ firstName?: string | null;
17
+ lastName?: string | null;
18
+ birthDate?: string | null;
19
+ deathDate?: string | null;
20
+ church?: string | null;
21
+ funeralDate?: string | null;
22
+ ceremony?: {
23
+ code?: string | null;
24
+ label?: string | null;
25
+ } | null;
26
+ showBirthDate?: boolean;
27
+ showDeathDate?: boolean;
28
+ showChurch?: boolean;
29
+ showFuneralDate?: boolean;
30
+ hideFuneralYear?: boolean;
31
+ }
32
+ interface DefaultAdTextFields {
33
+ intro?: string | null;
34
+ title?: string | null;
35
+ firstNamePlaceholder?: string;
36
+ lastNamePlaceholder?: string;
37
+ deceased?: string | null;
38
+ memorial?: string | null;
39
+ sender?: string | null;
40
+ thanks?: string | null;
41
+ donation?: string | null;
42
+ thanksIntro?: string | null;
43
+ briefIntroduction?: string | null;
44
+ ceremony?: string | null;
45
+ message?: string | null;
46
+ }
47
+ interface DefaultAdData {
48
+ type: DefaultAdType;
49
+ contact: DefaultAdContact;
50
+ text: DefaultAdTextFields;
51
+ icon?: DefaultAdIcon | null;
52
+ }
53
+ interface DefaultAdTypography {
54
+ fontFamily?: string;
55
+ secondaryFontFamily?: string;
56
+ introSize?: number;
57
+ introLeading?: number;
58
+ titleSize?: number;
59
+ titleLeading?: number;
60
+ nameSize?: number;
61
+ nameLeading?: number;
62
+ dateSize?: number;
63
+ longDateSize?: number;
64
+ dateLeading?: number;
65
+ bodySize?: number;
66
+ bodyLeading?: number;
67
+ memorialSize?: number;
68
+ memorialLeading?: number;
69
+ senderSize?: number;
70
+ senderLeading?: number;
71
+ }
72
+ interface DefaultAdSpacing {
73
+ iconToText?: number;
74
+ introToTitle?: number;
75
+ textToName?: number;
76
+ dateTop?: number;
77
+ deceasedTop?: number;
78
+ memorialTop?: number;
79
+ senderTop?: number;
80
+ ceremonyTop?: number;
81
+ thanksTop?: number;
82
+ donationTop?: number;
83
+ sectionGapMm?: number;
84
+ }
85
+ interface DefaultAdStyle {
86
+ columnsMm?: number;
87
+ heightMm?: number | null;
88
+ paddingMm?: number;
89
+ horizontalPaddingMm?: number;
90
+ border?: boolean;
91
+ borderWidthPt?: number;
92
+ typography?: DefaultAdTypography;
93
+ spacing?: DefaultAdSpacing;
94
+ }
95
+ interface DefaultAdFormatters {
96
+ date?: (value: string) => string;
97
+ funeralDate?: (value: string, hideYear: boolean) => string;
98
+ lowercaseFirst?: (value: string) => string;
99
+ }
100
+ interface DefaultAdProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "style"> {
101
+ data: DefaultAdData;
102
+ style?: DefaultAdStyle;
103
+ mode?: DefaultAdMode;
104
+ formatters?: DefaultAdFormatters;
105
+ showEmptyNamePlaceholder?: boolean;
106
+ emptyNamePlaceholder?: string;
107
+ rootStyle?: CSSProperties;
108
+ }
109
+ /** Shape accepted by the existing Strapi ad-template records. */
110
+ interface LegacyAdTemplate {
111
+ font1?: string;
112
+ font2?: string;
113
+ introSize?: number;
114
+ introLeading?: number;
115
+ titleSize?: number;
116
+ titleLeading?: number;
117
+ fullnameSize?: number;
118
+ fullnameLeading?: number;
119
+ datesTextMT?: number;
120
+ deceasedTextMT?: number;
121
+ memorialTextMT?: number;
122
+ senderTextMT?: number;
123
+ ceremonyTextMT?: number;
124
+ thanksTextMT?: number;
125
+ donationTextMT?: number;
126
+ textToIcon?: number;
127
+ titleToText?: number;
128
+ fullnameToText?: number;
129
+ }
130
+
131
+ declare function DefaultAd({ data, style, mode, formatters, showEmptyNamePlaceholder, emptyNamePlaceholder, className, rootStyle, ...htmlProps }: DefaultAdProps): react.JSX.Element;
132
+
133
+ declare const classicDefaultAdStyle: Readonly<DefaultAdStyle>;
134
+ declare const publicationDefaultAdStyle: Readonly<DefaultAdStyle>;
135
+ declare function styleFromLegacyTemplate(template?: LegacyAdTemplate | null): DefaultAdStyle;
136
+
137
+ export { DefaultAd, type DefaultAdContact, type DefaultAdData, type DefaultAdFormatters, type DefaultAdIcon, type DefaultAdMode, type DefaultAdProps, type DefaultAdSpacing, type DefaultAdStyle, type DefaultAdTextFields, type DefaultAdType, type DefaultAdTypography, type LegacyAdTemplate, classicDefaultAdStyle, publicationDefaultAdStyle, styleFromLegacyTemplate };
@@ -0,0 +1,137 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ type DefaultAdType = "obituaries" | "thanks";
5
+ type DefaultAdMode = "builder" | "preview" | "published";
6
+ interface DefaultAdIcon {
7
+ /** SVG child markup (for example, one or more path elements). Only use trusted markup. */
8
+ svg: string;
9
+ viewBox: string;
10
+ width: number | string;
11
+ height: number | string;
12
+ className?: string;
13
+ title?: string;
14
+ }
15
+ interface DefaultAdContact {
16
+ firstName?: string | null;
17
+ lastName?: string | null;
18
+ birthDate?: string | null;
19
+ deathDate?: string | null;
20
+ church?: string | null;
21
+ funeralDate?: string | null;
22
+ ceremony?: {
23
+ code?: string | null;
24
+ label?: string | null;
25
+ } | null;
26
+ showBirthDate?: boolean;
27
+ showDeathDate?: boolean;
28
+ showChurch?: boolean;
29
+ showFuneralDate?: boolean;
30
+ hideFuneralYear?: boolean;
31
+ }
32
+ interface DefaultAdTextFields {
33
+ intro?: string | null;
34
+ title?: string | null;
35
+ firstNamePlaceholder?: string;
36
+ lastNamePlaceholder?: string;
37
+ deceased?: string | null;
38
+ memorial?: string | null;
39
+ sender?: string | null;
40
+ thanks?: string | null;
41
+ donation?: string | null;
42
+ thanksIntro?: string | null;
43
+ briefIntroduction?: string | null;
44
+ ceremony?: string | null;
45
+ message?: string | null;
46
+ }
47
+ interface DefaultAdData {
48
+ type: DefaultAdType;
49
+ contact: DefaultAdContact;
50
+ text: DefaultAdTextFields;
51
+ icon?: DefaultAdIcon | null;
52
+ }
53
+ interface DefaultAdTypography {
54
+ fontFamily?: string;
55
+ secondaryFontFamily?: string;
56
+ introSize?: number;
57
+ introLeading?: number;
58
+ titleSize?: number;
59
+ titleLeading?: number;
60
+ nameSize?: number;
61
+ nameLeading?: number;
62
+ dateSize?: number;
63
+ longDateSize?: number;
64
+ dateLeading?: number;
65
+ bodySize?: number;
66
+ bodyLeading?: number;
67
+ memorialSize?: number;
68
+ memorialLeading?: number;
69
+ senderSize?: number;
70
+ senderLeading?: number;
71
+ }
72
+ interface DefaultAdSpacing {
73
+ iconToText?: number;
74
+ introToTitle?: number;
75
+ textToName?: number;
76
+ dateTop?: number;
77
+ deceasedTop?: number;
78
+ memorialTop?: number;
79
+ senderTop?: number;
80
+ ceremonyTop?: number;
81
+ thanksTop?: number;
82
+ donationTop?: number;
83
+ sectionGapMm?: number;
84
+ }
85
+ interface DefaultAdStyle {
86
+ columnsMm?: number;
87
+ heightMm?: number | null;
88
+ paddingMm?: number;
89
+ horizontalPaddingMm?: number;
90
+ border?: boolean;
91
+ borderWidthPt?: number;
92
+ typography?: DefaultAdTypography;
93
+ spacing?: DefaultAdSpacing;
94
+ }
95
+ interface DefaultAdFormatters {
96
+ date?: (value: string) => string;
97
+ funeralDate?: (value: string, hideYear: boolean) => string;
98
+ lowercaseFirst?: (value: string) => string;
99
+ }
100
+ interface DefaultAdProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "style"> {
101
+ data: DefaultAdData;
102
+ style?: DefaultAdStyle;
103
+ mode?: DefaultAdMode;
104
+ formatters?: DefaultAdFormatters;
105
+ showEmptyNamePlaceholder?: boolean;
106
+ emptyNamePlaceholder?: string;
107
+ rootStyle?: CSSProperties;
108
+ }
109
+ /** Shape accepted by the existing Strapi ad-template records. */
110
+ interface LegacyAdTemplate {
111
+ font1?: string;
112
+ font2?: string;
113
+ introSize?: number;
114
+ introLeading?: number;
115
+ titleSize?: number;
116
+ titleLeading?: number;
117
+ fullnameSize?: number;
118
+ fullnameLeading?: number;
119
+ datesTextMT?: number;
120
+ deceasedTextMT?: number;
121
+ memorialTextMT?: number;
122
+ senderTextMT?: number;
123
+ ceremonyTextMT?: number;
124
+ thanksTextMT?: number;
125
+ donationTextMT?: number;
126
+ textToIcon?: number;
127
+ titleToText?: number;
128
+ fullnameToText?: number;
129
+ }
130
+
131
+ declare function DefaultAd({ data, style, mode, formatters, showEmptyNamePlaceholder, emptyNamePlaceholder, className, rootStyle, ...htmlProps }: DefaultAdProps): react.JSX.Element;
132
+
133
+ declare const classicDefaultAdStyle: Readonly<DefaultAdStyle>;
134
+ declare const publicationDefaultAdStyle: Readonly<DefaultAdStyle>;
135
+ declare function styleFromLegacyTemplate(template?: LegacyAdTemplate | null): DefaultAdStyle;
136
+
137
+ export { DefaultAd, type DefaultAdContact, type DefaultAdData, type DefaultAdFormatters, type DefaultAdIcon, type DefaultAdMode, type DefaultAdProps, type DefaultAdSpacing, type DefaultAdStyle, type DefaultAdTextFields, type DefaultAdType, type DefaultAdTypography, type LegacyAdTemplate, classicDefaultAdStyle, publicationDefaultAdStyle, styleFromLegacyTemplate };
package/dist/index.js ADDED
@@ -0,0 +1,252 @@
1
+ // src/presets.ts
2
+ var classicDefaultAdStyle = {
3
+ columnsMm: 86,
4
+ heightMm: null,
5
+ paddingMm: 4,
6
+ horizontalPaddingMm: 2,
7
+ border: false,
8
+ borderWidthPt: 1.4,
9
+ typography: {
10
+ fontFamily: "var(--default-ad-font-primary, Schoolbook, Georgia, serif)",
11
+ secondaryFontFamily: "var(--default-ad-font-secondary, Schoolbook, Georgia, serif)",
12
+ introSize: 10,
13
+ introLeading: 12,
14
+ titleSize: 10,
15
+ titleLeading: 12,
16
+ nameSize: 14,
17
+ nameLeading: 16.8,
18
+ dateSize: 10,
19
+ longDateSize: 10,
20
+ dateLeading: 12,
21
+ bodySize: 10,
22
+ bodyLeading: 12,
23
+ memorialSize: 10,
24
+ memorialLeading: 12,
25
+ senderSize: 10,
26
+ senderLeading: 12
27
+ },
28
+ spacing: {
29
+ iconToText: 11,
30
+ introToTitle: 8,
31
+ textToName: 5.6,
32
+ dateTop: 5.6,
33
+ deceasedTop: 6,
34
+ memorialTop: 6,
35
+ senderTop: 8,
36
+ ceremonyTop: 8,
37
+ thanksTop: 7,
38
+ donationTop: 7,
39
+ sectionGapMm: 0
40
+ }
41
+ };
42
+ var publicationDefaultAdStyle = {
43
+ ...classicDefaultAdStyle,
44
+ typography: {
45
+ ...classicDefaultAdStyle.typography,
46
+ fontFamily: "var(--default-ad-font-primary, Raleway, Arial, sans-serif)",
47
+ secondaryFontFamily: "var(--default-ad-font-secondary, Athelas, Georgia, serif)",
48
+ introSize: 11,
49
+ introLeading: 13,
50
+ titleSize: 11,
51
+ titleLeading: 13,
52
+ nameSize: 17,
53
+ nameLeading: 15,
54
+ dateSize: 11.5,
55
+ longDateSize: 11,
56
+ bodySize: 12,
57
+ bodyLeading: 13,
58
+ memorialSize: 12,
59
+ memorialLeading: 13,
60
+ senderSize: 13,
61
+ senderLeading: 13
62
+ },
63
+ spacing: { ...classicDefaultAdStyle.spacing, sectionGapMm: 2 }
64
+ };
65
+ function styleFromLegacyTemplate(template) {
66
+ if (!template) return publicationDefaultAdStyle;
67
+ return {
68
+ ...publicationDefaultAdStyle,
69
+ typography: {
70
+ ...publicationDefaultAdStyle.typography,
71
+ fontFamily: template.font1 || publicationDefaultAdStyle.typography?.fontFamily,
72
+ secondaryFontFamily: template.font2 || publicationDefaultAdStyle.typography?.secondaryFontFamily,
73
+ introSize: template.introSize,
74
+ introLeading: template.introLeading,
75
+ titleSize: template.titleSize,
76
+ titleLeading: template.titleLeading,
77
+ nameSize: template.fullnameSize,
78
+ nameLeading: template.fullnameLeading
79
+ },
80
+ spacing: {
81
+ ...publicationDefaultAdStyle.spacing,
82
+ iconToText: template.textToIcon,
83
+ introToTitle: template.titleToText,
84
+ textToName: template.fullnameToText,
85
+ dateTop: template.datesTextMT,
86
+ deceasedTop: template.deceasedTextMT,
87
+ memorialTop: template.memorialTextMT,
88
+ senderTop: template.senderTextMT,
89
+ ceremonyTop: template.ceremonyTextMT,
90
+ thanksTop: template.thanksTextMT,
91
+ donationTop: template.donationTextMT
92
+ }
93
+ };
94
+ }
95
+
96
+ // src/utils.ts
97
+ var defaultFormatters = {
98
+ date(value) {
99
+ const match = value.match(/^(\d{4})-(\d{2})-(\d{2})/);
100
+ return match ? `${match[3]}.${match[2]}.${match[1]}` : value;
101
+ },
102
+ funeralDate(value, hideYear) {
103
+ if (!hideYear) return value;
104
+ return value.replace(/([.\/-])\d{4}(?=\D|$)/, "");
105
+ },
106
+ lowercaseFirst(value) {
107
+ return value ? value.charAt(0).toLocaleLowerCase() + value.slice(1) : value;
108
+ }
109
+ };
110
+ function mergeDefined(base, overrides) {
111
+ if (!overrides) return { ...base };
112
+ return Object.fromEntries(
113
+ Object.entries({ ...base, ...overrides }).filter(([, value]) => value !== void 0)
114
+ );
115
+ }
116
+ function decodeSvgMarkup(value) {
117
+ return value.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#(?:0*39|x0*27);/gi, "'").replace(/&amp;/g, "&");
118
+ }
119
+
120
+ // src/DefaultAd.tsx
121
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
122
+ function textStyle(size, leading, marginTop) {
123
+ return { fontSize: `${size}pt`, lineHeight: `${leading}pt`, marginTop: `${marginTop}pt` };
124
+ }
125
+ function Text({ children, className = "", style }) {
126
+ if (children === null || children === void 0 || children === "") return null;
127
+ return /* @__PURE__ */ jsx("div", { className: `gda-text ${className}`, style, children });
128
+ }
129
+ function DefaultAd({
130
+ data,
131
+ style,
132
+ mode = "published",
133
+ formatters,
134
+ showEmptyNamePlaceholder = mode === "builder",
135
+ emptyNamePlaceholder = "Fornavn Efternavn",
136
+ className = "",
137
+ rootStyle,
138
+ ...htmlProps
139
+ }) {
140
+ const typography = mergeDefined(
141
+ classicDefaultAdStyle.typography,
142
+ style?.typography
143
+ );
144
+ const spacing = mergeDefined(
145
+ classicDefaultAdStyle.spacing,
146
+ style?.spacing
147
+ );
148
+ const layout = mergeDefined(classicDefaultAdStyle, style);
149
+ const fmt = { ...defaultFormatters, ...formatters };
150
+ const { contact, text, icon, type } = data;
151
+ const hasName = Boolean(contact.firstName || contact.lastName);
152
+ const first = type === "thanks" ? text.thanksIntro : text.intro;
153
+ const second = type === "thanks" ? text.briefIntroduction : text.title;
154
+ const firstMargin = first && icon ? spacing.iconToText : 0;
155
+ const secondMargin = second ? first ? spacing.introToTitle : icon ? spacing.iconToText : 0 : 0;
156
+ const nameMargin = hasName ? first || second ? spacing.textToName : icon ? spacing.iconToText : 0 : 0;
157
+ const isSingleColumn = Number(layout.columnsMm) === 41;
158
+ const ceremonyCode = contact.ceremony?.code;
159
+ const ceremonyLabel = contact.ceremony?.label ?? ceremonyCode;
160
+ return /* @__PURE__ */ jsxs(
161
+ "div",
162
+ {
163
+ ...htmlProps,
164
+ "data-default-ad": "",
165
+ "data-ad-content": "",
166
+ "data-ad-ready": "true",
167
+ "data-mode": mode,
168
+ className: `gda-root ${className}`.trim(),
169
+ style: {
170
+ width: `${layout.columnsMm}mm`,
171
+ minWidth: `${layout.columnsMm}mm`,
172
+ ...layout.heightMm != null ? { height: `${layout.heightMm}mm` } : {},
173
+ padding: `${layout.paddingMm}mm ${layout.horizontalPaddingMm}mm`,
174
+ border: layout.border ? `${layout.borderWidthPt}pt solid black` : 0,
175
+ gap: `${spacing.sectionGapMm}mm`,
176
+ fontFamily: typography.fontFamily,
177
+ ...rootStyle
178
+ },
179
+ children: [
180
+ icon ? /* @__PURE__ */ jsx("div", { className: "gda-icon", children: /* @__PURE__ */ jsxs(
181
+ "svg",
182
+ {
183
+ className: icon.className,
184
+ xmlns: "http://www.w3.org/2000/svg",
185
+ width: Number(icon.width) + 16,
186
+ height: Number(icon.height) + 16,
187
+ viewBox: icon.viewBox,
188
+ role: icon.title ? "img" : void 0,
189
+ "aria-hidden": icon.title ? void 0 : true,
190
+ children: [
191
+ icon.title ? /* @__PURE__ */ jsx("title", { children: icon.title }) : null,
192
+ /* @__PURE__ */ jsx("g", { dangerouslySetInnerHTML: { __html: decodeSvgMarkup(icon.svg) } })
193
+ ]
194
+ }
195
+ ) }) : null,
196
+ /* @__PURE__ */ jsx(
197
+ Text,
198
+ {
199
+ className: type === "thanks" ? "gda-bold" : "",
200
+ style: textStyle(type === "thanks" ? 14 : typography.introSize, typography.introLeading, firstMargin),
201
+ children: type === "thanks" && first ? first : type === "obituaries" ? first : null
202
+ }
203
+ ),
204
+ /* @__PURE__ */ jsx(Text, { style: textStyle(typography.titleSize, typography.titleLeading, secondMargin), children: type === "thanks" && second ? fmt.lowercaseFirst(second) : type === "obituaries" ? second : null }),
205
+ hasName ? /* @__PURE__ */ jsx(Text, { className: "gda-bold gda-secondary-font", style: textStyle(typography.nameSize, typography.nameLeading, nameMargin), children: [contact.firstName, contact.lastName].filter(Boolean).join(" ") }) : showEmptyNamePlaceholder ? /* @__PURE__ */ jsx("div", { className: "gda-placeholder", children: emptyNamePlaceholder }) : null,
206
+ contact.showBirthDate && contact.birthDate || contact.showDeathDate && contact.deathDate ? /* @__PURE__ */ jsxs(
207
+ "div",
208
+ {
209
+ className: `gda-dates ${isSingleColumn ? "gda-dates-single" : ""}`,
210
+ style: { marginTop: `${spacing.dateTop}pt`, lineHeight: `${typography.dateLeading}pt` },
211
+ children: [
212
+ contact.showBirthDate && contact.birthDate ? /* @__PURE__ */ jsxs("span", { style: { fontSize: `${fmt.date(contact.birthDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }, children: [
213
+ "\u273B ",
214
+ fmt.date(contact.birthDate)
215
+ ] }) : null,
216
+ contact.showDeathDate && contact.deathDate ? /* @__PURE__ */ jsxs("span", { style: { fontSize: `${fmt.date(contact.deathDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }, children: [
217
+ /* @__PURE__ */ jsx("span", { className: "gda-death-cross", "aria-label": "died", children: "\u271D" }),
218
+ " ",
219
+ fmt.date(contact.deathDate)
220
+ ] }) : null
221
+ ]
222
+ }
223
+ ) : null,
224
+ type === "obituaries" ? /* @__PURE__ */ jsx(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop), children: text.deceased }) : null,
225
+ type === "thanks" ? /* @__PURE__ */ jsx(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop), children: text.ceremony ? fmt.lowercaseFirst(text.ceremony) : null }) : null,
226
+ type === "thanks" ? /* @__PURE__ */ jsx(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop), children: text.message }) : null,
227
+ /* @__PURE__ */ jsx(Text, { className: "gda-italic", style: textStyle(typography.memorialSize, typography.memorialLeading, spacing.memorialTop), children: text.memorial }),
228
+ text.sender ? /* @__PURE__ */ jsx(Text, { className: `${type === "obituaries" ? "gda-bold " : ""}gda-secondary-font`, style: textStyle(typography.senderSize, typography.senderLeading, spacing.senderTop), children: text.sender }) : null,
229
+ type === "obituaries" && ceremonyCode !== "NoCeremony" && (contact.showChurch || contact.showFuneralDate) && (contact.church || contact.funeralDate) ? /* @__PURE__ */ jsxs("div", { className: "gda-text", style: textStyle(typography.bodySize, typography.bodyLeading, spacing.ceremonyTop), children: [
230
+ contact.showChurch && contact.church ? /* @__PURE__ */ jsx("div", { children: contact.church.length > 15 ? /* @__PURE__ */ jsxs(Fragment, { children: [
231
+ ceremonyLabel,
232
+ /* @__PURE__ */ jsx("br", {}),
233
+ contact.church
234
+ ] }) : `${ceremonyLabel ?? ""} ${contact.church}`.trim() }) : null,
235
+ contact.showFuneralDate && contact.funeralDate ? /* @__PURE__ */ jsx("div", { children: fmt.funeralDate(contact.funeralDate, Boolean(contact.hideFuneralYear)) }) : null
236
+ ] }) : null,
237
+ /* @__PURE__ */ jsx(Text, { style: textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop), children: text.thanks }),
238
+ text.donation ? /* @__PURE__ */ jsxs(Fragment, { children: [
239
+ /* @__PURE__ */ jsx("div", { className: "gda-divider", style: { marginTop: `${spacing.donationTop}pt` } }),
240
+ /* @__PURE__ */ jsx(Text, { className: "gda-donation", style: textStyle(typography.bodySize, typography.bodyLeading, spacing.donationTop), children: text.donation })
241
+ ] }) : null
242
+ ]
243
+ }
244
+ );
245
+ }
246
+ export {
247
+ DefaultAd,
248
+ classicDefaultAdStyle,
249
+ publicationDefaultAdStyle,
250
+ styleFromLegacyTemplate
251
+ };
252
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/presets.ts","../src/utils.ts","../src/DefaultAd.tsx"],"sourcesContent":["import type { DefaultAdStyle, LegacyAdTemplate } from \"./types\";\n\nexport const classicDefaultAdStyle: Readonly<DefaultAdStyle> = {\n columnsMm: 86,\n heightMm: null,\n paddingMm: 4,\n horizontalPaddingMm: 2,\n border: false,\n borderWidthPt: 1.4,\n typography: {\n fontFamily: \"var(--default-ad-font-primary, Schoolbook, Georgia, serif)\",\n secondaryFontFamily: \"var(--default-ad-font-secondary, Schoolbook, Georgia, serif)\",\n introSize: 10,\n introLeading: 12,\n titleSize: 10,\n titleLeading: 12,\n nameSize: 14,\n nameLeading: 16.8,\n dateSize: 10,\n longDateSize: 10,\n dateLeading: 12,\n bodySize: 10,\n bodyLeading: 12,\n memorialSize: 10,\n memorialLeading: 12,\n senderSize: 10,\n senderLeading: 12,\n },\n spacing: {\n iconToText: 11,\n introToTitle: 8,\n textToName: 5.6,\n dateTop: 5.6,\n deceasedTop: 6,\n memorialTop: 6,\n senderTop: 8,\n ceremonyTop: 8,\n thanksTop: 7,\n donationTop: 7,\n sectionGapMm: 0,\n },\n};\n\nexport const publicationDefaultAdStyle: Readonly<DefaultAdStyle> = {\n ...classicDefaultAdStyle,\n typography: {\n ...classicDefaultAdStyle.typography,\n fontFamily: \"var(--default-ad-font-primary, Raleway, Arial, sans-serif)\",\n secondaryFontFamily: \"var(--default-ad-font-secondary, Athelas, Georgia, serif)\",\n introSize: 11,\n introLeading: 13,\n titleSize: 11,\n titleLeading: 13,\n nameSize: 17,\n nameLeading: 15,\n dateSize: 11.5,\n longDateSize: 11,\n bodySize: 12,\n bodyLeading: 13,\n memorialSize: 12,\n memorialLeading: 13,\n senderSize: 13,\n senderLeading: 13,\n },\n spacing: { ...classicDefaultAdStyle.spacing, sectionGapMm: 2 },\n};\n\nexport function styleFromLegacyTemplate(template?: LegacyAdTemplate | null): DefaultAdStyle {\n if (!template) return publicationDefaultAdStyle;\n return {\n ...publicationDefaultAdStyle,\n typography: {\n ...publicationDefaultAdStyle.typography,\n fontFamily: template.font1 || publicationDefaultAdStyle.typography?.fontFamily,\n secondaryFontFamily: template.font2 || publicationDefaultAdStyle.typography?.secondaryFontFamily,\n introSize: template.introSize,\n introLeading: template.introLeading,\n titleSize: template.titleSize,\n titleLeading: template.titleLeading,\n nameSize: template.fullnameSize,\n nameLeading: template.fullnameLeading,\n },\n spacing: {\n ...publicationDefaultAdStyle.spacing,\n iconToText: template.textToIcon,\n introToTitle: template.titleToText,\n textToName: template.fullnameToText,\n dateTop: template.datesTextMT,\n deceasedTop: template.deceasedTextMT,\n memorialTop: template.memorialTextMT,\n senderTop: template.senderTextMT,\n ceremonyTop: template.ceremonyTextMT,\n thanksTop: template.thanksTextMT,\n donationTop: template.donationTextMT,\n },\n };\n}\n","import type { DefaultAdFormatters } from \"./types\";\n\nexport const defaultFormatters: Required<DefaultAdFormatters> = {\n date(value) {\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n return match ? `${match[3]}.${match[2]}.${match[1]}` : value;\n },\n funeralDate(value, hideYear) {\n if (!hideYear) return value;\n return value.replace(/([.\\/-])\\d{4}(?=\\D|$)/, \"\");\n },\n lowercaseFirst(value) {\n return value ? value.charAt(0).toLocaleLowerCase() + value.slice(1) : value;\n },\n};\n\nexport function mergeDefined<T extends object>(base: T, overrides?: Partial<T>): T {\n if (!overrides) return { ...base };\n return Object.fromEntries(\n Object.entries({ ...base, ...overrides }).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport function decodeSvgMarkup(value: string): string {\n return value\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#(?:0*39|x0*27);/gi, \"'\")\n .replace(/&amp;/g, \"&\");\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport { classicDefaultAdStyle } from \"./presets\";\nimport type { DefaultAdProps, DefaultAdSpacing, DefaultAdTypography } from \"./types\";\nimport { decodeSvgMarkup, defaultFormatters, mergeDefined } from \"./utils\";\nimport \"./styles.css\";\n\nfunction textStyle(size: number, leading: number, marginTop: number): CSSProperties {\n return { fontSize: `${size}pt`, lineHeight: `${leading}pt`, marginTop: `${marginTop}pt` };\n}\n\nfunction Text({ children, className = \"\", style }: { children?: ReactNode; className?: string; style: CSSProperties }) {\n if (children === null || children === undefined || children === \"\") return null;\n return <div className={`gda-text ${className}`} style={style}>{children}</div>;\n}\n\nexport function DefaultAd({\n data,\n style,\n mode = \"published\",\n formatters,\n showEmptyNamePlaceholder = mode === \"builder\",\n emptyNamePlaceholder = \"Fornavn Efternavn\",\n className = \"\",\n rootStyle,\n ...htmlProps\n}: DefaultAdProps) {\n const typography = mergeDefined(\n classicDefaultAdStyle.typography as Required<DefaultAdTypography>,\n style?.typography,\n );\n const spacing = mergeDefined(\n classicDefaultAdStyle.spacing as Required<DefaultAdSpacing>,\n style?.spacing,\n );\n const layout = mergeDefined(classicDefaultAdStyle, style);\n const fmt = { ...defaultFormatters, ...formatters };\n const { contact, text, icon, type } = data;\n const hasName = Boolean(contact.firstName || contact.lastName);\n const first = type === \"thanks\" ? text.thanksIntro : text.intro;\n const second = type === \"thanks\" ? text.briefIntroduction : text.title;\n const firstMargin = first && icon ? spacing.iconToText : 0;\n const secondMargin = second ? (first ? spacing.introToTitle : icon ? spacing.iconToText : 0) : 0;\n const nameMargin = hasName ? (first || second ? spacing.textToName : icon ? spacing.iconToText : 0) : 0;\n const isSingleColumn = Number(layout.columnsMm) === 41;\n const ceremonyCode = contact.ceremony?.code;\n const ceremonyLabel = contact.ceremony?.label ?? ceremonyCode;\n\n return (\n <div\n {...htmlProps}\n data-default-ad=\"\"\n data-ad-content=\"\"\n data-ad-ready=\"true\"\n data-mode={mode}\n className={`gda-root ${className}`.trim()}\n style={{\n width: `${layout.columnsMm}mm`,\n minWidth: `${layout.columnsMm}mm`,\n ...(layout.heightMm != null ? { height: `${layout.heightMm}mm` } : {}),\n padding: `${layout.paddingMm}mm ${layout.horizontalPaddingMm}mm`,\n border: layout.border ? `${layout.borderWidthPt}pt solid black` : 0,\n gap: `${spacing.sectionGapMm}mm`,\n fontFamily: typography.fontFamily,\n ...rootStyle,\n }}\n >\n {icon ? (\n <div className=\"gda-icon\">\n <svg className={icon.className} xmlns=\"http://www.w3.org/2000/svg\"\n width={Number(icon.width) + 16} height={Number(icon.height) + 16}\n viewBox={icon.viewBox} role={icon.title ? \"img\" : undefined} aria-hidden={icon.title ? undefined : true}>\n {icon.title ? <title>{icon.title}</title> : null}\n <g dangerouslySetInnerHTML={{ __html: decodeSvgMarkup(icon.svg) }} />\n </svg>\n </div>\n ) : null}\n\n <Text className={type === \"thanks\" ? \"gda-bold\" : \"\"}\n style={textStyle(type === \"thanks\" ? 14 : typography.introSize, typography.introLeading, firstMargin)}>\n {type === \"thanks\" && first ? first : type === \"obituaries\" ? first : null}\n </Text>\n <Text style={textStyle(typography.titleSize, typography.titleLeading, secondMargin)}>\n {type === \"thanks\" && second ? fmt.lowercaseFirst(second) : type === \"obituaries\" ? second : null}\n </Text>\n\n {hasName ? (\n <Text className=\"gda-bold gda-secondary-font\" style={textStyle(typography.nameSize, typography.nameLeading, nameMargin)}>\n {[contact.firstName, contact.lastName].filter(Boolean).join(\" \")}\n </Text>\n ) : showEmptyNamePlaceholder ? <div className=\"gda-placeholder\">{emptyNamePlaceholder}</div> : null}\n\n {(contact.showBirthDate && contact.birthDate) || (contact.showDeathDate && contact.deathDate) ? (\n <div className={`gda-dates ${isSingleColumn ? \"gda-dates-single\" : \"\"}`}\n style={{ marginTop: `${spacing.dateTop}pt`, lineHeight: `${typography.dateLeading}pt` }}>\n {contact.showBirthDate && contact.birthDate ? (\n <span style={{ fontSize: `${fmt.date(contact.birthDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }}>\n &#10043; {fmt.date(contact.birthDate)}\n </span>\n ) : null}\n {contact.showDeathDate && contact.deathDate ? (\n <span style={{ fontSize: `${fmt.date(contact.deathDate).length > 10 ? typography.longDateSize : typography.dateSize}pt` }}>\n <span className=\"gda-death-cross\" aria-label=\"died\">✝</span> {fmt.date(contact.deathDate)}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {type === \"obituaries\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop)}>{text.deceased}</Text> : null}\n {type === \"thanks\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.deceasedTop)}>{text.ceremony ? fmt.lowercaseFirst(text.ceremony) : null}</Text> : null}\n {type === \"thanks\" ? <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop)}>{text.message}</Text> : null}\n <Text className=\"gda-italic\" style={textStyle(typography.memorialSize, typography.memorialLeading, spacing.memorialTop)}>{text.memorial}</Text>\n {text.sender ? <Text className={`${type === \"obituaries\" ? \"gda-bold \" : \"\"}gda-secondary-font`} style={textStyle(typography.senderSize, typography.senderLeading, spacing.senderTop)}>{text.sender}</Text> : null}\n\n {type === \"obituaries\" && ceremonyCode !== \"NoCeremony\" && (contact.showChurch || contact.showFuneralDate) && (contact.church || contact.funeralDate) ? (\n <div className=\"gda-text\" style={textStyle(typography.bodySize, typography.bodyLeading, spacing.ceremonyTop)}>\n {contact.showChurch && contact.church ? <div>{contact.church.length > 15 ? <>{ceremonyLabel}<br />{contact.church}</> : `${ceremonyLabel ?? \"\"} ${contact.church}`.trim()}</div> : null}\n {contact.showFuneralDate && contact.funeralDate ? <div>{fmt.funeralDate(contact.funeralDate, Boolean(contact.hideFuneralYear))}</div> : null}\n </div>\n ) : null}\n\n <Text style={textStyle(typography.bodySize, typography.bodyLeading, spacing.thanksTop)}>{text.thanks}</Text>\n {text.donation ? <><div className=\"gda-divider\" style={{ marginTop: `${spacing.donationTop}pt` }} /><Text className=\"gda-donation\" style={textStyle(typography.bodySize, typography.bodyLeading, spacing.donationTop)}>{text.donation}</Text></> : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "navne-default-ad",
3
+ "version": "1.0.0",
4
+ "description": "Reusable obituary and thank-you advertisement renderer",
5
+ "license": "UNLICENSED",
6
+ "sideEffects": ["**/*.css"],
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./styles.css": "./dist/index.css",
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": ["dist", "README.md", "AUDIT.md", "LICENSE"],
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "clean": "tsup --clean",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
25
+ "smoke": "node scripts/smoke.cjs",
26
+ "pack:check": "npm pack --dry-run"
27
+ },
28
+ "peerDependencies": {
29
+ "react": ">=18 <20",
30
+ "react-dom": ">=18 <20"
31
+ },
32
+ "devDependencies": {
33
+ "@testing-library/react": "^16.3.0",
34
+ "@types/react": "^19.1.0",
35
+ "@types/react-dom": "^19.1.0",
36
+ "jsdom": "^26.1.0",
37
+ "react": "^19.1.0",
38
+ "react-dom": "^19.1.0",
39
+ "tsup": "^8.5.0",
40
+ "typescript": "^5.8.3",
41
+ "vitest": "^3.2.4"
42
+ },
43
+ "engines": { "node": ">=18" },
44
+ "publishConfig": { "access": "public" }
45
+ }