@gearbox-protocol/permissionless-ui 1.1.7 → 1.2.0

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 (37) hide show
  1. package/dist/cjs/components/buttons/button.js +1 -1
  2. package/dist/cjs/components/buttons/copy-button.js +1 -8
  3. package/dist/cjs/components/buttons/external-button.js +1 -8
  4. package/dist/cjs/components/buttons/index.js +2 -0
  5. package/dist/cjs/components/buttons/navigation-button.js +58 -0
  6. package/dist/cjs/components/index.js +4 -2
  7. package/dist/cjs/components/layout/app-logo.js +67 -0
  8. package/dist/cjs/components/layout/footer.js +116 -0
  9. package/dist/cjs/components/layout/header.js +41 -0
  10. package/dist/cjs/components/layout/index.js +30 -0
  11. package/dist/cjs/components/layout/legal-disclaimer.js +75 -0
  12. package/dist/cjs/components/{page-layout.js → layout/page-layout.js} +2 -2
  13. package/dist/cjs/components/markdown-viewer.js +234 -0
  14. package/dist/esm/components/buttons/button.js +1 -1
  15. package/dist/esm/components/buttons/copy-button.js +1 -8
  16. package/dist/esm/components/buttons/external-button.js +1 -8
  17. package/dist/esm/components/buttons/index.js +1 -0
  18. package/dist/esm/components/buttons/navigation-button.js +24 -0
  19. package/dist/esm/components/index.js +2 -1
  20. package/dist/esm/components/layout/app-logo.js +33 -0
  21. package/dist/esm/components/layout/footer.js +82 -0
  22. package/dist/esm/components/layout/header.js +17 -0
  23. package/dist/esm/components/layout/index.js +5 -0
  24. package/dist/esm/components/layout/legal-disclaimer.js +41 -0
  25. package/dist/esm/components/{page-layout.js → layout/page-layout.js} +2 -2
  26. package/dist/esm/components/markdown-viewer.js +200 -0
  27. package/dist/types/components/buttons/index.d.ts +1 -0
  28. package/dist/types/components/buttons/navigation-button.d.ts +8 -0
  29. package/dist/types/components/index.d.ts +2 -1
  30. package/dist/types/components/layout/app-logo.d.ts +4 -0
  31. package/dist/types/components/layout/footer.d.ts +5 -0
  32. package/dist/types/components/layout/header.d.ts +6 -0
  33. package/dist/types/components/layout/index.d.ts +5 -0
  34. package/dist/types/components/layout/legal-disclaimer.d.ts +8 -0
  35. package/dist/types/components/markdown-viewer.d.ts +6 -0
  36. package/package.json +4 -1
  37. /package/dist/types/components/{page-layout.d.ts → layout/page-layout.d.ts} +0 -0
@@ -0,0 +1,200 @@
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 { PageLayout } from "./layout/index.js";
7
+ function slugify(text) {
8
+ return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
9
+ }
10
+ function getTextContent(children) {
11
+ if (typeof children === "string") {
12
+ return children;
13
+ }
14
+ if (typeof children === "number") {
15
+ return String(children);
16
+ }
17
+ if (Array.isArray(children)) {
18
+ return children.map(getTextContent).join("");
19
+ }
20
+ if (children && typeof children === "object" && "props" in children) {
21
+ return getTextContent(children.props.children);
22
+ }
23
+ return "";
24
+ }
25
+ function extractCustomId(children) {
26
+ const text = getTextContent(children);
27
+ const customIdMatch = text.match(/\{#([a-z0-9-]+)\}\s*$/i);
28
+ if (customIdMatch) {
29
+ const id = customIdMatch[1];
30
+ if (typeof children === "string") {
31
+ const displayText = text.replace(/\s*\{#[a-z0-9-]+\}\s*$/i, "").trim();
32
+ return { id, displayText };
33
+ }
34
+ return { id, displayText: children };
35
+ }
36
+ return { id: slugify(text), displayText: children };
37
+ }
38
+ function MarkdownViewer({ content, title }) {
39
+ const router = useRouter();
40
+ useEffect(() => {
41
+ const hash = window.location.hash;
42
+ if (hash) {
43
+ setTimeout(() => {
44
+ const element = document.getElementById(hash.slice(1));
45
+ if (element) {
46
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
47
+ }
48
+ }, 100);
49
+ }
50
+ }, []);
51
+ return /* @__PURE__ */ jsx(
52
+ PageLayout,
53
+ {
54
+ title: title || "",
55
+ backButton: { href: "/", text: "Back", onClick: () => router.back() },
56
+ children: /* @__PURE__ */ jsx("article", { className: "prose prose-invert prose-lg max-w-none", children: /* @__PURE__ */ jsx(
57
+ ReactMarkdown,
58
+ {
59
+ remarkPlugins: [remarkGfm],
60
+ components: {
61
+ h1: ({ children, ...props }) => {
62
+ const { id, displayText } = extractCustomId(children);
63
+ return /* @__PURE__ */ jsx(
64
+ "h1",
65
+ {
66
+ id,
67
+ className: "text-3xl font-bold text-foreground mt-8 mb-4 scroll-mt-24",
68
+ ...props,
69
+ children: displayText
70
+ }
71
+ );
72
+ },
73
+ h2: ({ children, ...props }) => {
74
+ const { id, displayText } = extractCustomId(children);
75
+ return /* @__PURE__ */ jsx(
76
+ "h2",
77
+ {
78
+ id,
79
+ className: "text-2xl font-semibold text-foreground mt-6 mb-3 scroll-mt-24",
80
+ ...props,
81
+ children: displayText
82
+ }
83
+ );
84
+ },
85
+ h3: ({ children, ...props }) => {
86
+ const { id, displayText } = extractCustomId(children);
87
+ return /* @__PURE__ */ jsx(
88
+ "h3",
89
+ {
90
+ id,
91
+ className: "text-xl font-semibold text-foreground mt-5 mb-2 scroll-mt-24",
92
+ ...props,
93
+ children: displayText
94
+ }
95
+ );
96
+ },
97
+ h4: ({ children, ...props }) => {
98
+ const { id, displayText } = extractCustomId(children);
99
+ return /* @__PURE__ */ jsx(
100
+ "h4",
101
+ {
102
+ id,
103
+ className: "text-lg font-semibold text-foreground mt-4 mb-2 scroll-mt-24",
104
+ ...props,
105
+ children: displayText
106
+ }
107
+ );
108
+ },
109
+ p: ({ ...props }) => /* @__PURE__ */ jsx(
110
+ "p",
111
+ {
112
+ className: "text-muted-foreground mb-4 leading-relaxed",
113
+ ...props
114
+ }
115
+ ),
116
+ a: ({ href, ...props }) => {
117
+ const isAnchorLink = href?.startsWith("#");
118
+ if (isAnchorLink && href) {
119
+ return /* @__PURE__ */ jsx(
120
+ "a",
121
+ {
122
+ href,
123
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
124
+ onClick: (e) => {
125
+ e.preventDefault();
126
+ const targetId = href.slice(1);
127
+ const element = document.getElementById(targetId);
128
+ if (element) {
129
+ element.scrollIntoView({
130
+ behavior: "smooth",
131
+ block: "start"
132
+ });
133
+ window.history.pushState(null, "", href);
134
+ }
135
+ },
136
+ ...props
137
+ }
138
+ );
139
+ }
140
+ return /* @__PURE__ */ jsx(
141
+ "a",
142
+ {
143
+ href,
144
+ className: "text-blue-400 hover:text-blue-300 underline transition-colors duration-200",
145
+ target: "_blank",
146
+ rel: "noopener noreferrer",
147
+ ...props
148
+ }
149
+ );
150
+ },
151
+ ul: ({ ...props }) => /* @__PURE__ */ jsx(
152
+ "ul",
153
+ {
154
+ className: "list-disc list-inside mb-4 text-muted-foreground space-y-2",
155
+ ...props
156
+ }
157
+ ),
158
+ ol: ({ ...props }) => /* @__PURE__ */ jsx(
159
+ "ol",
160
+ {
161
+ className: "list-decimal list-inside mb-4 text-muted-foreground space-y-2",
162
+ ...props
163
+ }
164
+ ),
165
+ li: ({ ...props }) => /* @__PURE__ */ jsx("li", { className: "ml-4 text-muted-foreground", ...props }),
166
+ blockquote: ({ ...props }) => /* @__PURE__ */ jsx(
167
+ "blockquote",
168
+ {
169
+ className: "border-l-4 border-gray-700 pl-4 my-4 italic text-muted-foreground",
170
+ ...props
171
+ }
172
+ ),
173
+ code: ({ className, ...props }) => {
174
+ const isInline = !className?.includes("language-");
175
+ return isInline ? /* @__PURE__ */ jsx(
176
+ "code",
177
+ {
178
+ className: "bg-gray-800 text-gray-200 px-1.5 py-0.5 rounded text-sm font-mono",
179
+ ...props
180
+ }
181
+ ) : /* @__PURE__ */ jsx(
182
+ "code",
183
+ {
184
+ className: "block bg-gray-800 text-gray-200 p-4 rounded-lg my-4 font-mono text-sm overflow-x-auto",
185
+ ...props
186
+ }
187
+ );
188
+ },
189
+ strong: ({ ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-bold text-foreground", ...props }),
190
+ em: ({ ...props }) => /* @__PURE__ */ jsx("em", { className: "italic text-foreground", ...props })
191
+ },
192
+ children: content
193
+ }
194
+ ) })
195
+ }
196
+ );
197
+ }
198
+ export {
199
+ MarkdownViewer
200
+ };
@@ -2,4 +2,5 @@ export * from "./back-button";
2
2
  export * from "./button";
3
3
  export * from "./copy-button";
4
4
  export * from "./external-button";
5
+ export * from "./navigation-button";
5
6
  export * from "./tab-button";
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export interface NavigationButtonProps {
3
+ href: string;
4
+ text: string;
5
+ isActive: boolean;
6
+ }
7
+ declare const NavigationButton: React.ForwardRefExoticComponent<NavigationButtonProps & React.RefAttributes<HTMLAnchorElement>>;
8
+ export { NavigationButton };
@@ -10,7 +10,8 @@ export * from "./dropdown-menu";
10
10
  export * from "./editable-table";
11
11
  export * from "./input";
12
12
  export * from "./label";
13
- export * from "./page-layout";
13
+ export * from "./layout";
14
+ export * from "./markdown-viewer";
14
15
  export * from "./search-bar";
15
16
  export * from "./select";
16
17
  export * from "./signatures";
@@ -0,0 +1,4 @@
1
+ export declare function AppLogo({ appName, size, }: {
2
+ appName: string;
3
+ size?: "default" | "small";
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { type LegalReferences } from "./legal-disclaimer";
2
+ export declare function Footer({ appName, legalReferences, }: {
3
+ appName: string;
4
+ legalReferences: LegalReferences;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { type NavigationButtonProps } from "../buttons";
2
+ export declare function Header({ appName, navigation, connectKitButton, }: {
3
+ appName: string;
4
+ navigation: NavigationButtonProps[];
5
+ connectKitButton: React.ReactNode;
6
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export * from "./app-logo";
2
+ export * from "./footer";
3
+ export * from "./header";
4
+ export * from "./legal-disclaimer";
5
+ export * from "./page-layout";
@@ -0,0 +1,8 @@
1
+ export interface LegalReferences {
2
+ termsOfService: string;
3
+ privacyNotice: string;
4
+ riskDisclosure: string;
5
+ }
6
+ export declare function LegalDisclaimer({ hrefs }: {
7
+ hrefs: LegalReferences;
8
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ interface MarkdownViewerProps {
2
+ content: string;
3
+ title?: string;
4
+ }
5
+ export declare function MarkdownViewer({ content, title }: MarkdownViewerProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/permissionless-ui",
3
- "version": "1.1.7",
3
+ "version": "1.2.0",
4
4
  "description": "Internal UI components",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/index.js",
@@ -52,6 +52,9 @@
52
52
  "next": "15.5.3",
53
53
  "react": "^18",
54
54
  "react-dom": "^18",
55
+ "react-markdown": "^9.0.3",
56
+ "react-markdown-math": "^1.0.2",
57
+ "remark-gfm": "^4.0.0",
55
58
  "sonner": "^1.7.2",
56
59
  "styled-jsx": "^5.1.6",
57
60
  "tailwind-merge": "^2.6.0",