@gearbox-protocol/permissionless-ui 1.11.2 → 1.11.4

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.
@@ -98,6 +98,7 @@ const components_liquidation_liquidationGraph_liquidationGraph = require('./liqu
98
98
  const components_liquidation_liquidationGraphLegend_liquidationGraphLegend = require('./liquidation/liquidation-graph-legend/liquidation-graph-legend.cjs');
99
99
  const components_liquidation_liquidationGraphTip_liquidationGraphTip = require('./liquidation/liquidation-graph-tip/liquidation-graph-tip.cjs');
100
100
  const components_loaderGuard_loaderGuard = require('./loader-guard/loader-guard.cjs');
101
+ const components_markdownViewer_markdownViewer = require('./markdown-viewer/markdown-viewer.cjs');
101
102
  const components_navbar_navbar = require('./navbar/navbar.cjs');
102
103
  const components_navbar_navbarIndicatorContext = require('./navbar/navbar-indicator-context.cjs');
103
104
  const components_navitem_navitem = require('./navitem/navitem.cjs');
@@ -288,6 +289,7 @@ exports.LiquidationGraph = components_liquidation_liquidationGraph_liquidationGr
288
289
  exports.LiquidationGraphLegend = components_liquidation_liquidationGraphLegend_liquidationGraphLegend.LiquidationGraphLegend;
289
290
  exports.LiquidationGraphTip = components_liquidation_liquidationGraphTip_liquidationGraphTip.LiquidationGraphTip;
290
291
  exports.LoaderGuard = components_loaderGuard_loaderGuard.LoaderGuard;
292
+ exports.MarkdownViewer = components_markdownViewer_markdownViewer.MarkdownViewer;
291
293
  exports.Navbar = components_navbar_navbar.Navbar;
292
294
  exports.NavbarNav = components_navbar_navbar.NavbarNav;
293
295
  exports.navbarVariants = components_navbar_navbar.navbarVariants;
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const components_markdownViewer_markdownViewer = require('./markdown-viewer.cjs');
6
+
7
+
8
+
9
+ exports.MarkdownViewer = components_markdownViewer_markdownViewer.MarkdownViewer;
@@ -0,0 +1,212 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const jsxRuntime = require('react/jsx-runtime');
6
+ const React = require('react');
7
+ const ReactMarkdown = require('react-markdown');
8
+ const remarkGfm = require('remark-gfm');
9
+ require('clsx');
10
+ require('tailwind-merge');
11
+ require('sonner');
12
+ require('@gearbox-protocol/sdk');
13
+ require('../layout/col/col.cjs');
14
+ require('../layout/container/container.cjs');
15
+ require('../layout/footer/footer.cjs');
16
+ require('../layout/grid/grid.cjs');
17
+ require('../layout/header/header.cjs');
18
+ require('../layout/layout/layout.cjs');
19
+ require('../base-link/base-link.cjs');
20
+ const components_layout_pageLayout_pageLayout = require('../layout/page-layout/page-layout.cjs');
21
+
22
+ function slugify(text) {
23
+ return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
24
+ }
25
+ function getTextContent(children) {
26
+ if (typeof children === "string") {
27
+ return children;
28
+ }
29
+ if (typeof children === "number") {
30
+ return String(children);
31
+ }
32
+ if (Array.isArray(children)) {
33
+ return children.map(getTextContent).join("");
34
+ }
35
+ if (children && typeof children === "object" && "props" in children && typeof children.props === "object" && children.props !== null && "children" in children.props) {
36
+ return getTextContent(
37
+ children.props.children
38
+ );
39
+ }
40
+ return "";
41
+ }
42
+ function extractCustomId(children) {
43
+ const text = getTextContent(children);
44
+ const customIdMatch = text.match(/\{#([a-z0-9-]+)\}\s*$/i);
45
+ if (customIdMatch) {
46
+ const id = customIdMatch[1];
47
+ if (typeof children === "string") {
48
+ const displayText = text.replace(/\s*\{#[a-z0-9-]+\}\s*$/i, "").trim();
49
+ return { id, displayText };
50
+ }
51
+ return { id, displayText: children };
52
+ }
53
+ return { id: slugify(text), displayText: children };
54
+ }
55
+ function MarkdownViewer({
56
+ content,
57
+ title,
58
+ backButton
59
+ }) {
60
+ React.useEffect(() => {
61
+ const hash = window.location.hash;
62
+ if (hash) {
63
+ setTimeout(() => {
64
+ const element = document.getElementById(hash.slice(1));
65
+ if (element) {
66
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
67
+ }
68
+ }, 100);
69
+ }
70
+ }, []);
71
+ return /* @__PURE__ */ jsxRuntime.jsx(components_layout_pageLayout_pageLayout.PageLayout, { title: title || "", backButton, children: /* @__PURE__ */ jsxRuntime.jsx("article", { className: "prose prose-invert prose-lg max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(
72
+ ReactMarkdown,
73
+ {
74
+ remarkPlugins: [remarkGfm],
75
+ components: {
76
+ h1: ({ children, ...props }) => {
77
+ const { id, displayText } = extractCustomId(children);
78
+ return /* @__PURE__ */ jsxRuntime.jsx(
79
+ "h1",
80
+ {
81
+ id,
82
+ className: "text-3xl font-bold text-foreground mt-8 mb-4 scroll-mt-24",
83
+ ...props,
84
+ children: displayText
85
+ }
86
+ );
87
+ },
88
+ h2: ({ children, ...props }) => {
89
+ const { id, displayText } = extractCustomId(children);
90
+ return /* @__PURE__ */ jsxRuntime.jsx(
91
+ "h2",
92
+ {
93
+ id,
94
+ className: "text-2xl font-semibold text-foreground mt-6 mb-3 scroll-mt-24",
95
+ ...props,
96
+ children: displayText
97
+ }
98
+ );
99
+ },
100
+ h3: ({ children, ...props }) => {
101
+ const { id, displayText } = extractCustomId(children);
102
+ return /* @__PURE__ */ jsxRuntime.jsx(
103
+ "h3",
104
+ {
105
+ id,
106
+ className: "text-xl font-semibold text-foreground mt-5 mb-2 scroll-mt-24",
107
+ ...props,
108
+ children: displayText
109
+ }
110
+ );
111
+ },
112
+ h4: ({ children, ...props }) => {
113
+ const { id, displayText } = extractCustomId(children);
114
+ return /* @__PURE__ */ jsxRuntime.jsx(
115
+ "h4",
116
+ {
117
+ id,
118
+ className: "text-lg font-semibold text-foreground mt-4 mb-2 scroll-mt-24",
119
+ ...props,
120
+ children: displayText
121
+ }
122
+ );
123
+ },
124
+ p: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
125
+ "p",
126
+ {
127
+ className: "text-muted-foreground mb-4 leading-relaxed",
128
+ ...props
129
+ }
130
+ ),
131
+ a: ({ href, ...props }) => {
132
+ const isAnchorLink = href?.startsWith("#");
133
+ if (isAnchorLink && href) {
134
+ return /* @__PURE__ */ jsxRuntime.jsx(
135
+ "a",
136
+ {
137
+ href,
138
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
139
+ onClick: (e) => {
140
+ e.preventDefault();
141
+ const targetId = href.slice(1);
142
+ const element = document.getElementById(targetId);
143
+ if (element) {
144
+ element.scrollIntoView({
145
+ behavior: "smooth",
146
+ block: "start"
147
+ });
148
+ window.history.pushState(null, "", href);
149
+ }
150
+ },
151
+ ...props
152
+ }
153
+ );
154
+ }
155
+ return /* @__PURE__ */ jsxRuntime.jsx(
156
+ "a",
157
+ {
158
+ href,
159
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
160
+ target: "_blank",
161
+ rel: "noopener noreferrer",
162
+ ...props
163
+ }
164
+ );
165
+ },
166
+ ul: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
167
+ "ul",
168
+ {
169
+ className: "list-disc list-inside mb-4 text-muted-foreground space-y-2",
170
+ ...props
171
+ }
172
+ ),
173
+ ol: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
174
+ "ol",
175
+ {
176
+ className: "list-decimal list-inside mb-4 text-muted-foreground space-y-2",
177
+ ...props
178
+ }
179
+ ),
180
+ li: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "ml-4 text-muted-foreground", ...props }),
181
+ blockquote: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
182
+ "blockquote",
183
+ {
184
+ className: "border-l-4 border-gray-700 pl-4 my-4 italic text-muted-foreground",
185
+ ...props
186
+ }
187
+ ),
188
+ code: ({ className, ...props }) => {
189
+ const isInline = !className?.includes("language-");
190
+ return isInline ? /* @__PURE__ */ jsxRuntime.jsx(
191
+ "code",
192
+ {
193
+ className: "bg-gray-800 text-gray-200 px-1.5 py-0.5 rounded text-sm font-mono",
194
+ ...props
195
+ }
196
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
197
+ "code",
198
+ {
199
+ className: "block bg-gray-800 text-gray-200 p-4 rounded-lg my-4 font-mono text-sm overflow-x-auto",
200
+ ...props
201
+ }
202
+ );
203
+ },
204
+ strong: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-bold text-foreground", ...props }),
205
+ em: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("em", { className: "italic text-foreground", ...props })
206
+ },
207
+ children: content
208
+ }
209
+ ) }) });
210
+ }
211
+
212
+ exports.MarkdownViewer = MarkdownViewer;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
5
  const components_auth_signinRequired = require('../auth/signin-required.cjs');
6
6
  const components_next_backButton = require('./back-button.cjs');
7
- const components_next_markdownViewer = require('./markdown-viewer.cjs');
7
+ const components_next_nextMarkdownViewer = require('./next-markdown-viewer.cjs');
8
8
  const components_next_siweProvider = require('./siwe-provider.cjs');
9
9
  const components_next_tokenIcon = require('./token-icon.cjs');
10
10
 
@@ -12,6 +12,6 @@ const components_next_tokenIcon = require('./token-icon.cjs');
12
12
 
13
13
  exports.SignInRequired = components_auth_signinRequired.SignInRequired;
14
14
  exports.BackButton = components_next_backButton.BackButton;
15
- exports.MarkdownViewer = components_next_markdownViewer.MarkdownViewer;
15
+ exports.NextMarkdownViewer = components_next_nextMarkdownViewer.NextMarkdownViewer;
16
16
  exports.SIWEClientProvider = components_next_siweProvider.SIWEClientProvider;
17
17
  exports.TokenIcon = components_next_tokenIcon.TokenIcon;
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const jsxRuntime = require('react/jsx-runtime');
6
+ const navigation = require('next/navigation');
7
+ const components_markdownViewer_markdownViewer = require('../markdown-viewer/markdown-viewer.cjs');
8
+
9
+ function NextMarkdownViewer({
10
+ content,
11
+ title,
12
+ backButtonHref = "/",
13
+ backButtonText = "Back"
14
+ }) {
15
+ const router = navigation.useRouter();
16
+ return /* @__PURE__ */ jsxRuntime.jsx(
17
+ components_markdownViewer_markdownViewer.MarkdownViewer,
18
+ {
19
+ content,
20
+ title,
21
+ backButton: {
22
+ href: backButtonHref,
23
+ text: backButtonText,
24
+ onClick: () => router.back()
25
+ }
26
+ }
27
+ );
28
+ }
29
+
30
+ exports.NextMarkdownViewer = NextMarkdownViewer;
@@ -96,6 +96,7 @@ const components_liquidation_liquidationGraph_liquidationGraph = require('./comp
96
96
  const components_liquidation_liquidationGraphLegend_liquidationGraphLegend = require('./components/liquidation/liquidation-graph-legend/liquidation-graph-legend.cjs');
97
97
  const components_liquidation_liquidationGraphTip_liquidationGraphTip = require('./components/liquidation/liquidation-graph-tip/liquidation-graph-tip.cjs');
98
98
  const components_loaderGuard_loaderGuard = require('./components/loader-guard/loader-guard.cjs');
99
+ const components_markdownViewer_markdownViewer = require('./components/markdown-viewer/markdown-viewer.cjs');
99
100
  const components_navbar_navbar = require('./components/navbar/navbar.cjs');
100
101
  const components_navbar_navbarIndicatorContext = require('./components/navbar/navbar-indicator-context.cjs');
101
102
  const components_navitem_navitem = require('./components/navitem/navitem.cjs');
@@ -306,6 +307,7 @@ exports.LiquidationGraph = components_liquidation_liquidationGraph_liquidationGr
306
307
  exports.LiquidationGraphLegend = components_liquidation_liquidationGraphLegend_liquidationGraphLegend.LiquidationGraphLegend;
307
308
  exports.LiquidationGraphTip = components_liquidation_liquidationGraphTip_liquidationGraphTip.LiquidationGraphTip;
308
309
  exports.LoaderGuard = components_loaderGuard_loaderGuard.LoaderGuard;
310
+ exports.MarkdownViewer = components_markdownViewer_markdownViewer.MarkdownViewer;
309
311
  exports.Navbar = components_navbar_navbar.Navbar;
310
312
  exports.NavbarNav = components_navbar_navbar.NavbarNav;
311
313
  exports.navbarVariants = components_navbar_navbar.navbarVariants;
@@ -94,6 +94,7 @@ export { LiquidationGraph } from './liquidation/liquidation-graph/liquidation-gr
94
94
  export { LiquidationGraphLegend } from './liquidation/liquidation-graph-legend/liquidation-graph-legend.js';
95
95
  export { LiquidationGraphTip } from './liquidation/liquidation-graph-tip/liquidation-graph-tip.js';
96
96
  export { LoaderGuard } from './loader-guard/loader-guard.js';
97
+ export { MarkdownViewer } from './markdown-viewer/markdown-viewer.js';
97
98
  export { Navbar, NavbarNav, navbarVariants } from './navbar/navbar.js';
98
99
  export { NavbarIndicatorProvider, useNavbarIndicator } from './navbar/navbar-indicator-context.js';
99
100
  export { NavItem, navitemVariants } from './navitem/navitem.js';
@@ -0,0 +1 @@
1
+ export { MarkdownViewer } from './markdown-viewer.js';
@@ -0,0 +1,208 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useEffect } from 'react';
3
+ import ReactMarkdown from 'react-markdown';
4
+ import remarkGfm from 'remark-gfm';
5
+ import 'clsx';
6
+ import 'tailwind-merge';
7
+ import 'sonner';
8
+ import '@gearbox-protocol/sdk';
9
+ import '../layout/col/col.js';
10
+ import '../layout/container/container.js';
11
+ import '../layout/footer/footer.js';
12
+ import '../layout/grid/grid.js';
13
+ import '../layout/header/header.js';
14
+ import '../layout/layout/layout.js';
15
+ import '../base-link/base-link.js';
16
+ import { PageLayout } from '../layout/page-layout/page-layout.js';
17
+
18
+ function slugify(text) {
19
+ return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
20
+ }
21
+ function getTextContent(children) {
22
+ if (typeof children === "string") {
23
+ return children;
24
+ }
25
+ if (typeof children === "number") {
26
+ return String(children);
27
+ }
28
+ if (Array.isArray(children)) {
29
+ return children.map(getTextContent).join("");
30
+ }
31
+ if (children && typeof children === "object" && "props" in children && typeof children.props === "object" && children.props !== null && "children" in children.props) {
32
+ return getTextContent(
33
+ children.props.children
34
+ );
35
+ }
36
+ return "";
37
+ }
38
+ function extractCustomId(children) {
39
+ const text = getTextContent(children);
40
+ const customIdMatch = text.match(/\{#([a-z0-9-]+)\}\s*$/i);
41
+ if (customIdMatch) {
42
+ const id = customIdMatch[1];
43
+ if (typeof children === "string") {
44
+ const displayText = text.replace(/\s*\{#[a-z0-9-]+\}\s*$/i, "").trim();
45
+ return { id, displayText };
46
+ }
47
+ return { id, displayText: children };
48
+ }
49
+ return { id: slugify(text), displayText: children };
50
+ }
51
+ function MarkdownViewer({
52
+ content,
53
+ title,
54
+ backButton
55
+ }) {
56
+ useEffect(() => {
57
+ const hash = window.location.hash;
58
+ if (hash) {
59
+ setTimeout(() => {
60
+ const element = document.getElementById(hash.slice(1));
61
+ if (element) {
62
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
63
+ }
64
+ }, 100);
65
+ }
66
+ }, []);
67
+ return /* @__PURE__ */ jsx(PageLayout, { title: title || "", backButton, children: /* @__PURE__ */ jsx("article", { className: "prose prose-invert prose-lg max-w-none", children: /* @__PURE__ */ jsx(
68
+ ReactMarkdown,
69
+ {
70
+ remarkPlugins: [remarkGfm],
71
+ components: {
72
+ h1: ({ children, ...props }) => {
73
+ const { id, displayText } = extractCustomId(children);
74
+ return /* @__PURE__ */ jsx(
75
+ "h1",
76
+ {
77
+ id,
78
+ className: "text-3xl font-bold text-foreground mt-8 mb-4 scroll-mt-24",
79
+ ...props,
80
+ children: displayText
81
+ }
82
+ );
83
+ },
84
+ h2: ({ children, ...props }) => {
85
+ const { id, displayText } = extractCustomId(children);
86
+ return /* @__PURE__ */ jsx(
87
+ "h2",
88
+ {
89
+ id,
90
+ className: "text-2xl font-semibold text-foreground mt-6 mb-3 scroll-mt-24",
91
+ ...props,
92
+ children: displayText
93
+ }
94
+ );
95
+ },
96
+ h3: ({ children, ...props }) => {
97
+ const { id, displayText } = extractCustomId(children);
98
+ return /* @__PURE__ */ jsx(
99
+ "h3",
100
+ {
101
+ id,
102
+ className: "text-xl font-semibold text-foreground mt-5 mb-2 scroll-mt-24",
103
+ ...props,
104
+ children: displayText
105
+ }
106
+ );
107
+ },
108
+ h4: ({ children, ...props }) => {
109
+ const { id, displayText } = extractCustomId(children);
110
+ return /* @__PURE__ */ jsx(
111
+ "h4",
112
+ {
113
+ id,
114
+ className: "text-lg font-semibold text-foreground mt-4 mb-2 scroll-mt-24",
115
+ ...props,
116
+ children: displayText
117
+ }
118
+ );
119
+ },
120
+ p: ({ ...props }) => /* @__PURE__ */ jsx(
121
+ "p",
122
+ {
123
+ className: "text-muted-foreground mb-4 leading-relaxed",
124
+ ...props
125
+ }
126
+ ),
127
+ a: ({ href, ...props }) => {
128
+ const isAnchorLink = href?.startsWith("#");
129
+ if (isAnchorLink && href) {
130
+ return /* @__PURE__ */ jsx(
131
+ "a",
132
+ {
133
+ href,
134
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
135
+ onClick: (e) => {
136
+ e.preventDefault();
137
+ const targetId = href.slice(1);
138
+ const element = document.getElementById(targetId);
139
+ if (element) {
140
+ element.scrollIntoView({
141
+ behavior: "smooth",
142
+ block: "start"
143
+ });
144
+ window.history.pushState(null, "", href);
145
+ }
146
+ },
147
+ ...props
148
+ }
149
+ );
150
+ }
151
+ return /* @__PURE__ */ jsx(
152
+ "a",
153
+ {
154
+ href,
155
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
156
+ target: "_blank",
157
+ rel: "noopener noreferrer",
158
+ ...props
159
+ }
160
+ );
161
+ },
162
+ ul: ({ ...props }) => /* @__PURE__ */ jsx(
163
+ "ul",
164
+ {
165
+ className: "list-disc list-inside mb-4 text-muted-foreground space-y-2",
166
+ ...props
167
+ }
168
+ ),
169
+ ol: ({ ...props }) => /* @__PURE__ */ jsx(
170
+ "ol",
171
+ {
172
+ className: "list-decimal list-inside mb-4 text-muted-foreground space-y-2",
173
+ ...props
174
+ }
175
+ ),
176
+ li: ({ ...props }) => /* @__PURE__ */ jsx("li", { className: "ml-4 text-muted-foreground", ...props }),
177
+ blockquote: ({ ...props }) => /* @__PURE__ */ jsx(
178
+ "blockquote",
179
+ {
180
+ className: "border-l-4 border-gray-700 pl-4 my-4 italic text-muted-foreground",
181
+ ...props
182
+ }
183
+ ),
184
+ code: ({ className, ...props }) => {
185
+ const isInline = !className?.includes("language-");
186
+ return isInline ? /* @__PURE__ */ jsx(
187
+ "code",
188
+ {
189
+ className: "bg-gray-800 text-gray-200 px-1.5 py-0.5 rounded text-sm font-mono",
190
+ ...props
191
+ }
192
+ ) : /* @__PURE__ */ jsx(
193
+ "code",
194
+ {
195
+ className: "block bg-gray-800 text-gray-200 p-4 rounded-lg my-4 font-mono text-sm overflow-x-auto",
196
+ ...props
197
+ }
198
+ );
199
+ },
200
+ strong: ({ ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-bold text-foreground", ...props }),
201
+ em: ({ ...props }) => /* @__PURE__ */ jsx("em", { className: "italic text-foreground", ...props })
202
+ },
203
+ children: content
204
+ }
205
+ ) }) });
206
+ }
207
+
208
+ export { MarkdownViewer };
@@ -1,5 +1,5 @@
1
1
  export { SignInRequired } from '../auth/signin-required.js';
2
2
  export { BackButton } from './back-button.js';
3
- export { MarkdownViewer } from './markdown-viewer.js';
3
+ export { NextMarkdownViewer } from './next-markdown-viewer.js';
4
4
  export { SIWEClientProvider } from './siwe-provider.js';
5
5
  export { TokenIcon } from './token-icon.js';
@@ -0,0 +1,26 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useRouter } from 'next/navigation';
3
+ import { MarkdownViewer } from '../markdown-viewer/markdown-viewer.js';
4
+
5
+ function NextMarkdownViewer({
6
+ content,
7
+ title,
8
+ backButtonHref = "/",
9
+ backButtonText = "Back"
10
+ }) {
11
+ const router = useRouter();
12
+ return /* @__PURE__ */ jsx(
13
+ MarkdownViewer,
14
+ {
15
+ content,
16
+ title,
17
+ backButton: {
18
+ href: backButtonHref,
19
+ text: backButtonText,
20
+ onClick: () => router.back()
21
+ }
22
+ }
23
+ );
24
+ }
25
+
26
+ export { NextMarkdownViewer };
package/dist/esm/index.js CHANGED
@@ -92,6 +92,7 @@ export { LiquidationGraph } from './components/liquidation/liquidation-graph/liq
92
92
  export { LiquidationGraphLegend } from './components/liquidation/liquidation-graph-legend/liquidation-graph-legend.js';
93
93
  export { LiquidationGraphTip } from './components/liquidation/liquidation-graph-tip/liquidation-graph-tip.js';
94
94
  export { LoaderGuard } from './components/loader-guard/loader-guard.js';
95
+ export { MarkdownViewer } from './components/markdown-viewer/markdown-viewer.js';
95
96
  export { Navbar, NavbarNav, navbarVariants } from './components/navbar/navbar.js';
96
97
  export { NavbarIndicatorProvider, useNavbarIndicator } from './components/navbar/navbar-indicator-context.js';
97
98
  export { NavItem, navitemVariants } from './components/navitem/navitem.js';
@@ -35,6 +35,7 @@ export * from './label';
35
35
  export * from './layout';
36
36
  export * from './liquidation';
37
37
  export * from './loader-guard';
38
+ export * from './markdown-viewer';
38
39
  export * from './navbar';
39
40
  export * from './navitem';
40
41
  export * from './not-found';
@@ -0,0 +1 @@
1
+ export { MarkdownViewer, type MarkdownViewerProps } from './markdown-viewer';
@@ -1,6 +1,11 @@
1
1
  export interface MarkdownViewerProps {
2
2
  content: string;
3
3
  title?: string;
4
+ backButton?: {
5
+ href: string;
6
+ text?: string;
7
+ onClick?: () => void;
8
+ };
4
9
  }
5
10
  /**
6
11
  * MarkdownViewer — component for rendering markdown content with custom styling.
@@ -12,6 +17,10 @@ export interface MarkdownViewerProps {
12
17
  * Props:
13
18
  * - `content` — markdown content string to render (required).
14
19
  * - `title` — optional page title displayed in PageLayout.
20
+ * - `backButton` — optional back button configuration object:
21
+ * - `href` — destination URL for back navigation (required).
22
+ * - `text` — custom text label (defaults to "Back" if not provided).
23
+ * - `onClick` — optional callback function executed on click.
15
24
  *
16
25
  * Features:
17
26
  * - Custom heading IDs with slugification or custom IDs (e.g., "## Heading {#custom-id}").
@@ -21,11 +30,11 @@ export interface MarkdownViewerProps {
21
30
  * - Internal anchor links with smooth scrolling.
22
31
  * - External links open in new tab.
23
32
  *
24
- * Note: Wraps content in PageLayout with back button. Uses prose styling with dark theme.
33
+ * Note: Wraps content in PageLayout. Uses prose styling with dark theme.
25
34
  * Automatically handles heading IDs for navigation.
26
35
  *
27
36
  * Do NOT use MarkdownViewer:
28
37
  * - for simple text content (use appropriate text components).
29
38
  * - when you need rich text editing (use appropriate rich text editor components).
30
39
  */
31
- export declare function MarkdownViewer({ content, title }: MarkdownViewerProps): import("react/jsx-runtime").JSX.Element;
40
+ export declare function MarkdownViewer({ content, title, backButton, }: MarkdownViewerProps): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,6 @@
5
5
  */
6
6
  export { SignInRequired } from '../auth/signin-required';
7
7
  export { BackButton } from './back-button';
8
- export { MarkdownViewer } from './markdown-viewer';
8
+ export { NextMarkdownViewer, type NextMarkdownViewerProps, } from './next-markdown-viewer';
9
9
  export { SIWEClientProvider } from './siwe-provider';
10
10
  export { TokenIcon } from './token-icon';
@@ -0,0 +1,23 @@
1
+ export interface NextMarkdownViewerProps {
2
+ content: string;
3
+ title?: string;
4
+ backButtonHref?: string;
5
+ backButtonText?: string;
6
+ }
7
+ /**
8
+ * NextMarkdownViewer — Next.js-specific wrapper for MarkdownViewer.
9
+ *
10
+ * @usage
11
+ * Use NextMarkdownViewer in Next.js applications to automatically handle
12
+ * back navigation using Next.js router.
13
+ *
14
+ * Props:
15
+ * - `content` — markdown content string to render (required).
16
+ * - `title` — optional page title displayed in PageLayout.
17
+ * - `backButtonHref` — optional href for back button (defaults to "/").
18
+ * - `backButtonText` — optional text for back button (defaults to "Back").
19
+ *
20
+ * Note: This component requires Next.js and uses "use client" directive.
21
+ * For non-Next.js applications, use the base MarkdownViewer component instead.
22
+ */
23
+ export declare function NextMarkdownViewer({ content, title, backButtonHref, backButtonText, }: NextMarkdownViewerProps): import("react/jsx-runtime").JSX.Element;
@@ -32,6 +32,7 @@ export * from './components/label';
32
32
  export * from './components/layout';
33
33
  export * from './components/liquidation';
34
34
  export * from './components/loader-guard';
35
+ export * from './components/markdown-viewer';
35
36
  export * from './components/navbar';
36
37
  export * from './components/navitem';
37
38
  export * from './components/not-found';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/permissionless-ui",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "description": "Internal UI components",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/index.js",
@@ -1,217 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const jsxRuntime = require('react/jsx-runtime');
6
- const navigation = require('next/navigation');
7
- const React = require('react');
8
- const ReactMarkdown = require('react-markdown');
9
- const remarkGfm = require('remark-gfm');
10
- require('clsx');
11
- require('tailwind-merge');
12
- require('sonner');
13
- require('@gearbox-protocol/sdk');
14
- require('../layout/col/col.cjs');
15
- require('../layout/container/container.cjs');
16
- require('../layout/footer/footer.cjs');
17
- require('../layout/grid/grid.cjs');
18
- require('../layout/header/header.cjs');
19
- require('../layout/layout/layout.cjs');
20
- require('../base-link/base-link.cjs');
21
- const components_layout_pageLayout_pageLayout = require('../layout/page-layout/page-layout.cjs');
22
-
23
- function slugify(text) {
24
- return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
25
- }
26
- function getTextContent(children) {
27
- if (typeof children === "string") {
28
- return children;
29
- }
30
- if (typeof children === "number") {
31
- return String(children);
32
- }
33
- if (Array.isArray(children)) {
34
- return children.map(getTextContent).join("");
35
- }
36
- if (children && typeof children === "object" && "props" in children && typeof children.props === "object" && children.props !== null && "children" in children.props) {
37
- return getTextContent(
38
- children.props.children
39
- );
40
- }
41
- return "";
42
- }
43
- function extractCustomId(children) {
44
- const text = getTextContent(children);
45
- const customIdMatch = text.match(/\{#([a-z0-9-]+)\}\s*$/i);
46
- if (customIdMatch) {
47
- const id = customIdMatch[1];
48
- if (typeof children === "string") {
49
- const displayText = text.replace(/\s*\{#[a-z0-9-]+\}\s*$/i, "").trim();
50
- return { id, displayText };
51
- }
52
- return { id, displayText: children };
53
- }
54
- return { id: slugify(text), displayText: children };
55
- }
56
- function MarkdownViewer({ content, title }) {
57
- const router = navigation.useRouter();
58
- React.useEffect(() => {
59
- const hash = window.location.hash;
60
- if (hash) {
61
- setTimeout(() => {
62
- const element = document.getElementById(hash.slice(1));
63
- if (element) {
64
- element.scrollIntoView({ behavior: "smooth", block: "start" });
65
- }
66
- }, 100);
67
- }
68
- }, []);
69
- return /* @__PURE__ */ jsxRuntime.jsx(
70
- components_layout_pageLayout_pageLayout.PageLayout,
71
- {
72
- title: title || "",
73
- backButton: { href: "/", text: "Back", onClick: () => router.back() },
74
- children: /* @__PURE__ */ jsxRuntime.jsx("article", { className: "prose prose-invert prose-lg max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(
75
- ReactMarkdown,
76
- {
77
- remarkPlugins: [remarkGfm],
78
- components: {
79
- h1: ({ children, ...props }) => {
80
- const { id, displayText } = extractCustomId(children);
81
- return /* @__PURE__ */ jsxRuntime.jsx(
82
- "h1",
83
- {
84
- id,
85
- className: "text-3xl font-bold text-foreground mt-8 mb-4 scroll-mt-24",
86
- ...props,
87
- children: displayText
88
- }
89
- );
90
- },
91
- h2: ({ children, ...props }) => {
92
- const { id, displayText } = extractCustomId(children);
93
- return /* @__PURE__ */ jsxRuntime.jsx(
94
- "h2",
95
- {
96
- id,
97
- className: "text-2xl font-semibold text-foreground mt-6 mb-3 scroll-mt-24",
98
- ...props,
99
- children: displayText
100
- }
101
- );
102
- },
103
- h3: ({ children, ...props }) => {
104
- const { id, displayText } = extractCustomId(children);
105
- return /* @__PURE__ */ jsxRuntime.jsx(
106
- "h3",
107
- {
108
- id,
109
- className: "text-xl font-semibold text-foreground mt-5 mb-2 scroll-mt-24",
110
- ...props,
111
- children: displayText
112
- }
113
- );
114
- },
115
- h4: ({ children, ...props }) => {
116
- const { id, displayText } = extractCustomId(children);
117
- return /* @__PURE__ */ jsxRuntime.jsx(
118
- "h4",
119
- {
120
- id,
121
- className: "text-lg font-semibold text-foreground mt-4 mb-2 scroll-mt-24",
122
- ...props,
123
- children: displayText
124
- }
125
- );
126
- },
127
- p: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
128
- "p",
129
- {
130
- className: "text-muted-foreground mb-4 leading-relaxed",
131
- ...props
132
- }
133
- ),
134
- a: ({ href, ...props }) => {
135
- const isAnchorLink = href?.startsWith("#");
136
- if (isAnchorLink && href) {
137
- return /* @__PURE__ */ jsxRuntime.jsx(
138
- "a",
139
- {
140
- href,
141
- className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
142
- onClick: (e) => {
143
- e.preventDefault();
144
- const targetId = href.slice(1);
145
- const element = document.getElementById(targetId);
146
- if (element) {
147
- element.scrollIntoView({
148
- behavior: "smooth",
149
- block: "start"
150
- });
151
- window.history.pushState(null, "", href);
152
- }
153
- },
154
- ...props
155
- }
156
- );
157
- }
158
- return /* @__PURE__ */ jsxRuntime.jsx(
159
- "a",
160
- {
161
- href,
162
- className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
163
- target: "_blank",
164
- rel: "noopener noreferrer",
165
- ...props
166
- }
167
- );
168
- },
169
- ul: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
170
- "ul",
171
- {
172
- className: "list-disc list-inside mb-4 text-muted-foreground space-y-2",
173
- ...props
174
- }
175
- ),
176
- ol: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
177
- "ol",
178
- {
179
- className: "list-decimal list-inside mb-4 text-muted-foreground space-y-2",
180
- ...props
181
- }
182
- ),
183
- li: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "ml-4 text-muted-foreground", ...props }),
184
- blockquote: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
185
- "blockquote",
186
- {
187
- className: "border-l-4 border-gray-700 pl-4 my-4 italic text-muted-foreground",
188
- ...props
189
- }
190
- ),
191
- code: ({ className, ...props }) => {
192
- const isInline = !className?.includes("language-");
193
- return isInline ? /* @__PURE__ */ jsxRuntime.jsx(
194
- "code",
195
- {
196
- className: "bg-gray-800 text-gray-200 px-1.5 py-0.5 rounded text-sm font-mono",
197
- ...props
198
- }
199
- ) : /* @__PURE__ */ jsxRuntime.jsx(
200
- "code",
201
- {
202
- className: "block bg-gray-800 text-gray-200 p-4 rounded-lg my-4 font-mono text-sm overflow-x-auto",
203
- ...props
204
- }
205
- );
206
- },
207
- strong: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-bold text-foreground", ...props }),
208
- em: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("em", { className: "italic text-foreground", ...props })
209
- },
210
- children: content
211
- }
212
- ) })
213
- }
214
- );
215
- }
216
-
217
- exports.MarkdownViewer = MarkdownViewer;
@@ -1,213 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { useRouter } from 'next/navigation';
3
- import { useEffect } from 'react';
4
- import ReactMarkdown from 'react-markdown';
5
- import remarkGfm from 'remark-gfm';
6
- import 'clsx';
7
- import 'tailwind-merge';
8
- import 'sonner';
9
- import '@gearbox-protocol/sdk';
10
- import '../layout/col/col.js';
11
- import '../layout/container/container.js';
12
- import '../layout/footer/footer.js';
13
- import '../layout/grid/grid.js';
14
- import '../layout/header/header.js';
15
- import '../layout/layout/layout.js';
16
- import '../base-link/base-link.js';
17
- import { PageLayout } from '../layout/page-layout/page-layout.js';
18
-
19
- function slugify(text) {
20
- return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
21
- }
22
- function getTextContent(children) {
23
- if (typeof children === "string") {
24
- return children;
25
- }
26
- if (typeof children === "number") {
27
- return String(children);
28
- }
29
- if (Array.isArray(children)) {
30
- return children.map(getTextContent).join("");
31
- }
32
- if (children && typeof children === "object" && "props" in children && typeof children.props === "object" && children.props !== null && "children" in children.props) {
33
- return getTextContent(
34
- children.props.children
35
- );
36
- }
37
- return "";
38
- }
39
- function extractCustomId(children) {
40
- const text = getTextContent(children);
41
- const customIdMatch = text.match(/\{#([a-z0-9-]+)\}\s*$/i);
42
- if (customIdMatch) {
43
- const id = customIdMatch[1];
44
- if (typeof children === "string") {
45
- const displayText = text.replace(/\s*\{#[a-z0-9-]+\}\s*$/i, "").trim();
46
- return { id, displayText };
47
- }
48
- return { id, displayText: children };
49
- }
50
- return { id: slugify(text), displayText: children };
51
- }
52
- function MarkdownViewer({ content, title }) {
53
- const router = useRouter();
54
- useEffect(() => {
55
- const hash = window.location.hash;
56
- if (hash) {
57
- setTimeout(() => {
58
- const element = document.getElementById(hash.slice(1));
59
- if (element) {
60
- element.scrollIntoView({ behavior: "smooth", block: "start" });
61
- }
62
- }, 100);
63
- }
64
- }, []);
65
- return /* @__PURE__ */ jsx(
66
- PageLayout,
67
- {
68
- title: title || "",
69
- backButton: { href: "/", text: "Back", onClick: () => router.back() },
70
- children: /* @__PURE__ */ jsx("article", { className: "prose prose-invert prose-lg max-w-none", children: /* @__PURE__ */ jsx(
71
- ReactMarkdown,
72
- {
73
- remarkPlugins: [remarkGfm],
74
- components: {
75
- h1: ({ children, ...props }) => {
76
- const { id, displayText } = extractCustomId(children);
77
- return /* @__PURE__ */ jsx(
78
- "h1",
79
- {
80
- id,
81
- className: "text-3xl font-bold text-foreground mt-8 mb-4 scroll-mt-24",
82
- ...props,
83
- children: displayText
84
- }
85
- );
86
- },
87
- h2: ({ children, ...props }) => {
88
- const { id, displayText } = extractCustomId(children);
89
- return /* @__PURE__ */ jsx(
90
- "h2",
91
- {
92
- id,
93
- className: "text-2xl font-semibold text-foreground mt-6 mb-3 scroll-mt-24",
94
- ...props,
95
- children: displayText
96
- }
97
- );
98
- },
99
- h3: ({ children, ...props }) => {
100
- const { id, displayText } = extractCustomId(children);
101
- return /* @__PURE__ */ jsx(
102
- "h3",
103
- {
104
- id,
105
- className: "text-xl font-semibold text-foreground mt-5 mb-2 scroll-mt-24",
106
- ...props,
107
- children: displayText
108
- }
109
- );
110
- },
111
- h4: ({ children, ...props }) => {
112
- const { id, displayText } = extractCustomId(children);
113
- return /* @__PURE__ */ jsx(
114
- "h4",
115
- {
116
- id,
117
- className: "text-lg font-semibold text-foreground mt-4 mb-2 scroll-mt-24",
118
- ...props,
119
- children: displayText
120
- }
121
- );
122
- },
123
- p: ({ ...props }) => /* @__PURE__ */ jsx(
124
- "p",
125
- {
126
- className: "text-muted-foreground mb-4 leading-relaxed",
127
- ...props
128
- }
129
- ),
130
- a: ({ href, ...props }) => {
131
- const isAnchorLink = href?.startsWith("#");
132
- if (isAnchorLink && href) {
133
- return /* @__PURE__ */ jsx(
134
- "a",
135
- {
136
- href,
137
- className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
138
- onClick: (e) => {
139
- e.preventDefault();
140
- const targetId = href.slice(1);
141
- const element = document.getElementById(targetId);
142
- if (element) {
143
- element.scrollIntoView({
144
- behavior: "smooth",
145
- block: "start"
146
- });
147
- window.history.pushState(null, "", href);
148
- }
149
- },
150
- ...props
151
- }
152
- );
153
- }
154
- return /* @__PURE__ */ jsx(
155
- "a",
156
- {
157
- href,
158
- className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
159
- target: "_blank",
160
- rel: "noopener noreferrer",
161
- ...props
162
- }
163
- );
164
- },
165
- ul: ({ ...props }) => /* @__PURE__ */ jsx(
166
- "ul",
167
- {
168
- className: "list-disc list-inside mb-4 text-muted-foreground space-y-2",
169
- ...props
170
- }
171
- ),
172
- ol: ({ ...props }) => /* @__PURE__ */ jsx(
173
- "ol",
174
- {
175
- className: "list-decimal list-inside mb-4 text-muted-foreground space-y-2",
176
- ...props
177
- }
178
- ),
179
- li: ({ ...props }) => /* @__PURE__ */ jsx("li", { className: "ml-4 text-muted-foreground", ...props }),
180
- blockquote: ({ ...props }) => /* @__PURE__ */ jsx(
181
- "blockquote",
182
- {
183
- className: "border-l-4 border-gray-700 pl-4 my-4 italic text-muted-foreground",
184
- ...props
185
- }
186
- ),
187
- code: ({ className, ...props }) => {
188
- const isInline = !className?.includes("language-");
189
- return isInline ? /* @__PURE__ */ jsx(
190
- "code",
191
- {
192
- className: "bg-gray-800 text-gray-200 px-1.5 py-0.5 rounded text-sm font-mono",
193
- ...props
194
- }
195
- ) : /* @__PURE__ */ jsx(
196
- "code",
197
- {
198
- className: "block bg-gray-800 text-gray-200 p-4 rounded-lg my-4 font-mono text-sm overflow-x-auto",
199
- ...props
200
- }
201
- );
202
- },
203
- strong: ({ ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-bold text-foreground", ...props }),
204
- em: ({ ...props }) => /* @__PURE__ */ jsx("em", { className: "italic text-foreground", ...props })
205
- },
206
- children: content
207
- }
208
- ) })
209
- }
210
- );
211
- }
212
-
213
- export { MarkdownViewer };