@fairmint/ui 0.4.10 → 0.4.11

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.
Files changed (140) hide show
  1. package/dist/components/BrandedLoadingScreen/BrandedLoadingScreen.cjs +1 -1
  2. package/dist/components/BrandedLoadingScreen/BrandedLoadingScreen.js +1 -1
  3. package/dist/components/ErrorFallback/ErrorFallback.cjs +1 -1
  4. package/dist/components/ErrorFallback/ErrorFallback.js +1 -1
  5. package/dist/components/form/FormField.cjs +1 -1
  6. package/dist/components/form/FormField.js +1 -1
  7. package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs +1 -1
  8. package/dist/components/generic/AgentSuggestion/AgentSuggestion.js +1 -1
  9. package/dist/components/generic/Banner/Banner.cjs +1 -1
  10. package/dist/components/generic/Banner/Banner.js +1 -1
  11. package/dist/components/generic/BottomSheet/BottomSheet.cjs +1 -1
  12. package/dist/components/generic/BottomSheet/BottomSheet.js +1 -1
  13. package/dist/components/generic/CompanyBanner/CompanyBanner.cjs +1 -1
  14. package/dist/components/generic/CompanyBanner/CompanyBanner.js +1 -1
  15. package/dist/components/generic/ConfidentialityBanner/ConfidentialityBanner.cjs +1 -1
  16. package/dist/components/generic/ConfidentialityBanner/ConfidentialityBanner.js +1 -1
  17. package/dist/components/generic/Currency/Currency.cjs +1 -1
  18. package/dist/components/generic/Currency/Currency.js +1 -1
  19. package/dist/components/generic/DataRow/DataRow.cjs +24 -3
  20. package/dist/components/generic/DataRow/DataRow.cjs.map +1 -1
  21. package/dist/components/generic/DataRow/DataRow.d.ts.map +1 -1
  22. package/dist/components/generic/DataRow/DataRow.js +24 -3
  23. package/dist/components/generic/DataRow/DataRow.js.map +1 -1
  24. package/dist/components/generic/DataTable/DataTable.cjs +2 -2
  25. package/dist/components/generic/DataTable/DataTable.cjs.map +1 -1
  26. package/dist/components/generic/DataTable/DataTable.js +2 -2
  27. package/dist/components/generic/DataTable/DataTable.js.map +1 -1
  28. package/dist/components/generic/DateDisplay/DateDisplay.cjs +1 -1
  29. package/dist/components/generic/DateDisplay/DateDisplay.js +1 -1
  30. package/dist/components/generic/DocumentRow/DocumentRow.cjs +1 -1
  31. package/dist/components/generic/DocumentRow/DocumentRow.js +1 -1
  32. package/dist/components/generic/EditableSection/EditableSection.cjs +1 -1
  33. package/dist/components/generic/EditableSection/EditableSection.js +1 -1
  34. package/dist/components/generic/EmptyState/EmptyState.cjs +1 -1
  35. package/dist/components/generic/EmptyState/EmptyState.js +1 -1
  36. package/dist/components/generic/ErrorPage/ErrorPage.cjs +1 -1
  37. package/dist/components/generic/ErrorPage/ErrorPage.js +1 -1
  38. package/dist/components/generic/Eyebrow/Eyebrow.cjs +1 -1
  39. package/dist/components/generic/Eyebrow/Eyebrow.js +1 -1
  40. package/dist/components/generic/FileDropzone/FileDropzone.cjs +1 -1
  41. package/dist/components/generic/FileDropzone/FileDropzone.js +1 -1
  42. package/dist/components/generic/ListRow/ListRow.cjs +5 -4
  43. package/dist/components/generic/ListRow/ListRow.cjs.map +1 -1
  44. package/dist/components/generic/ListRow/ListRow.d.ts.map +1 -1
  45. package/dist/components/generic/ListRow/ListRow.js +5 -4
  46. package/dist/components/generic/ListRow/ListRow.js.map +1 -1
  47. package/dist/components/generic/MultiSelectSearch/MultiSelectSearch.cjs +1 -1
  48. package/dist/components/generic/MultiSelectSearch/MultiSelectSearch.js +1 -1
  49. package/dist/components/generic/NotificationRow/NotificationRow.cjs +1 -1
  50. package/dist/components/generic/NotificationRow/NotificationRow.js +1 -1
  51. package/dist/components/generic/Percent/Percent.cjs +1 -1
  52. package/dist/components/generic/Percent/Percent.js +1 -1
  53. package/dist/components/generic/PhotoCropModal/PhotoCropModal.cjs +1 -1
  54. package/dist/components/generic/PhotoCropModal/PhotoCropModal.js +1 -1
  55. package/dist/components/generic/ProcessingState/ProcessingState.cjs +1 -1
  56. package/dist/components/generic/ProcessingState/ProcessingState.js +1 -1
  57. package/dist/components/generic/RadioCard/RadioCard.cjs +1 -1
  58. package/dist/components/generic/RadioCard/RadioCard.js +1 -1
  59. package/dist/components/generic/StatCard/StatCard.cjs +1 -1
  60. package/dist/components/generic/StatCard/StatCard.js +1 -1
  61. package/dist/components/generic/StepCard/StepCard.cjs +3 -2
  62. package/dist/components/generic/StepCard/StepCard.cjs.map +1 -1
  63. package/dist/components/generic/StepCard/StepCard.d.ts.map +1 -1
  64. package/dist/components/generic/StepCard/StepCard.js +3 -2
  65. package/dist/components/generic/StepCard/StepCard.js.map +1 -1
  66. package/dist/components/generic/TablePagination/TablePagination.cjs +1 -1
  67. package/dist/components/generic/TablePagination/TablePagination.js +1 -1
  68. package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.cjs +1 -1
  69. package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.js +1 -1
  70. package/dist/components/generic/TaskRow/TaskRow.cjs +1 -1
  71. package/dist/components/generic/TaskRow/TaskRow.js +1 -1
  72. package/dist/components/layout/AccountSheet/AccountSheet.cjs +1 -1
  73. package/dist/components/layout/AccountSheet/AccountSheet.js +1 -1
  74. package/dist/components/layout/MobileNav/MobileNav.cjs +1 -1
  75. package/dist/components/layout/MobileNav/MobileNav.js +1 -1
  76. package/dist/components/layout/PageHeader/PageHeader.cjs +1 -1
  77. package/dist/components/layout/PageHeader/PageHeader.js +1 -1
  78. package/dist/components/primitives/Glossary/GlossaryContext.cjs +39 -0
  79. package/dist/components/primitives/Glossary/GlossaryContext.cjs.map +1 -0
  80. package/dist/components/primitives/Glossary/GlossaryContext.d.ts +49 -0
  81. package/dist/components/primitives/Glossary/GlossaryContext.d.ts.map +1 -0
  82. package/dist/components/primitives/Glossary/GlossaryContext.js +39 -0
  83. package/dist/components/primitives/Glossary/GlossaryContext.js.map +1 -0
  84. package/dist/components/primitives/Glossary/GlossaryTerm.cjs +147 -0
  85. package/dist/components/primitives/Glossary/GlossaryTerm.cjs.map +1 -0
  86. package/dist/components/primitives/Glossary/GlossaryTerm.d.ts +10 -0
  87. package/dist/components/primitives/Glossary/GlossaryTerm.d.ts.map +1 -0
  88. package/dist/components/primitives/Glossary/GlossaryTerm.js +147 -0
  89. package/dist/components/primitives/Glossary/GlossaryTerm.js.map +1 -0
  90. package/dist/components/primitives/Glossary/index.d.ts +3 -0
  91. package/dist/components/primitives/Glossary/index.d.ts.map +1 -0
  92. package/dist/components/primitives/Text/Text.cjs +112 -0
  93. package/dist/components/primitives/Text/Text.cjs.map +1 -0
  94. package/dist/components/primitives/Text/Text.d.ts +22 -0
  95. package/dist/components/primitives/Text/Text.d.ts.map +1 -0
  96. package/dist/components/primitives/Text/Text.js +112 -0
  97. package/dist/components/primitives/Text/Text.js.map +1 -0
  98. package/dist/components/primitives/Text/index.d.ts +2 -0
  99. package/dist/components/primitives/Text/index.d.ts.map +1 -0
  100. package/dist/components/primitives/index.d.ts +2 -0
  101. package/dist/components/primitives/index.d.ts.map +1 -1
  102. package/dist/components/primitives/layout.cjs.map +1 -1
  103. package/dist/components/primitives/layout.d.ts +2 -1
  104. package/dist/components/primitives/layout.d.ts.map +1 -1
  105. package/dist/components/primitives/layout.js.map +1 -1
  106. package/dist/components/primitives/muiCompat.cjs +8 -8
  107. package/dist/components/primitives/muiCompat.cjs.map +1 -1
  108. package/dist/components/primitives/muiCompat.d.ts.map +1 -1
  109. package/dist/components/primitives/muiCompat.js +8 -8
  110. package/dist/components/primitives/muiCompat.js.map +1 -1
  111. package/dist/components/specific/DocumentRow/DocumentRow.cjs +1 -1
  112. package/dist/components/specific/DocumentRow/DocumentRow.js +1 -1
  113. package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.cjs +1 -1
  114. package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.js +1 -1
  115. package/dist/components/specific/WalletList/WalletList.cjs +1 -1
  116. package/dist/components/specific/WalletList/WalletList.js +1 -1
  117. package/dist/components/specific/WalletListItem/WalletListItem.cjs +3 -2
  118. package/dist/components/specific/WalletListItem/WalletListItem.cjs.map +1 -1
  119. package/dist/components/specific/WalletListItem/WalletListItem.d.ts.map +1 -1
  120. package/dist/components/specific/WalletListItem/WalletListItem.js +3 -2
  121. package/dist/components/specific/WalletListItem/WalletListItem.js.map +1 -1
  122. package/dist/constants/glossary.cjs +210 -0
  123. package/dist/constants/glossary.cjs.map +1 -0
  124. package/dist/constants/glossary.d.ts +26 -0
  125. package/dist/constants/glossary.d.ts.map +1 -0
  126. package/dist/constants/glossary.js +210 -0
  127. package/dist/constants/glossary.js.map +1 -0
  128. package/dist/fairmint-ui.cjs +13 -1
  129. package/dist/fairmint-ui.cjs.map +1 -1
  130. package/dist/fairmint-ui.js +13 -1
  131. package/dist/fairmint-ui.js.map +1 -1
  132. package/dist/index.d.ts +3 -0
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/utils/glossaryMatcher.cjs +89 -0
  135. package/dist/utils/glossaryMatcher.cjs.map +1 -0
  136. package/dist/utils/glossaryMatcher.d.ts +23 -0
  137. package/dist/utils/glossaryMatcher.d.ts.map +1 -0
  138. package/dist/utils/glossaryMatcher.js +89 -0
  139. package/dist/utils/glossaryMatcher.js.map +1 -0
  140. package/package.json +1 -1
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const glossary = require("../../../constants/glossary.cjs");
6
+ const GlossaryContext = React.createContext(null);
7
+ function GlossaryProvider({
8
+ children,
9
+ enabled = true,
10
+ terms = glossary.FINANCIAL_GLOSSARY,
11
+ onTermClick,
12
+ learnMoreText = "Click to learn more"
13
+ }) {
14
+ const value = React.useMemo(
15
+ () => ({
16
+ enabled,
17
+ terms,
18
+ onTermClick,
19
+ learnMoreText
20
+ }),
21
+ [enabled, terms, onTermClick, learnMoreText]
22
+ );
23
+ return /* @__PURE__ */ jsxRuntime.jsx(GlossaryContext.Provider, { value, children });
24
+ }
25
+ function useGlossaryContext() {
26
+ return React.useContext(GlossaryContext);
27
+ }
28
+ const GlossaryScopeContext = React.createContext(null);
29
+ function GlossaryScope({ children }) {
30
+ return /* @__PURE__ */ jsxRuntime.jsx(GlossaryScopeContext.Provider, { value: { active: true }, children });
31
+ }
32
+ function useGlossaryScope() {
33
+ return React.useContext(GlossaryScopeContext);
34
+ }
35
+ exports.GlossaryProvider = GlossaryProvider;
36
+ exports.GlossaryScope = GlossaryScope;
37
+ exports.useGlossaryContext = useGlossaryContext;
38
+ exports.useGlossaryScope = useGlossaryScope;
39
+ //# sourceMappingURL=GlossaryContext.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryContext.cjs","sources":["../../../../src/components/primitives/Glossary/GlossaryContext.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\nimport {\n FINANCIAL_GLOSSARY,\n type GlossaryTerm,\n type GlossaryTermData,\n type GlossaryTermDefinition,\n} from \"../../../constants/glossary\";\n\nexport type { GlossaryTermData, GlossaryTermDefinition };\n\nexport interface GlossaryContextValue {\n /** Whether glossary term matching and linkification is enabled. @default true */\n enabled: boolean;\n /** Active dictionary of terms to match against. Defaults to FINANCIAL_GLOSSARY. */\n terms: readonly GlossaryTerm[];\n /**\n * Optional click handler called when an interactive glossary term is activated.\n * If provided, terms render with interactive click affordances (e.g. opens Cap Table AI).\n * If omitted, terms render as definition-only glossary items with informative tooltips.\n */\n onTermClick?: (term: GlossaryTerm) => void;\n /**\n * Optional call-to-action text displayed in the tooltip footer when `onTermClick` is defined.\n * @default \"Click to learn more\"\n */\n learnMoreText?: string;\n}\n\nexport interface GlossaryProviderProps {\n children: ReactNode;\n /** Whether glossary term matching is active. Defaults to true. */\n enabled?: boolean;\n /** Custom dictionary of terms to replace the standard financial glossary. */\n terms?: readonly GlossaryTerm[];\n /** Callback fired when a user clicks/taps an interactive glossary term. */\n onTermClick?: (term: GlossaryTerm) => void;\n /** Custom tooltip action label (e.g. \"Click to learn more with Cap Table AI\"). */\n learnMoreText?: string;\n}\n\nconst GlossaryContext = createContext<GlossaryContextValue | null>(null);\n\nexport function GlossaryProvider({\n children,\n enabled = true,\n terms = FINANCIAL_GLOSSARY,\n onTermClick,\n learnMoreText = \"Click to learn more\",\n}: GlossaryProviderProps) {\n const value = useMemo<GlossaryContextValue>(\n () => ({\n enabled,\n terms,\n onTermClick,\n learnMoreText,\n }),\n [enabled, terms, onTermClick, learnMoreText],\n );\n\n return <GlossaryContext.Provider value={value}>{children}</GlossaryContext.Provider>;\n}\n\nexport function useGlossaryContext(): GlossaryContextValue | null {\n return useContext(GlossaryContext);\n}\n\n/**\n * Marks a section where automatic glossary parsing is enabled.\n *\n * Each `<Text>` block deduplicates its own terms to avoid repetitive visual noise\n * within a paragraph. The scope intentionally does not coordinate ownership across\n * components, which keeps glossary output stable across updates and unmounts.\n */\nexport interface GlossaryScopeContextValue {\n active: true;\n}\n\nconst GlossaryScopeContext = createContext<GlossaryScopeContextValue | null>(null);\n\nexport interface GlossaryScopeProps {\n children: ReactNode;\n}\n\nexport function GlossaryScope({ children }: GlossaryScopeProps) {\n return (\n <GlossaryScopeContext.Provider value={{ active: true }}>\n {children}\n </GlossaryScopeContext.Provider>\n );\n}\n\nexport function useGlossaryScope(): GlossaryScopeContextValue | null {\n return useContext(GlossaryScopeContext);\n}\n"],"names":["createContext","FINANCIAL_GLOSSARY","useMemo","jsx","useContext"],"mappings":";;;;;AAyCA,MAAM,kBAAkBA,MAAAA,cAA2C,IAAI;AAEhE,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,UAAU;AAAA,EACV,QAAQC,SAAAA;AAAAA,EACR;AAAA,EACA,gBAAgB;AAClB,GAA0B;AACxB,QAAM,QAAQC,MAAAA;AAAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,SAAS,OAAO,aAAa,aAAa;AAAA,EAAA;AAG7C,SAAOC,2BAAAA,IAAC,gBAAgB,UAAhB,EAAyB,OAAe,SAAA,CAAS;AAC3D;AAEO,SAAS,qBAAkD;AAChE,SAAOC,MAAAA,WAAW,eAAe;AACnC;AAaA,MAAM,uBAAuBJ,MAAAA,cAAgD,IAAI;AAM1E,SAAS,cAAc,EAAE,YAAgC;AAC9D,SACEG,2BAAAA,IAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,QAAQ,QAC7C,UACH;AAEJ;AAEO,SAAS,mBAAqD;AACnE,SAAOC,MAAAA,WAAW,oBAAoB;AACxC;;;;;"}
@@ -0,0 +1,49 @@
1
+ import { ReactNode } from 'react';
2
+ import { GlossaryTerm, GlossaryTermData, GlossaryTermDefinition } from '../../../constants/glossary';
3
+ export type { GlossaryTermData, GlossaryTermDefinition };
4
+ export interface GlossaryContextValue {
5
+ /** Whether glossary term matching and linkification is enabled. @default true */
6
+ enabled: boolean;
7
+ /** Active dictionary of terms to match against. Defaults to FINANCIAL_GLOSSARY. */
8
+ terms: readonly GlossaryTerm[];
9
+ /**
10
+ * Optional click handler called when an interactive glossary term is activated.
11
+ * If provided, terms render with interactive click affordances (e.g. opens Cap Table AI).
12
+ * If omitted, terms render as definition-only glossary items with informative tooltips.
13
+ */
14
+ onTermClick?: (term: GlossaryTerm) => void;
15
+ /**
16
+ * Optional call-to-action text displayed in the tooltip footer when `onTermClick` is defined.
17
+ * @default "Click to learn more"
18
+ */
19
+ learnMoreText?: string;
20
+ }
21
+ export interface GlossaryProviderProps {
22
+ children: ReactNode;
23
+ /** Whether glossary term matching is active. Defaults to true. */
24
+ enabled?: boolean;
25
+ /** Custom dictionary of terms to replace the standard financial glossary. */
26
+ terms?: readonly GlossaryTerm[];
27
+ /** Callback fired when a user clicks/taps an interactive glossary term. */
28
+ onTermClick?: (term: GlossaryTerm) => void;
29
+ /** Custom tooltip action label (e.g. "Click to learn more with Cap Table AI"). */
30
+ learnMoreText?: string;
31
+ }
32
+ export declare function GlossaryProvider({ children, enabled, terms, onTermClick, learnMoreText, }: GlossaryProviderProps): import("react").JSX.Element;
33
+ export declare function useGlossaryContext(): GlossaryContextValue | null;
34
+ /**
35
+ * Marks a section where automatic glossary parsing is enabled.
36
+ *
37
+ * Each `<Text>` block deduplicates its own terms to avoid repetitive visual noise
38
+ * within a paragraph. The scope intentionally does not coordinate ownership across
39
+ * components, which keeps glossary output stable across updates and unmounts.
40
+ */
41
+ export interface GlossaryScopeContextValue {
42
+ active: true;
43
+ }
44
+ export interface GlossaryScopeProps {
45
+ children: ReactNode;
46
+ }
47
+ export declare function GlossaryScope({ children }: GlossaryScopeProps): import("react").JSX.Element;
48
+ export declare function useGlossaryScope(): GlossaryScopeContextValue | null;
49
+ //# sourceMappingURL=GlossaryContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryContext.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Glossary/GlossaryContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC5B,MAAM,6BAA6B,CAAC;AAErC,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,CAAC;IACpB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,OAAc,EACd,KAA0B,EAC1B,WAAW,EACX,aAAqC,GACtC,EAAE,qBAAqB,+BAYvB;AAED,wBAAgB,kBAAkB,IAAI,oBAAoB,GAAG,IAAI,CAEhE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,IAAI,CAAC;CACd;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,+BAM7D;AAED,wBAAgB,gBAAgB,IAAI,yBAAyB,GAAG,IAAI,CAEnE"}
@@ -0,0 +1,39 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo, useContext, createContext } from "react";
3
+ import { FINANCIAL_GLOSSARY } from "../../../constants/glossary.js";
4
+ const GlossaryContext = createContext(null);
5
+ function GlossaryProvider({
6
+ children,
7
+ enabled = true,
8
+ terms = FINANCIAL_GLOSSARY,
9
+ onTermClick,
10
+ learnMoreText = "Click to learn more"
11
+ }) {
12
+ const value = useMemo(
13
+ () => ({
14
+ enabled,
15
+ terms,
16
+ onTermClick,
17
+ learnMoreText
18
+ }),
19
+ [enabled, terms, onTermClick, learnMoreText]
20
+ );
21
+ return /* @__PURE__ */ jsx(GlossaryContext.Provider, { value, children });
22
+ }
23
+ function useGlossaryContext() {
24
+ return useContext(GlossaryContext);
25
+ }
26
+ const GlossaryScopeContext = createContext(null);
27
+ function GlossaryScope({ children }) {
28
+ return /* @__PURE__ */ jsx(GlossaryScopeContext.Provider, { value: { active: true }, children });
29
+ }
30
+ function useGlossaryScope() {
31
+ return useContext(GlossaryScopeContext);
32
+ }
33
+ export {
34
+ GlossaryProvider,
35
+ GlossaryScope,
36
+ useGlossaryContext,
37
+ useGlossaryScope
38
+ };
39
+ //# sourceMappingURL=GlossaryContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryContext.js","sources":["../../../../src/components/primitives/Glossary/GlossaryContext.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\nimport {\n FINANCIAL_GLOSSARY,\n type GlossaryTerm,\n type GlossaryTermData,\n type GlossaryTermDefinition,\n} from \"../../../constants/glossary\";\n\nexport type { GlossaryTermData, GlossaryTermDefinition };\n\nexport interface GlossaryContextValue {\n /** Whether glossary term matching and linkification is enabled. @default true */\n enabled: boolean;\n /** Active dictionary of terms to match against. Defaults to FINANCIAL_GLOSSARY. */\n terms: readonly GlossaryTerm[];\n /**\n * Optional click handler called when an interactive glossary term is activated.\n * If provided, terms render with interactive click affordances (e.g. opens Cap Table AI).\n * If omitted, terms render as definition-only glossary items with informative tooltips.\n */\n onTermClick?: (term: GlossaryTerm) => void;\n /**\n * Optional call-to-action text displayed in the tooltip footer when `onTermClick` is defined.\n * @default \"Click to learn more\"\n */\n learnMoreText?: string;\n}\n\nexport interface GlossaryProviderProps {\n children: ReactNode;\n /** Whether glossary term matching is active. Defaults to true. */\n enabled?: boolean;\n /** Custom dictionary of terms to replace the standard financial glossary. */\n terms?: readonly GlossaryTerm[];\n /** Callback fired when a user clicks/taps an interactive glossary term. */\n onTermClick?: (term: GlossaryTerm) => void;\n /** Custom tooltip action label (e.g. \"Click to learn more with Cap Table AI\"). */\n learnMoreText?: string;\n}\n\nconst GlossaryContext = createContext<GlossaryContextValue | null>(null);\n\nexport function GlossaryProvider({\n children,\n enabled = true,\n terms = FINANCIAL_GLOSSARY,\n onTermClick,\n learnMoreText = \"Click to learn more\",\n}: GlossaryProviderProps) {\n const value = useMemo<GlossaryContextValue>(\n () => ({\n enabled,\n terms,\n onTermClick,\n learnMoreText,\n }),\n [enabled, terms, onTermClick, learnMoreText],\n );\n\n return <GlossaryContext.Provider value={value}>{children}</GlossaryContext.Provider>;\n}\n\nexport function useGlossaryContext(): GlossaryContextValue | null {\n return useContext(GlossaryContext);\n}\n\n/**\n * Marks a section where automatic glossary parsing is enabled.\n *\n * Each `<Text>` block deduplicates its own terms to avoid repetitive visual noise\n * within a paragraph. The scope intentionally does not coordinate ownership across\n * components, which keeps glossary output stable across updates and unmounts.\n */\nexport interface GlossaryScopeContextValue {\n active: true;\n}\n\nconst GlossaryScopeContext = createContext<GlossaryScopeContextValue | null>(null);\n\nexport interface GlossaryScopeProps {\n children: ReactNode;\n}\n\nexport function GlossaryScope({ children }: GlossaryScopeProps) {\n return (\n <GlossaryScopeContext.Provider value={{ active: true }}>\n {children}\n </GlossaryScopeContext.Provider>\n );\n}\n\nexport function useGlossaryScope(): GlossaryScopeContextValue | null {\n return useContext(GlossaryScopeContext);\n}\n"],"names":[],"mappings":";;;AAyCA,MAAM,kBAAkB,cAA2C,IAAI;AAEhE,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,UAAU;AAAA,EACV,QAAQ;AAAA,EACR;AAAA,EACA,gBAAgB;AAClB,GAA0B;AACxB,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,SAAS,OAAO,aAAa,aAAa;AAAA,EAAA;AAG7C,SAAO,oBAAC,gBAAgB,UAAhB,EAAyB,OAAe,SAAA,CAAS;AAC3D;AAEO,SAAS,qBAAkD;AAChE,SAAO,WAAW,eAAe;AACnC;AAaA,MAAM,uBAAuB,cAAgD,IAAI;AAM1E,SAAS,cAAc,EAAE,YAAgC;AAC9D,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,QAAQ,QAC7C,UACH;AAEJ;AAEO,SAAS,mBAAqD;AACnE,SAAO,WAAW,oBAAoB;AACxC;"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const useIsMobile = require("../../../hooks/useIsMobile.cjs");
6
+ const Popover = require("../Popover/Popover.cjs");
7
+ const Tooltip = require("../Tooltip/Tooltip.cjs");
8
+ const GlossaryContext = require("./GlossaryContext.cjs");
9
+ const UnstyledButton = require("../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.cjs");
10
+ function GlossaryTerm({ term, children }) {
11
+ const glossary = GlossaryContext.useGlossaryContext();
12
+ const isMobile = useIsMobile.useIsMobile();
13
+ const onTermClick = glossary?.onTermClick;
14
+ const learnMoreText = glossary?.learnMoreText ?? "Click to learn more";
15
+ const [mobileOpened, setMobileOpened] = React.useState(false);
16
+ const handleAction = React.useCallback(() => {
17
+ if (!onTermClick) return;
18
+ setMobileOpened(false);
19
+ onTermClick(term);
20
+ }, [onTermClick, term]);
21
+ const handleClick = (e) => {
22
+ e.stopPropagation();
23
+ if (isMobile) {
24
+ setMobileOpened((prev) => !prev);
25
+ return;
26
+ }
27
+ if (onTermClick) {
28
+ e.preventDefault();
29
+ handleAction();
30
+ }
31
+ };
32
+ const handleKeyDown = (e) => {
33
+ if (isMobile) {
34
+ if (e.key === "Enter" || e.key === " ") {
35
+ e.preventDefault();
36
+ e.stopPropagation();
37
+ setMobileOpened((prev) => !prev);
38
+ }
39
+ return;
40
+ }
41
+ if ((e.key === "Enter" || e.key === " ") && onTermClick) {
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ handleAction();
45
+ }
46
+ };
47
+ const termStyle = {
48
+ display: "inline",
49
+ padding: 0,
50
+ border: 0,
51
+ background: "transparent",
52
+ color: "inherit",
53
+ font: "inherit",
54
+ textDecoration: "underline dotted",
55
+ textDecorationColor: "color-mix(in srgb, currentColor 55%, transparent)",
56
+ textDecorationThickness: "1px",
57
+ textUnderlineOffset: "3px",
58
+ cursor: onTermClick ? isMobile ? "help" : "pointer" : "help"
59
+ };
60
+ const tooltipContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: term.explanation }),
62
+ onTermClick && (isMobile ? /* @__PURE__ */ jsxRuntime.jsxs(
63
+ "button",
64
+ {
65
+ onClick: (e) => {
66
+ e.stopPropagation();
67
+ handleAction();
68
+ },
69
+ style: {
70
+ background: "transparent",
71
+ border: 0,
72
+ padding: 0,
73
+ color: "inherit",
74
+ font: "inherit",
75
+ fontSize: "11px",
76
+ opacity: 0.85,
77
+ fontWeight: 500,
78
+ cursor: "pointer",
79
+ textAlign: "left",
80
+ textDecoration: "underline"
81
+ },
82
+ type: "button",
83
+ children: [
84
+ learnMoreText,
85
+ " →"
86
+ ]
87
+ }
88
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", opacity: 0.85, fontWeight: 500 }, children: learnMoreText }))
89
+ ] });
90
+ if (isMobile) {
91
+ return (
92
+ // The wrapper stops the completed Popover click from reaching parent cards
93
+ // without blocking Popover.Target's own toggle handler.
94
+ // biome-ignore lint/a11y/noStaticElementInteractions: propagation boundary around an interactive Popover
95
+ // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard activation does not bubble as a parent click
96
+ /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(
97
+ Popover.Popover,
98
+ {
99
+ onChange: setMobileOpened,
100
+ onClose: () => setMobileOpened(false),
101
+ opened: mobileOpened,
102
+ position: "top",
103
+ shadow: "md",
104
+ transitionProps: { duration: 0, exitDuration: 0 },
105
+ withArrow: true,
106
+ width: 260,
107
+ children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Popover.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(
109
+ UnstyledButton.UnstyledButton,
110
+ {
111
+ onClick: handleClick,
112
+ onKeyDown: handleKeyDown,
113
+ style: termStyle,
114
+ type: "button",
115
+ children
116
+ }
117
+ ) }),
118
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Popover.Dropdown, { style: mobileOpened ? { display: "block" } : void 0, children: tooltipContent })
119
+ ]
120
+ }
121
+ ) })
122
+ );
123
+ }
124
+ return /* @__PURE__ */ jsxRuntime.jsx(
125
+ Tooltip.Tooltip,
126
+ {
127
+ events: { focus: true, hover: true, touch: true },
128
+ label: tooltipContent,
129
+ multiline: true,
130
+ styles: onTermClick ? { tooltip: { pointerEvents: "auto" } } : void 0,
131
+ w: 260,
132
+ withArrow: true,
133
+ children: /* @__PURE__ */ jsxRuntime.jsx(
134
+ UnstyledButton.UnstyledButton,
135
+ {
136
+ onClick: handleClick,
137
+ onKeyDown: handleKeyDown,
138
+ style: termStyle,
139
+ type: "button",
140
+ children
141
+ }
142
+ )
143
+ }
144
+ );
145
+ }
146
+ exports.GlossaryTerm = GlossaryTerm;
147
+ //# sourceMappingURL=GlossaryTerm.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryTerm.cjs","sources":["../../../../src/components/primitives/Glossary/GlossaryTerm.tsx"],"sourcesContent":["import type { CSSProperties, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport type { GlossaryTerm as GlossaryTermData } from \"../../../constants/glossary\";\nimport { useIsMobile } from \"../../../hooks/useIsMobile\";\nimport { UnstyledButton } from \"../layout\";\nimport { Popover } from \"../Popover/Popover\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\nimport { useGlossaryContext } from \"./GlossaryContext\";\n\nexport interface GlossaryTermProps {\n /** The glossary term data. */\n term: GlossaryTermData;\n /** The text displayed in the copy (matches source text casing). */\n children: ReactNode;\n}\n\nexport function GlossaryTerm({ term, children }: GlossaryTermProps) {\n const glossary = useGlossaryContext();\n const isMobile = useIsMobile();\n const onTermClick = glossary?.onTermClick;\n const learnMoreText = glossary?.learnMoreText ?? \"Click to learn more\";\n\n const [mobileOpened, setMobileOpened] = useState(false);\n\n const handleAction = useCallback(() => {\n if (!onTermClick) return;\n setMobileOpened(false);\n onTermClick(term);\n }, [onTermClick, term]);\n\n const handleClick = (e: MouseEvent) => {\n e.stopPropagation();\n if (isMobile) {\n setMobileOpened((prev) => !prev);\n return;\n }\n\n if (onTermClick) {\n e.preventDefault();\n handleAction();\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (isMobile) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n setMobileOpened((prev) => !prev);\n }\n return;\n }\n\n if ((e.key === \"Enter\" || e.key === \" \") && onTermClick) {\n e.preventDefault();\n e.stopPropagation();\n handleAction();\n }\n };\n\n const termStyle: CSSProperties = {\n display: \"inline\",\n padding: 0,\n border: 0,\n background: \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n textDecoration: \"underline dotted\",\n textDecorationColor: \"color-mix(in srgb, currentColor 55%, transparent)\",\n textDecorationThickness: \"1px\",\n textUnderlineOffset: \"3px\",\n cursor: onTermClick ? (isMobile ? \"help\" : \"pointer\") : \"help\",\n };\n\n const tooltipContent = (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <span>{term.explanation}</span>\n {onTermClick &&\n (isMobile ? (\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleAction();\n }}\n style={{\n background: \"transparent\",\n border: 0,\n padding: 0,\n color: \"inherit\",\n font: \"inherit\",\n fontSize: \"11px\",\n opacity: 0.85,\n fontWeight: 500,\n cursor: \"pointer\",\n textAlign: \"left\",\n textDecoration: \"underline\",\n }}\n type=\"button\"\n >\n {learnMoreText} →\n </button>\n ) : (\n <span style={{ fontSize: \"11px\", opacity: 0.85, fontWeight: 500 }}>{learnMoreText}</span>\n ))}\n </div>\n );\n\n if (isMobile) {\n return (\n // The wrapper stops the completed Popover click from reaching parent cards\n // without blocking Popover.Target's own toggle handler.\n // biome-ignore lint/a11y/noStaticElementInteractions: propagation boundary around an interactive Popover\n // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard activation does not bubble as a parent click\n <span onClick={(event) => event.stopPropagation()}>\n <Popover\n onChange={setMobileOpened}\n onClose={() => setMobileOpened(false)}\n opened={mobileOpened}\n position=\"top\"\n shadow=\"md\"\n transitionProps={{ duration: 0, exitDuration: 0 }}\n withArrow\n width={260}\n >\n <Popover.Target>\n <UnstyledButton\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={termStyle}\n type=\"button\"\n >\n {children}\n </UnstyledButton>\n </Popover.Target>\n <Popover.Dropdown style={mobileOpened ? { display: \"block\" } : undefined}>\n {tooltipContent}\n </Popover.Dropdown>\n </Popover>\n </span>\n );\n }\n\n return (\n <Tooltip\n events={{ focus: true, hover: true, touch: true } as const}\n label={tooltipContent}\n multiline\n styles={onTermClick ? { tooltip: { pointerEvents: \"auto\" } } : undefined}\n w={260}\n withArrow\n >\n <UnstyledButton\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={termStyle}\n type=\"button\"\n >\n {children}\n </UnstyledButton>\n </Tooltip>\n );\n}\n"],"names":["useGlossaryContext","useIsMobile","useState","useCallback","jsxs","jsx","Popover","UnstyledButton","Tooltip"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { ReactNode } from 'react';
2
+ import { GlossaryTerm as GlossaryTermData } from '../../../constants/glossary';
3
+ export interface GlossaryTermProps {
4
+ /** The glossary term data. */
5
+ term: GlossaryTermData;
6
+ /** The text displayed in the copy (matches source text casing). */
7
+ children: ReactNode;
8
+ }
9
+ export declare function GlossaryTerm({ term, children }: GlossaryTermProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=GlossaryTerm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryTerm.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Glossary/GlossaryTerm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4C,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjF,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAOpF,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,IAAI,EAAE,gBAAgB,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BAiJjE"}
@@ -0,0 +1,147 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useCallback } from "react";
3
+ import { useIsMobile } from "../../../hooks/useIsMobile.js";
4
+ import { Popover } from "../Popover/Popover.js";
5
+ import { Tooltip } from "../Tooltip/Tooltip.js";
6
+ import { useGlossaryContext } from "./GlossaryContext.js";
7
+ import { UnstyledButton } from "../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.js";
8
+ function GlossaryTerm({ term, children }) {
9
+ const glossary = useGlossaryContext();
10
+ const isMobile = useIsMobile();
11
+ const onTermClick = glossary?.onTermClick;
12
+ const learnMoreText = glossary?.learnMoreText ?? "Click to learn more";
13
+ const [mobileOpened, setMobileOpened] = useState(false);
14
+ const handleAction = useCallback(() => {
15
+ if (!onTermClick) return;
16
+ setMobileOpened(false);
17
+ onTermClick(term);
18
+ }, [onTermClick, term]);
19
+ const handleClick = (e) => {
20
+ e.stopPropagation();
21
+ if (isMobile) {
22
+ setMobileOpened((prev) => !prev);
23
+ return;
24
+ }
25
+ if (onTermClick) {
26
+ e.preventDefault();
27
+ handleAction();
28
+ }
29
+ };
30
+ const handleKeyDown = (e) => {
31
+ if (isMobile) {
32
+ if (e.key === "Enter" || e.key === " ") {
33
+ e.preventDefault();
34
+ e.stopPropagation();
35
+ setMobileOpened((prev) => !prev);
36
+ }
37
+ return;
38
+ }
39
+ if ((e.key === "Enter" || e.key === " ") && onTermClick) {
40
+ e.preventDefault();
41
+ e.stopPropagation();
42
+ handleAction();
43
+ }
44
+ };
45
+ const termStyle = {
46
+ display: "inline",
47
+ padding: 0,
48
+ border: 0,
49
+ background: "transparent",
50
+ color: "inherit",
51
+ font: "inherit",
52
+ textDecoration: "underline dotted",
53
+ textDecorationColor: "color-mix(in srgb, currentColor 55%, transparent)",
54
+ textDecorationThickness: "1px",
55
+ textUnderlineOffset: "3px",
56
+ cursor: onTermClick ? isMobile ? "help" : "pointer" : "help"
57
+ };
58
+ const tooltipContent = /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
59
+ /* @__PURE__ */ jsx("span", { children: term.explanation }),
60
+ onTermClick && (isMobile ? /* @__PURE__ */ jsxs(
61
+ "button",
62
+ {
63
+ onClick: (e) => {
64
+ e.stopPropagation();
65
+ handleAction();
66
+ },
67
+ style: {
68
+ background: "transparent",
69
+ border: 0,
70
+ padding: 0,
71
+ color: "inherit",
72
+ font: "inherit",
73
+ fontSize: "11px",
74
+ opacity: 0.85,
75
+ fontWeight: 500,
76
+ cursor: "pointer",
77
+ textAlign: "left",
78
+ textDecoration: "underline"
79
+ },
80
+ type: "button",
81
+ children: [
82
+ learnMoreText,
83
+ " →"
84
+ ]
85
+ }
86
+ ) : /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", opacity: 0.85, fontWeight: 500 }, children: learnMoreText }))
87
+ ] });
88
+ if (isMobile) {
89
+ return (
90
+ // The wrapper stops the completed Popover click from reaching parent cards
91
+ // without blocking Popover.Target's own toggle handler.
92
+ // biome-ignore lint/a11y/noStaticElementInteractions: propagation boundary around an interactive Popover
93
+ // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard activation does not bubble as a parent click
94
+ /* @__PURE__ */ jsx("span", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxs(
95
+ Popover,
96
+ {
97
+ onChange: setMobileOpened,
98
+ onClose: () => setMobileOpened(false),
99
+ opened: mobileOpened,
100
+ position: "top",
101
+ shadow: "md",
102
+ transitionProps: { duration: 0, exitDuration: 0 },
103
+ withArrow: true,
104
+ width: 260,
105
+ children: [
106
+ /* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(
107
+ UnstyledButton,
108
+ {
109
+ onClick: handleClick,
110
+ onKeyDown: handleKeyDown,
111
+ style: termStyle,
112
+ type: "button",
113
+ children
114
+ }
115
+ ) }),
116
+ /* @__PURE__ */ jsx(Popover.Dropdown, { style: mobileOpened ? { display: "block" } : void 0, children: tooltipContent })
117
+ ]
118
+ }
119
+ ) })
120
+ );
121
+ }
122
+ return /* @__PURE__ */ jsx(
123
+ Tooltip,
124
+ {
125
+ events: { focus: true, hover: true, touch: true },
126
+ label: tooltipContent,
127
+ multiline: true,
128
+ styles: onTermClick ? { tooltip: { pointerEvents: "auto" } } : void 0,
129
+ w: 260,
130
+ withArrow: true,
131
+ children: /* @__PURE__ */ jsx(
132
+ UnstyledButton,
133
+ {
134
+ onClick: handleClick,
135
+ onKeyDown: handleKeyDown,
136
+ style: termStyle,
137
+ type: "button",
138
+ children
139
+ }
140
+ )
141
+ }
142
+ );
143
+ }
144
+ export {
145
+ GlossaryTerm
146
+ };
147
+ //# sourceMappingURL=GlossaryTerm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlossaryTerm.js","sources":["../../../../src/components/primitives/Glossary/GlossaryTerm.tsx"],"sourcesContent":["import type { CSSProperties, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport type { GlossaryTerm as GlossaryTermData } from \"../../../constants/glossary\";\nimport { useIsMobile } from \"../../../hooks/useIsMobile\";\nimport { UnstyledButton } from \"../layout\";\nimport { Popover } from \"../Popover/Popover\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\nimport { useGlossaryContext } from \"./GlossaryContext\";\n\nexport interface GlossaryTermProps {\n /** The glossary term data. */\n term: GlossaryTermData;\n /** The text displayed in the copy (matches source text casing). */\n children: ReactNode;\n}\n\nexport function GlossaryTerm({ term, children }: GlossaryTermProps) {\n const glossary = useGlossaryContext();\n const isMobile = useIsMobile();\n const onTermClick = glossary?.onTermClick;\n const learnMoreText = glossary?.learnMoreText ?? \"Click to learn more\";\n\n const [mobileOpened, setMobileOpened] = useState(false);\n\n const handleAction = useCallback(() => {\n if (!onTermClick) return;\n setMobileOpened(false);\n onTermClick(term);\n }, [onTermClick, term]);\n\n const handleClick = (e: MouseEvent) => {\n e.stopPropagation();\n if (isMobile) {\n setMobileOpened((prev) => !prev);\n return;\n }\n\n if (onTermClick) {\n e.preventDefault();\n handleAction();\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (isMobile) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n setMobileOpened((prev) => !prev);\n }\n return;\n }\n\n if ((e.key === \"Enter\" || e.key === \" \") && onTermClick) {\n e.preventDefault();\n e.stopPropagation();\n handleAction();\n }\n };\n\n const termStyle: CSSProperties = {\n display: \"inline\",\n padding: 0,\n border: 0,\n background: \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n textDecoration: \"underline dotted\",\n textDecorationColor: \"color-mix(in srgb, currentColor 55%, transparent)\",\n textDecorationThickness: \"1px\",\n textUnderlineOffset: \"3px\",\n cursor: onTermClick ? (isMobile ? \"help\" : \"pointer\") : \"help\",\n };\n\n const tooltipContent = (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <span>{term.explanation}</span>\n {onTermClick &&\n (isMobile ? (\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleAction();\n }}\n style={{\n background: \"transparent\",\n border: 0,\n padding: 0,\n color: \"inherit\",\n font: \"inherit\",\n fontSize: \"11px\",\n opacity: 0.85,\n fontWeight: 500,\n cursor: \"pointer\",\n textAlign: \"left\",\n textDecoration: \"underline\",\n }}\n type=\"button\"\n >\n {learnMoreText} →\n </button>\n ) : (\n <span style={{ fontSize: \"11px\", opacity: 0.85, fontWeight: 500 }}>{learnMoreText}</span>\n ))}\n </div>\n );\n\n if (isMobile) {\n return (\n // The wrapper stops the completed Popover click from reaching parent cards\n // without blocking Popover.Target's own toggle handler.\n // biome-ignore lint/a11y/noStaticElementInteractions: propagation boundary around an interactive Popover\n // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard activation does not bubble as a parent click\n <span onClick={(event) => event.stopPropagation()}>\n <Popover\n onChange={setMobileOpened}\n onClose={() => setMobileOpened(false)}\n opened={mobileOpened}\n position=\"top\"\n shadow=\"md\"\n transitionProps={{ duration: 0, exitDuration: 0 }}\n withArrow\n width={260}\n >\n <Popover.Target>\n <UnstyledButton\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={termStyle}\n type=\"button\"\n >\n {children}\n </UnstyledButton>\n </Popover.Target>\n <Popover.Dropdown style={mobileOpened ? { display: \"block\" } : undefined}>\n {tooltipContent}\n </Popover.Dropdown>\n </Popover>\n </span>\n );\n }\n\n return (\n <Tooltip\n events={{ focus: true, hover: true, touch: true } as const}\n label={tooltipContent}\n multiline\n styles={onTermClick ? { tooltip: { pointerEvents: \"auto\" } } : undefined}\n w={260}\n withArrow\n >\n <UnstyledButton\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n style={termStyle}\n type=\"button\"\n >\n {children}\n </UnstyledButton>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { type GlossaryContextValue, GlossaryProvider, type GlossaryProviderProps, GlossaryScope, type GlossaryScopeContextValue, type GlossaryScopeProps, type GlossaryTermData, type GlossaryTermDefinition, useGlossaryContext, useGlossaryScope, } from './GlossaryContext';
2
+ export { GlossaryTerm, type GlossaryTermProps } from './GlossaryTerm';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Glossary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,aAAa,EACb,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const glossaryMatcher = require("../../../utils/glossaryMatcher.cjs");
6
+ const GlossaryContext = require("../Glossary/GlossaryContext.cjs");
7
+ const GlossaryTerm = require("../Glossary/GlossaryTerm.cjs");
8
+ const createPolymorphicComponent = require("../../../node_modules/@mantine/core/esm/core/factory/create-polymorphic-component.cjs");
9
+ const Text$1 = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
10
+ const SKIP_CHILD_ELEMENTS = /^(a|button|input|select|textarea|code|pre|svg)$/i;
11
+ const _Text = React.forwardRef(
12
+ ({ children, glossary = true, ...props }, ref) => {
13
+ const glossaryContext = GlossaryContext.useGlossaryContext();
14
+ const glossaryScope = GlossaryContext.useGlossaryScope();
15
+ const component = "component" in props ? props.component : void 0;
16
+ const href = "href" in props ? props.href : void 0;
17
+ const to = "to" in props ? props.to : void 0;
18
+ const onClick = "onClick" in props ? props.onClick : void 0;
19
+ const role = "role" in props ? props.role : void 0;
20
+ const isInteractive = component === "a" || component === "button" || component !== void 0 && typeof component !== "string" || Boolean(href) || Boolean(to) || typeof onClick === "function" || role === "button";
21
+ const isGlossaryActive = glossary !== false && !isInteractive && Boolean(glossaryContext?.enabled) && Boolean(glossaryScope) && Boolean(glossaryContext?.terms?.length);
22
+ if (!isGlossaryActive || !glossaryContext || !glossaryScope) {
23
+ return /* @__PURE__ */ jsxRuntime.jsx(Text$1.Text, { ref, ...props, children });
24
+ }
25
+ const emittedInPass = /* @__PURE__ */ new Set();
26
+ const transformedChildren = transformChildren(children, glossaryContext.terms, emittedInPass);
27
+ return /* @__PURE__ */ jsxRuntime.jsx(Text$1.Text, { ref, ...props, children: transformedChildren });
28
+ }
29
+ );
30
+ _Text.displayName = "Text";
31
+ const Text = createPolymorphicComponent.createPolymorphicComponent(_Text);
32
+ function transformChildren(node, terms, emittedInPass) {
33
+ if (typeof node === "string") {
34
+ return linkifyString(node, terms, emittedInPass);
35
+ }
36
+ if (Array.isArray(node)) {
37
+ return transformArray(node, terms, emittedInPass);
38
+ }
39
+ if (React.isValidElement(node)) {
40
+ if (node.type !== React.Fragment && typeof node.type !== "string") {
41
+ return node;
42
+ }
43
+ if (typeof node.type === "string" && SKIP_CHILD_ELEMENTS.test(node.type)) {
44
+ return node;
45
+ }
46
+ if (hasChildren(node.props)) {
47
+ if ("onClick" in node.props || "role" in node.props && node.props.role === "button") {
48
+ return node;
49
+ }
50
+ return React.cloneElement(
51
+ node,
52
+ void 0,
53
+ transformChildren(node.props.children, terms, emittedInPass)
54
+ );
55
+ }
56
+ }
57
+ return node;
58
+ }
59
+ function transformArray(children, terms, emittedInPass) {
60
+ const result = [];
61
+ let textBuffer = [];
62
+ const flushTextBuffer = () => {
63
+ if (textBuffer.length === 0) return;
64
+ const combined = textBuffer.join("");
65
+ textBuffer = [];
66
+ if (combined.length === 0) return;
67
+ result.push(linkifyString(combined, terms, emittedInPass));
68
+ };
69
+ for (let i = 0; i < children.length; i++) {
70
+ const child = children[i];
71
+ if (typeof child === "string" || typeof child === "number") {
72
+ textBuffer.push(String(child));
73
+ } else {
74
+ flushTextBuffer();
75
+ result.push(transformChildren(child, terms, emittedInPass));
76
+ }
77
+ }
78
+ flushTextBuffer();
79
+ return result.length === children.length ? result : result;
80
+ }
81
+ function linkifyString(text, terms, emittedInPass) {
82
+ const matches = glossaryMatcher.matchGlossaryTerms(text, terms, emittedInPass);
83
+ if (matches.length === 0) return text;
84
+ const parts = [];
85
+ let cursor = 0;
86
+ let keyIndex = 0;
87
+ for (const match of matches) {
88
+ if (match.start < cursor) continue;
89
+ emittedInPass.add(match.termId);
90
+ if (match.start > cursor) {
91
+ parts.push(text.slice(cursor, match.start));
92
+ }
93
+ const termData = terms.find((t) => t.id === match.termId);
94
+ if (termData) {
95
+ parts.push(
96
+ /* @__PURE__ */ jsxRuntime.jsx(GlossaryTerm.GlossaryTerm, { term: termData, children: match.text }, `glossary-${match.termId}-${keyIndex++}`)
97
+ );
98
+ } else {
99
+ parts.push(match.text);
100
+ }
101
+ cursor = match.end;
102
+ }
103
+ if (cursor < text.length) {
104
+ parts.push(text.slice(cursor));
105
+ }
106
+ return parts.length === 1 ? parts[0] : parts;
107
+ }
108
+ function hasChildren(value) {
109
+ return typeof value === "object" && value !== null && "children" in value;
110
+ }
111
+ exports.Text = Text;
112
+ //# sourceMappingURL=Text.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Text.cjs","sources":["../../../../src/components/primitives/Text/Text.tsx"],"sourcesContent":["import {\n createPolymorphicComponent,\n Text as MantineText,\n type TextProps as MantineTextProps,\n} from \"@mantine/core\";\nimport { cloneElement, Fragment, forwardRef, isValidElement, type ReactNode } from \"react\";\nimport type { GlossaryTerm as GlossaryTermData } from \"../../../constants/glossary\";\nimport { matchGlossaryTerms } from \"../../../utils/glossaryMatcher\";\nimport { useGlossaryContext, useGlossaryScope } from \"../Glossary/GlossaryContext\";\nimport { GlossaryTerm } from \"../Glossary/GlossaryTerm\";\n\nexport interface TextProps extends MantineTextProps {\n children?: ReactNode;\n /**\n * Whether to automatically linkify financial glossary terms in this text block.\n * Defaults to `true` when wrapped inside an active `<GlossaryScope>`.\n * Set to `false` to explicitly disable glossary matching (e.g. for dynamic data, tables, user inputs).\n * @default true\n */\n glossary?: boolean;\n}\n\nconst SKIP_CHILD_ELEMENTS = /^(a|button|input|select|textarea|code|pre|svg)$/i;\n\nconst _Text = forwardRef<HTMLParagraphElement, TextProps>(\n ({ children, glossary = true, ...props }, ref) => {\n const glossaryContext = useGlossaryContext();\n const glossaryScope = useGlossaryScope();\n\n // Do not linkify if the Text element itself is interactive (component, href, to, onClick, role)\n const component = \"component\" in props ? props.component : undefined;\n const href = \"href\" in props ? props.href : undefined;\n const to = \"to\" in props ? props.to : undefined;\n const onClick = \"onClick\" in props ? props.onClick : undefined;\n const role = \"role\" in props ? props.role : undefined;\n const isInteractive =\n component === \"a\" ||\n component === \"button\" ||\n (component !== undefined && typeof component !== \"string\") ||\n Boolean(href) ||\n Boolean(to) ||\n typeof onClick === \"function\" ||\n role === \"button\";\n\n const isGlossaryActive =\n glossary !== false &&\n !isInteractive &&\n Boolean(glossaryContext?.enabled) &&\n Boolean(glossaryScope) &&\n Boolean(glossaryContext?.terms?.length);\n\n if (!isGlossaryActive || !glossaryContext || !glossaryScope) {\n return (\n <MantineText ref={ref} {...props}>\n {children}\n </MantineText>\n );\n }\n\n const emittedInPass = new Set<string>();\n const transformedChildren = transformChildren(children, glossaryContext.terms, emittedInPass);\n\n return (\n <MantineText ref={ref} {...props}>\n {transformedChildren}\n </MantineText>\n );\n },\n);\n\n_Text.displayName = \"Text\";\n\nexport const Text = createPolymorphicComponent<\"p\", TextProps>(_Text);\n\nfunction transformChildren(\n node: ReactNode,\n terms: readonly GlossaryTermData[],\n emittedInPass: Set<string>,\n): ReactNode {\n if (typeof node === \"string\") {\n return linkifyString(node, terms, emittedInPass);\n }\n\n if (Array.isArray(node)) {\n return transformArray(node, terms, emittedInPass);\n }\n\n if (isValidElement(node)) {\n if (node.type !== Fragment && typeof node.type !== \"string\") {\n return node;\n }\n\n if (typeof node.type === \"string\" && SKIP_CHILD_ELEMENTS.test(node.type)) {\n return node;\n }\n\n if (hasChildren(node.props)) {\n // Do not descend into child elements with interactive props\n if (\"onClick\" in node.props || (\"role\" in node.props && node.props.role === \"button\")) {\n return node;\n }\n return cloneElement(\n node,\n undefined,\n transformChildren(node.props.children, terms, emittedInPass),\n );\n }\n }\n\n return node;\n}\n\n/**\n * Process an array of React children by concatenating adjacent strings/numbers\n * into a single text run before matching, preventing false positives like \"ISO\"\n * matching inside the split text \"ISO{\"lated\"}\" (which renders as \"ISOlated\").\n */\nfunction transformArray(\n children: ReactNode[],\n terms: readonly GlossaryTermData[],\n emittedInPass: Set<string>,\n): ReactNode[] {\n const result: ReactNode[] = [];\n let textBuffer: Array<string | number> = [];\n\n const flushTextBuffer = () => {\n if (textBuffer.length === 0) return;\n const combined = textBuffer.join(\"\");\n textBuffer = [];\n if (combined.length === 0) return;\n result.push(linkifyString(combined, terms, emittedInPass));\n };\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (typeof child === \"string\" || typeof child === \"number\") {\n textBuffer.push(String(child));\n } else {\n flushTextBuffer();\n result.push(transformChildren(child, terms, emittedInPass));\n }\n }\n\n flushTextBuffer();\n return result.length === children.length ? result : (result as unknown as ReactNode[]);\n}\n\nfunction linkifyString(\n text: string,\n terms: readonly GlossaryTermData[],\n emittedInPass: Set<string>,\n): ReactNode {\n const matches = matchGlossaryTerms(text, terms, emittedInPass);\n if (matches.length === 0) return text;\n\n const parts: ReactNode[] = [];\n let cursor = 0;\n let keyIndex = 0;\n\n for (const match of matches) {\n if (match.start < cursor) continue;\n\n emittedInPass.add(match.termId);\n\n if (match.start > cursor) {\n parts.push(text.slice(cursor, match.start));\n }\n\n // Resolve term data directly from the active terms dictionary (supports custom dictionaries)\n const termData = terms.find((t) => t.id === match.termId);\n if (termData) {\n parts.push(\n <GlossaryTerm key={`glossary-${match.termId}-${keyIndex++}`} term={termData}>\n {match.text}\n </GlossaryTerm>,\n );\n } else {\n parts.push(match.text);\n }\n\n cursor = match.end;\n }\n\n if (cursor < text.length) {\n parts.push(text.slice(cursor));\n }\n\n return parts.length === 1 ? parts[0] : parts;\n}\n\nfunction hasChildren(value: unknown): value is { children?: ReactNode } {\n return typeof value === \"object\" && value !== null && \"children\" in value;\n}\n"],"names":["forwardRef","useGlossaryContext","useGlossaryScope","jsx","MantineText","createPolymorphicComponent","isValidElement","Fragment","cloneElement","matchGlossaryTerms","GlossaryTerm"],"mappings":"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"}