@salesmind-ai/design-system 0.3.0 → 0.3.1

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.
@@ -1,898 +1,10 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
1
+ export { ArticleMeta, BrandConfig, CareerForSchema, CustomerOrganizationMeta, FAQItem, GlossaryTermForSchema, HowToMeta, HowToStep, ItemForList, JsonLd, JsonLdProps, PersonMeta, PricingPlan, SeoBreadcrumbItem, ServiceMotion, TestimonialForSchema, TranscriptForSchema, VideoObjectMeta, aggregateRatingFromTestimonials, buildPageGraph, canonicalUrl, createEntityIds, createSchemaGenerators } from './server/index.cjs';
2
+ export { AnalyticsContextValue, AnalyticsEventProps, AnalyticsLoaderConfig, AnalyticsProvider, AnalyticsProviderProps, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, ConsentStatus, CookieConsent, CookieConsentLabels, CookieConsentProps, TrackFn, createAnalyticsLoader, loadClarity, loadGoogleAnalytics, useAnalytics, useCookieConsent } from './client/index.cjs';
3
3
  import { m as UtmParams } from '../types-DAlgDGzw.cjs';
4
4
  export { F as FirstTouchAttribution, U as UrlClassification, a as UtmAuditEntry, b as UtmBlockedError, c as UtmCampaign, d as UtmComplianceResult, e as UtmComplianceStatus, f as UtmConfidence, g as UtmContent, h as UtmMedium, i as UtmMediumAppPage, j as UtmMediumMessaging, k as UtmMediumWebPage, l as UtmOverrides, n as UtmSource, o as UtmSourceRequiringSeller, p as UtmTerm } from '../types-DAlgDGzw.cjs';
5
5
  export { U as UTM_CAMPAIGNS, a as UTM_CONTENTS, b as UTM_MEDIUMS_ALL, c as UTM_MEDIUMS_APP, d as UTM_MEDIUMS_MESSAGING, e as UTM_MEDIUMS_WEB, f as UTM_SOURCES, g as UTM_SOURCES_REQUIRING_SELLER, h as UTM_TERMS, i as buildBlockedError, j as buildUtmUrl, k as classifyAndEnforce, l as classifyUrl, m as createAuditEntry, n as isUtmExempt, o as isValidUtmParams, p as parseUtmParams, r as requiresSellerAttribution, q as requiresUtm, t as toFirstTouchAttribution, v as validateCompliance, s as validateUtmField } from '../audit-DwCmg32J.cjs';
6
-
7
- /**
8
- * Schema.org SEO Generator Types
9
- *
10
- * Framework-agnostic types for structured data generation.
11
- * Extracted from website/src/lib/seo.ts for reuse across all consumers.
12
- */
13
- /** Brand configuration required by schema generators */
14
- interface BrandConfig {
15
- name: string;
16
- url: string;
17
- description: string;
18
- tagline: string;
19
- founder: string;
20
- }
21
- interface BreadcrumbItem {
22
- name: string;
23
- url: string;
24
- }
25
- interface ArticleMeta {
26
- title: string;
27
- description: string;
28
- url: string;
29
- image?: string;
30
- publishedTime: string;
31
- modifiedTime: string;
32
- authorName: string;
33
- authorUrl?: string;
34
- authorSlug?: string;
35
- section: string;
36
- tags?: string[];
37
- speakableCssSelectors?: string[];
38
- about?: Record<string, unknown> | {
39
- '@id': string;
40
- };
41
- video?: Record<string, unknown> | {
42
- '@id': string;
43
- };
44
- }
45
- interface FAQItem {
46
- question: string;
47
- answer: string;
48
- }
49
- interface PersonMeta {
50
- name: string;
51
- jobTitle: string;
52
- slug?: string;
53
- url?: string;
54
- image?: string;
55
- sameAs?: string[];
56
- worksFor?: {
57
- name: string;
58
- '@id'?: string;
59
- };
60
- entityIdOverride?: string;
61
- }
62
- interface PricingPlan {
63
- name: string;
64
- description: string;
65
- price: string;
66
- priceCurrency?: string;
67
- billingPeriod?: string;
68
- }
69
- /** Lightweight testimonial shape for schema generation */
70
- interface TestimonialForSchema {
71
- id: string;
72
- customer_name: string;
73
- occupation?: string | null;
74
- star_rating?: number | null;
75
- review_date?: string | null;
76
- review_source?: string | null;
77
- review_link?: string | null;
78
- quote?: string | null;
79
- company?: string | null;
80
- authorEntityId?: string;
81
- }
82
- /** Lightweight career/job shape for schema generation */
83
- interface CareerForSchema {
84
- title: string;
85
- slug: string;
86
- department?: string | null;
87
- location?: string | null;
88
- type?: string | null;
89
- description?: string | null;
90
- created_at: string;
91
- published_at?: string | null;
92
- }
93
- /** Lightweight transcript shape for schema generation */
94
- interface TranscriptForSchema {
95
- title: string;
96
- slug: string;
97
- summary?: string | null;
98
- video_link?: string | null;
99
- transcript_text?: string | null;
100
- duration?: string | null;
101
- published_at?: string | null;
102
- path?: string;
103
- thumbnailUrl?: string;
104
- }
105
- /** Glossary term for DefinedTermSet schema */
106
- interface GlossaryTermForSchema {
107
- term: string;
108
- slug: string;
109
- definition: string;
110
- url?: string;
111
- }
112
- /** Single step in a HowTo schema */
113
- interface HowToStep {
114
- name: string;
115
- text: string;
116
- url?: string;
117
- image?: string;
118
- }
119
- /** HowTo metadata */
120
- interface HowToMeta {
121
- name: string;
122
- description: string;
123
- /** ISO 8601 duration, e.g. "PT30M" */
124
- totalTime?: string;
125
- image?: string;
126
- }
127
- /** Service/growth motion for Service schema */
128
- interface ServiceMotion {
129
- name: string;
130
- slug: string;
131
- description: string;
132
- url: string;
133
- price?: string;
134
- priceCurrency?: string;
135
- }
136
- /** Item for ItemList schema (hub/listing pages) */
137
- interface ItemForList {
138
- name: string;
139
- url: string;
140
- description?: string;
141
- image?: string;
142
- position?: number;
143
- }
144
- interface CustomerOrganizationMeta {
145
- name: string;
146
- slug: string;
147
- url?: string;
148
- logo?: string;
149
- industry?: string;
150
- description?: string;
151
- sameAs?: string[];
152
- }
153
- interface VideoObjectMeta {
154
- title: string;
155
- path: string;
156
- fragment?: string;
157
- description?: string;
158
- videoUrl?: string;
159
- embedUrl?: string;
160
- thumbnailUrl?: string;
161
- duration?: string;
162
- uploadDate?: string;
163
- transcript?: string;
164
- }
165
-
166
- /**
167
- * Schema.org Generator System
168
- *
169
- * Pure functions that generate structured data objects for SEO.
170
- * Each generator accepts a `BrandConfig` and optional `locale` for `inLanguage` injection.
171
- *
172
- * Architecture:
173
- * - Each generator returns an object with its own `@context` (standalone-safe).
174
- * - `buildPageGraph()` strips individual `@context` and wraps all schemas
175
- * in a single `{"@context": "...", "@graph": [...]}` for unified output.
176
- * - Use `JsonLd` React component to render the @graph into a single <script> tag.
177
- *
178
- * @example
179
- * ```ts
180
- * import { createSchemaGenerators, buildPageGraph } from '@salesmind-ai/design-system/web';
181
- *
182
- * const seo = createSchemaGenerators({
183
- * name: 'SalesMind AI',
184
- * url: 'https://sales-mind.ai',
185
- * description: 'AI sales automation',
186
- * tagline: 'AI-powered sales',
187
- * founder: 'Julien Gadea',
188
- * });
189
- *
190
- * const graph = buildPageGraph(
191
- * seo.organization(),
192
- * seo.website(),
193
- * seo.webPage('/pricing', 'Pricing', '...'),
194
- * );
195
- * ```
196
- */
197
-
198
- /**
199
- * Create stable entity ID anchors for @graph cross-referencing.
200
- * Every entity in the knowledge graph gets a permanent @id.
201
- * Google resolves @id references across the entire site.
202
- */
203
- declare function createEntityIds(brand: BrandConfig): {
204
- readonly organization: `${string}/#organization`;
205
- readonly website: `${string}/#website`;
206
- readonly software: `${string}/#software`;
207
- readonly product: `${string}/pricing#product`;
208
- readonly webpage: (path: string) => string;
209
- readonly article: (path: string) => string;
210
- readonly faq: (path: string) => string;
211
- readonly breadcrumb: (path: string) => string;
212
- readonly person: (slug: string) => string;
213
- readonly video: (path: string) => string;
214
- readonly review: (id: string) => string;
215
- readonly service: (slug: string) => string;
216
- readonly customerOrganization: (slug: string) => string;
217
- readonly customerPerson: (slug: string) => string;
218
- };
219
- /**
220
- * Create all schema generators bound to a specific brand configuration.
221
- * Returns an object with methods for each schema type.
222
- */
223
- declare function createSchemaGenerators(brand: BrandConfig, supportedLanguages?: readonly string[]): {
224
- /** Organization schema — Homepage + About page. */
225
- organization(locale?: string): {
226
- '@context': string;
227
- '@type': string;
228
- '@id': `${string}/#organization`;
229
- name: string;
230
- url: string;
231
- logo: {
232
- '@type': string;
233
- url: string;
234
- };
235
- description: string;
236
- inLanguage: string;
237
- availableLanguage: string[];
238
- founder: {
239
- '@type': string;
240
- name: string;
241
- };
242
- sameAs: string[];
243
- contactPoint: Record<string, unknown>[];
244
- areaServed: string;
245
- };
246
- /** WebSite schema — Homepage only (with SearchAction). */
247
- website(locale?: string): {
248
- '@context': string;
249
- '@type': string;
250
- '@id': `${string}/#website`;
251
- name: string;
252
- url: string;
253
- description: string;
254
- inLanguage: string;
255
- publisher: {
256
- '@type': string;
257
- '@id': `${string}/#organization`;
258
- name: string;
259
- };
260
- potentialAction: ({
261
- '@type': string;
262
- target: {
263
- '@type': string;
264
- urlTemplate: string;
265
- };
266
- 'query-input': string;
267
- } | {
268
- '@type': string;
269
- target: string;
270
- 'query-input'?: undefined;
271
- })[];
272
- };
273
- /** WebPage schema — Every public page. Links to WebSite + Breadcrumb via @id. */
274
- webPage(path: string, title: string, description: string, locale?: string, speakable?: Record<string, unknown>): {
275
- speakable?: Record<string, unknown> | undefined;
276
- '@context': string;
277
- '@type': string;
278
- '@id': string;
279
- url: string;
280
- name: string;
281
- description: string;
282
- inLanguage: string;
283
- isPartOf: {
284
- '@type': string;
285
- '@id': `${string}/#website`;
286
- };
287
- breadcrumb: {
288
- '@id': string;
289
- };
290
- potentialAction: {
291
- '@type': string;
292
- target: string;
293
- };
294
- };
295
- /** SoftwareApplication schema — Platform Hub, Platform Feature, Pricing. */
296
- softwareApplication(name?: string, description?: string, url?: string, locale?: string): {
297
- '@context': string;
298
- '@type': string;
299
- '@id': `${string}/#software`;
300
- name: string;
301
- description: string;
302
- url: string;
303
- applicationCategory: string;
304
- operatingSystem: string;
305
- inLanguage: string;
306
- availableLanguage: string[];
307
- offers: {
308
- '@type': string;
309
- priceCurrency: string;
310
- lowPrice: string;
311
- highPrice: string;
312
- offerCount: string;
313
- priceSpecification: {
314
- '@type': string;
315
- description: string;
316
- };
317
- };
318
- author: {
319
- '@type': string;
320
- '@id': `${string}/#organization`;
321
- name: string;
322
- };
323
- };
324
- /** Article schema — Blog posts, Comparison pages. */
325
- article(meta: ArticleMeta, locale?: string): {
326
- video?: Record<string, unknown> | {
327
- '@id': string;
328
- } | undefined;
329
- about?: Record<string, unknown> | {
330
- '@id': string;
331
- } | undefined;
332
- '@context': string;
333
- '@type': string;
334
- '@id': string;
335
- headline: string;
336
- description: string;
337
- url: string;
338
- image: string;
339
- datePublished: string;
340
- dateModified: string;
341
- inLanguage: string;
342
- author: {
343
- '@id': string;
344
- '@type'?: undefined;
345
- name?: undefined;
346
- url?: undefined;
347
- } | {
348
- '@type': string;
349
- name: string;
350
- url: string;
351
- '@id'?: undefined;
352
- };
353
- publisher: {
354
- '@type': string;
355
- '@id': `${string}/#organization`;
356
- name: string;
357
- logo: {
358
- '@type': string;
359
- url: string;
360
- };
361
- };
362
- isPartOf: {
363
- '@type': string;
364
- '@id': `${string}/#website`;
365
- };
366
- mainEntityOfPage: {
367
- '@id': string;
368
- };
369
- articleSection: string;
370
- keywords: string | undefined;
371
- speakable: {
372
- '@type': string;
373
- cssSelector: string[];
374
- };
375
- };
376
- /** FAQPage schema — FAQ hub, Solutions, Platform Features, Comparisons, Integrations. */
377
- faqPage(items: FAQItem[], pageUrl: string, locale?: string): {
378
- '@context': string;
379
- '@type': string;
380
- '@id': string;
381
- inLanguage: string;
382
- mainEntity: {
383
- '@type': string;
384
- name: string;
385
- acceptedAnswer: {
386
- '@type': string;
387
- text: string;
388
- inLanguage: string;
389
- };
390
- }[];
391
- };
392
- /** BreadcrumbList schema — Every public page. */
393
- breadcrumb(items: BreadcrumbItem[], locale?: string): {
394
- '@context': string;
395
- '@type': string;
396
- '@id': string;
397
- inLanguage: string;
398
- itemListElement: {
399
- '@type': string;
400
- position: number;
401
- name: string;
402
- item: string;
403
- }[];
404
- };
405
- /** Person schema — Team page, Blog author, Comparison author. */
406
- person(person: PersonMeta, locale?: string): {
407
- '@context': string;
408
- '@type': string;
409
- '@id': string;
410
- name: string;
411
- jobTitle: string;
412
- url: string | undefined;
413
- image: string | undefined;
414
- inLanguage: string;
415
- worksFor: {
416
- name: string;
417
- '@id'?: string | undefined;
418
- } | {
419
- '@type': string;
420
- '@id': `${string}/#organization`;
421
- name: string;
422
- };
423
- sameAs: string[];
424
- };
425
- /** Review schema — Generated from testimonials. */
426
- review(testimonial: TestimonialForSchema): {
427
- publisher?: {
428
- '@type': string;
429
- name: string;
430
- } | undefined;
431
- itemReviewed: {
432
- '@type': string;
433
- '@id': `${string}/#software`;
434
- name: string;
435
- };
436
- datePublished?: string | undefined;
437
- reviewRating?: {
438
- '@type': string;
439
- ratingValue: string;
440
- bestRating: string;
441
- worstRating: string;
442
- } | undefined;
443
- '@context': string;
444
- '@type': string;
445
- '@id': string;
446
- author: {
447
- jobTitle?: string | undefined;
448
- name: string;
449
- '@id'?: string | undefined;
450
- '@type': string;
451
- };
452
- reviewBody: string;
453
- };
454
- /** Product + multiple Offers schema — Pricing page. */
455
- productWithOffers(plans: PricingPlan[], testimonials?: TestimonialForSchema[], locale?: string): {
456
- offers: {
457
- priceSpecification?: {
458
- '@type': string;
459
- price: string;
460
- priceCurrency: string;
461
- billingDuration: string;
462
- } | undefined;
463
- '@type': string;
464
- name: string;
465
- description: string;
466
- price: string;
467
- priceCurrency: string;
468
- availability: string;
469
- url: string;
470
- }[];
471
- aggregateRating?: {
472
- '@type': string;
473
- ratingValue: string;
474
- ratingCount: string;
475
- bestRating: string;
476
- worstRating: string;
477
- } | undefined;
478
- '@context': string;
479
- '@type': string;
480
- '@id': `${string}/pricing#product`;
481
- name: string;
482
- description: string;
483
- brand: {
484
- '@type': string;
485
- '@id': `${string}/#organization`;
486
- name: string;
487
- };
488
- inLanguage: string;
489
- };
490
- /** VideoObject schema — Transcript detail pages. */
491
- videoObject(transcript: TranscriptForSchema, locale?: string): {
492
- transcript?: string | undefined;
493
- inLanguage: string;
494
- publisher: {
495
- '@type': string;
496
- '@id': `${string}/#organization`;
497
- name: string;
498
- };
499
- thumbnailUrl?: string | undefined;
500
- uploadDate?: string | undefined;
501
- duration?: string | undefined;
502
- embedUrl?: string | undefined;
503
- contentUrl?: string | undefined;
504
- '@context': string;
505
- '@type': string;
506
- '@id': string;
507
- name: string;
508
- description: string;
509
- };
510
- /** CustomerOrganization schema — Customer's company for Success Story pages. */
511
- customerOrganization(meta: CustomerOrganizationMeta): {
512
- sameAs?: string[] | undefined;
513
- industry?: string | undefined;
514
- description?: string | undefined;
515
- logo?: string | undefined;
516
- url?: string | undefined;
517
- '@context': string;
518
- '@type': string;
519
- '@id': string;
520
- name: string;
521
- };
522
- /** Generic VideoObject — Success story main video and shorts. */
523
- videoObjectGeneric(meta: VideoObjectMeta, locale?: string): {
524
- inLanguage: string;
525
- publisher: {
526
- '@id': `${string}/#organization`;
527
- };
528
- transcript?: string | undefined;
529
- uploadDate?: string | undefined;
530
- duration?: string | undefined;
531
- thumbnailUrl?: string | undefined;
532
- embedUrl?: string | undefined;
533
- contentUrl?: string | undefined;
534
- description?: string | undefined;
535
- '@context': string;
536
- '@type': string;
537
- '@id': string;
538
- name: string;
539
- };
540
- /** HowTo schema — Solution pages, tutorial blog posts. */
541
- howTo(steps: HowToStep[], meta: HowToMeta, locale?: string): {
542
- step: {
543
- image?: string | undefined;
544
- url?: string | undefined;
545
- '@type': string;
546
- position: number;
547
- name: string;
548
- text: string;
549
- }[];
550
- image?: string | undefined;
551
- totalTime?: string | undefined;
552
- '@context': string;
553
- '@type': string;
554
- name: string;
555
- description: string;
556
- inLanguage: string;
557
- };
558
- /** Service schema — Growth motion service offerings. */
559
- service(motion: ServiceMotion, locale?: string): {
560
- termsOfService: string;
561
- offers?: {
562
- '@type': string;
563
- price: string;
564
- priceCurrency: string;
565
- availability: string;
566
- } | undefined;
567
- '@context': string;
568
- '@type': string;
569
- '@id': string;
570
- name: string;
571
- description: string;
572
- url: string;
573
- provider: {
574
- '@type': string;
575
- '@id': `${string}/#organization`;
576
- name: string;
577
- };
578
- inLanguage: string;
579
- availableLanguage: string[];
580
- areaServed: string;
581
- };
582
- /** JobPosting schema — Career detail pages. */
583
- jobPosting(job: CareerForSchema, locale?: string): {
584
- inLanguage: string;
585
- jobLocation: {
586
- '@type': string;
587
- address: {
588
- '@type': string;
589
- addressLocality: string;
590
- };
591
- };
592
- '@context': string;
593
- '@type': string;
594
- '@id': string;
595
- title: string;
596
- description: string;
597
- datePosted: string;
598
- employmentType: string;
599
- hiringOrganization: {
600
- '@type': string;
601
- '@id': `${string}/#organization`;
602
- name: string;
603
- sameAs: string;
604
- };
605
- } | {
606
- inLanguage: string;
607
- jobLocationType: string;
608
- '@context': string;
609
- '@type': string;
610
- '@id': string;
611
- title: string;
612
- description: string;
613
- datePosted: string;
614
- employmentType: string;
615
- hiringOrganization: {
616
- '@type': string;
617
- '@id': `${string}/#organization`;
618
- name: string;
619
- sameAs: string;
620
- };
621
- };
622
- /** ItemList schema — Hub/listing pages. */
623
- itemList(items: ItemForList[], listName: string): {
624
- '@context': string;
625
- '@type': string;
626
- name: string;
627
- numberOfItems: number;
628
- itemListElement: {
629
- image?: string | undefined;
630
- description?: string | undefined;
631
- '@type': string;
632
- position: number;
633
- name: string;
634
- url: string;
635
- }[];
636
- };
637
- /** DefinedTermSet schema — Glossary page. */
638
- definedTermSet(terms: GlossaryTermForSchema[], locale?: string): {
639
- '@context': string;
640
- '@type': string;
641
- '@id': string;
642
- name: string;
643
- inLanguage: string;
644
- hasDefinedTerm: {
645
- '@type': string;
646
- name: string;
647
- description: string;
648
- url: string;
649
- }[];
650
- };
651
- /** Speakable — marks content sections suitable for voice assistant reading. */
652
- speakable(cssSelectors: string[]): Record<string, unknown>;
653
- /** Access the entity IDs for cross-referencing */
654
- entityIds: {
655
- readonly organization: `${string}/#organization`;
656
- readonly website: `${string}/#website`;
657
- readonly software: `${string}/#software`;
658
- readonly product: `${string}/pricing#product`;
659
- readonly webpage: (path: string) => string;
660
- readonly article: (path: string) => string;
661
- readonly faq: (path: string) => string;
662
- readonly breadcrumb: (path: string) => string;
663
- readonly person: (slug: string) => string;
664
- readonly video: (path: string) => string;
665
- readonly review: (id: string) => string;
666
- readonly service: (slug: string) => string;
667
- readonly customerOrganization: (slug: string) => string;
668
- readonly customerPerson: (slug: string) => string;
669
- };
670
- };
671
- /**
672
- * Compute AggregateRating from real testimonial data.
673
- * Falls back to hardcoded 4.7/150 when no rated testimonials exist.
674
- * Returns a fragment (no @context) — meant to be embedded in Product/SoftwareApp.
675
- */
676
- declare function aggregateRatingFromTestimonials(testimonials: TestimonialForSchema[]): {
677
- '@type': string;
678
- ratingValue: string;
679
- ratingCount: string;
680
- bestRating: string;
681
- worstRating: string;
682
- };
683
- /**
684
- * Assemble multiple schema entities into a single @graph array.
685
- * Strips individual `@context` from each schema — the wrapper provides it once.
686
- *
687
- * @example
688
- * ```ts
689
- * const graph = buildPageGraph(
690
- * seo.organization(),
691
- * seo.website(),
692
- * seo.webPage('/pricing', 'Pricing', '...'),
693
- * seo.breadcrumb(crumbs),
694
- * );
695
- * ```
696
- */
697
- declare function buildPageGraph(...schemas: Record<string, unknown>[]): Record<string, unknown>;
698
- /**
699
- * Build canonical URL from pathname.
700
- * Removes trailing slash (except root) and query params.
701
- *
702
- * @param baseUrl - The site's base URL (e.g. "https://sales-mind.ai")
703
- * @param pathname - The route path (e.g. "/pricing", "/blog/post/foo")
704
- * @param locale - BCP-47 locale code. 'en' = no prefix (default). Others get /{locale}/ prefix.
705
- */
706
- declare function canonicalUrl(baseUrl: string, pathname: string, locale?: string): string;
707
-
708
- /**
709
- * JsonLd — Renders structured data as a `<script type="application/ld+json">` tag.
710
- *
711
- * Framework-agnostic: works with any React-based framework (Next.js, Vite, Remix, etc.).
712
- * Safely serializes the data object and escapes `</script>` sequences.
713
- *
714
- * @example
715
- * ```tsx
716
- * import { JsonLd, buildPageGraph } from '@salesmind-ai/design-system/web';
717
- *
718
- * <JsonLd data={buildPageGraph(seo.organization(), seo.website())} />
719
- * ```
720
- */
721
- interface JsonLdProps {
722
- /** The structured data object (schema.org format) */
723
- data: Record<string, unknown>;
724
- /** Optional nonce for CSP headers */
725
- nonce?: string;
726
- }
727
- declare function JsonLd({ data, nonce }: JsonLdProps): react_jsx_runtime.JSX.Element;
728
-
729
- /**
730
- * Generic analytics script loader.
731
- *
732
- * Framework-agnostic: injects a `<script>` tag into `<head>` once,
733
- * guards against double-loading, and respects cookie consent.
734
- *
735
- * @example
736
- * ```ts
737
- * import { createAnalyticsLoader } from '@salesmind-ai/design-system/web';
738
- *
739
- * const loadGA = createAnalyticsLoader({
740
- * id: 'ga-script',
741
- * src: (gaId) => `https://www.googletagmanager.com/gtag/js?id=${gaId}`,
742
- * onLoad: (gaId) => {
743
- * window.dataLayer = window.dataLayer || [];
744
- * function gtag(...args: unknown[]) { window.dataLayer.push(args); }
745
- * gtag('js', new Date());
746
- * gtag('config', gaId);
747
- * },
748
- * });
749
- *
750
- * // Later, after consent:
751
- * loadGA('G-XXXXXX');
752
- * ```
753
- */
754
- interface AnalyticsLoaderConfig<TId extends string = string> {
755
- /** Unique DOM id for the script element (prevents double-loading) */
756
- id: string;
757
- /** Build the script src URL from the tracking ID */
758
- src: (trackingId: TId) => string;
759
- /** Async attribute on the script tag (default: true) */
760
- async?: boolean;
761
- /** Called after the script is appended to the DOM */
762
- onLoad?: (trackingId: TId) => void;
763
- /** Custom inline script content instead of an external src */
764
- inlineScript?: (trackingId: TId) => string;
765
- }
766
- /**
767
- * Create a reusable analytics loader function.
768
- * The returned function injects the script once and is safe to call multiple times.
769
- */
770
- declare function createAnalyticsLoader<TId extends string = string>(config: AnalyticsLoaderConfig<TId>): (trackingId: TId) => void;
771
- declare global {
772
- interface Window {
773
- dataLayer: unknown[];
774
- clarity?: (...args: unknown[]) => void;
775
- }
776
- }
777
- /**
778
- * Load Google Analytics (gtag.js).
779
- * Call with your GA measurement ID after cookie consent.
780
- */
781
- declare const loadGoogleAnalytics: (trackingId: string) => void;
782
- /**
783
- * Load Microsoft Clarity.
784
- * Call with your Clarity project ID after cookie consent.
785
- */
786
- declare const loadClarity: (trackingId: string) => void;
787
-
788
- /** Cookie consent state */
789
- type ConsentStatus = 'granted' | 'denied' | null;
790
- /** Event name dispatched on window when consent changes */
791
- declare const COOKIE_CONSENT_EVENT = "cookie_consent_granted";
792
- /** localStorage key for cookie consent */
793
- declare const COOKIE_CONSENT_KEY = "cookie_consent";
794
- /** Labels for i18n support */
795
- interface CookieConsentLabels {
796
- title?: string;
797
- description?: string;
798
- privacyLinkText?: string;
799
- acceptLabel?: string;
800
- declineLabel?: string;
801
- }
802
- interface CookieConsentProps {
803
- /** Delay in ms before showing the banner (default: 1000) */
804
- delay?: number;
805
- /** URL to the privacy policy page (default: "/legal/privacy") */
806
- privacyUrl?: string;
807
- /** Called when the user accepts cookies */
808
- onAccept?: () => void;
809
- /** Called when the user declines cookies */
810
- onDecline?: () => void;
811
- /** Override default labels for i18n */
812
- labels?: CookieConsentLabels;
813
- /** Custom className for the container */
814
- className?: string;
815
- }
816
- /**
817
- * CookieConsent — GDPR-compliant cookie consent banner.
818
- *
819
- * - Animated entrance/exit via CSS transitions (no framer-motion)
820
- * - Respects prior consent stored in localStorage
821
- * - Dispatches a `cookie_consent_granted` event on the window for analytics loaders
822
- * - Uses DS Button component
823
- *
824
- * @example
825
- * ```tsx
826
- * import { CookieConsent } from '@salesmind-ai/design-system/web';
827
- *
828
- * <CookieConsent
829
- * privacyUrl="/legal/privacy"
830
- * onAccept={() => loadGoogleAnalytics('G-XXXX')}
831
- * />
832
- * ```
833
- */
834
- declare function CookieConsent({ delay, privacyUrl, onAccept, onDecline, labels, className, }: CookieConsentProps): react_jsx_runtime.JSX.Element | null;
835
-
836
- /**
837
- * React hook that tracks cookie consent status.
838
- *
839
- * Returns `true` once the user has granted cookie consent,
840
- * `false` if denied, `null` if not yet decided.
841
- *
842
- * Listens for the `cookie_consent_granted` window event dispatched
843
- * by the CookieConsent component.
844
- *
845
- * @example
846
- * ```tsx
847
- * const hasConsent = useCookieConsent();
848
- *
849
- * useEffect(() => {
850
- * if (hasConsent) loadGoogleAnalytics('G-XXXX');
851
- * }, [hasConsent]);
852
- * ```
853
- */
854
- declare function useCookieConsent(): ConsentStatus;
855
-
856
- /** Arbitrary properties bag attached to every analytics event. */
857
- type AnalyticsEventProps = Record<string, string | number | boolean | undefined>;
858
- /** Signature for the track function provided by AnalyticsProvider. */
859
- type TrackFn = (event: string, props?: AnalyticsEventProps) => void;
860
- /** Value exposed by the AnalyticsContext. */
861
- interface AnalyticsContextValue {
862
- track: TrackFn;
863
- }
864
-
865
- /** Props for the AnalyticsProvider component */
866
- interface AnalyticsProviderProps {
867
- /** Callback invoked on every track() call. Wire this to your analytics backend. */
868
- onTrack: TrackFn;
869
- /** Enable console logging in development (default: false) */
870
- debug?: boolean;
871
- children: ReactNode;
872
- }
873
- /**
874
- * Provides analytics event tracking to all descendant DS components.
875
- *
876
- * @example
877
- * ```tsx
878
- * <AnalyticsProvider
879
- * onTrack={(event, props) => {
880
- * window.gtag?.('event', event, props);
881
- * }}
882
- * >
883
- * <App />
884
- * </AnalyticsProvider>
885
- * ```
886
- */
887
- declare function AnalyticsProvider({ onTrack, debug, children }: AnalyticsProviderProps): react_jsx_runtime.JSX.Element;
888
-
889
- /**
890
- * Hook that returns the analytics `track` function.
891
- *
892
- * Safe to call without a wrapping `<AnalyticsProvider>` — all calls
893
- * become no-ops in that case (Storybook, tests, SSR).
894
- */
895
- declare function useAnalytics(): AnalyticsContextValue;
6
+ import * as react_jsx_runtime from 'react/jsx-runtime';
7
+ import { ReactNode } from 'react';
896
8
 
897
9
  interface UtmProviderProps {
898
10
  /** Default UTM parameters for all descendants. */
@@ -918,4 +30,4 @@ declare function UtmProvider({ params, children }: UtmProviderProps): react_jsx_
918
30
  */
919
31
  declare function useUtmDefaults(): UtmParams | null;
920
32
 
921
- export { type AnalyticsContextValue, type AnalyticsEventProps, type AnalyticsLoaderConfig, AnalyticsProvider, type AnalyticsProviderProps, type ArticleMeta, type BrandConfig, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, type CareerForSchema, type ConsentStatus, CookieConsent, type CookieConsentLabels, type CookieConsentProps, type CustomerOrganizationMeta, type FAQItem, type GlossaryTermForSchema, type HowToMeta, type HowToStep, type ItemForList, JsonLd, type JsonLdProps, type PersonMeta, type PricingPlan, type BreadcrumbItem as SeoBreadcrumbItem, type ServiceMotion, type TestimonialForSchema, type TrackFn, type TranscriptForSchema, UtmParams, UtmProvider, type UtmProviderProps, type VideoObjectMeta, aggregateRatingFromTestimonials, buildPageGraph, canonicalUrl, createAnalyticsLoader, createEntityIds, createSchemaGenerators, loadClarity, loadGoogleAnalytics, useAnalytics, useCookieConsent, useUtmDefaults };
33
+ export { UtmParams, UtmProvider, type UtmProviderProps, useUtmDefaults };