fragment-headless-sdk 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import { IAnnouncementContent } from "../../types";
3
+ export default function AnnouncementButton({ content, }: {
4
+ content: IAnnouncementContent;
5
+ }): React.JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { ButtonType } from "../../constants";
3
- export default function BannerButton({ content }) {
4
- return (React.createElement("a", { href: content.buttonLink || "#", className: "whitespace-nowrap rounded-md px-3 py-2 font-medium text-base no-underline text-white hover:cursor-pointer hover:opacity-70", style: {
3
+ export default function AnnouncementButton({ content, }) {
4
+ return (React.createElement("a", { href: content.buttonLink || "#", className: "whitespace-nowrap rounded-md px-3 py-2 font-semibold text-sm no-underline text-white hover:cursor-pointer hover:opacity-70 py-2", style: {
5
5
  ...(content.buttonType === ButtonType.Text
6
6
  ? {
7
7
  textDecoration: "underline",
@@ -0,0 +1,3 @@
1
+ export declare function AnnouncementStyles({ seconds }: {
2
+ seconds?: number;
3
+ }): null;
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { useEffect } from "react";
3
- export function BannerStyles({ seconds = 15 }) {
3
+ export function AnnouncementStyles({ seconds = 15 }) {
4
4
  useEffect(() => {
5
5
  const style = document.createElement("style");
6
- style.id = "banner-styles"; // Ensure unique ID to avoid duplicates
6
+ style.id = "announcement-styles"; // Ensure unique ID to avoid duplicates
7
7
  style.textContent = `
8
8
  @keyframes marquee {
9
9
  0% {
@@ -22,11 +22,11 @@ export function BannerStyles({ seconds = 15 }) {
22
22
  padding-bottom: 4rem !important;
23
23
  }
24
24
  `;
25
- if (!document.getElementById("banner-styles")) {
25
+ if (!document.getElementById("announcement-styles")) {
26
26
  document.head.appendChild(style);
27
27
  }
28
28
  return () => {
29
- document.getElementById("banner-styles")?.remove();
29
+ document.getElementById("announcement-styles")?.remove();
30
30
  };
31
31
  }, [seconds]);
32
32
  return null;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { IBannerContent } from "../../types";
2
+ import { IAnnouncementContent } from "../../types";
3
3
  export default function CountdownTimer({ content, }: {
4
- content: IBannerContent;
4
+ content: IAnnouncementContent;
5
5
  }): React.JSX.Element;
@@ -26,12 +26,12 @@ export default function CountdownTimer({ content, }) {
26
26
  return () => clearInterval(interval);
27
27
  }, [content.counterEndDate]);
28
28
  const renderBlock = (value, label) => (React.createElement("div", { className: "flex flex-col items-center" },
29
- React.createElement("div", { className: "flex gap-1" }, value.split("").map((digit, i) => (React.createElement("span", { key: i, className: "w-6 h-7 rounded bg-black text-white text-xl font-bold flex items-center justify-center", style: {
29
+ React.createElement("div", { className: "flex gap-1" }, value.split("").map((digit, i) => (React.createElement("span", { key: i, className: "w-5 h-6 rounded bg-black text-white text-base font-bold flex items-center justify-center", style: {
30
30
  backgroundColor: content.counterBgColor || "#000000",
31
31
  color: content.counterDigitColor || "#FFFFFF",
32
32
  } }, digit)))),
33
- React.createElement("span", { className: "mt-0.5 text-xs" }, label)));
34
- return (React.createElement("div", { className: "flex items-center gap-1 bg-gray-100 rounded" },
33
+ React.createElement("span", { className: "mt-0.5 text-[10px]" }, label)));
34
+ return (React.createElement("div", { className: "flex items-center justify-center gap-1 p-2" },
35
35
  renderBlock(timeLeft.days, "Days"),
36
36
  React.createElement("span", { className: "text-xl font-semibold -mt-4" }, ":"),
37
37
  renderBlock(timeLeft.hours, "Hours"),
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { AnnouncementType } from "../../constants";
3
+ import { IAnnouncementContent } from "../../types";
4
+ export default function ({ content, type, handleClose, }: {
5
+ content: IAnnouncementContent;
6
+ type: AnnouncementType;
7
+ handleClose: () => void;
8
+ }): React.JSX.Element;
@@ -1,26 +1,28 @@
1
1
  import React from "react";
2
- import { BannerType, ButtonType } from "../../constants";
3
- import BannerButton from "./BannerButton";
4
- import { BannerStyles } from "./BannerStyles";
2
+ import { AnnouncementType, ButtonType } from "../../constants";
3
+ import AnnouncementButton from "./AnnouncementButton";
4
+ import { AnnouncementStyles } from "./AnnouncementStyles";
5
5
  import CountdownTimer from "./CountdownTimer";
6
6
  export default function ({ content, type, handleClose, }) {
7
7
  return (React.createElement("div", { className: "relative w-full", style: {
8
8
  backgroundColor: content.bgColor,
9
9
  color: content.textColor,
10
10
  } },
11
- React.createElement(BannerStyles, null),
12
- React.createElement("div", { className: "relative mx-auto flex max-w-screen-xl flex-col md:flex-row items-center justify-center gap-4 px-4 py-3 text-center md:text-left" },
13
- type === BannerType.Marquee ? (React.createElement("div", { className: "flex w-full flex-col md:flex-row items-center justify-between gap-2 md:gap-4 overflow-hidden md:pr-8" },
11
+ React.createElement(AnnouncementStyles, null),
12
+ React.createElement("div", { className: "relative mx-auto flex max-w-screen-xl flex-col md:flex-row items-center justify-center gap-4 px-10 md:px-4 py-2 md:py-0 text-center md:text-left min-h-[50px]" },
13
+ type === AnnouncementType.Marquee ? (React.createElement("div", { className: "flex w-full flex-col md:flex-row items-center justify-between gap-2 md:gap-4 overflow-hidden md:pr-8" },
14
14
  React.createElement("div", { className: "w-full md:flex-1 overflow-hidden" },
15
15
  React.createElement("div", { className: "whitespace-nowrap animate-marquee" },
16
16
  React.createElement("div", { className: "inline-block max-w-none text-base", dangerouslySetInnerHTML: {
17
- __html: content.bannerHtml || "",
17
+ __html: content.announcementHtml || "",
18
18
  } }))),
19
- content.buttonText && content.buttonType !== ButtonType.None && (React.createElement(BannerButton, { content: content })))) : (React.createElement("div", { className: "flex flex-col md:flex-row items-center justify-center gap-2 md:gap-4 w-full" },
19
+ content.buttonText && content.buttonType !== ButtonType.None && (React.createElement(AnnouncementButton, { content: content })))) : (React.createElement("div", { className: "flex flex-col md:flex-row items-center justify-center gap-2 md:gap-4 w-full" },
20
20
  React.createElement("div", { className: "max-w-none text-base font-semibold" },
21
- React.createElement("div", { dangerouslySetInnerHTML: { __html: content.bannerHtml || "" } })),
22
- type === BannerType.Countdown ? (React.createElement(CountdownTimer, { content: content })) : (content.buttonText &&
23
- content.buttonType !== ButtonType.None && (React.createElement(BannerButton, { content: content }))))),
21
+ React.createElement("div", { dangerouslySetInnerHTML: {
22
+ __html: content.announcementHtml || "",
23
+ } })),
24
+ type === AnnouncementType.Countdown ? (React.createElement(CountdownTimer, { content: content })) : (content.buttonText &&
25
+ content.buttonType !== ButtonType.None && (React.createElement(AnnouncementButton, { content: content }))))),
24
26
  React.createElement("div", { onClick: handleClose, className: "absolute right-4 top-1/2 -translate-y-1/2 text-3xl leading-none cursor-pointer", style: {
25
27
  color: content.textColor || "#000",
26
28
  } }, "\u00D7"))));
@@ -1,2 +1,2 @@
1
- export { default as Banner } from "./Banner";
1
+ export { default as Announcement } from "./Announcement";
2
2
  export { default as Hero } from "./Hero";
@@ -1,2 +1,2 @@
1
- export { default as Banner } from "./Banner";
1
+ export { default as Announcement } from "./Announcement";
2
2
  export { default as Hero } from "./Hero";
@@ -1,13 +1,13 @@
1
- export declare enum BannerType {
1
+ export declare enum AnnouncementType {
2
2
  Countdown = "countdown",
3
- Announcement = "announcement",
3
+ Static = "static",
4
4
  Marquee = "marquee"
5
5
  }
6
- export declare const bannerTypes: {
6
+ export declare const announcementTypes: {
7
7
  label: string;
8
- value: BannerType;
8
+ value: AnnouncementType;
9
9
  }[];
10
- export declare enum BannerStatus {
10
+ export declare enum AnnouncementStatus {
11
11
  Enabled = "enabled",
12
12
  Disabled = "disabled"
13
13
  }
@@ -0,0 +1,22 @@
1
+ export var AnnouncementType;
2
+ (function (AnnouncementType) {
3
+ AnnouncementType["Countdown"] = "countdown";
4
+ AnnouncementType["Static"] = "static";
5
+ AnnouncementType["Marquee"] = "marquee";
6
+ })(AnnouncementType || (AnnouncementType = {}));
7
+ export const announcementTypes = [
8
+ { label: "Static", value: AnnouncementType.Static },
9
+ { label: "Countdown Timer", value: AnnouncementType.Countdown },
10
+ { label: "Scrolling Text / Marquee", value: AnnouncementType.Marquee },
11
+ ];
12
+ export var AnnouncementStatus;
13
+ (function (AnnouncementStatus) {
14
+ AnnouncementStatus["Enabled"] = "enabled";
15
+ AnnouncementStatus["Disabled"] = "disabled";
16
+ })(AnnouncementStatus || (AnnouncementStatus = {}));
17
+ export var ButtonType;
18
+ (function (ButtonType) {
19
+ ButtonType["None"] = "none";
20
+ ButtonType["Default"] = "default";
21
+ ButtonType["Text"] = "text";
22
+ })(ButtonType || (ButtonType = {}));
@@ -1,2 +1,2 @@
1
- export * from "./banner";
1
+ export * from "./announcement";
2
2
  export * from "./hero";
@@ -1,2 +1,2 @@
1
- export * from "./banner";
1
+ export * from "./announcement";
2
2
  export * from "./hero";
@@ -1,14 +1,14 @@
1
- import { BannerStatus, BannerType, ButtonType } from "../constants";
1
+ import { AnnouncementStatus, AnnouncementType, ButtonType } from "../constants";
2
2
  export declare const buttonTypes: {
3
3
  label: string;
4
4
  value: ButtonType;
5
5
  }[];
6
- export interface IBannerContent {
6
+ export interface IAnnouncementContent {
7
7
  buttonType: ButtonType;
8
8
  buttonText: string;
9
9
  buttonLink: string;
10
10
  bgColor: string;
11
- bannerHtml: string;
11
+ announcementHtml: string;
12
12
  buttonColor: string;
13
13
  buttonTextColor: string;
14
14
  textColor: string;
@@ -16,13 +16,13 @@ export interface IBannerContent {
16
16
  counterBgColor?: string;
17
17
  counterDigitColor?: string;
18
18
  }
19
- export interface IBanner {
19
+ export interface IAnnouncement {
20
20
  id: string;
21
21
  shop: string;
22
- type: BannerType;
22
+ type: AnnouncementType;
23
23
  name: string;
24
- status: BannerStatus;
25
- content: IBannerContent | null;
24
+ status: AnnouncementStatus;
25
+ content: IAnnouncementContent | null;
26
26
  created_at: string;
27
27
  updated_at: string;
28
28
  }
@@ -1,2 +1,2 @@
1
- export * from "./banner";
1
+ export * from "./announcement";
2
2
  export * from "./hero";
@@ -1,2 +1,2 @@
1
- export * from "./banner";
1
+ export * from "./announcement";
2
2
  export * from "./hero";
@@ -1,6 +1,6 @@
1
1
  export declare enum ResourceType {
2
- HeroSections = "hero-sections",
3
- Banners = "banners"
2
+ HeroBanners = "hero-banners",
3
+ Announcements = "announcements"
4
4
  }
5
5
  type FetchResourceParams = {
6
6
  baseUrl: string;
@@ -1,7 +1,7 @@
1
1
  export var ResourceType;
2
2
  (function (ResourceType) {
3
- ResourceType["HeroSections"] = "hero-sections";
4
- ResourceType["Banners"] = "banners";
3
+ ResourceType["HeroBanners"] = "hero-banners";
4
+ ResourceType["Announcements"] = "announcements";
5
5
  })(ResourceType || (ResourceType = {}));
6
6
  export async function fetchResource({ baseUrl, apiKey, type, }) {
7
7
  if (!baseUrl || !apiKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fragment-headless-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -21,10 +21,10 @@ Fragment-Shopify App (CMS) → API Endpoint → fragment-shopify-sdk (Consumer)
21
21
  ## 🔧 Features
22
22
 
23
23
  - ✅ **Data Fetching**: Built-in utilities to fetch sections from fragment-shopify API
24
- - ✅ **React Components**: Pre-built Hero and Banner components with responsive design
24
+ - ✅ **React Components**: Pre-built Hero and Announcement components with responsive design
25
25
  - ✅ **TypeScript Support**: Full type definitions for all components and data structures
26
26
  - ✅ **Tailwind Integration**: Styled with Tailwind CSS for easy customization
27
- - ✅ **Multiple Banner Types**: Standard, marquee, and countdown banner variants
27
+ - ✅ **Multiple Announcement Types**: Standard, marquee, and countdown announcement variants
28
28
  - ✅ **Hero Sections**: Desktop/mobile responsive hero components with video support
29
29
 
30
30
  ---
@@ -62,7 +62,10 @@ module.exports = {
62
62
  "./app/**/*.{js,ts,jsx,tsx,mdx}",
63
63
  "./pages/**/*.{js,ts,jsx,tsx,mdx}",
64
64
  "./components/**/*.{js,ts,jsx,tsx,mdx}",
65
- path.join(__dirname, "node_modules/fragment-headless-sdk/dist/**/*.{js,ts,jsx,tsx}"),
65
+ path.join(
66
+ __dirname,
67
+ "node_modules/fragment-headless-sdk/dist/**/*.{js,ts,jsx,tsx}"
68
+ ),
66
69
  ],
67
70
  theme: {
68
71
  extend: {},
@@ -92,40 +95,40 @@ module.exports = {
92
95
  import { fetchResource, ResourceType } from "fragment-headless-sdk";
93
96
 
94
97
  // Fetch hero sections
95
- const heroes = await fetchResource({
98
+ const heroBanners = await fetchResource({
96
99
  baseUrl: process.env.EXTERNAL_API_URL, // Your fragment-shopify app URL
97
100
  apiKey: process.env.FRAGMENT_API_KEY, // API key from fragment-shopify (format: "keyId:secret")
98
- type: ResourceType.HeroSections,
101
+ type: ResourceType.HeroBanners,
99
102
  });
100
103
 
101
- // Fetch banners
102
- const banners = await fetchResource({
104
+ // Fetch announcements
105
+ const announcements = await fetchResource({
103
106
  baseUrl: process.env.EXTERNAL_API_URL,
104
107
  apiKey: process.env.FRAGMENT_API_KEY,
105
- type: ResourceType.Banners,
108
+ type: ResourceType.Announcements,
106
109
  });
107
110
  ```
108
111
 
109
112
  ### 2. Render Components
110
113
 
111
114
  ```tsx
112
- import { Banner, Hero } from "fragment-headless-sdk";
113
- import { BannerType } from "fragment-headless-sdk";
115
+ import { Announcement, Hero } from "fragment-headless-sdk";
116
+ import { AnnouncementType } from "fragment-headless-sdk";
114
117
 
115
118
  export default function Page() {
116
- const [showBanner, setShowBanner] = useState(true);
119
+ const [showAnnouncement, setShowAnnouncement] = useState(true);
117
120
 
118
121
  return (
119
122
  <>
120
123
  {/* Hero Section */}
121
- <Hero content={heroes[0]?.content} />
122
-
123
- {/* Banner */}
124
- {showBanner && banners[0] && (
125
- <Banner
126
- content={banners[0].content}
127
- type={banners[0].type as BannerType}
128
- handleClose={() => setShowBanner(false)}
124
+ <Hero content={heroBanners[0]?.content} />
125
+
126
+ {/* Announcement */}
127
+ {showAnnouncement && announcements[0] && (
128
+ <Announcement
129
+ content={announcements[0].content}
130
+ type={announcements[0].type as AnnouncementType}
131
+ handleClose={() => setShowAnnouncement(false)}
129
132
  />
130
133
  )}
131
134
  </>
@@ -149,8 +152,8 @@ Fetches sections from your fragment-shopify app.
149
152
 
150
153
  **ResourceType Options:**
151
154
 
152
- - `ResourceType.HeroSections` - Fetch hero sections
153
- - `ResourceType.Banners` - Fetch banner sections
155
+ - `ResourceType.HeroBanners` - Fetch hero banners
156
+ - `ResourceType.Announcements` - Fetch announcement sections
154
157
 
155
158
  **Returns:** `Promise<T[]>` - Array of fetched resources
156
159
 
@@ -216,37 +219,37 @@ interface IHeroContent {
216
219
  }
217
220
  ```
218
221
 
219
- ### Banner Component
222
+ ### Announcement Component
220
223
 
221
- Flexible banner component with multiple display types and countdown functionality.
224
+ Flexible announcement component with multiple display types and countdown functionality.
222
225
 
223
226
  ```tsx
224
- import { Banner, BannerType } from "fragment-headless-sdk";
227
+ import { Announcement, AnnouncementType } from "fragment-headless-sdk";
225
228
 
226
- <Banner
227
- content={bannerContent}
228
- type={BannerType.Standard}
229
- handleClose={() => setBannerVisible(false)}
229
+ <Announcement
230
+ content={announcementContent}
231
+ type={AnnouncementType.Announcement}
232
+ handleClose={() => setAnnouncementVisible(false)}
230
233
  />;
231
234
  ```
232
235
 
233
236
  **Props:**
234
237
 
235
- - `content: IBannerContent` - Banner configuration object
236
- - `type: BannerType` - Display type (Standard, Marquee, Countdown)
237
- - `handleClose: () => void` - Function called when banner is closed
238
+ - `content: IAnnouncementContent` - Announcement configuration object
239
+ - `type: AnnouncementType` - Display type (Announcement, Marquee, Countdown)
240
+ - `handleClose: () => void` - Function called when announcement is closed
238
241
 
239
- **Banner Types:**
242
+ **Announcement Types:**
240
243
 
241
- - `BannerType.Standard` - Regular banner with text and button
242
- - `BannerType.Marquee` - Scrolling marquee banner
243
- - `BannerType.Countdown` - Banner with countdown timer
244
+ - `AnnouncementType.Announcement` - Regular announcement with text and button
245
+ - `AnnouncementType.Marquee` - Scrolling marquee announcement
246
+ - `AnnouncementType.Countdown` - Announcement with countdown timer
244
247
 
245
- **IBannerContent Interface:**
248
+ **IAnnouncementContent Interface:**
246
249
 
247
250
  ```typescript
248
- interface IBannerContent {
249
- bannerHtml: string;
251
+ interface IAnnouncementContent {
252
+ announcementHtml: string;
250
253
  bgColor: string;
251
254
  textColor: string;
252
255
  buttonType: ButtonType;
@@ -323,7 +326,7 @@ Components use Tailwind utility classes. You can customize styling by:
323
326
  - Background image/video support
324
327
  - Customizable button styles through content props
325
328
 
326
- **Banner Component:**
329
+ **Announcement Component:**
327
330
 
328
331
  - Dynamic background and text colors via `content.bgColor` and `content.textColor`
329
332
  - Marquee animation with `animate-marquee` class
@@ -338,14 +341,14 @@ graph TD
338
341
  A[Fragment-Shopify App] --> B[API Endpoint]
339
342
  B --> C[fetchResource()]
340
343
  C --> D[Your React App]
341
- D --> E[Hero/Banner Components]
344
+ D --> E[Hero/Announcement Components]
342
345
  E --> F[Rendered UI]
343
346
  ```
344
347
 
345
348
  1. **Content Creation**: Editors create sections in fragment-shopify app
346
349
  2. **Publishing**: Sections are published and available via API
347
350
  3. **Data Fetching**: Your app calls `fetchResource()` to get section data
348
- 4. **Component Rendering**: Pass data to Hero/Banner components
351
+ 4. **Component Rendering**: Pass data to Hero/Announcement components
349
352
  5. **UI Display**: Components render responsive, styled sections
350
353
 
351
354
  ---
@@ -378,7 +381,7 @@ const sections = await fetchResource({...});
378
381
  fragment-headless-sdk/
379
382
  ├── src/
380
383
  │ ├── components/ # React components
381
- │ │ ├── Banner/ # Banner component variants
384
+ │ │ ├── Announcement/ # Announcement component variants
382
385
  │ │ └── Hero/ # Hero component variants
383
386
  │ ├── constants/ # Enums and constants
384
387
  │ ├── types/ # TypeScript interfaces
@@ -1,5 +0,0 @@
1
- import React from "react";
2
- import { IBannerContent } from "../../types";
3
- export default function BannerButton({ content }: {
4
- content: IBannerContent;
5
- }): React.JSX.Element;
@@ -1,3 +0,0 @@
1
- export declare function BannerStyles({ seconds }: {
2
- seconds?: number;
3
- }): null;
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- import { BannerType } from "../../constants";
3
- import { IBannerContent } from "../../types";
4
- export default function ({ content, type, handleClose, }: {
5
- content: IBannerContent;
6
- type: BannerType;
7
- handleClose: () => void;
8
- }): React.JSX.Element;
@@ -1,22 +0,0 @@
1
- export var BannerType;
2
- (function (BannerType) {
3
- BannerType["Countdown"] = "countdown";
4
- BannerType["Announcement"] = "announcement";
5
- BannerType["Marquee"] = "marquee";
6
- })(BannerType || (BannerType = {}));
7
- export const bannerTypes = [
8
- { label: "Announcement Banner", value: BannerType.Announcement },
9
- { label: "Countdown Timer", value: BannerType.Countdown },
10
- { label: "Scrolling Text / Marquee", value: BannerType.Marquee },
11
- ];
12
- export var BannerStatus;
13
- (function (BannerStatus) {
14
- BannerStatus["Enabled"] = "enabled";
15
- BannerStatus["Disabled"] = "disabled";
16
- })(BannerStatus || (BannerStatus = {}));
17
- export var ButtonType;
18
- (function (ButtonType) {
19
- ButtonType["None"] = "none";
20
- ButtonType["Default"] = "default";
21
- ButtonType["Text"] = "text";
22
- })(ButtonType || (ButtonType = {}));
File without changes