@mccustomapps/helaui 0.1.10 → 0.1.13
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 +44 -4
- package/dist/destination-card.css +134 -0
- package/dist/index.cjs +168 -5
- package/dist/index.d.cts +36 -1
- package/dist/index.d.ts +36 -1
- package/dist/index.js +166 -5
- package/dist/rain-background.css +8 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- [TextField](#textfield)
|
|
17
17
|
- [Calendar](#calendar)
|
|
18
18
|
- [SunMandala](#sunmandala)
|
|
19
|
+
- [DestinationCard](#destinationcard)
|
|
19
20
|
- [RainBackground](#rainbackground)
|
|
20
21
|
- [Theming](#theming)
|
|
21
22
|
- [i18n / Localisation](#i18n--localisation)
|
|
@@ -40,12 +41,13 @@ npm install @mccustomapps/helaui
|
|
|
40
41
|
import '@mccustomapps/helaui/textfield.css';
|
|
41
42
|
import '@mccustomapps/helaui/calendar.css';
|
|
42
43
|
import '@mccustomapps/helaui/sun-mandala.css';
|
|
44
|
+
import '@mccustomapps/helaui/destination-card.css';
|
|
43
45
|
import '@mccustomapps/helaui/rain-background.css';
|
|
44
46
|
import '@mccustomapps/helaui/sinhala.css'; // Sinhala font face
|
|
45
47
|
import '@mccustomapps/helaui/theme.css'; // CSS custom-property tokens
|
|
46
48
|
|
|
47
49
|
// Import components
|
|
48
|
-
import { TextField, Calendar, SunMandala, RainBackground } from '@mccustomapps/helaui';
|
|
50
|
+
import { TextField, Calendar, SunMandala, DestinationCard, RainBackground } from '@mccustomapps/helaui';
|
|
49
51
|
|
|
50
52
|
// Mount components
|
|
51
53
|
const field = new TextField({ variant: 'name' });
|
|
@@ -205,6 +207,42 @@ const mandala = new SunMandala({ src: '/my-mandala.png' });
|
|
|
205
207
|
|
|
206
208
|
---
|
|
207
209
|
|
|
210
|
+
### DestinationCard
|
|
211
|
+
|
|
212
|
+
A decorative parchment **card shell** — cream background, teal/gold frame, side Sinhala script, and a peacock/lotus footer. The inner area is empty so you can place your own content.
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
import { DestinationCard } from '@mccustomapps/helaui';
|
|
216
|
+
import '@mccustomapps/helaui/destination-card.css';
|
|
217
|
+
|
|
218
|
+
const card = new DestinationCard({
|
|
219
|
+
height: '280px',
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
document.getElementById('container').appendChild(card.element);
|
|
223
|
+
|
|
224
|
+
// Optional: put your own content in the empty inner area
|
|
225
|
+
card.body.appendChild(document.createElement('div'));
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Options — `DestinationCardOptions`**
|
|
229
|
+
|
|
230
|
+
| Option | Type | Default | Description |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `content` | `HTMLElement \| string` | — | Inner content |
|
|
233
|
+
| `height` | `string` | `'280px'` | Minimum height of the inner area |
|
|
234
|
+
| `backdrop` | `boolean` | `false` | Blurred photo stage behind the card |
|
|
235
|
+
| `backdropImage` | `string` | — | Image used for the blurred stage |
|
|
236
|
+
|
|
237
|
+
**Methods**
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
card.setContent(node) // replace inner content
|
|
241
|
+
card.destroy()
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
208
246
|
### RainBackground
|
|
209
247
|
|
|
210
248
|
An animated **tropical rain** background with falling food/leaf sprites. Built-in artwork is inlined in the JS bundle (no extra files to copy into `public/`).
|
|
@@ -216,7 +254,7 @@ import '@mccustomapps/helaui/rain-background.css';
|
|
|
216
254
|
const rain = new RainBackground();
|
|
217
255
|
```
|
|
218
256
|
|
|
219
|
-
**Next.js (App Router)** — use a Client Component. `RainBackground` already mounts itself on `document.body`; do not
|
|
257
|
+
**Next.js (App Router)** — use a Client Component. `RainBackground` already mounts itself on `document.body`; do **not** call `insertBefore` / `appendChild` on `rain.element` a second time.
|
|
220
258
|
|
|
221
259
|
```tsx
|
|
222
260
|
'use client';
|
|
@@ -227,7 +265,7 @@ import '@mccustomapps/helaui/rain-background.css';
|
|
|
227
265
|
|
|
228
266
|
export function HelaRain() {
|
|
229
267
|
useEffect(() => {
|
|
230
|
-
const rain = new RainBackground();
|
|
268
|
+
const rain = new RainBackground({ zIndex: 0 });
|
|
231
269
|
return () => rain.destroy();
|
|
232
270
|
}, []);
|
|
233
271
|
|
|
@@ -241,7 +279,7 @@ export function HelaRain() {
|
|
|
241
279
|
|---|---|---|---|
|
|
242
280
|
| `images` | `string[]` | built-in artwork | Image URLs |
|
|
243
281
|
| `density` | `number` | `28` | Number of particles |
|
|
244
|
-
| `minSize` / `maxSize` | `number` | `28` | Particle width in pixels |
|
|
282
|
+
| `minSize` / `maxSize` | `number` | `28` / `72` | Particle width in pixels |
|
|
245
283
|
| `minDuration` / `maxDuration` | `number` | `8` / `18` | Fall duration in seconds |
|
|
246
284
|
| `target` | `HTMLElement` | `document.body` | Mount container |
|
|
247
285
|
| `zIndex` | `number` | `0` | Stacking order |
|
|
@@ -339,6 +377,7 @@ import '@mccustomapps/helaui/sinhala.css'; // Sinhala font face
|
|
|
339
377
|
import '@mccustomapps/helaui/textfield.css'; // TextField styles
|
|
340
378
|
import '@mccustomapps/helaui/calendar.css'; // Calendar styles
|
|
341
379
|
import '@mccustomapps/helaui/sun-mandala.css'; // SunMandala styles
|
|
380
|
+
import '@mccustomapps/helaui/destination-card.css'; // DestinationCard styles
|
|
342
381
|
import '@mccustomapps/helaui/rain-background.css'; // RainBackground styles
|
|
343
382
|
```
|
|
344
383
|
|
|
@@ -353,6 +392,7 @@ import type {
|
|
|
353
392
|
TextFieldOptions,
|
|
354
393
|
CalendarOptions,
|
|
355
394
|
SunMandalaOptions,
|
|
395
|
+
DestinationCardOptions,
|
|
356
396
|
RainBackgroundOptions,
|
|
357
397
|
HelaTheme,
|
|
358
398
|
HelaThemeKey,
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/* HelaUI Destination Card — decorative parchment shell */
|
|
2
|
+
|
|
3
|
+
.helaui-destination-card-stage {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
align-items: stretch;
|
|
8
|
+
padding: 28px 20px;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
border-radius: 32px;
|
|
11
|
+
isolation: isolate;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.helaui-destination-card-stage__blur {
|
|
15
|
+
position: absolute;
|
|
16
|
+
inset: -24px;
|
|
17
|
+
background-size: cover;
|
|
18
|
+
background-position: center;
|
|
19
|
+
filter: blur(22px) saturate(1.1);
|
|
20
|
+
transform: scale(1.08);
|
|
21
|
+
z-index: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.helaui-destination-card-stage__blur::after {
|
|
25
|
+
content: '';
|
|
26
|
+
position: absolute;
|
|
27
|
+
inset: 0;
|
|
28
|
+
background: rgba(20, 28, 24, 0.28);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.helaui-destination-card {
|
|
32
|
+
--helaui-card-cream: #f9f3e6;
|
|
33
|
+
--helaui-card-ink: #2d1e17;
|
|
34
|
+
--helaui-card-teal: #1a4d4e;
|
|
35
|
+
--helaui-card-orange: var(--helaui-accent, #c86837);
|
|
36
|
+
|
|
37
|
+
position: relative;
|
|
38
|
+
z-index: 1;
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
width: min(100%, 380px);
|
|
42
|
+
margin: 0 auto;
|
|
43
|
+
padding: 14px 16px 0;
|
|
44
|
+
box-sizing: border-box;
|
|
45
|
+
background:
|
|
46
|
+
radial-gradient(circle at 12% 18%, rgba(26, 77, 78, 0.06), transparent 28%),
|
|
47
|
+
radial-gradient(circle at 88% 72%, rgba(200, 104, 55, 0.08), transparent 32%),
|
|
48
|
+
var(--helaui-card-cream);
|
|
49
|
+
color: var(--helaui-card-ink);
|
|
50
|
+
border: 1.5px solid var(--helaui-card-teal);
|
|
51
|
+
border-radius: 30px;
|
|
52
|
+
box-shadow:
|
|
53
|
+
inset 0 0 0 5px var(--helaui-card-cream),
|
|
54
|
+
inset 0 0 0 6.5px #c4a574,
|
|
55
|
+
0 18px 40px rgba(26, 32, 24, 0.28);
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
font-family: Georgia, 'Times New Roman', serif;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.helaui-destination-card__watermark {
|
|
61
|
+
pointer-events: none;
|
|
62
|
+
position: absolute;
|
|
63
|
+
inset: 0;
|
|
64
|
+
opacity: 0.09;
|
|
65
|
+
background-image:
|
|
66
|
+
radial-gradient(circle at 50% 50%, transparent 42%, rgba(26, 77, 78, 0.55) 43%, transparent 46%),
|
|
67
|
+
repeating-radial-gradient(circle at 50% 50%, rgba(26, 77, 78, 0.35) 0 1px, transparent 1px 18px);
|
|
68
|
+
background-size: 220px 220px, 220px 220px;
|
|
69
|
+
background-position: 80% 30%, 10% 80%;
|
|
70
|
+
mix-blend-mode: multiply;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.helaui-destination-card__script {
|
|
74
|
+
pointer-events: none;
|
|
75
|
+
position: absolute;
|
|
76
|
+
top: 22%;
|
|
77
|
+
right: 8px;
|
|
78
|
+
writing-mode: vertical-rl;
|
|
79
|
+
font-size: 0.72rem;
|
|
80
|
+
letter-spacing: 0.28em;
|
|
81
|
+
color: #c4a574;
|
|
82
|
+
opacity: 0.55;
|
|
83
|
+
z-index: 2;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.helaui-destination-card__body {
|
|
87
|
+
position: relative;
|
|
88
|
+
z-index: 1;
|
|
89
|
+
flex: 1;
|
|
90
|
+
min-height: 280px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.helaui-destination-card__footer {
|
|
94
|
+
position: relative;
|
|
95
|
+
height: 92px;
|
|
96
|
+
margin: 4px -16px 0;
|
|
97
|
+
background: linear-gradient(90deg, #c86837 0%, #b8432f 55%, #c86837 100%);
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.helaui-destination-card__footer::before {
|
|
102
|
+
content: '';
|
|
103
|
+
position: absolute;
|
|
104
|
+
inset: 0;
|
|
105
|
+
opacity: 0.22;
|
|
106
|
+
background-image:
|
|
107
|
+
radial-gradient(circle at 20% 40%, #f9f3e6 0 10%, transparent 11%),
|
|
108
|
+
radial-gradient(circle at 70% 70%, #f9f3e6 0 8%, transparent 9%),
|
|
109
|
+
radial-gradient(circle at 50% 20%, transparent 40%, rgba(249, 243, 230, 0.5) 41%, transparent 44%);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.helaui-destination-card__peacocks,
|
|
113
|
+
.helaui-destination-card__lotus {
|
|
114
|
+
position: absolute;
|
|
115
|
+
bottom: -4px;
|
|
116
|
+
z-index: 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.helaui-destination-card__peacocks {
|
|
120
|
+
left: 6px;
|
|
121
|
+
width: 58%;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.helaui-destination-card__peacocks svg,
|
|
125
|
+
.helaui-destination-card__lotus svg {
|
|
126
|
+
display: block;
|
|
127
|
+
width: 100%;
|
|
128
|
+
height: auto;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.helaui-destination-card__lotus {
|
|
132
|
+
right: 4px;
|
|
133
|
+
width: 34%;
|
|
134
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
BUILTIN_SUN_MANDALA_IMAGE: () => BUILTIN_SUN_MANDALA_IMAGE,
|
|
25
25
|
Calendar: () => Calendar,
|
|
26
26
|
DEFAULT_RAIN_IMAGES: () => DEFAULT_RAIN_IMAGES,
|
|
27
|
+
DestinationCard: () => DestinationCard,
|
|
27
28
|
RainBackground: () => RainBackground,
|
|
28
29
|
SINHALA_FONT_CLASS: () => SINHALA_FONT_CLASS,
|
|
29
30
|
SINHALA_FONT_FAMILY: () => SINHALA_FONT_FAMILY,
|
|
@@ -40,6 +41,7 @@ __export(index_exports, {
|
|
|
40
41
|
formatSinhalaNumeral: () => formatSinhalaNumeral,
|
|
41
42
|
getCalendarTranslation: () => getCalendarTranslation,
|
|
42
43
|
getDefaultRainImageUrls: () => getDefaultRainImageUrls,
|
|
44
|
+
getDestinationCardTranslation: () => getDestinationCardTranslation,
|
|
43
45
|
getLocale: () => getLocale,
|
|
44
46
|
getTextFieldTranslation: () => getTextFieldTranslation,
|
|
45
47
|
resetTheme: () => resetTheme,
|
|
@@ -119,6 +121,14 @@ var defaultTranslations = {
|
|
|
119
121
|
clear: "Clear",
|
|
120
122
|
selectMonth: "Select Month",
|
|
121
123
|
poyaDay: "Poya Day"
|
|
124
|
+
},
|
|
125
|
+
destinationCard: {
|
|
126
|
+
eyebrow: "Explore Sri Lanka",
|
|
127
|
+
reviewsLabel: "Reviews",
|
|
128
|
+
bookTrip: "Book Your Trip",
|
|
129
|
+
exploreNow: "Explore Now",
|
|
130
|
+
startFrom: "Start from",
|
|
131
|
+
perPerson: "/ person"
|
|
122
132
|
}
|
|
123
133
|
},
|
|
124
134
|
si: {
|
|
@@ -176,6 +186,14 @@ var defaultTranslations = {
|
|
|
176
186
|
clear: "\u0DB4\u0DD2\u0DBB\u0DD2\u0DC3\u0DD2\u0DAF\u0DD4 \u0D9A\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
177
187
|
selectMonth: "\u0DB8\u0DCF\u0DC3\u0DBA \u0DAD\u0DDD\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
178
188
|
poyaDay: "\u0DB4\u0DDD\u0DBA \u0DAF\u0DD2\u0DB1"
|
|
189
|
+
},
|
|
190
|
+
destinationCard: {
|
|
191
|
+
eyebrow: "\u0DC1\u0DCA\u200D\u0DBB\u0DD3 \u0DBD\u0D82\u0D9A\u0DCF\u0DC0 \u0DC3\u0DDC\u0DBA\u0DCF \u0DB6\u0DBD\u0DB1\u0DCA\u0DB1",
|
|
192
|
+
reviewsLabel: "\u0DC3\u0DB8\u0DCF\u0DBD\u0DDD\u0DA0\u0DB1",
|
|
193
|
+
bookTrip: "\u0D94\u0DB6\u0DDA \u0DC3\u0D82\u0DA0\u0DCF\u0DBB\u0DBA \u0DC0\u0DD9\u0DB1\u0DCA\u0D9A\u0DBB\u0DC0\u0DB1\u0DCA\u0DB1",
|
|
194
|
+
exploreNow: "\u0DAF\u0DD0\u0DB1\u0DCA \u0D9C\u0DC0\u0DDA\u0DC2\u0DAB\u0DBA \u0D9A\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
195
|
+
startFrom: "\u0D86\u0DBB\u0DB8\u0DCA\u0DB7\u0DBA",
|
|
196
|
+
perPerson: "/ \u0DB4\u0DD4\u0DAF\u0DCA\u0D9C\u0DBD\u0DBA\u0D9A\u0DD4\u0DA7"
|
|
179
197
|
}
|
|
180
198
|
}
|
|
181
199
|
};
|
|
@@ -265,6 +283,9 @@ function getTextFieldTranslation(variant, locale = currentLocale) {
|
|
|
265
283
|
function getCalendarTranslation(locale = currentLocale) {
|
|
266
284
|
return getMergedTranslations(locale).calendar ?? defaultTranslations[locale].calendar;
|
|
267
285
|
}
|
|
286
|
+
function getDestinationCardTranslation(locale = currentLocale) {
|
|
287
|
+
return getMergedTranslations(locale).destinationCard ?? defaultTranslations[locale].destinationCard;
|
|
288
|
+
}
|
|
268
289
|
function subscribeLocaleChange(listener) {
|
|
269
290
|
localeListeners.add(listener);
|
|
270
291
|
return () => localeListeners.delete(listener);
|
|
@@ -405,16 +426,43 @@ function pick(items) {
|
|
|
405
426
|
return items[Math.floor(Math.random() * items.length)];
|
|
406
427
|
}
|
|
407
428
|
function toImageUrl(source) {
|
|
408
|
-
|
|
429
|
+
if (typeof source === "string") return source;
|
|
430
|
+
if (source && typeof source === "object") {
|
|
431
|
+
const value = source;
|
|
432
|
+
if (typeof value.src === "string") return value.src;
|
|
433
|
+
if (typeof value.default === "string") return value.default;
|
|
434
|
+
if (value.default && typeof value.default === "object" && value.default !== null) {
|
|
435
|
+
const nested = value.default;
|
|
436
|
+
if (typeof nested.src === "string") return nested.src;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
throw new Error("RainBackground image must be a URL string.");
|
|
440
|
+
}
|
|
441
|
+
function toDisplayUrl(source, cache) {
|
|
442
|
+
const existing = cache.get(source);
|
|
443
|
+
if (existing) return existing;
|
|
444
|
+
if (!source.startsWith("data:")) return source;
|
|
445
|
+
const comma = source.indexOf(",");
|
|
446
|
+
if (comma === -1) return source;
|
|
447
|
+
const header = source.slice(0, comma);
|
|
448
|
+
const data = source.slice(comma + 1);
|
|
449
|
+
const mime = header.match(/^data:([^;,]+)/i)?.[1] ?? "image/png";
|
|
450
|
+
const binary = atob(data);
|
|
451
|
+
const bytes = new Uint8Array(binary.length);
|
|
452
|
+
for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
|
|
453
|
+
const url = URL.createObjectURL(new Blob([bytes], { type: mime }));
|
|
454
|
+
cache.set(source, url);
|
|
455
|
+
return url;
|
|
409
456
|
}
|
|
410
457
|
var RainBackground = class {
|
|
411
458
|
element;
|
|
459
|
+
objectUrls = [];
|
|
412
460
|
constructor(options = {}) {
|
|
413
461
|
const {
|
|
414
462
|
images = [...BUILTIN_RAIN_IMAGES],
|
|
415
463
|
density = 28,
|
|
416
464
|
minSize = 28,
|
|
417
|
-
maxSize =
|
|
465
|
+
maxSize = 72,
|
|
418
466
|
minDuration = 8,
|
|
419
467
|
maxDuration = 18,
|
|
420
468
|
target = document.body,
|
|
@@ -427,8 +475,11 @@ var RainBackground = class {
|
|
|
427
475
|
this.element.className = "helaui-rain-background";
|
|
428
476
|
this.element.setAttribute("aria-hidden", "true");
|
|
429
477
|
this.element.style.zIndex = String(zIndex);
|
|
478
|
+
const urlCache = /* @__PURE__ */ new Map();
|
|
479
|
+
const resolved = images.map((image) => toDisplayUrl(toImageUrl(image), urlCache));
|
|
480
|
+
this.objectUrls.push(...new Set(urlCache.values()));
|
|
430
481
|
for (let index = 0; index < density; index += 1) {
|
|
431
|
-
this.element.appendChild(this.createDrop(
|
|
482
|
+
this.element.appendChild(this.createDrop(resolved, minSize, maxSize, minDuration, maxDuration));
|
|
432
483
|
}
|
|
433
484
|
target.prepend(this.element);
|
|
434
485
|
}
|
|
@@ -436,9 +487,16 @@ var RainBackground = class {
|
|
|
436
487
|
const drop = document.createElement("div");
|
|
437
488
|
const duration = randomBetween(minDuration, maxDuration);
|
|
438
489
|
const size = randomBetween(minSize, maxSize);
|
|
439
|
-
const src =
|
|
490
|
+
const src = pick(images);
|
|
491
|
+
const img = document.createElement("img");
|
|
492
|
+
img.className = "helaui-rain-background__image";
|
|
493
|
+
img.src = src;
|
|
494
|
+
img.alt = "";
|
|
495
|
+
img.draggable = false;
|
|
496
|
+
img.decoding = "async";
|
|
497
|
+
img.loading = "eager";
|
|
498
|
+
img.setAttribute("fetchpriority", "high");
|
|
440
499
|
drop.className = "helaui-rain-background__drop";
|
|
441
|
-
drop.style.backgroundImage = `url(${JSON.stringify(src)})`;
|
|
442
500
|
drop.style.setProperty("--helaui-rain-x", `${randomBetween(0, 100)}%`);
|
|
443
501
|
drop.style.setProperty("--helaui-rain-size", `${size}px`);
|
|
444
502
|
drop.style.setProperty("--helaui-rain-duration", `${duration.toFixed(2)}s`);
|
|
@@ -446,11 +504,14 @@ var RainBackground = class {
|
|
|
446
504
|
drop.style.setProperty("--helaui-rain-rotation", `${randomBetween(-35, 35).toFixed(1)}deg`);
|
|
447
505
|
drop.style.setProperty("--helaui-rain-spin", `${randomBetween(90, 360).toFixed(0)}deg`);
|
|
448
506
|
drop.style.setProperty("--helaui-rain-drift", `${randomBetween(-40, 40).toFixed(0)}px`);
|
|
507
|
+
drop.appendChild(img);
|
|
449
508
|
return drop;
|
|
450
509
|
}
|
|
451
510
|
/** Removes the background from the DOM. */
|
|
452
511
|
destroy() {
|
|
453
512
|
this.element.remove();
|
|
513
|
+
for (const url of this.objectUrls) URL.revokeObjectURL(url);
|
|
514
|
+
this.objectUrls.length = 0;
|
|
454
515
|
}
|
|
455
516
|
};
|
|
456
517
|
var DEFAULT_RAIN_IMAGES = ["fritter.png", "swirl.png", "kokis.png", "leaf.png"];
|
|
@@ -924,6 +985,106 @@ var SunMandala = class {
|
|
|
924
985
|
}
|
|
925
986
|
};
|
|
926
987
|
|
|
988
|
+
// src/components/DestinationCard.ts
|
|
989
|
+
var PEACOCK_SVG = `
|
|
990
|
+
<svg viewBox="0 0 220 110" aria-hidden="true">
|
|
991
|
+
<g fill="none" stroke-linecap="round">
|
|
992
|
+
<path d="M18 92c8-28 28-52 58-62" stroke="#1a6b6c" stroke-width="5"/>
|
|
993
|
+
<path d="M32 96c10-22 30-40 56-46" stroke="#2a8f7a" stroke-width="4"/>
|
|
994
|
+
<path d="M48 100c10-16 26-28 46-32" stroke="#c86837" stroke-width="3.5"/>
|
|
995
|
+
<ellipse cx="28" cy="38" rx="7" ry="10" fill="#1a4d4e" transform="rotate(-20 28 38)"/>
|
|
996
|
+
<circle cx="26" cy="34" r="1.6" fill="#f9f3e6"/>
|
|
997
|
+
<path d="M22 42c8 6 18 8 28 4" stroke="#1a4d4e" stroke-width="3"/>
|
|
998
|
+
<circle cx="62" cy="28" r="9" fill="#1a6b6c" opacity=".85"/>
|
|
999
|
+
<circle cx="62" cy="28" r="4" fill="#d4af37"/>
|
|
1000
|
+
<circle cx="88" cy="42" r="10" fill="#2a8f7a" opacity=".8"/>
|
|
1001
|
+
<circle cx="88" cy="42" r="4" fill="#c86837"/>
|
|
1002
|
+
<circle cx="74" cy="62" r="9" fill="#1a4d4e" opacity=".75"/>
|
|
1003
|
+
<circle cx="74" cy="62" r="3.5" fill="#d4af37"/>
|
|
1004
|
+
<path d="M108 96c8-24 26-44 54-52" stroke="#1a6b6c" stroke-width="5"/>
|
|
1005
|
+
<path d="M118 100c8-18 24-32 48-36" stroke="#c86837" stroke-width="3.5"/>
|
|
1006
|
+
<ellipse cx="116" cy="48" rx="6.5" ry="9" fill="#1a4d4e" transform="rotate(-18 116 48)"/>
|
|
1007
|
+
<circle cx="114" cy="44" r="1.4" fill="#f9f3e6"/>
|
|
1008
|
+
<circle cx="148" cy="36" r="8" fill="#1a6b6c" opacity=".85"/>
|
|
1009
|
+
<circle cx="148" cy="36" r="3.5" fill="#d4af37"/>
|
|
1010
|
+
<circle cx="168" cy="52" r="8" fill="#2a8f7a" opacity=".8"/>
|
|
1011
|
+
<circle cx="168" cy="52" r="3.5" fill="#c86837"/>
|
|
1012
|
+
</g>
|
|
1013
|
+
<ellipse cx="96" cy="98" rx="10" ry="6" fill="#e8c9d4"/>
|
|
1014
|
+
<path d="M90 96c4-10 12-12 18-2" fill="#d46a8a"/>
|
|
1015
|
+
<path d="M94 98c3-7 9-8 13-1" fill="#f4c6d4"/>
|
|
1016
|
+
</svg>
|
|
1017
|
+
`;
|
|
1018
|
+
var LOTUS_SVG = `
|
|
1019
|
+
<svg viewBox="0 0 120 110" aria-hidden="true">
|
|
1020
|
+
<path d="M60 96c-16-18-28-34-28-50 0-10 8-16 16-12 6 3 10 12 12 22 2-14 8-28 18-34 8-5 16 0 16 12 0 16-12 32-34 62z" fill="#e8a0b8"/>
|
|
1021
|
+
<path d="M60 96c-10-16-22-36-18-54 3-12 14-16 18-6 4-16 16-24 24-18 8 6 6 22-2 36-8 14-16 28-22 42z" fill="#d46a8a"/>
|
|
1022
|
+
<path d="M60 98c6-20 8-38 4-52-3-10-12-12-14-4-4-12-2-24 8-28 10-4 18 6 18 18 0 16-6 34-16 66z" fill="#f3c3d2"/>
|
|
1023
|
+
<circle cx="60" cy="42" r="8" fill="#d4af37"/>
|
|
1024
|
+
<circle cx="60" cy="42" r="3.5" fill="#f9f3e6"/>
|
|
1025
|
+
</svg>
|
|
1026
|
+
`;
|
|
1027
|
+
function el(tag, className, text) {
|
|
1028
|
+
const node = document.createElement(tag);
|
|
1029
|
+
node.className = className;
|
|
1030
|
+
if (text !== void 0) node.textContent = text;
|
|
1031
|
+
return node;
|
|
1032
|
+
}
|
|
1033
|
+
var DestinationCard = class {
|
|
1034
|
+
element;
|
|
1035
|
+
card;
|
|
1036
|
+
body;
|
|
1037
|
+
constructor(options = {}) {
|
|
1038
|
+
const { content, height = "280px", backdrop = false, backdropImage } = options;
|
|
1039
|
+
this.card = el("article", "helaui-destination-card");
|
|
1040
|
+
this.card.setAttribute("aria-label", "HelaUI card");
|
|
1041
|
+
const watermark = el("div", "helaui-destination-card__watermark");
|
|
1042
|
+
watermark.setAttribute("aria-hidden", "true");
|
|
1043
|
+
this.card.appendChild(watermark);
|
|
1044
|
+
const script = el("div", `helaui-destination-card__script ${SINHALA_FONT_CLASS}`, "\u0DC1\u0DCA\u200D\u0DBB\u0DD3 \u0DBD\u0D82\u0D9A\u0DCF\u0DC0");
|
|
1045
|
+
script.setAttribute("aria-hidden", "true");
|
|
1046
|
+
this.card.appendChild(script);
|
|
1047
|
+
this.body = el("div", "helaui-destination-card__body");
|
|
1048
|
+
this.body.style.minHeight = height;
|
|
1049
|
+
if (typeof content === "string") {
|
|
1050
|
+
this.body.innerHTML = content;
|
|
1051
|
+
} else if (content) {
|
|
1052
|
+
this.body.appendChild(content);
|
|
1053
|
+
}
|
|
1054
|
+
this.card.appendChild(this.body);
|
|
1055
|
+
const footer = el("div", "helaui-destination-card__footer");
|
|
1056
|
+
footer.setAttribute("aria-hidden", "true");
|
|
1057
|
+
const peacocks = el("div", "helaui-destination-card__peacocks");
|
|
1058
|
+
peacocks.innerHTML = PEACOCK_SVG.trim();
|
|
1059
|
+
const lotus = el("div", "helaui-destination-card__lotus");
|
|
1060
|
+
lotus.innerHTML = LOTUS_SVG.trim();
|
|
1061
|
+
footer.append(peacocks, lotus);
|
|
1062
|
+
this.card.appendChild(footer);
|
|
1063
|
+
if (backdrop) {
|
|
1064
|
+
const stage = el("div", "helaui-destination-card-stage");
|
|
1065
|
+
const blur = el("div", "helaui-destination-card-stage__blur");
|
|
1066
|
+
if (backdropImage) {
|
|
1067
|
+
blur.style.backgroundImage = `url("${backdropImage.replace(/"/g, "")}")`;
|
|
1068
|
+
}
|
|
1069
|
+
stage.append(blur, this.card);
|
|
1070
|
+
this.element = stage;
|
|
1071
|
+
} else {
|
|
1072
|
+
this.element = this.card;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
setContent(content) {
|
|
1076
|
+
this.body.replaceChildren();
|
|
1077
|
+
if (typeof content === "string") {
|
|
1078
|
+
this.body.innerHTML = content;
|
|
1079
|
+
} else {
|
|
1080
|
+
this.body.appendChild(content);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
destroy() {
|
|
1084
|
+
this.element.remove();
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
927
1088
|
// src/theme/defaultTheme.ts
|
|
928
1089
|
var defaultTheme = {
|
|
929
1090
|
primary: "#8D153A",
|
|
@@ -999,6 +1160,7 @@ function createThemeStyle(theme = {}) {
|
|
|
999
1160
|
BUILTIN_SUN_MANDALA_IMAGE,
|
|
1000
1161
|
Calendar,
|
|
1001
1162
|
DEFAULT_RAIN_IMAGES,
|
|
1163
|
+
DestinationCard,
|
|
1002
1164
|
RainBackground,
|
|
1003
1165
|
SINHALA_FONT_CLASS,
|
|
1004
1166
|
SINHALA_FONT_FAMILY,
|
|
@@ -1015,6 +1177,7 @@ function createThemeStyle(theme = {}) {
|
|
|
1015
1177
|
formatSinhalaNumeral,
|
|
1016
1178
|
getCalendarTranslation,
|
|
1017
1179
|
getDefaultRainImageUrls,
|
|
1180
|
+
getDestinationCardTranslation,
|
|
1018
1181
|
getLocale,
|
|
1019
1182
|
getTextFieldTranslation,
|
|
1020
1183
|
resetTheme,
|
package/dist/index.d.cts
CHANGED
|
@@ -25,6 +25,14 @@ interface HelaTextFieldTranslations {
|
|
|
25
25
|
email: TextFieldStrings;
|
|
26
26
|
disabled: TextFieldStrings;
|
|
27
27
|
}
|
|
28
|
+
interface DestinationCardStrings {
|
|
29
|
+
eyebrow: string;
|
|
30
|
+
reviewsLabel: string;
|
|
31
|
+
bookTrip: string;
|
|
32
|
+
exploreNow: string;
|
|
33
|
+
startFrom: string;
|
|
34
|
+
perPerson: string;
|
|
35
|
+
}
|
|
28
36
|
interface CalendarStrings {
|
|
29
37
|
monthNames: [string, string, string, string, string, string, string, string, string, string, string, string];
|
|
30
38
|
sinhalaMonthNames: [string, string, string, string, string, string, string, string, string, string, string, string];
|
|
@@ -40,6 +48,7 @@ interface CalendarStrings {
|
|
|
40
48
|
interface HelaTranslations {
|
|
41
49
|
textField: HelaTextFieldTranslations;
|
|
42
50
|
calendar: CalendarStrings;
|
|
51
|
+
destinationCard: DestinationCardStrings;
|
|
43
52
|
}
|
|
44
53
|
type TextFieldVariant = keyof HelaTextFieldTranslations;
|
|
45
54
|
type DeepPartial<T> = {
|
|
@@ -84,6 +93,8 @@ declare function t(path: string, locale?: HelaLocale): string;
|
|
|
84
93
|
declare function getTextFieldTranslation(variant: TextFieldVariant, locale?: HelaLocale): TextFieldStrings;
|
|
85
94
|
/** Built-in Calendar strings for the active (or given) locale. */
|
|
86
95
|
declare function getCalendarTranslation(locale?: HelaLocale): CalendarStrings;
|
|
96
|
+
/** Built-in DestinationCard strings for the active (or given) locale. */
|
|
97
|
+
declare function getDestinationCardTranslation(locale?: HelaLocale): DestinationCardStrings;
|
|
87
98
|
/** Subscribe to locale or override changes. Returns an unsubscribe function. */
|
|
88
99
|
declare function subscribeLocaleChange(listener: () => void): () => void;
|
|
89
100
|
|
|
@@ -162,6 +173,7 @@ interface RainBackgroundOptions {
|
|
|
162
173
|
/** Full-screen animated background with falling image particles. */
|
|
163
174
|
declare class RainBackground {
|
|
164
175
|
readonly element: HTMLDivElement;
|
|
176
|
+
private readonly objectUrls;
|
|
165
177
|
constructor(options?: RainBackgroundOptions);
|
|
166
178
|
private createDrop;
|
|
167
179
|
/** Removes the background from the DOM. */
|
|
@@ -306,6 +318,29 @@ declare class SunMandala {
|
|
|
306
318
|
destroy(): void;
|
|
307
319
|
}
|
|
308
320
|
|
|
321
|
+
interface DestinationCardOptions {
|
|
322
|
+
/** Optional node or HTML placed in the empty inner area. */
|
|
323
|
+
content?: HTMLElement | string;
|
|
324
|
+
/** Minimum height of the inner area. Defaults to `280px`. */
|
|
325
|
+
height?: string;
|
|
326
|
+
/** Blurred photo stage behind the card. Defaults to `false`. */
|
|
327
|
+
backdrop?: boolean;
|
|
328
|
+
/** Image used for the optional blurred stage. */
|
|
329
|
+
backdropImage?: string;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Decorative parchment card shell — frame, watermark, side script, and footer motifs.
|
|
333
|
+
* The inner area is empty so callers can place their own content.
|
|
334
|
+
*/
|
|
335
|
+
declare class DestinationCard {
|
|
336
|
+
readonly element: HTMLElement;
|
|
337
|
+
readonly card: HTMLElement;
|
|
338
|
+
readonly body: HTMLDivElement;
|
|
339
|
+
constructor(options?: DestinationCardOptions);
|
|
340
|
+
setContent(content: HTMLElement | string): void;
|
|
341
|
+
destroy(): void;
|
|
342
|
+
}
|
|
343
|
+
|
|
309
344
|
/** HelaUI brand palette — all values are customizable. */
|
|
310
345
|
interface HelaTheme {
|
|
311
346
|
primary: string;
|
|
@@ -338,4 +373,4 @@ declare const defaultTheme: HelaTheme;
|
|
|
338
373
|
/** Maps theme keys to CSS custom property names. */
|
|
339
374
|
declare const THEME_VAR_MAP: Record<HelaThemeKey, string>;
|
|
340
375
|
|
|
341
|
-
export { type ApplyTranslationsOptions, BUILTIN_RAIN_IMAGES, BUILTIN_SUN_MANDALA_IMAGE, Calendar, type CalendarOptions, type CalendarStrings, DEFAULT_RAIN_IMAGES, type DeepPartial, type HelaLocale, type HelaTextFieldTranslations, type HelaTheme, type HelaThemeKey, type HelaTranslationOverrides, type HelaTranslations, type LocaleTranslationOverrides, RainBackground, type RainBackgroundOptions, SINHALA_FONT_CLASS, SINHALA_FONT_FAMILY, SINHALA_MONTH_NAMES, SunMandala, type SunMandalaOptions, THEME_VAR_MAP, TextField, type TextFieldOptions, type TextFieldStrings, type TextFieldVariant, applySinhalaFont, applyTheme, applyTranslations, createThemeStyle, defaultTheme, defaultTranslations, formatSinhalaNumeral, getCalendarTranslation, getDefaultRainImageUrls, getLocale, getTextFieldTranslation, resetTheme, resetTranslations, setLocale, sinhalaFontStyles, subscribeLocaleChange, t };
|
|
376
|
+
export { type ApplyTranslationsOptions, BUILTIN_RAIN_IMAGES, BUILTIN_SUN_MANDALA_IMAGE, Calendar, type CalendarOptions, type CalendarStrings, DEFAULT_RAIN_IMAGES, type DeepPartial, DestinationCard, type DestinationCardOptions, type DestinationCardStrings, type HelaLocale, type HelaTextFieldTranslations, type HelaTheme, type HelaThemeKey, type HelaTranslationOverrides, type HelaTranslations, type LocaleTranslationOverrides, RainBackground, type RainBackgroundOptions, SINHALA_FONT_CLASS, SINHALA_FONT_FAMILY, SINHALA_MONTH_NAMES, SunMandala, type SunMandalaOptions, THEME_VAR_MAP, TextField, type TextFieldOptions, type TextFieldStrings, type TextFieldVariant, applySinhalaFont, applyTheme, applyTranslations, createThemeStyle, defaultTheme, defaultTranslations, formatSinhalaNumeral, getCalendarTranslation, getDefaultRainImageUrls, getDestinationCardTranslation, getLocale, getTextFieldTranslation, resetTheme, resetTranslations, setLocale, sinhalaFontStyles, subscribeLocaleChange, t };
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,14 @@ interface HelaTextFieldTranslations {
|
|
|
25
25
|
email: TextFieldStrings;
|
|
26
26
|
disabled: TextFieldStrings;
|
|
27
27
|
}
|
|
28
|
+
interface DestinationCardStrings {
|
|
29
|
+
eyebrow: string;
|
|
30
|
+
reviewsLabel: string;
|
|
31
|
+
bookTrip: string;
|
|
32
|
+
exploreNow: string;
|
|
33
|
+
startFrom: string;
|
|
34
|
+
perPerson: string;
|
|
35
|
+
}
|
|
28
36
|
interface CalendarStrings {
|
|
29
37
|
monthNames: [string, string, string, string, string, string, string, string, string, string, string, string];
|
|
30
38
|
sinhalaMonthNames: [string, string, string, string, string, string, string, string, string, string, string, string];
|
|
@@ -40,6 +48,7 @@ interface CalendarStrings {
|
|
|
40
48
|
interface HelaTranslations {
|
|
41
49
|
textField: HelaTextFieldTranslations;
|
|
42
50
|
calendar: CalendarStrings;
|
|
51
|
+
destinationCard: DestinationCardStrings;
|
|
43
52
|
}
|
|
44
53
|
type TextFieldVariant = keyof HelaTextFieldTranslations;
|
|
45
54
|
type DeepPartial<T> = {
|
|
@@ -84,6 +93,8 @@ declare function t(path: string, locale?: HelaLocale): string;
|
|
|
84
93
|
declare function getTextFieldTranslation(variant: TextFieldVariant, locale?: HelaLocale): TextFieldStrings;
|
|
85
94
|
/** Built-in Calendar strings for the active (or given) locale. */
|
|
86
95
|
declare function getCalendarTranslation(locale?: HelaLocale): CalendarStrings;
|
|
96
|
+
/** Built-in DestinationCard strings for the active (or given) locale. */
|
|
97
|
+
declare function getDestinationCardTranslation(locale?: HelaLocale): DestinationCardStrings;
|
|
87
98
|
/** Subscribe to locale or override changes. Returns an unsubscribe function. */
|
|
88
99
|
declare function subscribeLocaleChange(listener: () => void): () => void;
|
|
89
100
|
|
|
@@ -162,6 +173,7 @@ interface RainBackgroundOptions {
|
|
|
162
173
|
/** Full-screen animated background with falling image particles. */
|
|
163
174
|
declare class RainBackground {
|
|
164
175
|
readonly element: HTMLDivElement;
|
|
176
|
+
private readonly objectUrls;
|
|
165
177
|
constructor(options?: RainBackgroundOptions);
|
|
166
178
|
private createDrop;
|
|
167
179
|
/** Removes the background from the DOM. */
|
|
@@ -306,6 +318,29 @@ declare class SunMandala {
|
|
|
306
318
|
destroy(): void;
|
|
307
319
|
}
|
|
308
320
|
|
|
321
|
+
interface DestinationCardOptions {
|
|
322
|
+
/** Optional node or HTML placed in the empty inner area. */
|
|
323
|
+
content?: HTMLElement | string;
|
|
324
|
+
/** Minimum height of the inner area. Defaults to `280px`. */
|
|
325
|
+
height?: string;
|
|
326
|
+
/** Blurred photo stage behind the card. Defaults to `false`. */
|
|
327
|
+
backdrop?: boolean;
|
|
328
|
+
/** Image used for the optional blurred stage. */
|
|
329
|
+
backdropImage?: string;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Decorative parchment card shell — frame, watermark, side script, and footer motifs.
|
|
333
|
+
* The inner area is empty so callers can place their own content.
|
|
334
|
+
*/
|
|
335
|
+
declare class DestinationCard {
|
|
336
|
+
readonly element: HTMLElement;
|
|
337
|
+
readonly card: HTMLElement;
|
|
338
|
+
readonly body: HTMLDivElement;
|
|
339
|
+
constructor(options?: DestinationCardOptions);
|
|
340
|
+
setContent(content: HTMLElement | string): void;
|
|
341
|
+
destroy(): void;
|
|
342
|
+
}
|
|
343
|
+
|
|
309
344
|
/** HelaUI brand palette — all values are customizable. */
|
|
310
345
|
interface HelaTheme {
|
|
311
346
|
primary: string;
|
|
@@ -338,4 +373,4 @@ declare const defaultTheme: HelaTheme;
|
|
|
338
373
|
/** Maps theme keys to CSS custom property names. */
|
|
339
374
|
declare const THEME_VAR_MAP: Record<HelaThemeKey, string>;
|
|
340
375
|
|
|
341
|
-
export { type ApplyTranslationsOptions, BUILTIN_RAIN_IMAGES, BUILTIN_SUN_MANDALA_IMAGE, Calendar, type CalendarOptions, type CalendarStrings, DEFAULT_RAIN_IMAGES, type DeepPartial, type HelaLocale, type HelaTextFieldTranslations, type HelaTheme, type HelaThemeKey, type HelaTranslationOverrides, type HelaTranslations, type LocaleTranslationOverrides, RainBackground, type RainBackgroundOptions, SINHALA_FONT_CLASS, SINHALA_FONT_FAMILY, SINHALA_MONTH_NAMES, SunMandala, type SunMandalaOptions, THEME_VAR_MAP, TextField, type TextFieldOptions, type TextFieldStrings, type TextFieldVariant, applySinhalaFont, applyTheme, applyTranslations, createThemeStyle, defaultTheme, defaultTranslations, formatSinhalaNumeral, getCalendarTranslation, getDefaultRainImageUrls, getLocale, getTextFieldTranslation, resetTheme, resetTranslations, setLocale, sinhalaFontStyles, subscribeLocaleChange, t };
|
|
376
|
+
export { type ApplyTranslationsOptions, BUILTIN_RAIN_IMAGES, BUILTIN_SUN_MANDALA_IMAGE, Calendar, type CalendarOptions, type CalendarStrings, DEFAULT_RAIN_IMAGES, type DeepPartial, DestinationCard, type DestinationCardOptions, type DestinationCardStrings, type HelaLocale, type HelaTextFieldTranslations, type HelaTheme, type HelaThemeKey, type HelaTranslationOverrides, type HelaTranslations, type LocaleTranslationOverrides, RainBackground, type RainBackgroundOptions, SINHALA_FONT_CLASS, SINHALA_FONT_FAMILY, SINHALA_MONTH_NAMES, SunMandala, type SunMandalaOptions, THEME_VAR_MAP, TextField, type TextFieldOptions, type TextFieldStrings, type TextFieldVariant, applySinhalaFont, applyTheme, applyTranslations, createThemeStyle, defaultTheme, defaultTranslations, formatSinhalaNumeral, getCalendarTranslation, getDefaultRainImageUrls, getDestinationCardTranslation, getLocale, getTextFieldTranslation, resetTheme, resetTranslations, setLocale, sinhalaFontStyles, subscribeLocaleChange, t };
|
package/dist/index.js
CHANGED
|
@@ -66,6 +66,14 @@ var defaultTranslations = {
|
|
|
66
66
|
clear: "Clear",
|
|
67
67
|
selectMonth: "Select Month",
|
|
68
68
|
poyaDay: "Poya Day"
|
|
69
|
+
},
|
|
70
|
+
destinationCard: {
|
|
71
|
+
eyebrow: "Explore Sri Lanka",
|
|
72
|
+
reviewsLabel: "Reviews",
|
|
73
|
+
bookTrip: "Book Your Trip",
|
|
74
|
+
exploreNow: "Explore Now",
|
|
75
|
+
startFrom: "Start from",
|
|
76
|
+
perPerson: "/ person"
|
|
69
77
|
}
|
|
70
78
|
},
|
|
71
79
|
si: {
|
|
@@ -123,6 +131,14 @@ var defaultTranslations = {
|
|
|
123
131
|
clear: "\u0DB4\u0DD2\u0DBB\u0DD2\u0DC3\u0DD2\u0DAF\u0DD4 \u0D9A\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
124
132
|
selectMonth: "\u0DB8\u0DCF\u0DC3\u0DBA \u0DAD\u0DDD\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
125
133
|
poyaDay: "\u0DB4\u0DDD\u0DBA \u0DAF\u0DD2\u0DB1"
|
|
134
|
+
},
|
|
135
|
+
destinationCard: {
|
|
136
|
+
eyebrow: "\u0DC1\u0DCA\u200D\u0DBB\u0DD3 \u0DBD\u0D82\u0D9A\u0DCF\u0DC0 \u0DC3\u0DDC\u0DBA\u0DCF \u0DB6\u0DBD\u0DB1\u0DCA\u0DB1",
|
|
137
|
+
reviewsLabel: "\u0DC3\u0DB8\u0DCF\u0DBD\u0DDD\u0DA0\u0DB1",
|
|
138
|
+
bookTrip: "\u0D94\u0DB6\u0DDA \u0DC3\u0D82\u0DA0\u0DCF\u0DBB\u0DBA \u0DC0\u0DD9\u0DB1\u0DCA\u0D9A\u0DBB\u0DC0\u0DB1\u0DCA\u0DB1",
|
|
139
|
+
exploreNow: "\u0DAF\u0DD0\u0DB1\u0DCA \u0D9C\u0DC0\u0DDA\u0DC2\u0DAB\u0DBA \u0D9A\u0DBB\u0DB1\u0DCA\u0DB1",
|
|
140
|
+
startFrom: "\u0D86\u0DBB\u0DB8\u0DCA\u0DB7\u0DBA",
|
|
141
|
+
perPerson: "/ \u0DB4\u0DD4\u0DAF\u0DCA\u0D9C\u0DBD\u0DBA\u0D9A\u0DD4\u0DA7"
|
|
126
142
|
}
|
|
127
143
|
}
|
|
128
144
|
};
|
|
@@ -212,6 +228,9 @@ function getTextFieldTranslation(variant, locale = currentLocale) {
|
|
|
212
228
|
function getCalendarTranslation(locale = currentLocale) {
|
|
213
229
|
return getMergedTranslations(locale).calendar ?? defaultTranslations[locale].calendar;
|
|
214
230
|
}
|
|
231
|
+
function getDestinationCardTranslation(locale = currentLocale) {
|
|
232
|
+
return getMergedTranslations(locale).destinationCard ?? defaultTranslations[locale].destinationCard;
|
|
233
|
+
}
|
|
215
234
|
function subscribeLocaleChange(listener) {
|
|
216
235
|
localeListeners.add(listener);
|
|
217
236
|
return () => localeListeners.delete(listener);
|
|
@@ -352,16 +371,43 @@ function pick(items) {
|
|
|
352
371
|
return items[Math.floor(Math.random() * items.length)];
|
|
353
372
|
}
|
|
354
373
|
function toImageUrl(source) {
|
|
355
|
-
|
|
374
|
+
if (typeof source === "string") return source;
|
|
375
|
+
if (source && typeof source === "object") {
|
|
376
|
+
const value = source;
|
|
377
|
+
if (typeof value.src === "string") return value.src;
|
|
378
|
+
if (typeof value.default === "string") return value.default;
|
|
379
|
+
if (value.default && typeof value.default === "object" && value.default !== null) {
|
|
380
|
+
const nested = value.default;
|
|
381
|
+
if (typeof nested.src === "string") return nested.src;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
throw new Error("RainBackground image must be a URL string.");
|
|
385
|
+
}
|
|
386
|
+
function toDisplayUrl(source, cache) {
|
|
387
|
+
const existing = cache.get(source);
|
|
388
|
+
if (existing) return existing;
|
|
389
|
+
if (!source.startsWith("data:")) return source;
|
|
390
|
+
const comma = source.indexOf(",");
|
|
391
|
+
if (comma === -1) return source;
|
|
392
|
+
const header = source.slice(0, comma);
|
|
393
|
+
const data = source.slice(comma + 1);
|
|
394
|
+
const mime = header.match(/^data:([^;,]+)/i)?.[1] ?? "image/png";
|
|
395
|
+
const binary = atob(data);
|
|
396
|
+
const bytes = new Uint8Array(binary.length);
|
|
397
|
+
for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
|
|
398
|
+
const url = URL.createObjectURL(new Blob([bytes], { type: mime }));
|
|
399
|
+
cache.set(source, url);
|
|
400
|
+
return url;
|
|
356
401
|
}
|
|
357
402
|
var RainBackground = class {
|
|
358
403
|
element;
|
|
404
|
+
objectUrls = [];
|
|
359
405
|
constructor(options = {}) {
|
|
360
406
|
const {
|
|
361
407
|
images = [...BUILTIN_RAIN_IMAGES],
|
|
362
408
|
density = 28,
|
|
363
409
|
minSize = 28,
|
|
364
|
-
maxSize =
|
|
410
|
+
maxSize = 72,
|
|
365
411
|
minDuration = 8,
|
|
366
412
|
maxDuration = 18,
|
|
367
413
|
target = document.body,
|
|
@@ -374,8 +420,11 @@ var RainBackground = class {
|
|
|
374
420
|
this.element.className = "helaui-rain-background";
|
|
375
421
|
this.element.setAttribute("aria-hidden", "true");
|
|
376
422
|
this.element.style.zIndex = String(zIndex);
|
|
423
|
+
const urlCache = /* @__PURE__ */ new Map();
|
|
424
|
+
const resolved = images.map((image) => toDisplayUrl(toImageUrl(image), urlCache));
|
|
425
|
+
this.objectUrls.push(...new Set(urlCache.values()));
|
|
377
426
|
for (let index = 0; index < density; index += 1) {
|
|
378
|
-
this.element.appendChild(this.createDrop(
|
|
427
|
+
this.element.appendChild(this.createDrop(resolved, minSize, maxSize, minDuration, maxDuration));
|
|
379
428
|
}
|
|
380
429
|
target.prepend(this.element);
|
|
381
430
|
}
|
|
@@ -383,9 +432,16 @@ var RainBackground = class {
|
|
|
383
432
|
const drop = document.createElement("div");
|
|
384
433
|
const duration = randomBetween(minDuration, maxDuration);
|
|
385
434
|
const size = randomBetween(minSize, maxSize);
|
|
386
|
-
const src =
|
|
435
|
+
const src = pick(images);
|
|
436
|
+
const img = document.createElement("img");
|
|
437
|
+
img.className = "helaui-rain-background__image";
|
|
438
|
+
img.src = src;
|
|
439
|
+
img.alt = "";
|
|
440
|
+
img.draggable = false;
|
|
441
|
+
img.decoding = "async";
|
|
442
|
+
img.loading = "eager";
|
|
443
|
+
img.setAttribute("fetchpriority", "high");
|
|
387
444
|
drop.className = "helaui-rain-background__drop";
|
|
388
|
-
drop.style.backgroundImage = `url(${JSON.stringify(src)})`;
|
|
389
445
|
drop.style.setProperty("--helaui-rain-x", `${randomBetween(0, 100)}%`);
|
|
390
446
|
drop.style.setProperty("--helaui-rain-size", `${size}px`);
|
|
391
447
|
drop.style.setProperty("--helaui-rain-duration", `${duration.toFixed(2)}s`);
|
|
@@ -393,11 +449,14 @@ var RainBackground = class {
|
|
|
393
449
|
drop.style.setProperty("--helaui-rain-rotation", `${randomBetween(-35, 35).toFixed(1)}deg`);
|
|
394
450
|
drop.style.setProperty("--helaui-rain-spin", `${randomBetween(90, 360).toFixed(0)}deg`);
|
|
395
451
|
drop.style.setProperty("--helaui-rain-drift", `${randomBetween(-40, 40).toFixed(0)}px`);
|
|
452
|
+
drop.appendChild(img);
|
|
396
453
|
return drop;
|
|
397
454
|
}
|
|
398
455
|
/** Removes the background from the DOM. */
|
|
399
456
|
destroy() {
|
|
400
457
|
this.element.remove();
|
|
458
|
+
for (const url of this.objectUrls) URL.revokeObjectURL(url);
|
|
459
|
+
this.objectUrls.length = 0;
|
|
401
460
|
}
|
|
402
461
|
};
|
|
403
462
|
var DEFAULT_RAIN_IMAGES = ["fritter.png", "swirl.png", "kokis.png", "leaf.png"];
|
|
@@ -871,6 +930,106 @@ var SunMandala = class {
|
|
|
871
930
|
}
|
|
872
931
|
};
|
|
873
932
|
|
|
933
|
+
// src/components/DestinationCard.ts
|
|
934
|
+
var PEACOCK_SVG = `
|
|
935
|
+
<svg viewBox="0 0 220 110" aria-hidden="true">
|
|
936
|
+
<g fill="none" stroke-linecap="round">
|
|
937
|
+
<path d="M18 92c8-28 28-52 58-62" stroke="#1a6b6c" stroke-width="5"/>
|
|
938
|
+
<path d="M32 96c10-22 30-40 56-46" stroke="#2a8f7a" stroke-width="4"/>
|
|
939
|
+
<path d="M48 100c10-16 26-28 46-32" stroke="#c86837" stroke-width="3.5"/>
|
|
940
|
+
<ellipse cx="28" cy="38" rx="7" ry="10" fill="#1a4d4e" transform="rotate(-20 28 38)"/>
|
|
941
|
+
<circle cx="26" cy="34" r="1.6" fill="#f9f3e6"/>
|
|
942
|
+
<path d="M22 42c8 6 18 8 28 4" stroke="#1a4d4e" stroke-width="3"/>
|
|
943
|
+
<circle cx="62" cy="28" r="9" fill="#1a6b6c" opacity=".85"/>
|
|
944
|
+
<circle cx="62" cy="28" r="4" fill="#d4af37"/>
|
|
945
|
+
<circle cx="88" cy="42" r="10" fill="#2a8f7a" opacity=".8"/>
|
|
946
|
+
<circle cx="88" cy="42" r="4" fill="#c86837"/>
|
|
947
|
+
<circle cx="74" cy="62" r="9" fill="#1a4d4e" opacity=".75"/>
|
|
948
|
+
<circle cx="74" cy="62" r="3.5" fill="#d4af37"/>
|
|
949
|
+
<path d="M108 96c8-24 26-44 54-52" stroke="#1a6b6c" stroke-width="5"/>
|
|
950
|
+
<path d="M118 100c8-18 24-32 48-36" stroke="#c86837" stroke-width="3.5"/>
|
|
951
|
+
<ellipse cx="116" cy="48" rx="6.5" ry="9" fill="#1a4d4e" transform="rotate(-18 116 48)"/>
|
|
952
|
+
<circle cx="114" cy="44" r="1.4" fill="#f9f3e6"/>
|
|
953
|
+
<circle cx="148" cy="36" r="8" fill="#1a6b6c" opacity=".85"/>
|
|
954
|
+
<circle cx="148" cy="36" r="3.5" fill="#d4af37"/>
|
|
955
|
+
<circle cx="168" cy="52" r="8" fill="#2a8f7a" opacity=".8"/>
|
|
956
|
+
<circle cx="168" cy="52" r="3.5" fill="#c86837"/>
|
|
957
|
+
</g>
|
|
958
|
+
<ellipse cx="96" cy="98" rx="10" ry="6" fill="#e8c9d4"/>
|
|
959
|
+
<path d="M90 96c4-10 12-12 18-2" fill="#d46a8a"/>
|
|
960
|
+
<path d="M94 98c3-7 9-8 13-1" fill="#f4c6d4"/>
|
|
961
|
+
</svg>
|
|
962
|
+
`;
|
|
963
|
+
var LOTUS_SVG = `
|
|
964
|
+
<svg viewBox="0 0 120 110" aria-hidden="true">
|
|
965
|
+
<path d="M60 96c-16-18-28-34-28-50 0-10 8-16 16-12 6 3 10 12 12 22 2-14 8-28 18-34 8-5 16 0 16 12 0 16-12 32-34 62z" fill="#e8a0b8"/>
|
|
966
|
+
<path d="M60 96c-10-16-22-36-18-54 3-12 14-16 18-6 4-16 16-24 24-18 8 6 6 22-2 36-8 14-16 28-22 42z" fill="#d46a8a"/>
|
|
967
|
+
<path d="M60 98c6-20 8-38 4-52-3-10-12-12-14-4-4-12-2-24 8-28 10-4 18 6 18 18 0 16-6 34-16 66z" fill="#f3c3d2"/>
|
|
968
|
+
<circle cx="60" cy="42" r="8" fill="#d4af37"/>
|
|
969
|
+
<circle cx="60" cy="42" r="3.5" fill="#f9f3e6"/>
|
|
970
|
+
</svg>
|
|
971
|
+
`;
|
|
972
|
+
function el(tag, className, text) {
|
|
973
|
+
const node = document.createElement(tag);
|
|
974
|
+
node.className = className;
|
|
975
|
+
if (text !== void 0) node.textContent = text;
|
|
976
|
+
return node;
|
|
977
|
+
}
|
|
978
|
+
var DestinationCard = class {
|
|
979
|
+
element;
|
|
980
|
+
card;
|
|
981
|
+
body;
|
|
982
|
+
constructor(options = {}) {
|
|
983
|
+
const { content, height = "280px", backdrop = false, backdropImage } = options;
|
|
984
|
+
this.card = el("article", "helaui-destination-card");
|
|
985
|
+
this.card.setAttribute("aria-label", "HelaUI card");
|
|
986
|
+
const watermark = el("div", "helaui-destination-card__watermark");
|
|
987
|
+
watermark.setAttribute("aria-hidden", "true");
|
|
988
|
+
this.card.appendChild(watermark);
|
|
989
|
+
const script = el("div", `helaui-destination-card__script ${SINHALA_FONT_CLASS}`, "\u0DC1\u0DCA\u200D\u0DBB\u0DD3 \u0DBD\u0D82\u0D9A\u0DCF\u0DC0");
|
|
990
|
+
script.setAttribute("aria-hidden", "true");
|
|
991
|
+
this.card.appendChild(script);
|
|
992
|
+
this.body = el("div", "helaui-destination-card__body");
|
|
993
|
+
this.body.style.minHeight = height;
|
|
994
|
+
if (typeof content === "string") {
|
|
995
|
+
this.body.innerHTML = content;
|
|
996
|
+
} else if (content) {
|
|
997
|
+
this.body.appendChild(content);
|
|
998
|
+
}
|
|
999
|
+
this.card.appendChild(this.body);
|
|
1000
|
+
const footer = el("div", "helaui-destination-card__footer");
|
|
1001
|
+
footer.setAttribute("aria-hidden", "true");
|
|
1002
|
+
const peacocks = el("div", "helaui-destination-card__peacocks");
|
|
1003
|
+
peacocks.innerHTML = PEACOCK_SVG.trim();
|
|
1004
|
+
const lotus = el("div", "helaui-destination-card__lotus");
|
|
1005
|
+
lotus.innerHTML = LOTUS_SVG.trim();
|
|
1006
|
+
footer.append(peacocks, lotus);
|
|
1007
|
+
this.card.appendChild(footer);
|
|
1008
|
+
if (backdrop) {
|
|
1009
|
+
const stage = el("div", "helaui-destination-card-stage");
|
|
1010
|
+
const blur = el("div", "helaui-destination-card-stage__blur");
|
|
1011
|
+
if (backdropImage) {
|
|
1012
|
+
blur.style.backgroundImage = `url("${backdropImage.replace(/"/g, "")}")`;
|
|
1013
|
+
}
|
|
1014
|
+
stage.append(blur, this.card);
|
|
1015
|
+
this.element = stage;
|
|
1016
|
+
} else {
|
|
1017
|
+
this.element = this.card;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
setContent(content) {
|
|
1021
|
+
this.body.replaceChildren();
|
|
1022
|
+
if (typeof content === "string") {
|
|
1023
|
+
this.body.innerHTML = content;
|
|
1024
|
+
} else {
|
|
1025
|
+
this.body.appendChild(content);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
destroy() {
|
|
1029
|
+
this.element.remove();
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
|
|
874
1033
|
// src/theme/defaultTheme.ts
|
|
875
1034
|
var defaultTheme = {
|
|
876
1035
|
primary: "#8D153A",
|
|
@@ -945,6 +1104,7 @@ export {
|
|
|
945
1104
|
BUILTIN_SUN_MANDALA_IMAGE,
|
|
946
1105
|
Calendar,
|
|
947
1106
|
DEFAULT_RAIN_IMAGES,
|
|
1107
|
+
DestinationCard,
|
|
948
1108
|
RainBackground,
|
|
949
1109
|
SINHALA_FONT_CLASS,
|
|
950
1110
|
SINHALA_FONT_FAMILY,
|
|
@@ -961,6 +1121,7 @@ export {
|
|
|
961
1121
|
formatSinhalaNumeral,
|
|
962
1122
|
getCalendarTranslation,
|
|
963
1123
|
getDefaultRainImageUrls,
|
|
1124
|
+
getDestinationCardTranslation,
|
|
964
1125
|
getLocale,
|
|
965
1126
|
getTextFieldTranslation,
|
|
966
1127
|
resetTheme,
|
package/dist/rain-background.css
CHANGED
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
animation: helaui-rain-fall var(--helaui-rain-duration, 10s) linear infinite;
|
|
18
18
|
animation-delay: var(--helaui-rain-delay, 0s);
|
|
19
19
|
transform: rotate(var(--helaui-rain-rotation, 0deg));
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.helaui-rain-background__image {
|
|
23
|
+
display: block;
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
object-fit: contain;
|
|
27
|
+
pointer-events: none;
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
@keyframes helaui-rain-fall {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mccustomapps/helaui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "HelaUI components with Sinhala font support",
|
|
5
5
|
"author": "mccustomapps",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"./calendar.css": "./dist/calendar.css",
|
|
27
27
|
"./rain-background.css": "./dist/rain-background.css",
|
|
28
28
|
"./sun-mandala.css": "./dist/sun-mandala.css",
|
|
29
|
+
"./destination-card.css": "./dist/destination-card.css",
|
|
29
30
|
"./theme.css": "./dist/theme.css",
|
|
30
31
|
"./assets/rain/*": "./dist/assets/rain/*",
|
|
31
32
|
"./assets/sun-mandala/*": "./dist/assets/sun-mandala/*"
|