zuljaman-banner-components 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/README.md +242 -0
- package/dist/adapters/NextJSAdapter.d.ts +17 -0
- package/dist/adapters/NextJSAdapter.d.ts.map +1 -0
- package/dist/adapters/NextJSAdapter.js +7 -0
- package/dist/adapters/SSRAdapter.d.ts +8 -0
- package/dist/adapters/SSRAdapter.d.ts.map +1 -0
- package/dist/adapters/SSRAdapter.js +2 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/components/BannerVisor.d.ts +12 -0
- package/dist/components/BannerVisor.d.ts.map +1 -0
- package/dist/components/BannerVisor.js +99 -0
- package/dist/components/Style1/BannerStyle1.d.ts +18 -0
- package/dist/components/Style1/BannerStyle1.d.ts.map +1 -0
- package/dist/components/Style1/BannerStyle1.js +22 -0
- package/dist/components/Style1/substyles/BannerSubstyle1.d.ts +12 -0
- package/dist/components/Style1/substyles/BannerSubstyle1.d.ts.map +1 -0
- package/dist/components/Style1/substyles/BannerSubstyle1.js +44 -0
- package/dist/components/Style1/substyles/BannerSubstyle2.d.ts +12 -0
- package/dist/components/Style1/substyles/BannerSubstyle2.d.ts.map +1 -0
- package/dist/components/Style1/substyles/BannerSubstyle2.js +44 -0
- package/dist/components/Style1/substyles/BannerSubstyle3.d.ts +12 -0
- package/dist/components/Style1/substyles/BannerSubstyle3.d.ts.map +1 -0
- package/dist/components/Style1/substyles/BannerSubstyle3.js +53 -0
- package/dist/components/Style1/substyles/index.d.ts +7 -0
- package/dist/components/Style1/substyles/index.d.ts.map +1 -0
- package/dist/components/Style1/substyles/index.js +6 -0
- package/dist/components/Style2/BannerStyle2.d.ts +18 -0
- package/dist/components/Style2/BannerStyle2.d.ts.map +1 -0
- package/dist/components/Style2/BannerStyle2.js +27 -0
- package/dist/components/Style2/substyles/BannerSubstyle1.d.ts +12 -0
- package/dist/components/Style2/substyles/BannerSubstyle1.d.ts.map +1 -0
- package/dist/components/Style2/substyles/BannerSubstyle1.js +27 -0
- package/dist/components/Style2/substyles/BannerSubstyle2.d.ts +12 -0
- package/dist/components/Style2/substyles/BannerSubstyle2.d.ts.map +1 -0
- package/dist/components/Style2/substyles/BannerSubstyle2.js +27 -0
- package/dist/components/Style2/substyles/BannerSubstyle3.d.ts +12 -0
- package/dist/components/Style2/substyles/BannerSubstyle3.d.ts.map +1 -0
- package/dist/components/Style2/substyles/BannerSubstyle3.js +27 -0
- package/dist/components/Style2/substyles/index.d.ts +7 -0
- package/dist/components/Style2/substyles/index.d.ts.map +1 -0
- package/dist/components/Style2/substyles/index.js +6 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6 -0
- package/dist/constants/index.d.ts +5 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +4 -0
- package/dist/constants/styleConfigs.d.ts +11 -0
- package/dist/constants/styleConfigs.d.ts.map +1 -0
- package/dist/constants/styleConfigs.js +24 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/styles/index.d.ts +5 -0
- package/dist/styles/index.d.ts.map +1 -0
- package/dist/styles/index.js +4 -0
- package/dist/styles/shadowUtils.d.ts +21 -0
- package/dist/styles/shadowUtils.d.ts.map +1 -0
- package/dist/styles/shadowUtils.js +107 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +29 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# @zuljaman/banner-components
|
|
2
|
+
|
|
3
|
+
Platform-agnostic banner components for Next.js and AWS Lambda platforms. This shared package consolidates banner components from both the Next.js app and AWS Lambda implementations, providing a single source of truth with enhanced features and TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Platform Agnostic**: Works with Next.js, AWS Lambda, and other React environments
|
|
8
|
+
- ✅ **TypeScript Support**: Full TypeScript definitions with enhanced type safety
|
|
9
|
+
- ✅ **Adapter Pattern**: Clean separation of platform-specific image handling
|
|
10
|
+
- ✅ **Dynamic Font Sizing**: Automatic font size calculation based on content length
|
|
11
|
+
- ✅ **Advanced Shadow Effects**: Gradient-based shadow system with randomization
|
|
12
|
+
- ✅ **Multiple Styles**: Support for different banner styles and substyles
|
|
13
|
+
- ✅ **Responsive Design**: Automatic scaling based on container dimensions
|
|
14
|
+
- ✅ **Zero Dependencies**: Minimal external dependencies for maximum compatibility
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @zuljaman/banner-components
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Next.js Usage
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { BannerVisor } from '@zuljaman/banner-components';
|
|
28
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/NextJSAdapter';
|
|
29
|
+
|
|
30
|
+
function MyBannerComponent() {
|
|
31
|
+
return (
|
|
32
|
+
<BannerVisor
|
|
33
|
+
bannerStyle={1}
|
|
34
|
+
bannerSubstyle={1}
|
|
35
|
+
postType="POST"
|
|
36
|
+
copy1="Your primary text here"
|
|
37
|
+
copy2="Your secondary text here"
|
|
38
|
+
logoUrl="/path/to/logo.png"
|
|
39
|
+
backgroundImageUrl="/path/to/background.jpg"
|
|
40
|
+
ImageComponent={ImageComponent}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### AWS Lambda / SSR Usage
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { BannerVisor } from '@zuljaman/banner-components';
|
|
50
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/SSRAdapter';
|
|
51
|
+
|
|
52
|
+
function MyBannerComponent() {
|
|
53
|
+
return (
|
|
54
|
+
<BannerVisor
|
|
55
|
+
bannerStyle={1}
|
|
56
|
+
bannerSubstyle={1}
|
|
57
|
+
postType="POST"
|
|
58
|
+
copy1="Your primary text here"
|
|
59
|
+
copy2="Your secondary text here"
|
|
60
|
+
logoUrl="/path/to/logo.png"
|
|
61
|
+
backgroundImageUrl="/path/to/background.jpg"
|
|
62
|
+
ImageComponent={ImageComponent}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Components
|
|
69
|
+
|
|
70
|
+
### BannerVisor
|
|
71
|
+
|
|
72
|
+
The main banner component that handles routing between different styles and substyles.
|
|
73
|
+
|
|
74
|
+
**Props:**
|
|
75
|
+
- `bannerStyle: number` - Style identifier (1-2)
|
|
76
|
+
- `bannerSubstyle: number` - Substyle identifier (1-3)
|
|
77
|
+
- `postType: PostType` - "POST" or "STORY" for different dimensions
|
|
78
|
+
- `copy1?: string` - Primary text content
|
|
79
|
+
- `copy2?: string` - Secondary text content
|
|
80
|
+
- `logoUrl?: string` - URL for logo image
|
|
81
|
+
- `backgroundImageUrl?: string` - URL for background image
|
|
82
|
+
- `sizeMultiplier?: number` - Manual size scaling (optional)
|
|
83
|
+
- `ImageComponent: React.ComponentType<ImageProps>` - Platform-specific image component
|
|
84
|
+
|
|
85
|
+
### Style Components
|
|
86
|
+
|
|
87
|
+
#### BannerStyle1
|
|
88
|
+
Enhanced banner style with sophisticated layout and shadow effects.
|
|
89
|
+
|
|
90
|
+
#### BannerStyle2
|
|
91
|
+
Alternative banner style optimized for different content types.
|
|
92
|
+
|
|
93
|
+
### Substyles
|
|
94
|
+
|
|
95
|
+
Each style includes 3 substyles (BannerSubstyle1, BannerSubstyle2, BannerSubstyle3) with different layouts:
|
|
96
|
+
- **Substyle 1**: Logo top-left, text bottom
|
|
97
|
+
- **Substyle 2**: Logo top-left with side text, centered bottom text
|
|
98
|
+
- **Substyle 3**: Logo and text side-by-side, bottom text
|
|
99
|
+
|
|
100
|
+
## Platform Adapters
|
|
101
|
+
|
|
102
|
+
### NextJSAdapter
|
|
103
|
+
Uses Next.js optimized Image component with automatic optimization.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/NextJSAdapter';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### SSRAdapter
|
|
110
|
+
Uses standard HTML img tags for server-side rendering environments.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/SSRAdapter';
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Utilities
|
|
117
|
+
|
|
118
|
+
### Font Size Calculation
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { calculateStyleFontSizes } from '@zuljaman/banner-components';
|
|
122
|
+
|
|
123
|
+
const fontSizes = calculateStyleFontSizes("Primary text", "Secondary text", {
|
|
124
|
+
baseSizeRem1: 4.8,
|
|
125
|
+
baseSizeRem2: 4.8,
|
|
126
|
+
maxLengthThreshold: 40,
|
|
127
|
+
reductionFactor: 0.15
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Shadow Effects
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { createAbstractShadowStyle } from '@zuljaman/banner-components/styles';
|
|
135
|
+
|
|
136
|
+
const shadowStyle = createAbstractShadowStyle({
|
|
137
|
+
direction: "bottom",
|
|
138
|
+
size: "70%",
|
|
139
|
+
intensity: 0.8
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## TypeScript Support
|
|
144
|
+
|
|
145
|
+
Full TypeScript definitions are included:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import type {
|
|
149
|
+
BannerVisorProps,
|
|
150
|
+
BannerSubstyleProps,
|
|
151
|
+
PostType,
|
|
152
|
+
ImageProps,
|
|
153
|
+
StyleFontConfig
|
|
154
|
+
} from '@zuljaman/banner-components';
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Constants
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import {
|
|
161
|
+
DEFAULT_BANNER_WIDTH,
|
|
162
|
+
DEFAULT_BANNER_HEIGHT,
|
|
163
|
+
DEFAULT_STORY_WIDTH,
|
|
164
|
+
DEFAULT_STORY_HEIGHT,
|
|
165
|
+
STYLE_FONT_CONFIGS
|
|
166
|
+
} from '@zuljaman/banner-components/constants';
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Migration Guide
|
|
170
|
+
|
|
171
|
+
### From Next.js App
|
|
172
|
+
|
|
173
|
+
Replace existing imports:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Before
|
|
177
|
+
import { BannerVisor } from '@/components/BannerStyles';
|
|
178
|
+
|
|
179
|
+
// After
|
|
180
|
+
import { BannerVisor } from '@zuljaman/banner-components';
|
|
181
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/NextJSAdapter';
|
|
182
|
+
|
|
183
|
+
// Pass ImageComponent as prop
|
|
184
|
+
<BannerVisor {...props} ImageComponent={ImageComponent} />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### From AWS Lambda
|
|
188
|
+
|
|
189
|
+
Replace existing imports:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Before
|
|
193
|
+
import { BannerVisor } from '../components/BannerStyles/BannerVisor';
|
|
194
|
+
|
|
195
|
+
// After
|
|
196
|
+
import { BannerVisor } from '@zuljaman/banner-components';
|
|
197
|
+
import { ImageComponent } from '@zuljaman/banner-components/adapters/SSRAdapter';
|
|
198
|
+
|
|
199
|
+
// Pass ImageComponent as prop
|
|
200
|
+
<BannerVisor {...props} ImageComponent={ImageComponent} />
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Development
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Install dependencies
|
|
207
|
+
npm install
|
|
208
|
+
|
|
209
|
+
# Build the package
|
|
210
|
+
npm run build
|
|
211
|
+
|
|
212
|
+
# Watch for changes during development
|
|
213
|
+
npm run dev
|
|
214
|
+
|
|
215
|
+
# Clean build artifacts
|
|
216
|
+
npm run clean
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
|
222
|
+
|
|
223
|
+
## Contributing
|
|
224
|
+
|
|
225
|
+
This package consolidates banner components from multiple Zuljaman projects. When contributing:
|
|
226
|
+
|
|
227
|
+
1. Ensure changes maintain backward compatibility
|
|
228
|
+
2. Update TypeScript definitions
|
|
229
|
+
3. Test with both Next.js and AWS Lambda adapters
|
|
230
|
+
4. Follow existing code patterns and styling
|
|
231
|
+
|
|
232
|
+
## Architecture
|
|
233
|
+
|
|
234
|
+
The package uses an adapter pattern to handle platform-specific image components while maintaining shared logic for:
|
|
235
|
+
|
|
236
|
+
- Font size calculations
|
|
237
|
+
- Shadow effect generation
|
|
238
|
+
- Layout and styling
|
|
239
|
+
- Type definitions
|
|
240
|
+
- Constants and configurations
|
|
241
|
+
|
|
242
|
+
This approach ensures 100% code reuse while supporting platform-specific optimizations.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js Image component adapter factory
|
|
3
|
+
* Provides optimized image rendering for Next.js applications
|
|
4
|
+
*
|
|
5
|
+
* Usage in Next.js applications:
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import NextImage from 'next/image';
|
|
8
|
+
* import { createNextJSAdapter } from '@zuljaman/banner-components/adapters/NextJSAdapter';
|
|
9
|
+
*
|
|
10
|
+
* const ImageComponent = createNextJSAdapter(NextImage);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import type { ImageProps } from '../types';
|
|
15
|
+
export declare const createNextJSAdapter: (NextImage: React.ComponentType<any>) => React.FC<ImageProps>;
|
|
16
|
+
export declare const ImageComponent: React.FC<ImageProps>;
|
|
17
|
+
//# sourceMappingURL=NextJSAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NextJSAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/NextJSAdapter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,mBAAmB,GAAI,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,yBAMtE,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAE/C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const createNextJSAdapter = (NextImage) => {
|
|
3
|
+
const ImageComponent = ({ src, alt, ...props }) => (_jsx(NextImage, { src: src, alt: alt, ...props }));
|
|
4
|
+
return ImageComponent;
|
|
5
|
+
};
|
|
6
|
+
// For backward compatibility, export a basic component that will work in build
|
|
7
|
+
export const ImageComponent = ({ src, alt, ...props }) => (_jsx("img", { src: src, alt: alt, ...props }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR (Server-Side Rendering) Image component adapter
|
|
3
|
+
* Provides standard img tag for AWS Lambda and non-Next.js environments
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { ImageProps } from '../types';
|
|
7
|
+
export declare const ImageComponent: React.FC<ImageProps>;
|
|
8
|
+
//# sourceMappingURL=SSRAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SSRAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/SSRAdapter.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAE/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,IAAI,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic BannerVisor component
|
|
3
|
+
* Extracted from Next.js app and adapted for cross-platform use
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { BannerVisorProps, ImageProps } from "../types";
|
|
7
|
+
interface BannerVisorComponentProps extends BannerVisorProps {
|
|
8
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
9
|
+
}
|
|
10
|
+
export declare const BannerVisor: React.FC<BannerVisorComponentProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=BannerVisor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerVisor.d.ts","sourceRoot":"","sources":["../../src/components/BannerVisor.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAY7D,UAAU,yBAA0B,SAAQ,gBAAgB;IAC1D,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAUD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAuJ3D,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic BannerVisor component
|
|
3
|
+
* Extracted from Next.js app and adapted for cross-platform use
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useState, useRef, useEffect } from "react";
|
|
8
|
+
import clsx from "clsx";
|
|
9
|
+
import { DEFAULT_BANNER_WIDTH, DEFAULT_BANNER_HEIGHT, DEFAULT_STORY_WIDTH, DEFAULT_STORY_HEIGHT, } from "../constants";
|
|
10
|
+
// Import style components (will be created next)
|
|
11
|
+
import { BannerStyle1 } from "./Style1/BannerStyle1";
|
|
12
|
+
import { BannerStyle2 } from "./Style2/BannerStyle2";
|
|
13
|
+
const NoImageComponent = () => {
|
|
14
|
+
return (_jsx("div", { className: "w-full grow flex items-center justify-center text-neutral-500", children: _jsx("p", { children: "No image selected" }) }));
|
|
15
|
+
};
|
|
16
|
+
export const BannerVisor = ({ bannerStyle = 1, // Default to style 1 if undefined
|
|
17
|
+
backgroundImageUrl, copy1, copy2, bannerSubstyle, logoUrl, postType, sizeMultiplier: externalSizeMultiplier, ImageComponent, }) => {
|
|
18
|
+
const [internalSizeMultiplier, setInternalSizeMultiplier] = useState(1);
|
|
19
|
+
const containerRef = useRef(null);
|
|
20
|
+
// Use external size multiplier if provided, otherwise use internal
|
|
21
|
+
const sizeMultiplier = externalSizeMultiplier ?? internalSizeMultiplier;
|
|
22
|
+
const bannerContentProps = {
|
|
23
|
+
copy1,
|
|
24
|
+
copy2,
|
|
25
|
+
bannerSubstyle,
|
|
26
|
+
logoUrl,
|
|
27
|
+
backgroundImageUrl,
|
|
28
|
+
sizeMultiplier,
|
|
29
|
+
ImageComponent,
|
|
30
|
+
};
|
|
31
|
+
const hasBannerContent = copy1 || copy2 || logoUrl;
|
|
32
|
+
const renderBannerStyle = () => {
|
|
33
|
+
if (!hasBannerContent)
|
|
34
|
+
return null;
|
|
35
|
+
// Determine the style ID, defaulting to 1 if null or invalid
|
|
36
|
+
const effectiveBannerStyle = bannerStyle === null ? 1 : bannerStyle;
|
|
37
|
+
switch (effectiveBannerStyle) {
|
|
38
|
+
case 1:
|
|
39
|
+
return _jsx(BannerStyle1, { ...bannerContentProps });
|
|
40
|
+
case 2:
|
|
41
|
+
return _jsx(BannerStyle2, { ...bannerContentProps });
|
|
42
|
+
default:
|
|
43
|
+
// Default to BannerStyle1
|
|
44
|
+
return _jsx(BannerStyle1, { ...bannerContentProps });
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
// Only use internal size calculation if no external multiplier is provided
|
|
49
|
+
if (externalSizeMultiplier !== undefined)
|
|
50
|
+
return;
|
|
51
|
+
const container = containerRef.current;
|
|
52
|
+
if (!container)
|
|
53
|
+
return;
|
|
54
|
+
// Determine target dimensions based on postType
|
|
55
|
+
const isStory = postType === "STORY";
|
|
56
|
+
const targetWidth = isStory ? DEFAULT_STORY_WIDTH : DEFAULT_BANNER_WIDTH;
|
|
57
|
+
const targetHeight = isStory ? DEFAULT_STORY_HEIGHT : DEFAULT_BANNER_HEIGHT;
|
|
58
|
+
const updateSize = () => {
|
|
59
|
+
const actualWidth = container.clientWidth;
|
|
60
|
+
const actualHeight = container.clientHeight;
|
|
61
|
+
if (actualWidth > 0 && actualHeight > 0) {
|
|
62
|
+
const widthRatio = actualWidth / targetWidth;
|
|
63
|
+
const heightRatio = actualHeight / targetHeight;
|
|
64
|
+
const newSizeMultiplier = Math.min(widthRatio, heightRatio);
|
|
65
|
+
// Update state only if the value has significantly changed
|
|
66
|
+
setInternalSizeMultiplier((prev) => Math.abs(prev - newSizeMultiplier) > 1e-6 ? newSizeMultiplier : prev);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
setInternalSizeMultiplier(1); // Reset if dimensions are zero
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// Update size initially
|
|
73
|
+
updateSize();
|
|
74
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
75
|
+
// Recalculate size on resize
|
|
76
|
+
updateSize();
|
|
77
|
+
});
|
|
78
|
+
resizeObserver.observe(container);
|
|
79
|
+
return () => {
|
|
80
|
+
if (container) {
|
|
81
|
+
resizeObserver.unobserve(container);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// Add postType to dependency array to recalculate when it changes
|
|
85
|
+
}, [postType, externalSizeMultiplier]);
|
|
86
|
+
return (_jsx("div", { className: "relative w-full h-full bg-black rounded-sm flex items-center justify-center overflow-hidden", ref: containerRef, children: hasBannerContent || backgroundImageUrl ? (_jsx("div", { className: clsx("relative flex items-center justify-center h-full"), children: _jsxs("div", { className: "relative", style: {
|
|
87
|
+
transform: `scale(${sizeMultiplier})`,
|
|
88
|
+
width: `${(postType === "STORY"
|
|
89
|
+
? DEFAULT_STORY_WIDTH
|
|
90
|
+
: DEFAULT_BANNER_WIDTH) / 16}rem`,
|
|
91
|
+
height: `${(postType === "STORY"
|
|
92
|
+
? DEFAULT_STORY_HEIGHT
|
|
93
|
+
: DEFAULT_BANNER_HEIGHT) / 16}rem`,
|
|
94
|
+
}, children: [!hasBannerContent && backgroundImageUrl && (_jsx(ImageComponent, { src: backgroundImageUrl, alt: "Background", width: postType === "STORY"
|
|
95
|
+
? DEFAULT_STORY_WIDTH
|
|
96
|
+
: DEFAULT_BANNER_WIDTH, height: postType === "STORY"
|
|
97
|
+
? DEFAULT_STORY_HEIGHT
|
|
98
|
+
: DEFAULT_BANNER_HEIGHT, className: "object-cover w-full h-full absolute inset-0", style: { objectFit: "cover" } })), hasBannerContent && (_jsx("div", { className: "flex items-center justify-center overflow-hidden w-full h-full", children: renderBannerStyle() }))] }) })) : (_jsx(NoImageComponent, {})) }));
|
|
99
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerStyle1 component - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { ImageProps } from "../../types";
|
|
7
|
+
interface BannerStyle1Props {
|
|
8
|
+
copy1?: string;
|
|
9
|
+
copy2?: string;
|
|
10
|
+
bannerSubstyle?: number;
|
|
11
|
+
logoUrl?: string;
|
|
12
|
+
sizeMultiplier?: number;
|
|
13
|
+
backgroundImageUrl?: string;
|
|
14
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
15
|
+
}
|
|
16
|
+
export declare const BannerStyle1: React.FC<BannerStyle1Props>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=BannerStyle1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerStyle1.d.ts","sourceRoot":"","sources":["../../../src/components/Style1/BannerStyle1.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAiCpD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BannerSubstyle1, BannerSubstyle2, BannerSubstyle3 } from "./substyles";
|
|
3
|
+
import { calculateStyleFontSizes } from "../../utils";
|
|
4
|
+
export const BannerStyle1 = ({ copy1, copy2, bannerSubstyle = 1, logoUrl, backgroundImageUrl, ImageComponent, }) => {
|
|
5
|
+
// Use the utility function to calculate font sizes with Style1 parameters
|
|
6
|
+
const fontSizes = calculateStyleFontSizes(copy1, copy2, {
|
|
7
|
+
baseSizeRem1: 4.8,
|
|
8
|
+
baseSizeRem2: 4.8,
|
|
9
|
+
maxLengthThreshold: 40,
|
|
10
|
+
reductionFactor: 0.15
|
|
11
|
+
});
|
|
12
|
+
const substyleProps = {
|
|
13
|
+
copy1,
|
|
14
|
+
fontSize_01: fontSizes.fontSize_01,
|
|
15
|
+
copy2,
|
|
16
|
+
fontSize_02: fontSizes.fontSize_02,
|
|
17
|
+
logoUrl,
|
|
18
|
+
backgroundImageUrl,
|
|
19
|
+
ImageComponent,
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs("div", { className: "w-full h-full text-white", children: [bannerSubstyle === 1 && _jsx(BannerSubstyle1, { ...substyleProps }), bannerSubstyle === 2 && _jsx(BannerSubstyle2, { ...substyleProps }), bannerSubstyle === 3 && _jsx(BannerSubstyle3, { ...substyleProps })] }));
|
|
22
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerSubstyle1 for Style1 - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { BannerSubstyleProps, ImageProps } from "../../../types";
|
|
7
|
+
interface BannerSubstyle1Props extends BannerSubstyleProps {
|
|
8
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
9
|
+
}
|
|
10
|
+
export declare const BannerSubstyle1: React.FC<BannerSubstyle1Props>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=BannerSubstyle1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerSubstyle1.d.ts","sourceRoot":"","sources":["../../../../src/components/Style1/substyles/BannerSubstyle1.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtE,UAAU,oBAAqB,SAAQ,mBAAmB;IACxD,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6G1D,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerSubstyle1 for Style1 - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useMemo } from "react";
|
|
8
|
+
import { createAbstractShadowStyle } from "../../../styles/shadowUtils";
|
|
9
|
+
export const BannerSubstyle1 = ({ copy1, copy2, fontSize_01, fontSize_02, logoUrl, backgroundImageUrl, ImageComponent, }) => {
|
|
10
|
+
const { shadowStyle, logoShadowStyle } = useMemo(() => {
|
|
11
|
+
// --- Randomized Shadow Parameters ---
|
|
12
|
+
// Text Shadow (Bottom)
|
|
13
|
+
const baseTextSize = 70;
|
|
14
|
+
const textVariationSize = 20; // +/- 10%
|
|
15
|
+
const randomTextSize = Math.floor(baseTextSize + (Math.random() - 0.5) * textVariationSize);
|
|
16
|
+
const baseTextIntensity = 0.85;
|
|
17
|
+
const textVariationIntensity = 0.2; // +/- 0.1
|
|
18
|
+
const randomTextIntensity = baseTextIntensity + (Math.random() - 0.5) * textVariationIntensity;
|
|
19
|
+
// Logo Shadow (Top-Left)
|
|
20
|
+
const baseLogoSize = 150;
|
|
21
|
+
const logoVariationSize = 20; // +/- 10%
|
|
22
|
+
const randomLogoSize = Math.floor(baseLogoSize + (Math.random() - 0.5) * logoVariationSize);
|
|
23
|
+
const baseLogoIntensity = 0.75;
|
|
24
|
+
const logoVariationIntensity = 0.2; // +/- 0.1
|
|
25
|
+
const randomLogoIntensity = baseLogoIntensity + (Math.random() - 0.5) * logoVariationIntensity;
|
|
26
|
+
// --- Generate Styles with Random Values ---
|
|
27
|
+
const shadowStyle = createAbstractShadowStyle({
|
|
28
|
+
// direction: "bottom", // Default
|
|
29
|
+
size: `${randomTextSize}%`,
|
|
30
|
+
intensity: randomTextIntensity,
|
|
31
|
+
});
|
|
32
|
+
const logoShadowStyle = createAbstractShadowStyle({
|
|
33
|
+
direction: "top-left",
|
|
34
|
+
size: `${randomLogoSize}%`,
|
|
35
|
+
intensity: randomLogoIntensity,
|
|
36
|
+
});
|
|
37
|
+
return { shadowStyle, logoShadowStyle };
|
|
38
|
+
}, []); // Empty dependency array ensures this runs only once on mount
|
|
39
|
+
return (_jsxs("div", { className: "inset-0 flex flex-col items-start justify-between h-full text-center pb-20 relative isolate overflow-hidden gap-4", children: [backgroundImageUrl && (_jsx(ImageComponent, { src: backgroundImageUrl, alt: "Background", width: 1080, height: 1350, className: "object-cover absolute inset-0 w-full h-full -z-10", style: { objectFit: "cover" } })), _jsx("div", { style: shadowStyle, className: "relative z-10", "aria-hidden": "true" }), _jsx("div", { style: logoShadowStyle, className: "relative z-10", "aria-hidden": "true" }), _jsx("div", { className: "relative px-20 pt-20 z-20", children: _jsx("div", { className: "relative w-64 h-64", children: logoUrl && (_jsx(ImageComponent, { src: logoUrl, alt: "Logo", width: 256, height: 256, className: "object-contain absolute inset-0 w-full h-full", style: { objectFit: "contain" } })) }) }), _jsxs("div", { className: "w-full px-20 relative z-20", children: [_jsx("p", { style: {
|
|
40
|
+
fontSize: fontSize_01,
|
|
41
|
+
}, className: "leading-tight whitespace-pre-wrap", children: copy1 }), _jsx("p", { style: {
|
|
42
|
+
fontSize: fontSize_02,
|
|
43
|
+
}, className: "font-bold leading-tight whitespace-pre-wrap", children: copy2 })] })] }));
|
|
44
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerSubstyle2 for Style1 - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { BannerSubstyleProps, ImageProps } from "../../../types";
|
|
7
|
+
interface BannerSubstyle2Props extends BannerSubstyleProps {
|
|
8
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
9
|
+
}
|
|
10
|
+
export declare const BannerSubstyle2: React.FC<BannerSubstyle2Props>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=BannerSubstyle2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerSubstyle2.d.ts","sourceRoot":"","sources":["../../../../src/components/Style1/substyles/BannerSubstyle2.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtE,UAAU,oBAAqB,SAAQ,mBAAmB;IACxD,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA8G1D,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerSubstyle2 for Style1 - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useMemo } from "react";
|
|
8
|
+
import { createAbstractShadowStyle } from "../../../styles/shadowUtils";
|
|
9
|
+
export const BannerSubstyle2 = ({ copy1, copy2, fontSize_01, fontSize_02, logoUrl, backgroundImageUrl, ImageComponent, }) => {
|
|
10
|
+
const { shadowStyle, logoShadowStyle } = useMemo(() => {
|
|
11
|
+
// --- Randomized Shadow Parameters ---
|
|
12
|
+
// Text Shadow (Bottom)
|
|
13
|
+
const baseTextSize = 70;
|
|
14
|
+
const textVariationSize = 20; // +/- 10%
|
|
15
|
+
const randomTextSize = Math.floor(baseTextSize + (Math.random() - 0.5) * textVariationSize);
|
|
16
|
+
const baseTextIntensity = 0.85;
|
|
17
|
+
const textVariationIntensity = 0.2; // +/- 0.1
|
|
18
|
+
const randomTextIntensity = baseTextIntensity + (Math.random() - 0.5) * textVariationIntensity;
|
|
19
|
+
// Logo Shadow (Top-Left)
|
|
20
|
+
const baseLogoSize = 250;
|
|
21
|
+
const logoVariationSize = 20; // +/- 10%
|
|
22
|
+
const randomLogoSize = Math.floor(baseLogoSize + (Math.random() - 0.5) * logoVariationSize);
|
|
23
|
+
const baseLogoIntensity = 0.65;
|
|
24
|
+
const logoVariationIntensity = 0.2; // +/- 0.1
|
|
25
|
+
const randomLogoIntensity = baseLogoIntensity + (Math.random() - 0.5) * logoVariationIntensity;
|
|
26
|
+
// --- Generate Styles with Random Values ---
|
|
27
|
+
const shadowStyle = createAbstractShadowStyle({
|
|
28
|
+
// direction: "bottom", // Default
|
|
29
|
+
size: `${randomTextSize}%`,
|
|
30
|
+
intensity: randomTextIntensity,
|
|
31
|
+
});
|
|
32
|
+
const logoShadowStyle = createAbstractShadowStyle({
|
|
33
|
+
direction: "top-left",
|
|
34
|
+
size: `${randomLogoSize}%`,
|
|
35
|
+
intensity: randomLogoIntensity,
|
|
36
|
+
});
|
|
37
|
+
return { shadowStyle, logoShadowStyle };
|
|
38
|
+
}, []); // Empty dependency array ensures this runs only once on mount
|
|
39
|
+
return (_jsxs("div", { className: "inset-0 flex flex-col items-start justify-between h-full pb-20 relative isolate overflow-hidden gap-4", children: [backgroundImageUrl && (_jsx(ImageComponent, { src: backgroundImageUrl, alt: "Background", width: 1080, height: 1350, className: "object-cover absolute inset-0 w-full h-full -z-10 opacity-75", style: { objectFit: 'cover' } })), _jsx("div", { style: shadowStyle, className: "relative z-10", "aria-hidden": "true" }), _jsxs("div", { className: "relative px-20 pt-20 z-20", children: [_jsx("div", { style: logoShadowStyle, className: "relative z-10", "aria-hidden": "true" }), _jsx("div", { className: "relative w-64 h-64", children: logoUrl && (_jsx(ImageComponent, { src: logoUrl, alt: "Logo", width: 256, height: 256, className: "object-contain absolute inset-0 w-full h-full", style: { objectFit: 'contain' } })) }), _jsx("p", { style: {
|
|
40
|
+
fontSize: `calc(${fontSize_01} * 0.8)`,
|
|
41
|
+
}, className: "w-1/2 mt-8 leading-tight whitespace-pre-wrap", children: copy1 })] }), _jsx("div", { className: "w-full px-20 relative z-20", children: _jsx("p", { style: {
|
|
42
|
+
fontSize: fontSize_02,
|
|
43
|
+
}, className: "font-bold text-center leading-tight whitespace-pre-wrap", children: copy2 }) })] }));
|
|
44
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BannerSubstyle3 for Style1 - Platform-agnostic version
|
|
3
|
+
* Extracted from Next.js app implementation
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { BannerSubstyleProps, ImageProps } from "../../../types";
|
|
7
|
+
interface BannerSubstyle3Props extends BannerSubstyleProps {
|
|
8
|
+
ImageComponent: React.ComponentType<ImageProps>;
|
|
9
|
+
}
|
|
10
|
+
export declare const BannerSubstyle3: React.FC<BannerSubstyle3Props>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=BannerSubstyle3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerSubstyle3.d.ts","sourceRoot":"","sources":["../../../../src/components/Style1/substyles/BannerSubstyle3.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtE,UAAU,oBAAqB,SAAQ,mBAAmB;IACxD,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAQD,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6G1D,CAAC"}
|