@0xsquid/ui 0.21.1-beta.0 → 0.22.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.
- package/dist/cjs/index.js +32 -12
- package/dist/cjs/types/components/badges/BadgeImage.d.ts +6 -1
- package/dist/cjs/types/components/lists/ListItem.d.ts +2 -1
- package/dist/cjs/types/stories/badges/BadgeImage.stories.d.ts +4 -0
- package/dist/cjs/types/stories/controls/RangeInput.stories.d.ts +1 -1
- package/dist/esm/index.js +32 -12
- package/dist/esm/types/components/badges/BadgeImage.d.ts +6 -1
- package/dist/esm/types/components/lists/ListItem.d.ts +2 -1
- package/dist/esm/types/stories/badges/BadgeImage.stories.d.ts +4 -0
- package/dist/esm/types/stories/controls/RangeInput.stories.d.ts +1 -1
- package/dist/index.d.ts +8 -2
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -2637,24 +2637,41 @@ const mainImageSizeClassMap = {
|
|
|
2637
2637
|
md: 'tw-w-10 tw-h-10',
|
|
2638
2638
|
};
|
|
2639
2639
|
const loadingSkeletonClassName = 'tw-bg-grey-500';
|
|
2640
|
-
|
|
2640
|
+
var ImageState;
|
|
2641
|
+
(function (ImageState) {
|
|
2642
|
+
ImageState[ImageState["LOADING"] = 0] = "LOADING";
|
|
2643
|
+
ImageState[ImageState["LOADED"] = 1] = "LOADED";
|
|
2644
|
+
ImageState[ImageState["ERROR"] = 2] = "ERROR";
|
|
2645
|
+
})(ImageState || (ImageState = {}));
|
|
2646
|
+
function BadgeImage({ imageUrl: _imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, rounded = false, placeholderImageUrl, }) {
|
|
2647
|
+
const imageUrl = (_imageUrl === null || _imageUrl === void 0 ? void 0 : _imageUrl.trim()) || placeholderImageUrl;
|
|
2641
2648
|
const [imagesLoadState, setImageLoadState] = React.useState({
|
|
2642
|
-
|
|
2643
|
-
|
|
2649
|
+
badge: ImageState.LOADING,
|
|
2650
|
+
mainImage: ImageState.LOADING,
|
|
2644
2651
|
});
|
|
2645
2652
|
const badgeImageClassName = cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]);
|
|
2646
2653
|
const mainImageClassName = cn('tw-h-full tw-w-full tw-absolute', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs');
|
|
2647
|
-
return imageUrl ? (jsxRuntime.jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [
|
|
2654
|
+
return imageUrl ? (jsxRuntime.jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [imagesLoadState.mainImage !== ImageState.LOADED &&
|
|
2655
|
+
(placeholderImageUrl ? (jsxRuntime.jsx("img", { src: placeholderImageUrl, alt: "", className: mainImageClassName })) : (jsxRuntime.jsx("div", { className: cn(mainImageClassName, loadingSkeletonClassName) }))), jsxRuntime.jsx("img", { src: imageUrl, alt: "", onError: () => {
|
|
2656
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImage: ImageState.ERROR })));
|
|
2657
|
+
}, onLoad: () => {
|
|
2648
2658
|
// update state when image is fully loaded
|
|
2649
|
-
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), {
|
|
2659
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImage: ImageState.LOADED })));
|
|
2650
2660
|
}, className: cn(mainImageClassName,
|
|
2651
2661
|
// hide main image while it is loading, and display it when it is loaded
|
|
2652
|
-
imagesLoadState.
|
|
2662
|
+
imagesLoadState.mainImage === ImageState.LOADED
|
|
2663
|
+
? 'tw-block'
|
|
2664
|
+
: 'tw-hidden') }), badgeUrl ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [imagesLoadState.badge !== ImageState.LOADED &&
|
|
2665
|
+
(placeholderImageUrl ? (jsxRuntime.jsx("img", { src: placeholderImageUrl, alt: "", className: badgeImageClassName })) : (jsxRuntime.jsx("div", { className: cn(badgeImageClassName, loadingSkeletonClassName) }))), jsxRuntime.jsx("img", { src: badgeUrl, alt: "", onError: () => {
|
|
2666
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badge: ImageState.ERROR })));
|
|
2667
|
+
}, onLoad: () => {
|
|
2653
2668
|
// update state when badge image is fully loaded
|
|
2654
|
-
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), {
|
|
2669
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badge: ImageState.LOADED })));
|
|
2655
2670
|
}, className: cn(badgeImageClassName,
|
|
2656
2671
|
// hide badge image while it is loading, and display it when it is loaded
|
|
2657
|
-
imagesLoadState.
|
|
2672
|
+
imagesLoadState.badge === ImageState.LOADED
|
|
2673
|
+
? 'tw-block'
|
|
2674
|
+
: 'tw-hidden') })] })) : null] })) : null;
|
|
2658
2675
|
}
|
|
2659
2676
|
|
|
2660
2677
|
/******************************************************************************
|
|
@@ -17082,7 +17099,7 @@ const collapsedListItemClassMap = {
|
|
|
17082
17099
|
large: 'tw-w-[80px]',
|
|
17083
17100
|
};
|
|
17084
17101
|
function ListItem(_a) {
|
|
17085
|
-
var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps, compactOnMobile } = _a, props = __rest$1(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps", "compactOnMobile"]);
|
|
17102
|
+
var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, placeholderImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps, compactOnMobile } = _a, props = __rest$1(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "placeholderImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps", "compactOnMobile"]);
|
|
17086
17103
|
const subtitleClassName = cn('tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500', compactOnMobile ? 'tw-hidden mobile-lg:tw-block' : 'tw-block');
|
|
17087
17104
|
// 'small' variant does not have detail
|
|
17088
17105
|
const showDetail = size === 'large' && (!!detail || !!icon || showDetailOnHoverOnly);
|
|
@@ -17115,7 +17132,7 @@ function ListItem(_a) {
|
|
|
17115
17132
|
const itemProps = isInteractive ? props : {};
|
|
17116
17133
|
return (jsxRuntime.jsx("li", Object.assign({}, containerProps, { className: cn('tw-flex tw-max-w-full tw-bg-grey-900 tw-text-grey-300', listItemSizeMap[size], compactOnMobile
|
|
17117
17134
|
? `${collapsedListItemClassMap[size]} mobile-lg:tw-w-full`
|
|
17118
|
-
: 'tw-w-full', className), children: jsxRuntime.jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsxRuntime.jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, size: "md", rounded: rounded })) })) : (jsxRuntime.jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxRuntime.jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
|
|
17135
|
+
: 'tw-w-full', className), children: jsxRuntime.jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsxRuntime.jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, placeholderImageUrl: placeholderImageUrl, size: "md", rounded: rounded })) })) : (jsxRuntime.jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsxRuntime.jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxRuntime.jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
|
|
17119
17136
|
// 'large' variant has extra padding
|
|
17120
17137
|
size === 'large' ? 'tw-w-[56%] tw-pl-squid-xxs' : 'tw-w-[67%]'), children: [typeof itemTitle === 'string' ? (jsxRuntime.jsx(BodyText, { size: "small", className: cn('tw-max-w-full tw-truncate', subtitle && 'tw-h-[17px] !tw-leading-[17px]', compactOnMobile ? 'tw-hidden mobile-lg:tw-block' : 'tw-block'), children: itemTitle })) : (itemTitle), size === 'large' &&
|
|
17121
17138
|
((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (loadingComponent()) : subtitle ? (jsxRuntime.jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsxRuntime.jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxRuntime.jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
|
|
@@ -24435,6 +24452,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24435
24452
|
}
|
|
24436
24453
|
};
|
|
24437
24454
|
const handleSwitchInputMode = () => {
|
|
24455
|
+
var _a;
|
|
24438
24456
|
if (inputValue !== '') {
|
|
24439
24457
|
const convertedAmount = inputMode === InputMode.TOKEN
|
|
24440
24458
|
? convertTokenAmountToUSD(inputValue, token.price, maxUsdDecimals)
|
|
@@ -24442,6 +24460,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24442
24460
|
setInputValue(convertedAmount);
|
|
24443
24461
|
}
|
|
24444
24462
|
setInputMode((prevMode) => prevMode === InputMode.TOKEN ? InputMode.USD : InputMode.TOKEN);
|
|
24463
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
24445
24464
|
};
|
|
24446
24465
|
const getRawAmounts = (amount) => {
|
|
24447
24466
|
if (amount === '')
|
|
@@ -24489,7 +24508,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24489
24508
|
const { isTokenAmountVerySmall, isUsdAmountVerySmall } = getRawAmounts(inputValue);
|
|
24490
24509
|
const amountFormatted = React.useMemo(() => {
|
|
24491
24510
|
var _a;
|
|
24492
|
-
if (inputValue === '')
|
|
24511
|
+
if (isNaN(Number(inputValue)) || inputValue === '')
|
|
24493
24512
|
return '0';
|
|
24494
24513
|
if (inputMode === InputMode.TOKEN) {
|
|
24495
24514
|
if (direction === 'from') {
|
|
@@ -24517,9 +24536,10 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24517
24536
|
const balanceFormatted = React.useMemo(() => {
|
|
24518
24537
|
return formatAmount(balance !== null && balance !== void 0 ? balance : '0');
|
|
24519
24538
|
}, [balance]);
|
|
24539
|
+
const inputRef = React.useRef(null);
|
|
24520
24540
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isInteractive && !isLoading ? (jsxRuntime.jsxs("form", { className: "tw-relative tw-h-[80.6px] tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] tw-text-heading-small tw-font-heading-regular mobile-lg:tw-h-[75px] mobile-lg:tw-px-squid-m", onSubmit: (e) => {
|
|
24521
24541
|
e.preventDefault();
|
|
24522
|
-
}, children: [inputMode === InputMode.USD && (jsxRuntime.jsx("span", { className: "tw-absolute tw-left-5 tw-top-[11px] tw-leading-[43px] tw-text-grey-600 mobile-lg:tw-left-[30px]", children: "$" })), jsxRuntime.jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, placeholder: "0", className: cn('tw-h-[55px] tw-w-full tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-grey-300 placeholder:tw-text-grey-600 hover:tw-bg-material-light-thin focus:tw-bg-material-light-thin focus:tw-text-royal-400 focus:tw-outline-none', inputMode === InputMode.USD && 'tw-pl-[33px]') })] })) : (jsxRuntime.jsx("div", { className: cn('tw-w-full tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: jsxRuntime.jsx("div", { className: "tw-flex tw-h-[55px] tw-w-full tw-items-center tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-heading-small tw-font-heading-regular tw-text-grey-300", children: jsxRuntime.jsx("span", { children: inputValue || 0 }) }) })), !showDetails ? null : (jsxRuntime.jsxs("footer", { className: cn('tw-flex tw-h-squid-m tw-max-h-squid-m tw-items-center tw-justify-between tw-gap-2 tw-px-squid-xs tw-text-grey-500 mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: [error ? (jsxRuntime.jsx("div", { className: "tw-px-squid-xs", children: jsxRuntime.jsx(ErrorMessage, { message: error.message }) })) : (jsxRuntime.jsx(Tooltip, Object.assign({}, (isLoading
|
|
24542
|
+
}, children: [inputMode === InputMode.USD && (jsxRuntime.jsx("span", { className: "tw-absolute tw-left-5 tw-top-[11px] tw-leading-[43px] tw-text-grey-600 mobile-lg:tw-left-[30px]", children: "$" })), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, placeholder: "0", className: cn('tw-h-[55px] tw-w-full tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-grey-300 placeholder:tw-text-grey-600 hover:tw-bg-material-light-thin focus:tw-bg-material-light-thin focus:tw-text-royal-400 focus:tw-outline-none', inputMode === InputMode.USD && 'tw-pl-[33px]') })] })) : (jsxRuntime.jsx("div", { className: cn('tw-w-full tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: jsxRuntime.jsx("div", { className: "tw-flex tw-h-[55px] tw-w-full tw-items-center tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-heading-small tw-font-heading-regular tw-text-grey-300", children: jsxRuntime.jsx("span", { children: inputValue || 0 }) }) })), !showDetails ? null : (jsxRuntime.jsxs("footer", { className: cn('tw-flex tw-h-squid-m tw-max-h-squid-m tw-items-center tw-justify-between tw-gap-2 tw-px-squid-xs tw-text-grey-500 mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: [error ? (jsxRuntime.jsx("div", { className: "tw-px-squid-xs", children: jsxRuntime.jsx(ErrorMessage, { message: error.message }) })) : (jsxRuntime.jsx(Tooltip, Object.assign({}, (isLoading
|
|
24523
24543
|
? undefined
|
|
24524
24544
|
: inputMode === InputMode.TOKEN
|
|
24525
24545
|
? inputModeButton === null || inputModeButton === void 0 ? void 0 : inputModeButton.tokenModeTooltip
|
|
@@ -4,7 +4,12 @@ interface BadgeImageProps {
|
|
|
4
4
|
size?: BadgeSize;
|
|
5
5
|
extraMarginForBadge?: boolean;
|
|
6
6
|
rounded?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The URL of the placeholder image. Will be displayed while the images are loading
|
|
9
|
+
* or if there's an error loading them.
|
|
10
|
+
*/
|
|
11
|
+
placeholderImageUrl?: string;
|
|
7
12
|
}
|
|
8
13
|
type BadgeSize = 'sm' | 'md';
|
|
9
|
-
export declare function BadgeImage({ imageUrl, badgeUrl, size, extraMarginForBadge, rounded, }: BadgeImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
+
export declare function BadgeImage({ imageUrl: _imageUrl, badgeUrl, size, extraMarginForBadge, rounded, placeholderImageUrl, }: BadgeImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
15
|
export {};
|
|
@@ -3,6 +3,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
3
3
|
itemTitle: string | React.ReactNode;
|
|
4
4
|
mainImageUrl?: string;
|
|
5
5
|
secondaryImageUrl?: string;
|
|
6
|
+
placeholderImageUrl?: string;
|
|
6
7
|
subtitle?: string;
|
|
7
8
|
subtitleOnHover?: React.ReactNode;
|
|
8
9
|
detail?: string;
|
|
@@ -22,5 +23,5 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
22
23
|
compactOnMobile?: boolean;
|
|
23
24
|
}
|
|
24
25
|
type ListItemSize = 'small' | 'large';
|
|
25
|
-
export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, placeholderImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
26
27
|
export {};
|
|
@@ -9,3 +9,7 @@ export declare const ExtraMarginForBadge: Story;
|
|
|
9
9
|
export declare const Rounded: Story;
|
|
10
10
|
export declare const SizeMedium: Story;
|
|
11
11
|
export declare const SizeSmall: Story;
|
|
12
|
+
export declare const CustomPlaceholderForBrokenImage: Story;
|
|
13
|
+
export declare const CustomPlaceholderForLoadingImage: Story;
|
|
14
|
+
export declare const CustomPlaceholderForBrokenBadgeImage: Story;
|
|
15
|
+
export declare const CustomPlaceholderForLoadingBadgeImage: Story;
|
package/dist/esm/index.js
CHANGED
|
@@ -2617,24 +2617,41 @@ const mainImageSizeClassMap = {
|
|
|
2617
2617
|
md: 'tw-w-10 tw-h-10',
|
|
2618
2618
|
};
|
|
2619
2619
|
const loadingSkeletonClassName = 'tw-bg-grey-500';
|
|
2620
|
-
|
|
2620
|
+
var ImageState;
|
|
2621
|
+
(function (ImageState) {
|
|
2622
|
+
ImageState[ImageState["LOADING"] = 0] = "LOADING";
|
|
2623
|
+
ImageState[ImageState["LOADED"] = 1] = "LOADED";
|
|
2624
|
+
ImageState[ImageState["ERROR"] = 2] = "ERROR";
|
|
2625
|
+
})(ImageState || (ImageState = {}));
|
|
2626
|
+
function BadgeImage({ imageUrl: _imageUrl, badgeUrl, size = 'sm', extraMarginForBadge, rounded = false, placeholderImageUrl, }) {
|
|
2627
|
+
const imageUrl = (_imageUrl === null || _imageUrl === void 0 ? void 0 : _imageUrl.trim()) || placeholderImageUrl;
|
|
2621
2628
|
const [imagesLoadState, setImageLoadState] = useState({
|
|
2622
|
-
|
|
2623
|
-
|
|
2629
|
+
badge: ImageState.LOADING,
|
|
2630
|
+
mainImage: ImageState.LOADING,
|
|
2624
2631
|
});
|
|
2625
2632
|
const badgeImageClassName = cn('tw-absolute -tw-right-1/3 tw-bottom-0 tw-z-10 tw-m-0 -tw-translate-x-1/3 tw-rounded-md tw-border-[1px] tw-border-grey-800', badgeSizeClassMap[size]);
|
|
2626
2633
|
const mainImageClassName = cn('tw-h-full tw-w-full tw-absolute', rounded ? ' tw-rounded-full' : 'tw-rounded-squid-xs');
|
|
2627
|
-
return imageUrl ? (jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [
|
|
2634
|
+
return imageUrl ? (jsxs("div", { className: cn('tw-relative', extraMarginForBadge && badgeUrl ? 'tw-mr-1.5' : null, mainImageSizeClassMap[size]), children: [imagesLoadState.mainImage !== ImageState.LOADED &&
|
|
2635
|
+
(placeholderImageUrl ? (jsx("img", { src: placeholderImageUrl, alt: "", className: mainImageClassName })) : (jsx("div", { className: cn(mainImageClassName, loadingSkeletonClassName) }))), jsx("img", { src: imageUrl, alt: "", onError: () => {
|
|
2636
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImage: ImageState.ERROR })));
|
|
2637
|
+
}, onLoad: () => {
|
|
2628
2638
|
// update state when image is fully loaded
|
|
2629
|
-
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), {
|
|
2639
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { mainImage: ImageState.LOADED })));
|
|
2630
2640
|
}, className: cn(mainImageClassName,
|
|
2631
2641
|
// hide main image while it is loading, and display it when it is loaded
|
|
2632
|
-
imagesLoadState.
|
|
2642
|
+
imagesLoadState.mainImage === ImageState.LOADED
|
|
2643
|
+
? 'tw-block'
|
|
2644
|
+
: 'tw-hidden') }), badgeUrl ? (jsxs(Fragment, { children: [imagesLoadState.badge !== ImageState.LOADED &&
|
|
2645
|
+
(placeholderImageUrl ? (jsx("img", { src: placeholderImageUrl, alt: "", className: badgeImageClassName })) : (jsx("div", { className: cn(badgeImageClassName, loadingSkeletonClassName) }))), jsx("img", { src: badgeUrl, alt: "", onError: () => {
|
|
2646
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badge: ImageState.ERROR })));
|
|
2647
|
+
}, onLoad: () => {
|
|
2633
2648
|
// update state when badge image is fully loaded
|
|
2634
|
-
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), {
|
|
2649
|
+
setImageLoadState((prevState) => (Object.assign(Object.assign({}, prevState), { badge: ImageState.LOADED })));
|
|
2635
2650
|
}, className: cn(badgeImageClassName,
|
|
2636
2651
|
// hide badge image while it is loading, and display it when it is loaded
|
|
2637
|
-
imagesLoadState.
|
|
2652
|
+
imagesLoadState.badge === ImageState.LOADED
|
|
2653
|
+
? 'tw-block'
|
|
2654
|
+
: 'tw-hidden') })] })) : null] })) : null;
|
|
2638
2655
|
}
|
|
2639
2656
|
|
|
2640
2657
|
/******************************************************************************
|
|
@@ -17062,7 +17079,7 @@ const collapsedListItemClassMap = {
|
|
|
17062
17079
|
large: 'tw-w-[80px]',
|
|
17063
17080
|
};
|
|
17064
17081
|
function ListItem(_a) {
|
|
17065
|
-
var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps, compactOnMobile } = _a, props = __rest$1(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps", "compactOnMobile"]);
|
|
17082
|
+
var { itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, placeholderImageUrl, size = 'large', mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded = false, detailButtonClassName, loading, containerProps, compactOnMobile } = _a, props = __rest$1(_a, ["itemTitle", "mainImageUrl", "subtitle", "subtitleOnHover", "detail", "icon", "secondaryImageUrl", "placeholderImageUrl", "size", "mainIcon", "className", "isSelected", "onDetailClick", "showDetailOnHoverOnly", "rounded", "detailButtonClassName", "loading", "containerProps", "compactOnMobile"]);
|
|
17066
17083
|
const subtitleClassName = cn('tw-h-[14px] tw-max-w-full tw-truncate !tw-leading-[16px] tw-text-grey-500', compactOnMobile ? 'tw-hidden mobile-lg:tw-block' : 'tw-block');
|
|
17067
17084
|
// 'small' variant does not have detail
|
|
17068
17085
|
const showDetail = size === 'large' && (!!detail || !!icon || showDetailOnHoverOnly);
|
|
@@ -17095,7 +17112,7 @@ function ListItem(_a) {
|
|
|
17095
17112
|
const itemProps = isInteractive ? props : {};
|
|
17096
17113
|
return (jsx("li", Object.assign({}, containerProps, { className: cn('tw-flex tw-max-w-full tw-bg-grey-900 tw-text-grey-300', listItemSizeMap[size], compactOnMobile
|
|
17097
17114
|
? `${collapsedListItemClassMap[size]} mobile-lg:tw-w-full`
|
|
17098
|
-
: 'tw-w-full', className), children: jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, size: "md", rounded: rounded })) })) : (jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
|
|
17115
|
+
: 'tw-w-full', className), children: jsxs(ItemTag, Object.assign({}, itemProps, { className: cn('tw-group/list-item tw-flex tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-gap-squid-xs tw-rounded-squid-s tw-px-squid-xs tw-py-squid-xxs', isSelected && 'tw-bg-material-light-thin', isInteractive && 'hover:tw-bg-material-light-thin'), children: [size === 'large' ? (jsx("div", { className: "tw-h-10 tw-w-10", children: mainIcon ? (mainIcon) : (jsx(BadgeImage, { extraMarginForBadge: false, imageUrl: mainImageUrl, badgeUrl: secondaryImageUrl, placeholderImageUrl: placeholderImageUrl, size: "md", rounded: rounded })) })) : (jsx("div", { className: "tw-flex tw-min-h-[30px] tw-min-w-[30px] tw-items-center tw-justify-center", children: mainIcon ? (mainIcon) : (jsx("img", { src: mainImageUrl, className: "tw-h-[30px] tw-w-[30px] tw-rounded-squid-xs" })) })), jsxs("div", { className: cn('tw-flex tw-h-[40px] tw-flex-1 tw-flex-col tw-items-start tw-justify-center tw-gap-squid-xxs',
|
|
17099
17116
|
// 'large' variant has extra padding
|
|
17100
17117
|
size === 'large' ? 'tw-w-[56%] tw-pl-squid-xxs' : 'tw-w-[67%]'), children: [typeof itemTitle === 'string' ? (jsx(BodyText, { size: "small", className: cn('tw-max-w-full tw-truncate', subtitle && 'tw-h-[17px] !tw-leading-[17px]', compactOnMobile ? 'tw-hidden mobile-lg:tw-block' : 'tw-block'), children: itemTitle })) : (itemTitle), size === 'large' &&
|
|
17101
17118
|
((loading === null || loading === void 0 ? void 0 : loading.subtitle) ? (loadingComponent()) : subtitle ? (jsxs(CaptionText, { className: subtitleClassName, children: [subtitleOnHover && (jsx(CaptionText, { className: cn(subtitleClassName, 'tw-hidden group-hover/list-item:tw-block'), children: subtitleOnHover })), subtitle] })) : null)] }), showDetail && (jsxs(DetailTag, Object.assign({}, detailProps, { className: cn('tw-flex tw-w-fit tw-items-center tw-justify-center tw-rounded-squid-xs', size === 'large' ? 'tw-h-squid-xl' : 'tw-h-squid-l', showDetailOnHoverOnly
|
|
@@ -24415,6 +24432,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24415
24432
|
}
|
|
24416
24433
|
};
|
|
24417
24434
|
const handleSwitchInputMode = () => {
|
|
24435
|
+
var _a;
|
|
24418
24436
|
if (inputValue !== '') {
|
|
24419
24437
|
const convertedAmount = inputMode === InputMode.TOKEN
|
|
24420
24438
|
? convertTokenAmountToUSD(inputValue, token.price, maxUsdDecimals)
|
|
@@ -24422,6 +24440,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24422
24440
|
setInputValue(convertedAmount);
|
|
24423
24441
|
}
|
|
24424
24442
|
setInputMode((prevMode) => prevMode === InputMode.TOKEN ? InputMode.USD : InputMode.TOKEN);
|
|
24443
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
24425
24444
|
};
|
|
24426
24445
|
const getRawAmounts = (amount) => {
|
|
24427
24446
|
if (amount === '')
|
|
@@ -24469,7 +24488,7 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24469
24488
|
const { isTokenAmountVerySmall, isUsdAmountVerySmall } = getRawAmounts(inputValue);
|
|
24470
24489
|
const amountFormatted = useMemo(() => {
|
|
24471
24490
|
var _a;
|
|
24472
|
-
if (inputValue === '')
|
|
24491
|
+
if (isNaN(Number(inputValue)) || inputValue === '')
|
|
24473
24492
|
return '0';
|
|
24474
24493
|
if (inputMode === InputMode.TOKEN) {
|
|
24475
24494
|
if (direction === 'from') {
|
|
@@ -24497,9 +24516,10 @@ function NumericInput({ priceImpactPercentage, balance = '0', error, criticalPri
|
|
|
24497
24516
|
const balanceFormatted = useMemo(() => {
|
|
24498
24517
|
return formatAmount(balance !== null && balance !== void 0 ? balance : '0');
|
|
24499
24518
|
}, [balance]);
|
|
24519
|
+
const inputRef = useRef(null);
|
|
24500
24520
|
return (jsxs(Fragment, { children: [isInteractive && !isLoading ? (jsxs("form", { className: "tw-relative tw-h-[80.6px] tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] tw-text-heading-small tw-font-heading-regular mobile-lg:tw-h-[75px] mobile-lg:tw-px-squid-m", onSubmit: (e) => {
|
|
24501
24521
|
e.preventDefault();
|
|
24502
|
-
}, children: [inputMode === InputMode.USD && (jsx("span", { className: "tw-absolute tw-left-5 tw-top-[11px] tw-leading-[43px] tw-text-grey-600 mobile-lg:tw-left-[30px]", children: "$" })), jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, placeholder: "0", className: cn('tw-h-[55px] tw-w-full tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-grey-300 placeholder:tw-text-grey-600 hover:tw-bg-material-light-thin focus:tw-bg-material-light-thin focus:tw-text-royal-400 focus:tw-outline-none', inputMode === InputMode.USD && 'tw-pl-[33px]') })] })) : (jsx("div", { className: cn('tw-w-full tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: jsx("div", { className: "tw-flex tw-h-[55px] tw-w-full tw-items-center tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-heading-small tw-font-heading-regular tw-text-grey-300", children: jsx("span", { children: inputValue || 0 }) }) })), !showDetails ? null : (jsxs("footer", { className: cn('tw-flex tw-h-squid-m tw-max-h-squid-m tw-items-center tw-justify-between tw-gap-2 tw-px-squid-xs tw-text-grey-500 mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: [error ? (jsx("div", { className: "tw-px-squid-xs", children: jsx(ErrorMessage, { message: error.message }) })) : (jsx(Tooltip, Object.assign({}, (isLoading
|
|
24522
|
+
}, children: [inputMode === InputMode.USD && (jsx("span", { className: "tw-absolute tw-left-5 tw-top-[11px] tw-leading-[43px] tw-text-grey-600 mobile-lg:tw-left-[30px]", children: "$" })), jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, placeholder: "0", className: cn('tw-h-[55px] tw-w-full tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-grey-300 placeholder:tw-text-grey-600 hover:tw-bg-material-light-thin focus:tw-bg-material-light-thin focus:tw-text-royal-400 focus:tw-outline-none', inputMode === InputMode.USD && 'tw-pl-[33px]') })] })) : (jsx("div", { className: cn('tw-w-full tw-px-squid-xs tw-pb-[15px] tw-pt-[5px] mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: jsx("div", { className: "tw-flex tw-h-[55px] tw-w-full tw-items-center tw-rounded-squid-s tw-bg-transparent tw-px-squid-xs tw-py-squid-s tw-text-heading-small tw-font-heading-regular tw-text-grey-300", children: jsx("span", { children: inputValue || 0 }) }) })), !showDetails ? null : (jsxs("footer", { className: cn('tw-flex tw-h-squid-m tw-max-h-squid-m tw-items-center tw-justify-between tw-gap-2 tw-px-squid-xs tw-text-grey-500 mobile-lg:tw-px-squid-m', isLoading && loadingClassName), children: [error ? (jsx("div", { className: "tw-px-squid-xs", children: jsx(ErrorMessage, { message: error.message }) })) : (jsx(Tooltip, Object.assign({}, (isLoading
|
|
24503
24523
|
? undefined
|
|
24504
24524
|
: inputMode === InputMode.TOKEN
|
|
24505
24525
|
? inputModeButton === null || inputModeButton === void 0 ? void 0 : inputModeButton.tokenModeTooltip
|
|
@@ -4,7 +4,12 @@ interface BadgeImageProps {
|
|
|
4
4
|
size?: BadgeSize;
|
|
5
5
|
extraMarginForBadge?: boolean;
|
|
6
6
|
rounded?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The URL of the placeholder image. Will be displayed while the images are loading
|
|
9
|
+
* or if there's an error loading them.
|
|
10
|
+
*/
|
|
11
|
+
placeholderImageUrl?: string;
|
|
7
12
|
}
|
|
8
13
|
type BadgeSize = 'sm' | 'md';
|
|
9
|
-
export declare function BadgeImage({ imageUrl, badgeUrl, size, extraMarginForBadge, rounded, }: BadgeImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
+
export declare function BadgeImage({ imageUrl: _imageUrl, badgeUrl, size, extraMarginForBadge, rounded, placeholderImageUrl, }: BadgeImageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
15
|
export {};
|
|
@@ -3,6 +3,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
3
3
|
itemTitle: string | React.ReactNode;
|
|
4
4
|
mainImageUrl?: string;
|
|
5
5
|
secondaryImageUrl?: string;
|
|
6
|
+
placeholderImageUrl?: string;
|
|
6
7
|
subtitle?: string;
|
|
7
8
|
subtitleOnHover?: React.ReactNode;
|
|
8
9
|
detail?: string;
|
|
@@ -22,5 +23,5 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
22
23
|
compactOnMobile?: boolean;
|
|
23
24
|
}
|
|
24
25
|
type ListItemSize = 'small' | 'large';
|
|
25
|
-
export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, placeholderImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
26
27
|
export {};
|
|
@@ -9,3 +9,7 @@ export declare const ExtraMarginForBadge: Story;
|
|
|
9
9
|
export declare const Rounded: Story;
|
|
10
10
|
export declare const SizeMedium: Story;
|
|
11
11
|
export declare const SizeSmall: Story;
|
|
12
|
+
export declare const CustomPlaceholderForBrokenImage: Story;
|
|
13
|
+
export declare const CustomPlaceholderForLoadingImage: Story;
|
|
14
|
+
export declare const CustomPlaceholderForBrokenBadgeImage: Story;
|
|
15
|
+
export declare const CustomPlaceholderForLoadingBadgeImage: Story;
|
package/dist/index.d.ts
CHANGED
|
@@ -11,9 +11,14 @@ interface BadgeImageProps {
|
|
|
11
11
|
size?: BadgeSize;
|
|
12
12
|
extraMarginForBadge?: boolean;
|
|
13
13
|
rounded?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The URL of the placeholder image. Will be displayed while the images are loading
|
|
16
|
+
* or if there's an error loading them.
|
|
17
|
+
*/
|
|
18
|
+
placeholderImageUrl?: string;
|
|
14
19
|
}
|
|
15
20
|
type BadgeSize = 'sm' | 'md';
|
|
16
|
-
declare function BadgeImage({ imageUrl, badgeUrl, size, extraMarginForBadge, rounded, }: BadgeImageProps): react_jsx_runtime.JSX.Element | null;
|
|
21
|
+
declare function BadgeImage({ imageUrl: _imageUrl, badgeUrl, size, extraMarginForBadge, rounded, placeholderImageUrl, }: BadgeImageProps): react_jsx_runtime.JSX.Element | null;
|
|
17
22
|
|
|
18
23
|
type TextSize = 'small' | 'medium' | 'large';
|
|
19
24
|
type SwitchSize = 'small' | 'large';
|
|
@@ -1224,6 +1229,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
1224
1229
|
itemTitle: string | React.ReactNode;
|
|
1225
1230
|
mainImageUrl?: string;
|
|
1226
1231
|
secondaryImageUrl?: string;
|
|
1232
|
+
placeholderImageUrl?: string;
|
|
1227
1233
|
subtitle?: string;
|
|
1228
1234
|
subtitleOnHover?: React.ReactNode;
|
|
1229
1235
|
detail?: string;
|
|
@@ -1243,7 +1249,7 @@ interface ListItemProps extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
1243
1249
|
compactOnMobile?: boolean;
|
|
1244
1250
|
}
|
|
1245
1251
|
type ListItemSize = 'small' | 'large';
|
|
1246
|
-
declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): react_jsx_runtime.JSX.Element;
|
|
1252
|
+
declare function ListItem({ itemTitle, mainImageUrl, subtitle, subtitleOnHover, detail, icon, secondaryImageUrl, placeholderImageUrl, size, mainIcon, className, isSelected, onDetailClick, showDetailOnHoverOnly, rounded, detailButtonClassName, loading, containerProps, compactOnMobile, ...props }: ListItemProps): react_jsx_runtime.JSX.Element;
|
|
1247
1253
|
|
|
1248
1254
|
interface MenuItemProps {
|
|
1249
1255
|
label: string;
|
package/package.json
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
"url": "git+https://github.com/0xsquid/squid-ui.git"
|
|
6
6
|
},
|
|
7
7
|
"description": "Squid's UI components",
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.22.0",
|
|
9
9
|
"author": "",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"resolutions": {
|
|
12
12
|
"string-width": "4.2.3"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
-
"
|
|
15
|
+
"dev": "concurrently 'yarn:watch:*'",
|
|
16
16
|
"watch:storybook": "storybook dev -p 6006",
|
|
17
17
|
"build-storybook": "storybook build",
|
|
18
18
|
"watch:build-tailwind": "yarn build-tailwind --watch",
|