@deriv-web-design/ui 0.1.5 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "Generated by scripts/generate-component-manifest.ts from the TypeScript types. Do not edit by hand. Props inherited from React HTMLAttributes are intentionally omitted. `default` is the value declared in the component's own parameter destructuring; a prop whose effective default is applied further down the tree (e.g. cards[].showLink) has no `default` here — see block-registry.json `fields` for documented effective defaults.",
3
3
  "package": "@deriv-web-design/ui",
4
- "componentCount": 44,
4
+ "componentCount": 52,
5
5
  "components": {
6
6
  "Accordion": {
7
7
  "name": "Accordion",
@@ -1024,6 +1024,45 @@
1024
1024
  }
1025
1025
  }
1026
1026
  },
1027
+ "DynamicTable": {
1028
+ "name": "DynamicTable",
1029
+ "source": "templates/DynamicTable/DynamicTable.tsx",
1030
+ "props": {
1031
+ "columns": {
1032
+ "type": "DynamicTableColumnDef[]",
1033
+ "required": true,
1034
+ "description": "Column definitions (order matters). Extra columns beyond the variant are ignored.",
1035
+ "items": {
1036
+ "header": {
1037
+ "type": "string | string[]",
1038
+ "required": true,
1039
+ "description": "Header label text. Pass an array for multi-line headers (e.g. [\"Spread\", \"reduction\"])."
1040
+ },
1041
+ "key": {
1042
+ "type": "string",
1043
+ "required": true,
1044
+ "description": "Unique key matching the row data field"
1045
+ }
1046
+ }
1047
+ },
1048
+ "rows": {
1049
+ "type": "DynamicTableRowData[]",
1050
+ "required": true,
1051
+ "description": "Row data"
1052
+ },
1053
+ "sectionTitle": {
1054
+ "type": "string",
1055
+ "required": false,
1056
+ "description": "Optional section title rendered above the table"
1057
+ },
1058
+ "variant": {
1059
+ "type": "DynamicTableVariant",
1060
+ "required": false,
1061
+ "description": "Column-count variant. - `Three columns` — one label column + two comparison columns - `Four columns` — one label column + three comparison columns",
1062
+ "default": "Three columns"
1063
+ }
1064
+ }
1065
+ },
1027
1066
  "FaqAccordion": {
1028
1067
  "name": "FaqAccordion",
1029
1068
  "source": "templates/FaqAccordion/FaqAccordion.tsx",
@@ -1087,6 +1126,377 @@
1087
1126
  }
1088
1127
  }
1089
1128
  },
1129
+ "FeatureBlog": {
1130
+ "name": "FeatureBlog",
1131
+ "source": "templates/FeatureBlog/FeatureBlog.tsx",
1132
+ "props": {
1133
+ "className": {
1134
+ "type": "string",
1135
+ "required": false,
1136
+ "description": "Extra class name merged onto the root `<section>`."
1137
+ },
1138
+ "linkHref": {
1139
+ "type": "string",
1140
+ "required": false,
1141
+ "description": "Href for the \"See all\" link"
1142
+ },
1143
+ "linkText": {
1144
+ "type": "string",
1145
+ "required": false,
1146
+ "description": "Label for the \"See all\" link (default: \"See all press releases\")",
1147
+ "defaultExpression": "FEATURE_BLOG_TEXT_CONTENT.linkText"
1148
+ },
1149
+ "onLinkClick": {
1150
+ "type": "(() => void)",
1151
+ "required": false
1152
+ },
1153
+ "posts": {
1154
+ "type": "FeatureBlogPost[]",
1155
+ "required": true,
1156
+ "description": "Posts rendered as a responsive card grid.",
1157
+ "items": {
1158
+ "category": {
1159
+ "type": "string",
1160
+ "required": false,
1161
+ "description": "Category label, e.g. \"Company\""
1162
+ },
1163
+ "date": {
1164
+ "type": "string",
1165
+ "required": false,
1166
+ "description": "Publish date label, e.g. \"July 24, 2026\""
1167
+ },
1168
+ "href": {
1169
+ "type": "string",
1170
+ "required": false,
1171
+ "description": "Link target — wraps the card in an anchor when set"
1172
+ },
1173
+ "onClick": {
1174
+ "type": "(() => void)",
1175
+ "required": false,
1176
+ "description": "Click handler — used when `href` is not set"
1177
+ },
1178
+ "summary": {
1179
+ "type": "string",
1180
+ "required": true,
1181
+ "description": "Post summary / dek text"
1182
+ },
1183
+ "thumbnail": {
1184
+ "type": "string",
1185
+ "required": true,
1186
+ "description": "Card thumbnail image"
1187
+ },
1188
+ "thumbnailAlt": {
1189
+ "type": "string",
1190
+ "required": false
1191
+ },
1192
+ "title": {
1193
+ "type": "string",
1194
+ "required": true,
1195
+ "description": "Post headline"
1196
+ }
1197
+ }
1198
+ },
1199
+ "showLink": {
1200
+ "type": "boolean",
1201
+ "required": false,
1202
+ "description": "Show the \"See all\" link below the grid (default: true)",
1203
+ "default": true
1204
+ },
1205
+ "title": {
1206
+ "type": "string",
1207
+ "required": false,
1208
+ "description": "Section heading. Defaults to \"Deriv press releases\".",
1209
+ "defaultExpression": "FEATURE_BLOG_TEXT_CONTENT.title"
1210
+ }
1211
+ }
1212
+ },
1213
+ "FeatureBlogCategories": {
1214
+ "name": "FeatureBlogCategories",
1215
+ "source": "templates/FeatureBlogCategories/FeatureBlogCategories.tsx",
1216
+ "props": {
1217
+ "activeCategoryId": {
1218
+ "type": "string",
1219
+ "required": false,
1220
+ "description": "Controlled active category tab id"
1221
+ },
1222
+ "allCategoryId": {
1223
+ "type": "string",
1224
+ "required": false,
1225
+ "description": "Id used internally for the auto-prepended \"show everything\" tab (default: \"all\")",
1226
+ "defaultExpression": "FEATURE_BLOG_CATEGORIES_TEXT_CONTENT.allCategoryId"
1227
+ },
1228
+ "allCategoryLabel": {
1229
+ "type": "string",
1230
+ "required": false,
1231
+ "description": "Label for the auto-prepended \"show everything\" tab (default: \"View all\")",
1232
+ "defaultExpression": "FEATURE_BLOG_CATEGORIES_TEXT_CONTENT.allCategoryLabel"
1233
+ },
1234
+ "categories": {
1235
+ "type": "FeatureBlogCategoryTab[]",
1236
+ "required": true,
1237
+ "description": "Category tabs, CMS-managed. An \"all\" tab is always prepended automatically.",
1238
+ "items": {
1239
+ "id": {
1240
+ "type": "string",
1241
+ "required": true,
1242
+ "description": "Stable identifier — must match `FeatureBlogCategoryPost.category` for filtering to work. CMS-managed."
1243
+ },
1244
+ "label": {
1245
+ "type": "string",
1246
+ "required": true,
1247
+ "description": "Tab label shown in the pill row. CMS-managed."
1248
+ }
1249
+ }
1250
+ },
1251
+ "className": {
1252
+ "type": "string",
1253
+ "required": false,
1254
+ "description": "Extra class name merged onto the root `<section>`."
1255
+ },
1256
+ "defaultActiveCategoryId": {
1257
+ "type": "string",
1258
+ "required": false,
1259
+ "description": "Initial active tab id for uncontrolled usage (default: `allCategoryId`)"
1260
+ },
1261
+ "emptyStateText": {
1262
+ "type": "string",
1263
+ "required": false,
1264
+ "description": "Message shown when no posts match the active tab + search query",
1265
+ "defaultExpression": "FEATURE_BLOG_CATEGORIES_TEXT_CONTENT.emptyStateText"
1266
+ },
1267
+ "onCategoryChange": {
1268
+ "type": "((id: string) => void)",
1269
+ "required": false,
1270
+ "description": "Called whenever a different tab is selected"
1271
+ },
1272
+ "onSearchChange": {
1273
+ "type": "((value: string) => void)",
1274
+ "required": false,
1275
+ "description": "Called on every keystroke in the search field with the current value"
1276
+ },
1277
+ "posts": {
1278
+ "type": "FeatureBlogCategoryPost[]",
1279
+ "required": true,
1280
+ "description": "All posts — filtered client-side by the active tab and search query",
1281
+ "items": {
1282
+ "category": {
1283
+ "type": "string",
1284
+ "required": true,
1285
+ "description": "Category tab id this post belongs to (matches a `categories[].id`). Posts also always match the \"all\" tab."
1286
+ },
1287
+ "categoryLabel": {
1288
+ "type": "string",
1289
+ "required": false,
1290
+ "description": "Category chip label shown on the card. Defaults to the matching tab's `label` when omitted."
1291
+ },
1292
+ "date": {
1293
+ "type": "string",
1294
+ "required": false,
1295
+ "description": "Publish date label, e.g. \"July 24, 2026\""
1296
+ },
1297
+ "href": {
1298
+ "type": "string",
1299
+ "required": false,
1300
+ "description": "Destination URL. Absolute `http(s)://` URLs are treated as external and open in a new tab (`target=\"_blank\" rel=\"noopener noreferrer\"`); relative/internal paths (e.g. \"/newsroom/my-article\") navigate as a normal same-tab inner-page link."
1301
+ },
1302
+ "onClick": {
1303
+ "type": "(() => void)",
1304
+ "required": false,
1305
+ "description": "Click handler — used when `href` is not set (renders a `<button>`)"
1306
+ },
1307
+ "summary": {
1308
+ "type": "string",
1309
+ "required": true,
1310
+ "description": "Post summary / dek text"
1311
+ },
1312
+ "thumbnail": {
1313
+ "type": "string",
1314
+ "required": true,
1315
+ "description": "Card thumbnail image"
1316
+ },
1317
+ "thumbnailAlt": {
1318
+ "type": "string",
1319
+ "required": false
1320
+ },
1321
+ "title": {
1322
+ "type": "string",
1323
+ "required": true,
1324
+ "description": "Post headline"
1325
+ }
1326
+ }
1327
+ },
1328
+ "searchAriaLabel": {
1329
+ "type": "string",
1330
+ "required": false,
1331
+ "description": "Accessible label for the search field (defaults to `searchPlaceholder`)"
1332
+ },
1333
+ "searchPlaceholder": {
1334
+ "type": "string",
1335
+ "required": false,
1336
+ "description": "Placeholder text for the search field (default: \"Search\")",
1337
+ "defaultExpression": "FEATURE_BLOG_CATEGORIES_TEXT_CONTENT.searchPlaceholder"
1338
+ },
1339
+ "title": {
1340
+ "type": "string",
1341
+ "required": false,
1342
+ "description": "Section heading. Defaults to \"Deriv press releases\".",
1343
+ "defaultExpression": "FEATURE_BLOG_CATEGORIES_TEXT_CONTENT.title"
1344
+ }
1345
+ }
1346
+ },
1347
+ "FeatureBlogPage": {
1348
+ "name": "FeatureBlogPage",
1349
+ "source": "templates/FeatureBlogPage/FeatureBlogPage.tsx",
1350
+ "props": {
1351
+ "author": {
1352
+ "type": "FeatureBlogAuthor",
1353
+ "required": false,
1354
+ "description": "Article author, shown in the meta row next to the publish date"
1355
+ },
1356
+ "category": {
1357
+ "type": "string",
1358
+ "required": false,
1359
+ "description": "Small category label rendered above the title (e.g. \"Press releases\")"
1360
+ },
1361
+ "className": {
1362
+ "type": "string",
1363
+ "required": false,
1364
+ "description": "Additional CSS class on the outer `<section>`"
1365
+ },
1366
+ "content": {
1367
+ "type": "FeatureBlogContentBlock[]",
1368
+ "required": true,
1369
+ "description": "Main article body, rendered from plain data blocks (required, at least 1 item)",
1370
+ "items": {
1371
+ "caption": {
1372
+ "type": "string",
1373
+ "required": false,
1374
+ "description": "Optional caption rendered below an \"image\" block"
1375
+ },
1376
+ "cite": {
1377
+ "type": "string",
1378
+ "required": false,
1379
+ "description": "Citation / source line for \"quote\" blocks"
1380
+ },
1381
+ "id": {
1382
+ "type": "string",
1383
+ "required": false,
1384
+ "description": "Stable anchor id for a \"heading\" block; auto-generated (slugified) from `text` when omitted"
1385
+ },
1386
+ "image": {
1387
+ "type": "string",
1388
+ "required": false,
1389
+ "description": "Image source for \"image\" blocks"
1390
+ },
1391
+ "imageAlt": {
1392
+ "type": "string",
1393
+ "required": false
1394
+ },
1395
+ "items": {
1396
+ "type": "string[]",
1397
+ "required": false,
1398
+ "description": "List entries for \"list\" blocks"
1399
+ },
1400
+ "level": {
1401
+ "type": "2 | 3",
1402
+ "required": false,
1403
+ "description": "Heading level for \"heading\" blocks (default: 2). Only level-2 headings are collected into the table of contents — level-3 headings render inline as sub-sections but are not listed."
1404
+ },
1405
+ "ordered": {
1406
+ "type": "boolean",
1407
+ "required": false,
1408
+ "description": "Render a \"list\" block as `<ol>` instead of `<ul>` (default: false)"
1409
+ },
1410
+ "text": {
1411
+ "type": "string",
1412
+ "required": false,
1413
+ "description": "Text content for \"heading\" / \"paragraph\" / \"quote\" blocks"
1414
+ },
1415
+ "type": {
1416
+ "type": "FeatureBlogContentBlockType",
1417
+ "required": true,
1418
+ "description": "Block kind — \"heading\"/\"paragraph\"/\"quote\" use `text`, \"list\" uses `items`, \"image\" uses `image`"
1419
+ }
1420
+ }
1421
+ },
1422
+ "copiedLabel": {
1423
+ "type": "string",
1424
+ "required": false,
1425
+ "description": "Label shown briefly after \"copy link\" succeeds (default: \"Copied!\")",
1426
+ "default": "Copied!"
1427
+ },
1428
+ "heroImage": {
1429
+ "type": "string",
1430
+ "required": false,
1431
+ "description": "Hero image rendered below the title / meta row"
1432
+ },
1433
+ "heroImageAlt": {
1434
+ "type": "string",
1435
+ "required": false
1436
+ },
1437
+ "hideShare": {
1438
+ "type": "boolean",
1439
+ "required": false,
1440
+ "description": "Hide the share row entirely (default: false)",
1441
+ "default": false
1442
+ },
1443
+ "hideToc": {
1444
+ "type": "boolean",
1445
+ "required": false,
1446
+ "description": "Hide the table of contents entirely (default: false) — e.g. for very short articles with no level-2 headings",
1447
+ "default": false
1448
+ },
1449
+ "onShare": {
1450
+ "type": "((platform: FeatureBlogSharePlatform | \"copy\") => void)",
1451
+ "required": false,
1452
+ "description": "Fired whenever a share icon (including \"copy link\") is activated"
1453
+ },
1454
+ "publishDate": {
1455
+ "type": "string",
1456
+ "required": false,
1457
+ "description": "Publish date label shown in the meta row (e.g. \"July 24, 2026\")"
1458
+ },
1459
+ "sharePlatforms": {
1460
+ "type": "FeatureBlogSharePlatform[]",
1461
+ "required": false,
1462
+ "description": "Which social platforms to show, in order (default: all four)",
1463
+ "defaultExpression": "[\"facebook\", \"twitter\", \"telegram\", \"linkedin\"]"
1464
+ },
1465
+ "shareText": {
1466
+ "type": "string",
1467
+ "required": false,
1468
+ "description": "Text passed to platforms that accept share text (X/Twitter, Telegram); defaults to `title`"
1469
+ },
1470
+ "shareTitle": {
1471
+ "type": "string",
1472
+ "required": false,
1473
+ "description": "\"Share article\" label above the share icons (default: \"Share article\")",
1474
+ "default": "Share article"
1475
+ },
1476
+ "shareUrl": {
1477
+ "type": "string",
1478
+ "required": false,
1479
+ "description": "Canonical URL used to build every share link and for \"copy link\"; sharing is hidden when omitted"
1480
+ },
1481
+ "title": {
1482
+ "type": "string",
1483
+ "required": true,
1484
+ "description": "Article headline, rendered as the page's `<h1>` (required)"
1485
+ },
1486
+ "tocDefaultOpen": {
1487
+ "type": "boolean",
1488
+ "required": false,
1489
+ "description": "Whether the table of contents starts expanded (default: true)",
1490
+ "default": true
1491
+ },
1492
+ "tocTitle": {
1493
+ "type": "string",
1494
+ "required": false,
1495
+ "description": "Table of contents card heading (default: \"Contents\")",
1496
+ "default": "Contents"
1497
+ }
1498
+ }
1499
+ },
1090
1500
  "FeatureBullets": {
1091
1501
  "name": "FeatureBullets",
1092
1502
  "source": "templates/FeatureBullets/FeatureBullets.tsx",
@@ -1280,6 +1690,108 @@
1280
1690
  }
1281
1691
  }
1282
1692
  },
1693
+ "FeatureOffices": {
1694
+ "name": "FeatureOffices",
1695
+ "source": "templates/FeatureOffices/FeatureOffices.tsx",
1696
+ "props": {
1697
+ "activeRegionId": {
1698
+ "type": "string",
1699
+ "required": false,
1700
+ "description": "Controlled active region tab id"
1701
+ },
1702
+ "className": {
1703
+ "type": "string",
1704
+ "required": false,
1705
+ "description": "Extra class name merged onto the root `<section>`."
1706
+ },
1707
+ "defaultActiveRegionId": {
1708
+ "type": "string",
1709
+ "required": false,
1710
+ "description": "Initial active tab id for uncontrolled usage (default: `regions[0].id`)"
1711
+ },
1712
+ "linkText": {
1713
+ "type": "string",
1714
+ "required": false,
1715
+ "description": "Default label for each office's \"See location\" link.",
1716
+ "defaultExpression": "FEATURE_OFFICES_TEXT_CONTENT.linkText"
1717
+ },
1718
+ "offices": {
1719
+ "type": "FeatureOffice[]",
1720
+ "required": true,
1721
+ "description": "All offices — filtered client-side by the active region tab.",
1722
+ "items": {
1723
+ "address": {
1724
+ "type": "string",
1725
+ "required": true,
1726
+ "description": "Full postal address. Use \"\\n\" to break the address onto multiple lines."
1727
+ },
1728
+ "city": {
1729
+ "type": "string",
1730
+ "required": true,
1731
+ "description": "City name, e.g. \"London\"."
1732
+ },
1733
+ "country": {
1734
+ "type": "string",
1735
+ "required": true,
1736
+ "description": "Country name, e.g. \"United Kingdom\"."
1737
+ },
1738
+ "flagAlt": {
1739
+ "type": "string",
1740
+ "required": false,
1741
+ "description": "Alt text for the flag image. Defaults to `country` when omitted."
1742
+ },
1743
+ "flagImage": {
1744
+ "type": "string",
1745
+ "required": true,
1746
+ "description": "Flag image shown above the office name (real flag artwork, not an emoji)."
1747
+ },
1748
+ "href": {
1749
+ "type": "string",
1750
+ "required": false,
1751
+ "description": "Destination URL for the \"See location\" link (typically a map link). When omitted, the office card renders with no link."
1752
+ },
1753
+ "linkText": {
1754
+ "type": "string",
1755
+ "required": false,
1756
+ "description": "Overrides the default \"See location\" link label for this office."
1757
+ },
1758
+ "region": {
1759
+ "type": "string",
1760
+ "required": true,
1761
+ "description": "Region tab id this office belongs to (matches a `regions[].id`)."
1762
+ }
1763
+ }
1764
+ },
1765
+ "onRegionChange": {
1766
+ "type": "((id: string) => void)",
1767
+ "required": false,
1768
+ "description": "Called whenever a different region tab is selected"
1769
+ },
1770
+ "regions": {
1771
+ "type": "FeatureOfficeRegion[]",
1772
+ "required": true,
1773
+ "description": "Region tabs, CMS-managed. At least one is required.",
1774
+ "items": {
1775
+ "id": {
1776
+ "type": "string",
1777
+ "required": true,
1778
+ "description": "Stable identifier — must match `FeatureOffice.region` for filtering to work. CMS-managed."
1779
+ },
1780
+ "label": {
1781
+ "type": "string",
1782
+ "required": true,
1783
+ "description": "Tab label shown in the pill row. CMS-managed."
1784
+ }
1785
+ }
1786
+ },
1787
+ "title": {
1788
+ "type": "string",
1789
+ "required": false,
1790
+ "description": "Section heading. Defaults to \"Our offices\".",
1791
+ "defaultExpression": "FEATURE_OFFICES_TEXT_CONTENT.title"
1792
+ }
1793
+ }
1794
+ },
1283
1795
  "FeatureScroll": {
1284
1796
  "name": "FeatureScroll",
1285
1797
  "source": "templates/FeatureScroll/FeatureScroll.tsx",
@@ -1408,6 +1920,12 @@
1408
1920
  "description": "Alt text for the Investors in People badge",
1409
1921
  "default": "Investors in People - Platinum"
1410
1922
  },
1923
+ "investorsInPeopleInHeader": {
1924
+ "type": "boolean",
1925
+ "required": false,
1926
+ "description": "Moves the \"Investors in People\" badge into the header row (desktop only, replacing the AI summary bar's slot) and centers the social icons between the logo and the badge, instead of showing the badge in the sidebar/stacked position below the nav.",
1927
+ "default": false
1928
+ },
1411
1929
  "investorsInPeopleSrc": {
1412
1930
  "type": "string",
1413
1931
  "required": false,
@@ -1444,6 +1962,11 @@
1444
1962
  "required": false,
1445
1963
  "description": "Social media links shown in the header row",
1446
1964
  "default": []
1965
+ },
1966
+ "tradingView": {
1967
+ "type": "FooterTradeOnProps",
1968
+ "required": false,
1969
+ "description": "\"Trade on TradingView\" promotion banner"
1447
1970
  }
1448
1971
  }
1449
1972
  },
@@ -1459,22 +1982,27 @@
1459
1982
  "leftVisual": {
1460
1983
  "type": "ReactNode",
1461
1984
  "required": false,
1462
- "description": "Left floating visual for the Visuals variant. Accepts a ReactNode or image URL string."
1985
+ "description": "Left floating visual for the \"visuals\" variant. Accepts a ReactNode or image URL string."
1463
1986
  },
1464
1987
  "primaryButton": {
1465
1988
  "type": "HeaderButtonProps",
1466
1989
  "required": false,
1467
- "description": "Primary CTA button (coral). Shown on both variants."
1990
+ "description": "Primary CTA button (coral). Shown on all variants."
1468
1991
  },
1469
1992
  "rightVisual": {
1470
1993
  "type": "ReactNode",
1471
1994
  "required": false,
1472
- "description": "Right floating visual for the Visuals variant. Accepts a ReactNode or image URL string."
1995
+ "description": "Right floating visual for the \"visuals\" variant. Accepts a ReactNode or image URL string."
1996
+ },
1997
+ "search": {
1998
+ "type": "HeaderSearchProps",
1999
+ "required": false,
2000
+ "description": "Search field configuration for the \"dark-search\" variant (e.g. Help Centre header). The field always renders for that variant; this prop only customises it."
1473
2001
  },
1474
2002
  "secondaryButton": {
1475
2003
  "type": "HeaderButtonProps",
1476
2004
  "required": false,
1477
- "description": "Secondary CTA button (white outline). Shown on both variants."
2005
+ "description": "Secondary CTA button (white outline). Shown on all variants."
1478
2006
  },
1479
2007
  "subtitle": {
1480
2008
  "type": "string",
@@ -1489,7 +2017,7 @@
1489
2017
  "variant": {
1490
2018
  "type": "HeaderVariant",
1491
2019
  "required": true,
1492
- "description": "Layout variant: - \"visuals\" — light grey bg + SVG grid, center-aligned text, floating visuals left & right, parallax scroll effect on visuals, min-height 540px - \"minimal\" — same as visuals but without the floating graphics"
2020
+ "description": "Layout variant: - \"visuals\" — light grey bg + SVG grid, center-aligned text, floating visuals left & right, parallax scroll effect on visuals, min-height 540px - \"minimal\" — same as visuals but without the floating graphics - \"dark\" — dark navy bg + SVG grid, center-aligned text, no floating visuals, min-height 420px on mobile/tablet, 460px on desktop (shorter than the light variants) - \"dark-search\" — same as \"dark\" plus a search field below the text, for pages such as the Help Centre index"
1493
2021
  }
1494
2022
  }
1495
2023
  },
@@ -1830,7 +2358,7 @@
1830
2358
  "imageUrl": {
1831
2359
  "type": "string",
1832
2360
  "required": false,
1833
- "description": "URL of the photo. - `\"split\"`: fills the right-hand panel; stacks below text on mobile. - `\"full-bg\"`: covers the entire card as a background image."
2361
+ "description": "URL of the photo. - `\"split-left\"`: fills the right-hand panel; stacks below text on mobile. - `\"split-right\"`: fills the left-hand panel; stacks above text on mobile. - `\"full-bg-left\"` / `\"full-bg-right\"`: covers the entire card as a background image."
1834
2362
  },
1835
2363
  "onCtaClick": {
1836
2364
  "type": "(() => void)",
@@ -1844,10 +2372,10 @@
1844
2372
  "default": "Join our global community"
1845
2373
  },
1846
2374
  "variant": {
1847
- "type": "\"split\" | \"full-bg\"",
2375
+ "type": "\"split-left\" | \"split-right\" | \"full-bg-left\" | \"full-bg-right\"",
1848
2376
  "required": false,
1849
- "description": "Layout variant. - `\"split\"` (default): image fills the right-hand panel; text on the left. - `\"full-bg\"`: image covers the entire card as a background; text overlaid on top.",
1850
- "default": "split"
2377
+ "description": "Layout variant. - `\"split-left\"` (default): text on the left; image fills the right-hand panel. - `\"split-right\"`: image fills the left-hand panel; text on the right. - `\"full-bg-left\"`: image covers the entire card as a background; text overlaid on the left. - `\"full-bg-right\"`: image covers the entire card as a background; text overlaid on the right.",
2378
+ "default": "split-left"
1851
2379
  }
1852
2380
  }
1853
2381
  },
@@ -2033,6 +2561,75 @@
2033
2561
  }
2034
2562
  }
2035
2563
  },
2564
+ "ParallaxBanner": {
2565
+ "name": "ParallaxBanner",
2566
+ "source": "templates/ParallaxBanner/ParallaxBanner.tsx",
2567
+ "props": {
2568
+ "cards": {
2569
+ "type": "ParallaxBannerCultureCard[]",
2570
+ "required": false,
2571
+ "description": "Four (or more) short value/culture cards rendered in a grid below the banner. Ignored when `variant` is `\"banner-only\"`. Defaults to `DEFAULT_CULTURE_CARDS`.",
2572
+ "defaultExpression": "DEFAULT_CULTURE_CARDS"
2573
+ },
2574
+ "className": {
2575
+ "type": "string",
2576
+ "required": false,
2577
+ "description": "Extra class name merged onto the root `<section>`"
2578
+ },
2579
+ "ctaHref": {
2580
+ "type": "string",
2581
+ "required": false,
2582
+ "description": "CTA link href"
2583
+ },
2584
+ "ctaLabel": {
2585
+ "type": "string",
2586
+ "required": false,
2587
+ "description": "CTA link label. Defaults to \"Culture at Deriv\".",
2588
+ "defaultExpression": "PARALLAX_BANNER_TEXT_CONTENT.ctaLabel"
2589
+ },
2590
+ "description": {
2591
+ "type": "string",
2592
+ "required": false,
2593
+ "description": "Supporting copy beneath the headline",
2594
+ "defaultExpression": "PARALLAX_BANNER_TEXT_CONTENT.description"
2595
+ },
2596
+ "enableParallax": {
2597
+ "type": "boolean",
2598
+ "required": false,
2599
+ "description": "Enables the subtle scroll-linked parallax on the banner photo. Automatically disabled when the user has `prefers-reduced-motion` set. Defaults to `true`.",
2600
+ "default": true
2601
+ },
2602
+ "imageAlt": {
2603
+ "type": "string",
2604
+ "required": false,
2605
+ "description": "Accessible alt text for the banner photo",
2606
+ "default": ""
2607
+ },
2608
+ "imageUrl": {
2609
+ "type": "string",
2610
+ "required": false,
2611
+ "description": "URL of the photo shown in the banner's image panel",
2612
+ "defaultExpression": "PLACEHOLDER_IMAGE"
2613
+ },
2614
+ "onCtaClick": {
2615
+ "type": "(() => void)",
2616
+ "required": false,
2617
+ "description": "Callback fired when the CTA link is clicked"
2618
+ },
2619
+ "title": {
2620
+ "type": "string",
2621
+ "required": false,
2622
+ "description": "Banner headline. Defaults to \"Our culture\".",
2623
+ "defaultExpression": "PARALLAX_BANNER_TEXT_CONTENT.title"
2624
+ },
2625
+ "variant": {
2626
+ "type": "\"default\" | \"banner-only\"",
2627
+ "required": false,
2628
+ "description": "Layout variant. - `\"default\"`: banner card plus a grid of culture/value cards beneath it. - `\"banner-only\"`: just the banner card — no cards grid.",
2629
+ "default": "default"
2630
+ }
2631
+ }
2632
+ },
2036
2633
  "Stats": {
2037
2634
  "name": "Stats",
2038
2635
  "source": "templates/Stats/StatsV2.tsx",
@@ -2371,7 +2968,7 @@
2371
2968
  "items": {
2372
2969
  "type": "TestimonialItem[]",
2373
2970
  "required": true,
2374
- "description": "Array of testimonial items to display in the carousel",
2971
+ "description": "Array of testimonial items to display",
2375
2972
  "items": {
2376
2973
  "authorLocation": {
2377
2974
  "type": "string",
@@ -2392,6 +2989,16 @@
2392
2989
  "type": "string",
2393
2990
  "required": true,
2394
2991
  "description": "The testimonial quote text"
2992
+ },
2993
+ "rating": {
2994
+ "type": "number",
2995
+ "required": false,
2996
+ "description": "`trustpilot` variant only — star rating out of 5 shown on the card. Supports halves (e.g. `4.5`). Defaults to `5`."
2997
+ },
2998
+ "reviewUrl": {
2999
+ "type": "string",
3000
+ "required": false,
3001
+ "description": "`trustpilot` variant only — link to the full review on Trustpilot. When omitted, the card links to `trustpilotUrl` instead."
2395
3002
  }
2396
3003
  }
2397
3004
  },
@@ -2399,6 +3006,21 @@
2399
3006
  "type": "string",
2400
3007
  "required": false,
2401
3008
  "description": "Section heading"
3009
+ },
3010
+ "trustpilotScore": {
3011
+ "type": "number",
3012
+ "required": false,
3013
+ "description": "`trustpilot` variant only — overall TrustScore shown in the footer badge (out of 5)."
3014
+ },
3015
+ "trustpilotUrl": {
3016
+ "type": "string",
3017
+ "required": false,
3018
+ "description": "`trustpilot` variant only — URL to the brand's Trustpilot profile page. Used by the footer rating badge link, and as the fallback link for any item without its own `reviewUrl`."
3019
+ },
3020
+ "variant": {
3021
+ "type": "\"default\" | \"trustpilot\"",
3022
+ "required": false,
3023
+ "description": "Visual style. - `default` (default): single-slide auto-advancing quote carousel with dot pagination. - `trustpilot`: horizontally-scrollable row of star-rated review cards, a \"Trustpilot\" rating badge, and prev/next controls — modeled after deriv.com's homepage \"What our customers say\" section."
2402
3024
  }
2403
3025
  }
2404
3026
  },
@@ -2417,6 +3039,72 @@
2417
3039
  "description": "The large body copy that animates word-by-word on scroll"
2418
3040
  }
2419
3041
  }
3042
+ },
3043
+ "TradingCalculator": {
3044
+ "name": "TradingCalculator",
3045
+ "source": "templates/TradingCalculator/TradingCalculator.tsx",
3046
+ "props": {
3047
+ "className": {
3048
+ "type": "string",
3049
+ "required": false,
3050
+ "description": "Extra class name merged onto the root `<section>`."
3051
+ },
3052
+ "defaultSymbol": {
3053
+ "type": "string",
3054
+ "required": false,
3055
+ "description": "Symbol code to preselect on mount once symbols have loaded, e.g. \"EURUSD\"."
3056
+ },
3057
+ "exchangeRateWsUrl": {
3058
+ "type": "string | null",
3059
+ "required": false,
3060
+ "description": "Deriv's public WebSocket API endpoint, used to fetch live USD exchange rates when a selected instrument's base/profit currency isn't already USD. `app_id=1089` is Deriv's public demo app id (safe to ship — it is not a secret, only a rate-limited API client identifier); register your own at https://api.deriv.com for production traffic volumes. Pass `null` to disable live conversion — non-USD instruments then show \"N/A\" for any value that would have required it, instead of a silently wrong number.",
3061
+ "defaultExpression": "DEFAULT_EXCHANGE_RATE_WS_URL"
3062
+ },
3063
+ "symbols": {
3064
+ "type": "TradingSymbolSpec[]",
3065
+ "required": false,
3066
+ "description": "Live instrument specs (contract size, leverage, swap rates, live price...). When omitted, the component fetches them itself from `symbolsEndpoint` on mount. Pass this to supply your own data — tests, Storybook, SSR, or a project-side proxy/cache in front of the feed."
3067
+ },
3068
+ "symbolsEndpoint": {
3069
+ "type": "string",
3070
+ "required": false,
3071
+ "description": "JSON endpoint returning an array of `TradingSymbolSpec`. This is Deriv's own public, unauthenticated feed — the same one deriv.com/trading-calculators uses — refreshed continuously server-side.",
3072
+ "defaultExpression": "DEFAULT_SYMBOLS_ENDPOINT"
3073
+ },
3074
+ "variant": {
3075
+ "type": "TradingCalculatorVariant",
3076
+ "required": false,
3077
+ "description": "Which single-purpose calculator page this instance mirrors — controls which result(s) the \"Results\" panel shows. See `TradingCalculatorVariant` for what each value maps to.",
3078
+ "default": "main"
3079
+ }
3080
+ }
3081
+ },
3082
+ "TradingCalculatorHowTo": {
3083
+ "name": "TradingCalculatorHowTo",
3084
+ "source": "templates/TradingCalculatorHowTo/TradingCalculatorHowTo.tsx",
3085
+ "props": {
3086
+ "className": {
3087
+ "type": "string",
3088
+ "required": false,
3089
+ "description": "Extra class name merged onto the root `<section>`."
3090
+ },
3091
+ "description": {
3092
+ "type": "string",
3093
+ "required": false,
3094
+ "description": "Section description, shown under the title. Defaults to the canonical copy for `variant`."
3095
+ },
3096
+ "title": {
3097
+ "type": "string",
3098
+ "required": false,
3099
+ "description": "Section heading. Defaults to the canonical heading for `variant`, e.g. \"How to calculate margin requirements\"."
3100
+ },
3101
+ "variant": {
3102
+ "type": "TradingCalculatorHowToVariant",
3103
+ "required": false,
3104
+ "description": "Which deriv.com \"How to calculate…\" page this instance mirrors.",
3105
+ "default": "margin"
3106
+ }
3107
+ }
2420
3108
  }
2421
3109
  },
2422
3110
  "aliases": {