@arcblock/ux 2.10.36 → 2.10.38

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. package/lib/Address/compact-text.d.ts +27 -0
  2. package/lib/Address/did-address.d.ts +16 -0
  3. package/lib/Address/index.d.ts +15 -0
  4. package/lib/Address/responsive-did-address.d.ts +33 -0
  5. package/lib/AnimationWaiter/index.d.ts +54 -0
  6. package/lib/Async/index.d.ts +30 -0
  7. package/lib/BlockletContext/index.d.ts +31 -0
  8. package/lib/BlockletV2/blocklet.d.ts +18 -0
  9. package/lib/BlockletV2/blocklet.js +156 -0
  10. package/lib/BlockletV2/components/icon-text.d.ts +7 -0
  11. package/lib/BlockletV2/components/icon-text.js +30 -0
  12. package/lib/BlockletV2/index.d.ts +4 -0
  13. package/lib/BlockletV2/index.js +4 -0
  14. package/lib/BlockletV2/utils.d.ts +4 -0
  15. package/lib/BlockletV2/utils.js +71 -0
  16. package/lib/Button/wrap.js +2 -2
  17. package/lib/ButtonGroup/index.d.ts +2 -0
  18. package/lib/CardSelector/index.d.ts +34 -0
  19. package/lib/Center/index.d.ts +18 -0
  20. package/lib/ClickToCopy/copy-button.d.ts +27 -0
  21. package/lib/ClickToCopy/hook.d.ts +9 -0
  22. package/lib/ClickToCopy/index.d.ts +32 -0
  23. package/lib/CodeBlock/LightBox.d.ts +5 -0
  24. package/lib/CodeBlock/index.d.ts +27 -0
  25. package/lib/ContactForm/index.d.ts +41 -0
  26. package/lib/CookieConsent/index.d.ts +34 -0
  27. package/lib/CountDown/index.d.ts +30 -0
  28. package/lib/DID/index.d.ts +23 -0
  29. package/lib/DidLogo/index.d.ts +26 -0
  30. package/lib/DriftBot/index.d.ts +24 -0
  31. package/lib/Earth/index.d.ts +2 -0
  32. package/lib/Earth/util.d.ts +7 -0
  33. package/lib/ErrorBoundary/fallback.d.ts +21 -0
  34. package/lib/ErrorBoundary/index.d.ts +1 -0
  35. package/lib/Footer/index.d.ts +27 -0
  36. package/lib/Header/auto-hidden.d.ts +14 -0
  37. package/lib/Header/header.d.ts +55 -0
  38. package/lib/Header/index.d.ts +2 -0
  39. package/lib/Header/responsive-header.d.ts +29 -0
  40. package/lib/Icon/image.d.ts +37 -0
  41. package/lib/InfoRow/index.d.ts +33 -0
  42. package/lib/Layout/dashboard/external-link.d.ts +15 -0
  43. package/lib/Layout/dashboard/full-page.d.ts +12 -0
  44. package/lib/Layout/dashboard/index.d.ts +40 -0
  45. package/lib/Layout/dashboard/sidebar.d.ts +21 -0
  46. package/lib/Layout/dashboard-legacy/header.d.ts +37 -0
  47. package/lib/Layout/dashboard-legacy/index.d.ts +57 -0
  48. package/lib/Layout/dashboard-legacy/sidebar.d.ts +27 -0
  49. package/lib/Layout/index.d.ts +57 -0
  50. package/lib/LoadingMask/index.d.ts +32 -0
  51. package/lib/Locale/browser-lang.d.ts +2 -0
  52. package/lib/Locale/context.d.ts +39 -0
  53. package/lib/Locale/languages.d.ts +57 -0
  54. package/lib/Locale/selector.d.ts +27 -0
  55. package/lib/Locale/util.d.ts +3 -0
  56. package/lib/Metric/index.d.ts +32 -0
  57. package/lib/MuiWrap/index.d.ts +3 -2
  58. package/lib/NFTDisplay/aspect-ratio-container.d.ts +13 -0
  59. package/lib/NFTDisplay/broken.d.ts +14 -0
  60. package/lib/NFTDisplay/displayApi.d.ts +2 -0
  61. package/lib/NFTDisplay/index.d.ts +12 -0
  62. package/lib/NFTDisplay/index.js +7 -0
  63. package/lib/NFTDisplay/loading.d.ts +1 -0
  64. package/lib/NFTDisplay/svg-embedder/img.d.ts +24 -0
  65. package/lib/NFTDisplay/svg-embedder/inline-svg.d.ts +14 -0
  66. package/lib/NavMenu/index.d.ts +1 -0
  67. package/lib/NavMenu/nav-menu.d.ts +56 -0
  68. package/lib/NavMenu/style.d.ts +2 -0
  69. package/lib/PageScroller/index.d.ts +2 -0
  70. package/lib/PageScroller/story/FifthComponent.d.ts +1 -0
  71. package/lib/PageScroller/story/FirstComponent.d.ts +1 -0
  72. package/lib/PageScroller/story/FourthComponent.d.ts +1 -0
  73. package/lib/PageScroller/story/FullPage.d.ts +1 -0
  74. package/lib/PageScroller/story/PageContain.d.ts +1 -0
  75. package/lib/PageScroller/story/SecondComponent.d.ts +1 -0
  76. package/lib/PageScroller/story/ThirdComponent.d.ts +1 -0
  77. package/lib/PageScroller/usePrevValue.d.ts +1 -0
  78. package/lib/Passport/index.d.ts +2 -0
  79. package/lib/Passport/passport.d.ts +31 -0
  80. package/lib/PoweredByArcBlock/index.d.ts +15 -0
  81. package/lib/PricingTable/PricingPlan.d.ts +10 -0
  82. package/lib/PricingTable/index.d.ts +2 -0
  83. package/lib/QRCode/index.d.ts +23 -0
  84. package/lib/RelativeTime/index.d.ts +41 -0
  85. package/lib/Result/common.d.ts +52 -0
  86. package/lib/Result/index.d.ts +19 -0
  87. package/lib/Result/result.d.ts +30 -0
  88. package/lib/Result/translations.d.ts +55 -0
  89. package/lib/Screenshot/BaseScreenshot/index.d.ts +25 -0
  90. package/lib/Screenshot/BaseScreenshot/shells/Macbook.d.ts +21 -0
  91. package/lib/Screenshot/BaseScreenshot/shells/Phone.d.ts +21 -0
  92. package/lib/Screenshot/index.d.ts +29 -0
  93. package/lib/SessionBlocklet/index.d.ts +20 -0
  94. package/lib/SessionManager/index.d.ts +2 -0
  95. package/lib/SessionPermission/index.d.ts +18 -0
  96. package/lib/SessionUser/components/logged-in.d.ts +32 -0
  97. package/lib/SessionUser/components/session-user-item.d.ts +2 -0
  98. package/lib/SessionUser/components/session-user-switch.d.ts +22 -0
  99. package/lib/SessionUser/components/un-login.d.ts +24 -0
  100. package/lib/SessionUser/components/user-info.d.ts +30 -0
  101. package/lib/SessionUser/index.d.ts +31 -0
  102. package/lib/SessionUser/libs/translation.d.ts +31 -0
  103. package/lib/SessionUser/libs/utils.d.ts +9 -0
  104. package/lib/Sparkline/index.d.ts +1 -0
  105. package/lib/Spinner/index.d.ts +2 -0
  106. package/lib/SplitButton/index.d.ts +2 -1
  107. package/lib/SplitButton/index.js +1 -1
  108. package/lib/Success/index.d.ts +22 -0
  109. package/lib/Tabs/index.d.ts +27 -0
  110. package/lib/TextCollapse/index.d.ts +2 -0
  111. package/lib/Typography/index.d.ts +25 -0
  112. package/lib/Util/federated.d.ts +61 -0
  113. package/lib/Util/passport.d.ts +33 -0
  114. package/lib/Util/wallet.d.ts +3 -0
  115. package/lib/Video/index.d.ts +19 -0
  116. package/lib/Wallet/Action.d.ts +21 -0
  117. package/lib/Wallet/Download.d.ts +33 -0
  118. package/lib/Wallet/Open.d.ts +16 -0
  119. package/lib/WalletOSIcon/index.d.ts +26 -0
  120. package/lib/WebWalletSWKeeper/index.d.ts +21 -0
  121. package/lib/WechatPrompt/index.d.ts +1 -0
  122. package/lib/index.d.ts +36 -0
  123. package/lib/withTheme/index.d.ts +7 -0
  124. package/lib/withTracker/error_boundary.d.ts +9 -0
  125. package/lib/withTracker/index.d.ts +2 -0
  126. package/package.json +10 -7
  127. package/src/BlockletV2/blocklet.tsx +130 -0
  128. package/src/BlockletV2/components/icon-text.tsx +29 -0
  129. package/src/BlockletV2/index.ts +5 -0
  130. package/src/BlockletV2/utils.js +75 -0
  131. package/src/Button/wrap.js +9 -5
  132. package/src/MuiWrap/index.tsx +3 -2
  133. package/src/NFTDisplay/index.js +23 -0
  134. package/src/SplitButton/index.tsx +2 -2
@@ -0,0 +1,19 @@
1
+ declare function Video(props: any): import("react/jsx-runtime").JSX.Element;
2
+ declare namespace Video {
3
+ namespace propTypes {
4
+ let url: PropTypes.Validator<NonNullable<NonNullable<string | object | null | undefined>>>;
5
+ let width: PropTypes.Requireable<NonNullable<string | number | null | undefined>>;
6
+ let height: PropTypes.Requireable<NonNullable<string | number | null | undefined>>;
7
+ let style: PropTypes.Requireable<NonNullable<string | object | null | undefined>>;
8
+ }
9
+ namespace defaultProps {
10
+ let width_1: number;
11
+ export { width_1 as width };
12
+ let height_1: number;
13
+ export { height_1 as height };
14
+ let style_1: {};
15
+ export { style_1 as style };
16
+ }
17
+ }
18
+ export default Video;
19
+ import PropTypes from 'prop-types';
@@ -0,0 +1,21 @@
1
+ declare function WalletAction(props: any): import("react/jsx-runtime").JSX.Element;
2
+ declare namespace WalletAction {
3
+ namespace propTypes {
4
+ let action: PropTypes.Requireable<string>;
5
+ let size: PropTypes.Requireable<string>;
6
+ let textLayout: PropTypes.Requireable<string>;
7
+ let style: PropTypes.Requireable<NonNullable<string | object | null | undefined>>;
8
+ }
9
+ namespace defaultProps {
10
+ let action_1: string;
11
+ export { action_1 as action };
12
+ let textLayout_1: string;
13
+ export { textLayout_1 as textLayout };
14
+ let size_1: string;
15
+ export { size_1 as size };
16
+ let style_1: {};
17
+ export { style_1 as style };
18
+ }
19
+ }
20
+ export default WalletAction;
21
+ import PropTypes from 'prop-types';
@@ -0,0 +1,33 @@
1
+ declare function WalletDownload(props: any): import("react/jsx-runtime").JSX.Element;
2
+ declare namespace WalletDownload {
3
+ namespace propTypes {
4
+ let title: PropTypes.Requireable<string>;
5
+ let layout: PropTypes.Requireable<string>;
6
+ let storeLayout: PropTypes.Requireable<string>;
7
+ let style: PropTypes.Requireable<NonNullable<string | object | null | undefined>>;
8
+ let iosLink: PropTypes.Requireable<string>;
9
+ let androidLink: PropTypes.Requireable<string>;
10
+ let androidDownLoadUrl: PropTypes.Requireable<string>;
11
+ let locale: PropTypes.Requireable<string>;
12
+ }
13
+ namespace defaultProps {
14
+ let title_1: string;
15
+ export { title_1 as title };
16
+ let layout_1: string;
17
+ export { layout_1 as layout };
18
+ let storeLayout_1: string;
19
+ export { storeLayout_1 as storeLayout };
20
+ let iosLink_1: string;
21
+ export { iosLink_1 as iosLink };
22
+ let androidLink_1: string;
23
+ export { androidLink_1 as androidLink };
24
+ let androidDownLoadUrl_1: string;
25
+ export { androidDownLoadUrl_1 as androidDownLoadUrl };
26
+ let style_1: {};
27
+ export { style_1 as style };
28
+ let locale_1: string;
29
+ export { locale_1 as locale };
30
+ }
31
+ }
32
+ export default WalletDownload;
33
+ import PropTypes from 'prop-types';
@@ -0,0 +1,16 @@
1
+ declare function OpenInWallet({ locale, link }: {
2
+ locale: any;
3
+ link: any;
4
+ }): import("react/jsx-runtime").JSX.Element | null;
5
+ declare namespace OpenInWallet {
6
+ namespace propTypes {
7
+ let locale: PropTypes.Requireable<string>;
8
+ let link: PropTypes.Validator<string>;
9
+ }
10
+ namespace defaultProps {
11
+ let locale_1: string;
12
+ export { locale_1 as locale };
13
+ }
14
+ }
15
+ export default OpenInWallet;
16
+ import PropTypes from 'prop-types';
@@ -0,0 +1,26 @@
1
+ declare function WalletOSIcon({ loading, walletOS, provider, color }: {
2
+ loading: any;
3
+ walletOS: any;
4
+ provider: any;
5
+ color: any;
6
+ }): import("react/jsx-runtime").JSX.Element | null;
7
+ declare namespace WalletOSIcon {
8
+ namespace propTypes {
9
+ let loading: PropTypes.Requireable<boolean>;
10
+ let walletOS: PropTypes.Requireable<string>;
11
+ let provider: PropTypes.Requireable<string>;
12
+ let color: PropTypes.Requireable<string>;
13
+ }
14
+ namespace defaultProps {
15
+ let loading_1: boolean;
16
+ export { loading_1 as loading };
17
+ let walletOS_1: null;
18
+ export { walletOS_1 as walletOS };
19
+ let provider_1: null;
20
+ export { provider_1 as provider };
21
+ let color_1: string;
22
+ export { color_1 as color };
23
+ }
24
+ }
25
+ export default WalletOSIcon;
26
+ import PropTypes from 'prop-types';
@@ -0,0 +1,21 @@
1
+ export default WebWalletSWKeeper;
2
+ export function withWebWalletSWKeeper(Component: any): ({ webWalletUrl, maxIdleTime, ...rest }: {
3
+ [x: string]: any;
4
+ webWalletUrl: any;
5
+ maxIdleTime: any;
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ declare function WebWalletSWKeeper({ webWalletUrl, maxIdleTime }: {
8
+ webWalletUrl: any;
9
+ maxIdleTime: any;
10
+ }): null;
11
+ declare namespace WebWalletSWKeeper {
12
+ namespace propTypes {
13
+ let webWalletUrl: PropTypes.Validator<string>;
14
+ let maxIdleTime: PropTypes.Requireable<number>;
15
+ }
16
+ namespace defaultProps {
17
+ export { DEFAULT_MAX_IDLE_TIME as maxIdleTime };
18
+ }
19
+ }
20
+ import PropTypes from 'prop-types';
21
+ declare const DEFAULT_MAX_IDLE_TIME: number;
@@ -0,0 +1 @@
1
+ export default function WechatPrompt(): import("react/jsx-runtime").JSX.Element | null;
package/lib/index.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ import ActionButton from './ActionButton';
2
+ import ActivityIndicator from './ActivityIndicator';
3
+ import Address from './Address';
4
+ import Alert from './Alert';
5
+ import AnimationWaiter from './AnimationWaiter';
6
+ import Async from './Async';
7
+ import Avatar from './Avatar';
8
+ import Badge from './Badge';
9
+ import Button from './Button';
10
+ import ClickToCopy from './ClickToCopy';
11
+ import CodeBlock from './CodeBlock';
12
+ import ContactForm from './ContactForm';
13
+ import CountDown from './CountDown';
14
+ import Earth from './Earth';
15
+ import Footer from './Footer';
16
+ import Icon from './Icon';
17
+ import LocaleSelector from './Locale/selector';
18
+ import Logo from './Logo';
19
+ import Tabs from './Tabs';
20
+ import RelativeTime from './RelativeTime';
21
+ import SessionManager from './SessionManager';
22
+ import Datatable from './Datatable';
23
+ import Dialog from './Dialog';
24
+ import DidLogo from './DidLogo';
25
+ import Tag from './Tag';
26
+ import TextCollapse from './TextCollapse';
27
+ import Toast from './Toast';
28
+ import Video from './Video';
29
+ import WebWalletSWKeeper from './WebWalletSWKeeper';
30
+ import WalletAction from './Wallet/Action';
31
+ import WalletDownload from './Wallet/Download';
32
+ import WechatPrompt from './WechatPrompt';
33
+ import withTheme from './withTheme';
34
+ import withTracker from './withTracker';
35
+ import Img from './Img';
36
+ export { ActionButton, ActivityIndicator, Address, Alert, AnimationWaiter, Async, Avatar, Badge, Button, ClickToCopy, CodeBlock, ContactForm, CountDown, Earth, Footer, Icon, LocaleSelector, Logo, Tabs, RelativeTime, SessionManager, Datatable, Dialog, DidLogo, Tag, TextCollapse, Theme, Toast, Util, Video, WebWalletSWKeeper, WalletAction, WalletDownload, WechatPrompt, withTheme, withTracker, Img };
@@ -0,0 +1,7 @@
1
+ export default withTheme;
2
+ declare function withTheme(Component: any, { mode, pageWidth, palette, typography }?: {
3
+ mode?: string | undefined;
4
+ pageWidth?: string | undefined;
5
+ palette: any;
6
+ typography: any;
7
+ }): (props: any) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ export default class ErrorBoundary extends Component<any, any, any> {
2
+ constructor(props: any);
3
+ state: {
4
+ error: null;
5
+ };
6
+ componentDidCatch(error: any, info: any): void;
7
+ render(): any;
8
+ }
9
+ import { Component } from 'react';
@@ -0,0 +1,2 @@
1
+ declare function _default(WrappedComponent: any, options?: {}): (props: any) => import("react/jsx-runtime").JSX.Element;
2
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.10.36",
3
+ "version": "2.10.38",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -17,7 +17,7 @@
17
17
  "url": "git+https://github.com/ArcBlock/ux.git"
18
18
  },
19
19
  "scripts": {
20
- "lint": "eslint src tests --ext js --ext jsx && tsc --noEmit --emitDeclarationOnly false",
20
+ "lint": "eslint src tests --ext js,jsx,ts,tsx",
21
21
  "lint:fix": "npm run lint -- --fix",
22
22
  "build": "npm run build:clean && npm run build:babel && npm run build:types",
23
23
  "build:clean": "rm -rf lib",
@@ -44,6 +44,8 @@
44
44
  "@babel/preset-react": "^7.18.6",
45
45
  "@babel/preset-typescript": "^7.24.7",
46
46
  "@types/react": "^18.3.4",
47
+ "@typescript-eslint/eslint-plugin": "^8.7.0",
48
+ "@typescript-eslint/parser": "^8.7.0",
47
49
  "babel-plugin-inline-react-svg": "^1.1.2",
48
50
  "copyfiles": "^2.4.1",
49
51
  "eslint-plugin-react-hooks": "^4.6.0",
@@ -51,7 +53,7 @@
51
53
  "jest": "^29.7.0",
52
54
  "jest-environment-jsdom": "^29.7.0",
53
55
  "moment-timezone": "^0.5.37",
54
- "typescript": "^5.5.4"
56
+ "typescript": "5.5.4"
55
57
  },
56
58
  "peerDependencies": {
57
59
  "@emotion/react": "^11.10.4",
@@ -61,18 +63,19 @@
61
63
  "react": ">=18.2.0",
62
64
  "react-router-dom": ">=6.22.3"
63
65
  },
64
- "gitHead": "828b8514875e49150504e46b250b938f33bf3669",
66
+ "gitHead": "ec30518daa2eb50dc076fe00e7dfde253ba8b7cb",
65
67
  "dependencies": {
66
68
  "@arcblock/did-motif": "^1.1.13",
67
- "@arcblock/icons": "^2.10.36",
68
- "@arcblock/nft-display": "^2.10.36",
69
- "@arcblock/react-hooks": "^2.10.36",
69
+ "@arcblock/icons": "^2.10.38",
70
+ "@arcblock/nft-display": "^2.10.38",
71
+ "@arcblock/react-hooks": "^2.10.38",
70
72
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
71
73
  "@fontsource/inter": "^5.0.16",
72
74
  "@fontsource/ubuntu-mono": "^5.0.18",
73
75
  "@iconify-icons/logos": "^1.2.36",
74
76
  "@iconify-icons/material-symbols": "^1.2.58",
75
77
  "@iconify-icons/mdi": "^1.2.48",
78
+ "@iconify-icons/tabler": "^1.2.95",
76
79
  "@iconify/react": "^4.1.1",
77
80
  "@solana/qr-code-styling": "^1.6.0-beta.0",
78
81
  "@testing-library/react": "^14.0.0",
@@ -0,0 +1,130 @@
1
+ import React, { isValidElement } from 'react';
2
+
3
+ import Download from '@iconify-icons/tabler/cloud-download';
4
+ import { Icon } from '@iconify/react';
5
+ import { Card, CardContent, CircularProgress, Stack, Typography } from '@mui/material';
6
+ import Avatar from '../Avatar';
7
+ import Button from '../Button';
8
+ import { useTheme } from '../Theme';
9
+ import IconText from './components/icon-text';
10
+ import { formatDownloadCount, strippedString } from './utils';
11
+
12
+ export interface IBlockletStore
13
+ extends Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, 'title' | 'className'> {
14
+ did?: string;
15
+ title: string;
16
+ description?: string;
17
+ cover?: string;
18
+ avatar: string;
19
+ author: string;
20
+ download: string;
21
+ button?: React.ReactNode;
22
+ buttonText?: string;
23
+ buttonDisabled?: boolean;
24
+ buttonLoading?: boolean;
25
+ onButtonClick?: Function;
26
+ onMainClick?: Function;
27
+ className?: string;
28
+ }
29
+
30
+ export default function BlockletStore(props: IBlockletStore) {
31
+ const {
32
+ title,
33
+ description = '',
34
+ cover = '',
35
+ avatar,
36
+ author,
37
+ download,
38
+ did,
39
+ buttonText = 'Install',
40
+ buttonDisabled,
41
+ buttonLoading,
42
+ button,
43
+ onButtonClick = () => {},
44
+ onMainClick,
45
+ className,
46
+ ref,
47
+ ...rest
48
+ } = props;
49
+
50
+ const theme = useTheme();
51
+
52
+ const wrapHandler =
53
+ (handler: Function, stopFn = () => false) =>
54
+ (e: React.MouseEvent<HTMLElement>, ...args: any[]) => {
55
+ const isFunction = handler instanceof Function;
56
+ if (stopFn() || isFunction) {
57
+ e.preventDefault();
58
+ e.stopPropagation();
59
+ if (isFunction) {
60
+ handler(...args);
61
+ }
62
+ }
63
+ };
64
+
65
+ const handleMainClick = onMainClick && wrapHandler(onMainClick);
66
+ const handleButtonClick = wrapHandler(onButtonClick, () => {
67
+ // stop click while custom button or buttonDisabled or buttonLoading
68
+ return !!(button || buttonDisabled || buttonLoading);
69
+ });
70
+
71
+ const titleProps = isValidElement(title)
72
+ ? { children: title }
73
+ : { title: strippedString(title), dangerouslySetInnerHTML: { __html: title } };
74
+
75
+ const descriptionProps = isValidElement(description)
76
+ ? { children: description }
77
+ : { title: strippedString(description), dangerouslySetInnerHTML: { __html: description } };
78
+
79
+ return (
80
+ <Card variant="outlined" sx={{ borderRadius: 2 }} onClick={handleMainClick} {...rest}>
81
+ <CardContent sx={{ display: 'flex', justifyContent: 'space-between' }}>
82
+ <Stack flex={1} direction="row" gap={2} alignItems="center" overflow="hidden">
83
+ <Avatar src={cover} did={did} size={40} variant="rounded" />
84
+ <Typography
85
+ flex={1}
86
+ component="h6"
87
+ variant="h6"
88
+ sx={{ textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}
89
+ {...titleProps}
90
+ />
91
+ {button ||
92
+ (onButtonClick && (
93
+ <Button
94
+ color="reverse"
95
+ variant="outlined"
96
+ size="small"
97
+ disabled={buttonDisabled || buttonLoading}
98
+ style={{ borderColor: theme.palette.grey[300], borderRadius: 8 }}
99
+ onClick={handleButtonClick}>
100
+ {buttonLoading && <CircularProgress size={15} style={{ marginRight: 3, color: 'inherit' }} />}
101
+ {buttonText}
102
+ </Button>
103
+ ))}
104
+ </Stack>
105
+ </CardContent>
106
+ <CardContent sx={{ py: 0 }}>
107
+ <Typography
108
+ component="div"
109
+ variant="body2"
110
+ color="text.secondary"
111
+ sx={{
112
+ lineClamp: 2,
113
+ display: '-webkit-box',
114
+ WebkitLineClamp: 2,
115
+ WebkitBoxOrient: 'vertical',
116
+ overflow: 'hidden',
117
+ height: 40,
118
+ }}
119
+ {...descriptionProps}
120
+ />
121
+ </CardContent>
122
+ <CardContent sx={{ display: 'flex', alignItems: 'center', gap: 4, color: 'grey.800' }}>
123
+ <IconText icon={<Avatar src={avatar} did={did} size={20} variant="circle" />}>{author}</IconText>
124
+ <IconText icon={<Icon icon={Download} />} title={download}>
125
+ {formatDownloadCount(download)}
126
+ </IconText>
127
+ </CardContent>
128
+ </Card>
129
+ );
130
+ }
@@ -0,0 +1,29 @@
1
+ import { Stack, Typography } from '@mui/material';
2
+ import React from 'react';
3
+
4
+ export default function IconText({
5
+ icon,
6
+ children,
7
+ maxWidth = 100,
8
+ title,
9
+ }: {
10
+ icon?: React.ReactNode;
11
+ children?: React.ReactNode;
12
+ maxWidth?: number;
13
+ title?: string;
14
+ }) {
15
+ return (
16
+ children && (
17
+ <Stack direction="row" alignItems="center" gap={1} sx={{ maxWidth, overflow: 'hidden' }}>
18
+ {icon}
19
+ <Typography
20
+ flex={1}
21
+ variant="body2"
22
+ sx={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
23
+ title={title || (typeof children === 'string' ? children : undefined)}>
24
+ {children}
25
+ </Typography>
26
+ </Stack>
27
+ )
28
+ );
29
+ }
@@ -0,0 +1,5 @@
1
+ import ActionButton, { strippedString } from './utils';
2
+ import Blocklet from './blocklet';
3
+
4
+ export { ActionButton, strippedString };
5
+ export default Blocklet;
@@ -0,0 +1,75 @@
1
+ import { styled } from '../Theme';
2
+
3
+ const ActionButton = styled('div')`
4
+ background-color: transparent !important;
5
+ & > :not(.Mui-disabled) {
6
+ position: relative;
7
+ z-index: 1;
8
+ &::before {
9
+ content: '';
10
+ position: absolute;
11
+ height: 100%;
12
+ width: 100%;
13
+ left: 0;
14
+ top: 0;
15
+ transition: opacity 0.3s;
16
+ }
17
+ &:hover::before {
18
+ opacity: 0;
19
+ }
20
+ &::after {
21
+ content: '';
22
+ position: absolute;
23
+ height: 100%;
24
+ width: 100%;
25
+ top: 0;
26
+ left: 0;
27
+ border-radius: 2px;
28
+ background-color: ${(props) => props.theme.palette.primary.main};
29
+ transform: scale(0.1);
30
+ opacity: 0;
31
+ z-index: -1;
32
+ transition:
33
+ transform 0.3s,
34
+ opacity 0.3s,
35
+ background-color 0.3s;
36
+ }
37
+ &:hover::after {
38
+ opacity: 1;
39
+ transform-origin: center;
40
+ transform: scale(1);
41
+ }
42
+ }
43
+ & > :not(.Mui-disabled) {
44
+ background-color: transparent !important;
45
+ color: ${(props) => props.theme.palette.primary.main}!important;
46
+ }
47
+ & > :not(.Mui-disabled) {
48
+ &:hover {
49
+ color: ${(props) => props.theme.palette.common.white}!important;
50
+ }
51
+ }
52
+ `;
53
+
54
+ export default ActionButton;
55
+
56
+ export const strippedString = (originalString = '') => {
57
+ return originalString.replace(/(<([^>]+)>)/gi, '').trim();
58
+ };
59
+
60
+ export const formatDownloadCount = (num = '') => {
61
+ const n = parseInt(num, 10);
62
+ if (Number.isNaN(n)) {
63
+ return num;
64
+ }
65
+ if (n < 1000) {
66
+ return n;
67
+ }
68
+ if (n < 1000000) {
69
+ return `${(n / 1000).toFixed(1)}k`;
70
+ }
71
+ if (n < 1000000000) {
72
+ return `${(n / 1000000).toFixed(1)}m`;
73
+ }
74
+ return `${(n / 1000000000).toFixed(1)}b`;
75
+ };
@@ -72,11 +72,15 @@ export default function (BaseComponent) {
72
72
  /**
73
73
  * @type {import('react').CSSProperties}
74
74
  */
75
- const styles = Object.assign({}, style, {
76
- boxShadow: 'none',
77
- textTransform: 'capitalize',
78
- ...matched,
79
- });
75
+ const styles = Object.assign(
76
+ {},
77
+ {
78
+ boxShadow: 'none',
79
+ textTransform: 'capitalize',
80
+ ...matched,
81
+ },
82
+ style
83
+ );
80
84
  let _rest = rest;
81
85
  if (!matched) {
82
86
  // mui button 本身支持的 color 交由 mui 处理
@@ -1,9 +1,10 @@
1
1
  import { Box, BoxProps, Typography, TypographyProps } from '@mui/material';
2
+ import { ElementType } from 'react';
2
3
 
3
- export function TBox<C extends React.ElementType>({ component, ...rest }: BoxProps<C, { component: C }>) {
4
+ export function TBox<C extends ElementType>({ component, ...rest }: BoxProps<C, { component: C }>) {
4
5
  return <Box component={component} {...rest} />;
5
6
  }
6
7
 
7
- export function TTypography<C extends React.ElementType>({ component, ...rest }: TypographyProps<C, { component: C }>) {
8
+ export function TTypography<C extends ElementType>({ component, ...rest }: TypographyProps<C, { component: C }>) {
8
9
  return <Typography component={component} {...rest} />;
9
10
  }
@@ -201,6 +201,29 @@ function NFTDisplay({
201
201
  const renderObject = () => {
202
202
  const objectType = state.urlType || 'image/svg+xml';
203
203
  const url = getFullContentUrl();
204
+
205
+ // do naive image render
206
+ const pathname = new URL(url).pathname.toLowerCase();
207
+ const imageExtensions = [
208
+ '.jpg',
209
+ '.jpeg',
210
+ '.png',
211
+ '.gif',
212
+ '.bmp',
213
+ '.webp',
214
+ '.svg',
215
+ '.tiff',
216
+ '.tif',
217
+ '.ico',
218
+ '.jfif',
219
+ '.pjpeg',
220
+ '.pjp',
221
+ '.avif',
222
+ ];
223
+ if (imageExtensions.some((ext) => pathname.endsWith(ext))) {
224
+ return renderImg();
225
+ }
226
+
204
227
  return (
205
228
  // eslint-disable-next-line jsx-a11y/alt-text
206
229
  <object
@@ -1,4 +1,4 @@
1
- import { useState, useRef, isValidElement } from 'react';
1
+ import React, { useState, useRef, isValidElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import ExpandMore from '@mui/icons-material/ExpandMore';
4
4
  import Popper from '@mui/material/Popper';
@@ -17,7 +17,7 @@ export interface SplitButtonProps extends Omit<ButtonGroupProps, 'children'> {
17
17
  | React.ReactElement<MenuItemProps, typeof MenuItem>
18
18
  | React.ReactElement<MenuItemProps, typeof MenuItem>[]
19
19
  | MenuItemProps[];
20
- children?: JSX.Element | (() => JSX.Element);
20
+ children?: React.ReactNode | (() => React.ReactNode);
21
21
  onClick?: () => void;
22
22
  menuButtonProps?: ButtonProps;
23
23
  }