@xsolla/xui-core 0.102.0 → 0.103.0-pr170.1772104239

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/index.d.mts CHANGED
@@ -2978,6 +2978,9 @@ declare const shadow: {
2978
2978
  };
2979
2979
 
2980
2980
  declare const fonts: {
2981
+ heading: string;
2982
+ body: string;
2983
+ /** @deprecated Use `heading` or `body` instead */
2981
2984
  primary: string;
2982
2985
  };
2983
2986
  declare const typography: {
@@ -2992,6 +2995,24 @@ declare const isNative: boolean;
2992
2995
  declare const isIOS: boolean;
2993
2996
  declare const isAndroid: boolean;
2994
2997
 
2998
+ /**
2999
+ * React component that loads the toolkit's font-face declarations.
3000
+ * Drop-in for any framework — works in Next.js, Vite, CRA, etc.
3001
+ *
3002
+ * Renders nothing to the DOM. Injects a single `<style>` tag into `<head>` on mount.
3003
+ */
3004
+ declare const FontLoader: React.FC;
3005
+
3006
+ /**
3007
+ * @font-face CSS for all toolkit fonts, loaded from Xsolla CDN.
3008
+ *
3009
+ * Pilat Wide — heading/display font, registered at weights 600–800.
3010
+ *
3011
+ * Aktiv Grotesk — body font, mapped from the Sharp Grotesk CDN files
3012
+ * which are the same typeface under a legacy name.
3013
+ */
3014
+ declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 served from Sharp Grotesk CDN files \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n";
3015
+
2995
3016
  type ThemeMode = "dark" | "light" | "pentagram-dark" | "pentagram-light" | "xsolla-dark" | "xsolla-light" | "xsollaDark" | "xsollaLight" | "ltg-dark";
2996
3017
  declare const themeConfig: (mode?: ThemeMode) => {
2997
3018
  colors: {
@@ -4485,10 +4506,14 @@ declare const themeConfig: (mode?: ThemeMode) => {
4485
4506
  modal: string;
4486
4507
  };
4487
4508
  fonts: {
4509
+ heading: string;
4510
+ body: string;
4488
4511
  primary: string;
4489
4512
  };
4490
4513
  typography: {
4491
4514
  primary: string;
4515
+ heading: string;
4516
+ body: string;
4492
4517
  };
4493
4518
  sizing: {
4494
4519
  button: (size: "xl" | "lg" | "md" | "sm" | "xs") => {
@@ -4746,26 +4771,31 @@ declare const themeConfig: (mode?: ThemeMode) => {
4746
4771
  padding: number;
4747
4772
  fontSize: number;
4748
4773
  iconSize: number;
4774
+ radius: number;
4749
4775
  } | {
4750
4776
  height: number;
4751
4777
  padding: number;
4752
4778
  fontSize: number;
4753
4779
  iconSize: number;
4780
+ radius: number;
4754
4781
  } | {
4755
4782
  height: number;
4756
4783
  padding: number;
4757
4784
  fontSize: number;
4758
4785
  iconSize: number;
4786
+ radius: number;
4759
4787
  } | {
4760
4788
  height: number;
4761
4789
  padding: number;
4762
4790
  fontSize: number;
4763
4791
  iconSize: number;
4792
+ radius: number;
4764
4793
  } | {
4765
4794
  height: number;
4766
4795
  padding: number;
4767
4796
  fontSize: number;
4768
4797
  iconSize: number;
4798
+ radius: number;
4769
4799
  };
4770
4800
  switch: (size: "xl" | "lg" | "md" | "sm") => {
4771
4801
  width: number;
@@ -5405,6 +5435,8 @@ interface DesignSystemContextType {
5405
5435
  declare const XUIProvider: React.FC<{
5406
5436
  children: React.ReactNode;
5407
5437
  initialMode?: ThemeMode;
5438
+ /** Load toolkit fonts from the Xsolla CDN. Defaults to true on web, no-ops on native. */
5439
+ loadFonts?: boolean;
5408
5440
  }>;
5409
5441
  declare const useDesignSystem: () => DesignSystemContextType;
5410
5442
  declare const useId: () => string;
@@ -5421,4 +5453,4 @@ declare const ModalIdContext: React.Context<string | null>;
5421
5453
  */
5422
5454
  declare const useModalId: () => string | null;
5423
5455
 
5424
- export { ModalIdContext, type ThemeColors, type ThemeMode, XUIProvider, colors, fonts, isAndroid, isIOS, isNative, isWeb, radius, shadow, spacing, themeConfig, typography, useDesignSystem, useId, useModalId };
5456
+ export { FontLoader, ModalIdContext, type ThemeColors, type ThemeMode, XUIProvider, colors, fontFacesCSS, fonts, isAndroid, isIOS, isNative, isWeb, radius, shadow, spacing, themeConfig, typography, useDesignSystem, useId, useModalId };
package/index.d.ts CHANGED
@@ -2978,6 +2978,9 @@ declare const shadow: {
2978
2978
  };
2979
2979
 
2980
2980
  declare const fonts: {
2981
+ heading: string;
2982
+ body: string;
2983
+ /** @deprecated Use `heading` or `body` instead */
2981
2984
  primary: string;
2982
2985
  };
2983
2986
  declare const typography: {
@@ -2992,6 +2995,24 @@ declare const isNative: boolean;
2992
2995
  declare const isIOS: boolean;
2993
2996
  declare const isAndroid: boolean;
2994
2997
 
2998
+ /**
2999
+ * React component that loads the toolkit's font-face declarations.
3000
+ * Drop-in for any framework — works in Next.js, Vite, CRA, etc.
3001
+ *
3002
+ * Renders nothing to the DOM. Injects a single `<style>` tag into `<head>` on mount.
3003
+ */
3004
+ declare const FontLoader: React.FC;
3005
+
3006
+ /**
3007
+ * @font-face CSS for all toolkit fonts, loaded from Xsolla CDN.
3008
+ *
3009
+ * Pilat Wide — heading/display font, registered at weights 600–800.
3010
+ *
3011
+ * Aktiv Grotesk — body font, mapped from the Sharp Grotesk CDN files
3012
+ * which are the same typeface under a legacy name.
3013
+ */
3014
+ declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 served from Sharp Grotesk CDN files \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n";
3015
+
2995
3016
  type ThemeMode = "dark" | "light" | "pentagram-dark" | "pentagram-light" | "xsolla-dark" | "xsolla-light" | "xsollaDark" | "xsollaLight" | "ltg-dark";
2996
3017
  declare const themeConfig: (mode?: ThemeMode) => {
2997
3018
  colors: {
@@ -4485,10 +4506,14 @@ declare const themeConfig: (mode?: ThemeMode) => {
4485
4506
  modal: string;
4486
4507
  };
4487
4508
  fonts: {
4509
+ heading: string;
4510
+ body: string;
4488
4511
  primary: string;
4489
4512
  };
4490
4513
  typography: {
4491
4514
  primary: string;
4515
+ heading: string;
4516
+ body: string;
4492
4517
  };
4493
4518
  sizing: {
4494
4519
  button: (size: "xl" | "lg" | "md" | "sm" | "xs") => {
@@ -4746,26 +4771,31 @@ declare const themeConfig: (mode?: ThemeMode) => {
4746
4771
  padding: number;
4747
4772
  fontSize: number;
4748
4773
  iconSize: number;
4774
+ radius: number;
4749
4775
  } | {
4750
4776
  height: number;
4751
4777
  padding: number;
4752
4778
  fontSize: number;
4753
4779
  iconSize: number;
4780
+ radius: number;
4754
4781
  } | {
4755
4782
  height: number;
4756
4783
  padding: number;
4757
4784
  fontSize: number;
4758
4785
  iconSize: number;
4786
+ radius: number;
4759
4787
  } | {
4760
4788
  height: number;
4761
4789
  padding: number;
4762
4790
  fontSize: number;
4763
4791
  iconSize: number;
4792
+ radius: number;
4764
4793
  } | {
4765
4794
  height: number;
4766
4795
  padding: number;
4767
4796
  fontSize: number;
4768
4797
  iconSize: number;
4798
+ radius: number;
4769
4799
  };
4770
4800
  switch: (size: "xl" | "lg" | "md" | "sm") => {
4771
4801
  width: number;
@@ -5405,6 +5435,8 @@ interface DesignSystemContextType {
5405
5435
  declare const XUIProvider: React.FC<{
5406
5436
  children: React.ReactNode;
5407
5437
  initialMode?: ThemeMode;
5438
+ /** Load toolkit fonts from the Xsolla CDN. Defaults to true on web, no-ops on native. */
5439
+ loadFonts?: boolean;
5408
5440
  }>;
5409
5441
  declare const useDesignSystem: () => DesignSystemContextType;
5410
5442
  declare const useId: () => string;
@@ -5421,4 +5453,4 @@ declare const ModalIdContext: React.Context<string | null>;
5421
5453
  */
5422
5454
  declare const useModalId: () => string | null;
5423
5455
 
5424
- export { ModalIdContext, type ThemeColors, type ThemeMode, XUIProvider, colors, fonts, isAndroid, isIOS, isNative, isWeb, radius, shadow, spacing, themeConfig, typography, useDesignSystem, useId, useModalId };
5456
+ export { FontLoader, ModalIdContext, type ThemeColors, type ThemeMode, XUIProvider, colors, fontFacesCSS, fonts, isAndroid, isIOS, isNative, isWeb, radius, shadow, spacing, themeConfig, typography, useDesignSystem, useId, useModalId };
package/index.js CHANGED
@@ -30,9 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.tsx
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ FontLoader: () => FontLoader,
33
34
  ModalIdContext: () => ModalIdContext,
34
35
  XUIProvider: () => XUIProvider,
35
36
  colors: () => colors,
37
+ fontFacesCSS: () => fontFacesCSS,
36
38
  fonts: () => fonts,
37
39
  isAndroid: () => isAndroid,
38
40
  isIOS: () => isIOS,
@@ -48,7 +50,7 @@ __export(index_exports, {
48
50
  useModalId: () => useModalId
49
51
  });
50
52
  module.exports = __toCommonJS(index_exports);
51
- var import_react = __toESM(require("react"));
53
+ var import_react2 = __toESM(require("react"));
52
54
 
53
55
  // src/tokens/xsolla-dark.json
54
56
  var xsolla_dark_default = {
@@ -1577,22 +1579,108 @@ var shadow = {
1577
1579
 
1578
1580
  // src/tokens/fonts.ts
1579
1581
  var fonts = {
1580
- // Use a string that works for web but can be parsed/ignored by native
1581
- primary: '"Pilat Wide Bold", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
1582
+ heading: '"Pilat Wide", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
1583
+ body: '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
1584
+ /** @deprecated Use `heading` or `body` instead */
1585
+ primary: '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
1582
1586
  };
1583
1587
  var typography = {
1584
1588
  button: {
1585
- fontFamily: fonts.primary,
1589
+ fontFamily: fonts.body,
1586
1590
  fontWeight: "bold"
1587
1591
  }
1588
1592
  };
1589
1593
 
1594
+ // src/fonts/FontLoader.tsx
1595
+ var import_react = require("react");
1596
+
1590
1597
  // src/platform.ts
1591
1598
  var isWeb = typeof document !== "undefined";
1592
1599
  var isNative = !isWeb;
1593
1600
  var isIOS = isNative && typeof global !== "undefined" && global.Platform?.OS === "ios";
1594
1601
  var isAndroid = isNative && typeof global !== "undefined" && global.Platform?.OS === "android";
1595
1602
 
1603
+ // src/fonts/fontFaces.ts
1604
+ var CDN_BASE = "https://cdn.xsolla.net/strapi-v2-bucket-prod";
1605
+ var fontFacesCSS = `
1606
+ /* \u2500\u2500 Pilat Wide (headings) \u2500\u2500 */
1607
+
1608
+ @font-face {
1609
+ font-family: 'Pilat Wide';
1610
+ src: url('${CDN_BASE}/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');
1611
+ font-weight: 600;
1612
+ font-style: normal;
1613
+ font-display: swap;
1614
+ }
1615
+ @font-face {
1616
+ font-family: 'Pilat Wide';
1617
+ src: url('${CDN_BASE}/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');
1618
+ font-weight: 700;
1619
+ font-style: normal;
1620
+ font-display: swap;
1621
+ }
1622
+ @font-face {
1623
+ font-family: 'Pilat Wide';
1624
+ src: url('${CDN_BASE}/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');
1625
+ font-weight: 800;
1626
+ font-style: normal;
1627
+ font-display: swap;
1628
+ }
1629
+
1630
+ /* \u2500\u2500 Aktiv Grotesk (body) \u2014 served from Sharp Grotesk CDN files \u2500\u2500 */
1631
+
1632
+ @font-face {
1633
+ font-family: 'Aktiv Grotesk';
1634
+ src: url('${CDN_BASE}/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');
1635
+ font-weight: 300;
1636
+ font-style: normal;
1637
+ font-display: swap;
1638
+ }
1639
+ @font-face {
1640
+ font-family: 'Aktiv Grotesk';
1641
+ src: url('${CDN_BASE}/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');
1642
+ font-weight: 400;
1643
+ font-style: normal;
1644
+ font-display: swap;
1645
+ }
1646
+ @font-face {
1647
+ font-family: 'Aktiv Grotesk';
1648
+ src: url('${CDN_BASE}/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');
1649
+ font-weight: 500;
1650
+ font-style: normal;
1651
+ font-display: swap;
1652
+ }
1653
+ @font-face {
1654
+ font-family: 'Aktiv Grotesk';
1655
+ src: url('${CDN_BASE}/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');
1656
+ font-weight: 700;
1657
+ font-style: normal;
1658
+ font-display: swap;
1659
+ }
1660
+ `;
1661
+
1662
+ // src/fonts/FontLoader.tsx
1663
+ var injected = false;
1664
+ function injectFontStyles() {
1665
+ if (!isWeb || injected) return;
1666
+ const style = document.createElement("style");
1667
+ style.setAttribute("data-xui-fonts", "");
1668
+ style.textContent = fontFacesCSS;
1669
+ document.head.appendChild(style);
1670
+ injected = true;
1671
+ }
1672
+ var FontLoader = () => {
1673
+ const mountedRef = (0, import_react.useRef)(false);
1674
+ (0, import_react.useEffect)(() => {
1675
+ if (!mountedRef.current) {
1676
+ injectFontStyles();
1677
+ mountedRef.current = true;
1678
+ }
1679
+ }, []);
1680
+ return null;
1681
+ };
1682
+ FontLoader.displayName = "FontLoader";
1683
+
1596
1684
  // src/index.tsx
1597
1685
  var import_jsx_runtime = require("react/jsx-runtime");
1598
1686
  var themeConfig = (mode = "dark") => ({
@@ -1602,7 +1690,9 @@ var themeConfig = (mode = "dark") => ({
1602
1690
  shadow,
1603
1691
  fonts,
1604
1692
  typography: {
1605
- primary: fonts.primary
1693
+ primary: fonts.body,
1694
+ heading: fonts.heading,
1695
+ body: fonts.body
1606
1696
  },
1607
1697
  sizing: {
1608
1698
  button: (size) => {
@@ -1815,7 +1905,7 @@ var themeConfig = (mode = "dark") => ({
1815
1905
  paddingHorizontal: 12,
1816
1906
  fontSize: 20,
1817
1907
  iconSize: 18,
1818
- radius: 4,
1908
+ radius: 8,
1819
1909
  borderWidth: 2,
1820
1910
  fieldGap: 8,
1821
1911
  lineHeight: 20
@@ -1826,7 +1916,7 @@ var themeConfig = (mode = "dark") => ({
1826
1916
  paddingHorizontal: 12,
1827
1917
  fontSize: 18,
1828
1918
  iconSize: 18,
1829
- radius: 4,
1919
+ radius: 8,
1830
1920
  borderWidth: 2,
1831
1921
  fieldGap: 6,
1832
1922
  lineHeight: 18
@@ -1837,7 +1927,7 @@ var themeConfig = (mode = "dark") => ({
1837
1927
  paddingHorizontal: 12,
1838
1928
  fontSize: 16,
1839
1929
  iconSize: 18,
1840
- radius: 2,
1930
+ radius: 8,
1841
1931
  borderWidth: 1,
1842
1932
  fieldGap: 4,
1843
1933
  lineHeight: 16
@@ -1848,7 +1938,7 @@ var themeConfig = (mode = "dark") => ({
1848
1938
  paddingHorizontal: 10,
1849
1939
  fontSize: 14,
1850
1940
  iconSize: 18,
1851
- radius: 2,
1941
+ radius: 4,
1852
1942
  borderWidth: 1,
1853
1943
  fieldGap: 4,
1854
1944
  lineHeight: 14
@@ -1859,7 +1949,7 @@ var themeConfig = (mode = "dark") => ({
1859
1949
  paddingHorizontal: 10,
1860
1950
  fontSize: 12,
1861
1951
  iconSize: 18,
1862
- radius: 2,
1952
+ radius: 4,
1863
1953
  borderWidth: 1,
1864
1954
  fieldGap: 4,
1865
1955
  lineHeight: 10
@@ -1869,21 +1959,51 @@ var themeConfig = (mode = "dark") => ({
1869
1959
  },
1870
1960
  inputPin: (size) => {
1871
1961
  const configs = {
1872
- xl: { size: 64, gap: 10, fontSize: 20, radius: 4, borderWidth: 2 },
1873
- lg: { size: 56, gap: 8, fontSize: 18, radius: 4, borderWidth: 2 },
1874
- md: { size: 48, gap: 6, fontSize: 16, radius: 2, borderWidth: 1 },
1875
- sm: { size: 40, gap: 4, fontSize: 14, radius: 2, borderWidth: 1 },
1876
- xs: { size: 32, gap: 4, fontSize: 12, radius: 2, borderWidth: 1 }
1962
+ xl: { size: 64, gap: 10, fontSize: 20, radius: 8, borderWidth: 1 },
1963
+ lg: { size: 56, gap: 8, fontSize: 18, radius: 8, borderWidth: 1 },
1964
+ md: { size: 48, gap: 6, fontSize: 16, radius: 8, borderWidth: 1 },
1965
+ sm: { size: 40, gap: 4, fontSize: 14, radius: 4, borderWidth: 1 },
1966
+ xs: { size: 32, gap: 4, fontSize: 12, radius: 4, borderWidth: 1 }
1877
1967
  };
1878
1968
  return configs[size];
1879
1969
  },
1880
1970
  textarea: (size) => {
1881
1971
  const configs = {
1882
- xl: { height: 144, padding: spacing.xl, fontSize: 20, iconSize: 32 },
1883
- lg: { height: 128, padding: spacing.l, fontSize: 18, iconSize: 28 },
1884
- md: { height: 112, padding: spacing.m, fontSize: 16, iconSize: 24 },
1885
- sm: { height: 96, padding: spacing.s, fontSize: 14, iconSize: 20 },
1886
- xs: { height: 80, padding: spacing.xs, fontSize: 12, iconSize: 16 }
1972
+ xl: {
1973
+ height: 144,
1974
+ padding: spacing.xl,
1975
+ fontSize: 20,
1976
+ iconSize: 32,
1977
+ radius: 8
1978
+ },
1979
+ lg: {
1980
+ height: 128,
1981
+ padding: spacing.l,
1982
+ fontSize: 18,
1983
+ iconSize: 28,
1984
+ radius: 8
1985
+ },
1986
+ md: {
1987
+ height: 112,
1988
+ padding: spacing.m,
1989
+ fontSize: 16,
1990
+ iconSize: 24,
1991
+ radius: 8
1992
+ },
1993
+ sm: {
1994
+ height: 96,
1995
+ padding: spacing.s,
1996
+ fontSize: 14,
1997
+ iconSize: 20,
1998
+ radius: 4
1999
+ },
2000
+ xs: {
2001
+ height: 80,
2002
+ padding: spacing.xs,
2003
+ fontSize: 12,
2004
+ iconSize: 16,
2005
+ radius: 4
2006
+ }
1887
2007
  };
1888
2008
  return configs[size];
1889
2009
  },
@@ -2509,12 +2629,12 @@ var themeConfig = (mode = "dark") => ({
2509
2629
  }
2510
2630
  }
2511
2631
  });
2512
- var DesignSystemContext = (0, import_react.createContext)(
2632
+ var DesignSystemContext = (0, import_react2.createContext)(
2513
2633
  void 0
2514
2634
  );
2515
- var XUIProvider = ({ children, initialMode = "dark" }) => {
2516
- const [mode, setMode] = (0, import_react.useState)(initialMode);
2517
- const value = (0, import_react.useMemo)(
2635
+ var XUIProvider = ({ children, initialMode = "dark", loadFonts = true }) => {
2636
+ const [mode, setMode] = (0, import_react2.useState)(initialMode);
2637
+ const value = (0, import_react2.useMemo)(
2518
2638
  () => ({
2519
2639
  mode,
2520
2640
  setMode,
@@ -2522,10 +2642,13 @@ var XUIProvider = ({ children, initialMode = "dark" }) => {
2522
2642
  }),
2523
2643
  [mode]
2524
2644
  );
2525
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DesignSystemContext.Provider, { value, children });
2645
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DesignSystemContext.Provider, { value, children: [
2646
+ loadFonts && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontLoader, {}),
2647
+ children
2648
+ ] });
2526
2649
  };
2527
2650
  var useDesignSystem = () => {
2528
- const context = (0, import_react.useContext)(DesignSystemContext);
2651
+ const context = (0, import_react2.useContext)(DesignSystemContext);
2529
2652
  if (!context) {
2530
2653
  return {
2531
2654
  mode: "dark",
@@ -2537,19 +2660,21 @@ var useDesignSystem = () => {
2537
2660
  return context;
2538
2661
  };
2539
2662
  var idCounter = 0;
2540
- var hasReactUseId = typeof import_react.default.useId === "function";
2663
+ var hasReactUseId = typeof import_react2.default.useId === "function";
2541
2664
  var useIdFallback = () => {
2542
- const [id] = (0, import_react.useState)(() => `xui-${++idCounter}`);
2665
+ const [id] = (0, import_react2.useState)(() => `xui-${++idCounter}`);
2543
2666
  return id;
2544
2667
  };
2545
- var useId = hasReactUseId ? import_react.default.useId : useIdFallback;
2546
- var ModalIdContext = (0, import_react.createContext)(null);
2547
- var useModalId = () => (0, import_react.useContext)(ModalIdContext);
2668
+ var useId = hasReactUseId ? import_react2.default.useId : useIdFallback;
2669
+ var ModalIdContext = (0, import_react2.createContext)(null);
2670
+ var useModalId = () => (0, import_react2.useContext)(ModalIdContext);
2548
2671
  // Annotate the CommonJS export names for ESM import in node:
2549
2672
  0 && (module.exports = {
2673
+ FontLoader,
2550
2674
  ModalIdContext,
2551
2675
  XUIProvider,
2552
2676
  colors,
2677
+ fontFacesCSS,
2553
2678
  fonts,
2554
2679
  isAndroid,
2555
2680
  isIOS,
package/index.js.flow CHANGED
@@ -2684,13 +2684,36 @@ surfaceHover: string,
2684
2684
  popover: string,
2685
2685
  modal: string,...
2686
2686
  };declare var fonts: {
2687
+ heading: string,
2688
+ body: string,
2689
+
2690
+ /**
2691
+ * @deprecated Use `heading` or `body` instead
2692
+ */
2687
2693
  primary: string,...
2688
2694
  };declare var typography: {
2689
2695
  button: {
2690
2696
  fontFamily: string,
2691
2697
  fontWeight: string,...
2692
2698
  },...
2693
- };declare var isWeb: boolean;declare var isNative: boolean;declare var isIOS: boolean;declare var isAndroid: boolean;declare type ThemeMode = "dark"
2699
+ };declare var isWeb: boolean;declare var isNative: boolean;declare var isIOS: boolean;declare var isAndroid: boolean;
2700
+ /**
2701
+ * React component that loads the toolkit's font-face declarations.
2702
+ * Drop-in for any framework — works in Next.js, Vite, CRA, etc.
2703
+ *
2704
+ * Renders nothing to the DOM. Injects a single `<style>` tag into `<head>` on mount.
2705
+ */
2706
+ declare var FontLoader: React.FC;
2707
+ /**
2708
+ * @font-face CSS for all toolkit fonts, loaded from Xsolla CDN.
2709
+ *
2710
+ * Pilat Wide — heading/display font, registered at weights 600–800.
2711
+ *
2712
+ * Aktiv Grotesk — body font, mapped from the Sharp Grotesk CDN files
2713
+ * which are the same typeface under a legacy name.
2714
+ */
2715
+ declare var fontFacesCSS: "\n /* ── Pilat Wide (headings) ── */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* ── Aktiv Grotesk (body) — served from Sharp Grotesk CDN files ── */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n"
2716
+ ;declare type ThemeMode = "dark"
2694
2717
  | "light"
2695
2718
  | "pentagram-dark"
2696
2719
  | "pentagram-light"
@@ -4195,10 +4218,14 @@ popover: string,
4195
4218
  modal: string,...
4196
4219
  },
4197
4220
  fonts: {
4221
+ heading: string,
4222
+ body: string,
4198
4223
  primary: string,...
4199
4224
  },
4200
4225
  typography: {
4201
- primary: string,...
4226
+ primary: string,
4227
+ heading: string,
4228
+ body: string,...
4202
4229
  },
4203
4230
  sizing: {
4204
4231
  button: (
@@ -4498,31 +4525,36 @@ size: "xl"
4498
4525
  height: number,
4499
4526
  padding: number,
4500
4527
  fontSize: number,
4501
- iconSize: number,...
4528
+ iconSize: number,
4529
+ radius: number,...
4502
4530
  }
4503
4531
  | {
4504
4532
  height: number,
4505
4533
  padding: number,
4506
4534
  fontSize: number,
4507
- iconSize: number,...
4535
+ iconSize: number,
4536
+ radius: number,...
4508
4537
  }
4509
4538
  | {
4510
4539
  height: number,
4511
4540
  padding: number,
4512
4541
  fontSize: number,
4513
- iconSize: number,...
4542
+ iconSize: number,
4543
+ radius: number,...
4514
4544
  }
4515
4545
  | {
4516
4546
  height: number,
4517
4547
  padding: number,
4518
4548
  fontSize: number,
4519
- iconSize: number,...
4549
+ iconSize: number,
4550
+ radius: number,...
4520
4551
  }
4521
4552
  | {
4522
4553
  height: number,
4523
4554
  padding: number,
4524
4555
  fontSize: number,
4525
- iconSize: number,...
4556
+ iconSize: number,
4557
+ radius: number,...
4526
4558
  },
4527
4559
  switch: (
4528
4560
  size: "xl" | "lg" | "md" | "sm") => {
@@ -5238,7 +5270,12 @@ setMode: (mode: ThemeMode) => void,
5238
5270
  theme: $Call<<R>((...args: any[]) => R) => R, typeof themeConfig>,
5239
5271
  } declare var XUIProvider: React.FC<{
5240
5272
  children: React.ReactNode,
5241
- initialMode?: ThemeMode,...
5273
+ initialMode?: ThemeMode,
5274
+
5275
+ /**
5276
+ * Load toolkit fonts from the Xsolla CDN. Defaults to true on web, no-ops on native.
5277
+ */
5278
+ loadFonts?: boolean,...
5242
5279
  }>;declare var useDesignSystem: () => DesignSystemContextType;declare var useId: () => string;
5243
5280
  /**
5244
5281
  * Context for the current modal's ID.
@@ -5255,5 +5292,5 @@ declare var useModalId: () => string | null;export type {
5255
5292
  ThemeColors,ThemeMode
5256
5293
  }
5257
5294
  declare export {
5258
- ModalIdContext,XUIProvider,colors,fonts,isAndroid,isIOS,isNative,isWeb,radius,shadow,spacing,themeConfig,typography,useDesignSystem,useId,useModalId
5295
+ FontLoader,ModalIdContext,XUIProvider,colors,fontFacesCSS,fonts,isAndroid,isIOS,isNative,isWeb,radius,shadow,spacing,themeConfig,typography,useDesignSystem,useId,useModalId
5259
5296
  }