@mccustomapps/helaui 0.1.12 → 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 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/`).
@@ -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);
@@ -964,6 +985,106 @@ var SunMandala = class {
964
985
  }
965
986
  };
966
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
+
967
1088
  // src/theme/defaultTheme.ts
968
1089
  var defaultTheme = {
969
1090
  primary: "#8D153A",
@@ -1039,6 +1160,7 @@ function createThemeStyle(theme = {}) {
1039
1160
  BUILTIN_SUN_MANDALA_IMAGE,
1040
1161
  Calendar,
1041
1162
  DEFAULT_RAIN_IMAGES,
1163
+ DestinationCard,
1042
1164
  RainBackground,
1043
1165
  SINHALA_FONT_CLASS,
1044
1166
  SINHALA_FONT_FAMILY,
@@ -1055,6 +1177,7 @@ function createThemeStyle(theme = {}) {
1055
1177
  formatSinhalaNumeral,
1056
1178
  getCalendarTranslation,
1057
1179
  getDefaultRainImageUrls,
1180
+ getDestinationCardTranslation,
1058
1181
  getLocale,
1059
1182
  getTextFieldTranslation,
1060
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
 
@@ -307,6 +318,29 @@ declare class SunMandala {
307
318
  destroy(): void;
308
319
  }
309
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
+
310
344
  /** HelaUI brand palette — all values are customizable. */
311
345
  interface HelaTheme {
312
346
  primary: string;
@@ -339,4 +373,4 @@ declare const defaultTheme: HelaTheme;
339
373
  /** Maps theme keys to CSS custom property names. */
340
374
  declare const THEME_VAR_MAP: Record<HelaThemeKey, string>;
341
375
 
342
- 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
 
@@ -307,6 +318,29 @@ declare class SunMandala {
307
318
  destroy(): void;
308
319
  }
309
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
+
310
344
  /** HelaUI brand palette — all values are customizable. */
311
345
  interface HelaTheme {
312
346
  primary: string;
@@ -339,4 +373,4 @@ declare const defaultTheme: HelaTheme;
339
373
  /** Maps theme keys to CSS custom property names. */
340
374
  declare const THEME_VAR_MAP: Record<HelaThemeKey, string>;
341
375
 
342
- 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);
@@ -911,6 +930,106 @@ var SunMandala = class {
911
930
  }
912
931
  };
913
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
+
914
1033
  // src/theme/defaultTheme.ts
915
1034
  var defaultTheme = {
916
1035
  primary: "#8D153A",
@@ -985,6 +1104,7 @@ export {
985
1104
  BUILTIN_SUN_MANDALA_IMAGE,
986
1105
  Calendar,
987
1106
  DEFAULT_RAIN_IMAGES,
1107
+ DestinationCard,
988
1108
  RainBackground,
989
1109
  SINHALA_FONT_CLASS,
990
1110
  SINHALA_FONT_FAMILY,
@@ -1001,6 +1121,7 @@ export {
1001
1121
  formatSinhalaNumeral,
1002
1122
  getCalendarTranslation,
1003
1123
  getDefaultRainImageUrls,
1124
+ getDestinationCardTranslation,
1004
1125
  getLocale,
1005
1126
  getTextFieldTranslation,
1006
1127
  resetTheme,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mccustomapps/helaui",
3
- "version": "0.1.12",
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/*"