@iota/apps-ui-kit 0.5.1 → 0.7.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/CHANGELOG.md +27 -0
- package/dist/index.d.ts +186 -20
- package/dist/index.es.js +3701 -6345
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +33 -165
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +11 -4
- package/src/lib/components/atoms/badge/badge.classes.ts +18 -18
- package/src/lib/components/atoms/badge/badge.enums.ts +1 -1
- package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +1 -1
- package/src/lib/components/atoms/button/button.classes.ts +12 -12
- package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +15 -3
- package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +15 -36
- package/src/lib/components/atoms/checkbox/Checkbox.tsx +20 -9
- package/src/lib/components/atoms/divider/divider.classes.ts +1 -1
- package/src/lib/components/atoms/header/Header.tsx +1 -1
- package/src/lib/components/atoms/image/Image.tsx +32 -0
- package/src/lib/components/atoms/image/index.ts +4 -0
- package/src/lib/components/atoms/index.ts +3 -1
- package/src/lib/components/atoms/info-box/InfoBox.tsx +2 -8
- package/src/lib/components/atoms/info-box/infoBox.classes.ts +8 -9
- package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +5 -5
- package/src/lib/components/atoms/label-text/LabelText.tsx +4 -6
- package/src/lib/components/atoms/list-item/ListItem.tsx +3 -4
- package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +1 -1
- package/src/lib/components/atoms/media-fallback/MediaFallback.tsx +12 -0
- package/src/lib/components/atoms/media-fallback/index.ts +4 -0
- package/src/lib/components/atoms/panel/Panel.tsx +2 -4
- package/src/lib/components/atoms/radio-button/RadioButton.tsx +4 -8
- package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +3 -2
- package/src/lib/components/atoms/skeleton/Skeleton.tsx +1 -3
- package/src/lib/components/atoms/snackbar/snackbar.classes.ts +8 -8
- package/src/lib/components/atoms/toggle/toggle.classes.ts +6 -6
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +115 -13
- package/src/lib/components/atoms/video/Video.tsx +33 -0
- package/src/lib/components/atoms/video/index.ts +4 -0
- package/src/lib/components/atoms/video/video.constants.ts +31 -0
- package/src/lib/components/molecules/account/Account.tsx +4 -4
- package/src/lib/components/molecules/address/Address.tsx +1 -1
- package/src/lib/components/molecules/asset-media-renderer/AssetMediaRenderer.tsx +50 -0
- package/src/lib/components/molecules/asset-media-renderer/index.ts +4 -0
- package/src/lib/components/molecules/card/CardAction.tsx +3 -5
- package/src/lib/components/molecules/card/CardBody.tsx +3 -2
- package/src/lib/components/molecules/card/card.classes.ts +3 -3
- package/src/lib/components/molecules/chip/Chip.tsx +9 -2
- package/src/lib/components/molecules/chip/chip.classes.ts +5 -5
- package/src/lib/components/molecules/chip/chip.enums.ts +5 -0
- package/src/lib/components/molecules/chip/index.ts +1 -0
- package/src/lib/components/molecules/display-stats/DisplayStats.tsx +2 -2
- package/src/lib/components/molecules/display-stats/displayStats.classes.ts +6 -6
- package/src/lib/components/molecules/dropdown/Dropdown.tsx +1 -1
- package/src/lib/components/molecules/index.ts +2 -0
- package/src/lib/components/molecules/input/Input.tsx +3 -5
- package/src/lib/components/molecules/input/InputWrapper.tsx +1 -1
- package/src/lib/components/molecules/input/TextArea.tsx +2 -5
- package/src/lib/components/molecules/input/input.classes.ts +7 -8
- package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +4 -4
- package/src/lib/components/molecules/search/Search.tsx +10 -7
- package/src/lib/components/molecules/search/search.classes.ts +5 -5
- package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +5 -1
- package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +2 -2
- package/src/lib/components/molecules/select/Select.tsx +6 -13
- package/src/lib/components/molecules/table-cell/TableCell.tsx +2 -2
- package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +2 -2
- package/src/lib/components/molecules/title/Title.tsx +3 -3
- package/src/lib/components/{atoms → molecules}/visual-asset-card/VisualAssetCard.tsx +26 -40
- package/src/lib/components/organisms/accordion/Accordion.tsx +2 -3
- package/src/lib/components/organisms/accordion/accordion.classes.ts +1 -1
- package/src/lib/components/organisms/dialog/Dialog.tsx +4 -4
- package/src/lib/components/organisms/navbar/Navbar.tsx +2 -2
- package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +1 -1
- package/src/lib/components/organisms/table/Table.tsx +4 -4
- package/src/lib/constants/colors.constants.ts +107 -8
- package/src/lib/styles/base.css +97 -0
- package/src/lib/styles/components.css +687 -0
- package/src/lib/styles/fonts.css +2 -0
- package/src/lib/styles/index.css +754 -136
- package/src/lib/styles/utilities.css +53 -0
- package/src/lib/tailwind/base.presets.ts +14 -9
- package/src/lib/tailwind/constants/customColors.constants.ts +13 -0
- package/src/lib/tailwind/constants/fontFamily.constants.ts +8 -0
- package/src/lib/tailwind/constants/fontSizes.constants.ts +9 -9
- package/src/lib/tailwind/constants/index.ts +1 -0
- package/src/lib/tailwind/plugins.ts +4 -0
- package/src/lib/tailwind/responsive.presets.ts +1 -1
- package/src/storybook/blocks/Showcase.tsx +2 -2
- package/src/storybook/blocks/TypeSetItem.tsx +3 -3
- package/src/storybook/stories/atoms/Skeleton.stories.tsx +1 -1
- package/src/storybook/stories/atoms/Tooltip.stories.tsx +4 -2
- package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +3 -2
- package/src/storybook/stories/components/VariableSpacingShowcase.tsx +2 -2
- package/src/storybook/stories/design-tokens/colors.stories.mdx +9 -0
- package/src/storybook/stories/molecules/Account.stories.tsx +3 -1
- package/src/storybook/stories/molecules/Search.stories.tsx +2 -2
- package/src/storybook/stories/molecules/TableCell.stories.tsx +1 -1
- package/src/storybook/stories/molecules/TextArea.stories.tsx +1 -1
- /package/src/lib/components/{atoms → molecules}/visual-asset-card/index.ts +0 -0
- /package/src/lib/components/{atoms → molecules}/visual-asset-card/visualAssetCard.enums.ts +0 -0
|
@@ -15,10 +15,11 @@ interface SecondaryTextProps {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function SecondaryText({ children, hasErrorStyles }: SecondaryTextProps) {
|
|
18
|
-
const ERROR_STYLES =
|
|
18
|
+
const ERROR_STYLES =
|
|
19
|
+
'group-[.errored]:w-full group-[.errored]:secondary-text-error-color group-[.errored]:bg-error-surface group-[.errored]:rounded-xl group-[.errored]:py-1 group-[.errored]:px-2';
|
|
19
20
|
return (
|
|
20
21
|
<p
|
|
21
|
-
className={cx('text-
|
|
22
|
+
className={cx('secondary-text-color text-label-lg', {
|
|
22
23
|
[ERROR_STYLES]: hasErrorStyles,
|
|
23
24
|
})}
|
|
24
25
|
>
|
|
@@ -36,9 +36,7 @@ export function Skeleton({
|
|
|
36
36
|
widthClass,
|
|
37
37
|
heightClass,
|
|
38
38
|
isRounded && 'rounded-full',
|
|
39
|
-
hasSecondaryColors
|
|
40
|
-
? 'bg-neutral-80 dark:bg-neutral-10'
|
|
41
|
-
: 'bg-neutral-90 dark:bg-neutral-12',
|
|
39
|
+
hasSecondaryColors ? 'skeleton-secondary-bg' : 'skeleton-bg',
|
|
42
40
|
)}
|
|
43
41
|
>
|
|
44
42
|
{children}
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
import { SnackbarType } from './snackbar.enums';
|
|
5
5
|
|
|
6
6
|
export const TEXT_COLOR: Record<SnackbarType, string> = {
|
|
7
|
-
[SnackbarType.Default]: 'text-
|
|
8
|
-
[SnackbarType.Error]: 'text-
|
|
9
|
-
[SnackbarType.Warning]: 'text-
|
|
10
|
-
[SnackbarType.Success]: 'text-
|
|
7
|
+
[SnackbarType.Default]: 'text-on-default',
|
|
8
|
+
[SnackbarType.Error]: 'text-on-error',
|
|
9
|
+
[SnackbarType.Warning]: 'text-on-warning',
|
|
10
|
+
[SnackbarType.Success]: 'text-on-success',
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export const BACKGROUND_COLOR: Record<SnackbarType, string> = {
|
|
14
|
-
[SnackbarType.Default]: 'bg-
|
|
15
|
-
[SnackbarType.Error]: 'bg-error-
|
|
16
|
-
[SnackbarType.Warning]: 'bg-warning-
|
|
17
|
-
[SnackbarType.Success]: 'bg-
|
|
14
|
+
[SnackbarType.Default]: 'bg-default-surface',
|
|
15
|
+
[SnackbarType.Error]: 'bg-error-surface',
|
|
16
|
+
[SnackbarType.Warning]: 'bg-warning-surface',
|
|
17
|
+
[SnackbarType.Success]: 'bg-success-surface',
|
|
18
18
|
};
|
|
@@ -6,9 +6,9 @@ import { ToggleSize } from './toggle.enums';
|
|
|
6
6
|
export const TOGGLE = 'relative inline-flex items-center p-xxs border rounded-full cursor-pointer';
|
|
7
7
|
|
|
8
8
|
export const TOGGLE_STATES = {
|
|
9
|
-
active: 'bg-
|
|
10
|
-
inactive: '
|
|
11
|
-
disabledActive: 'bg-
|
|
9
|
+
active: 'toggle-bg-active toggle-border-active',
|
|
10
|
+
inactive: 'toggle-bg-inactive toggle-border-inactive',
|
|
11
|
+
disabledActive: 'toggle-bg-disabled-active toggle-border-disabled-active',
|
|
12
12
|
disabled: 'opacity-40 cursor-not-allowed',
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -29,8 +29,8 @@ export const TOGGLE_THUMB_POSITION = {
|
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
export const TOGGLE_THUMB_COLOR = {
|
|
32
|
-
unchecked: '
|
|
33
|
-
checked: '
|
|
32
|
+
unchecked: 'toggle-thumb-color',
|
|
33
|
+
checked: 'toggle-thumb-color-checked',
|
|
34
34
|
};
|
|
35
35
|
export const TOGGLE_THUMB_SIZE = {
|
|
36
36
|
[ToggleSize.Small]: 'h-3 w-3',
|
|
@@ -38,4 +38,4 @@ export const TOGGLE_THUMB_SIZE = {
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export const TOGGLE_CONTAINER = 'inline-flex items-center gap-2';
|
|
41
|
-
export const TOGGLE_LABEL = 'text-label-lg
|
|
41
|
+
export const TOGGLE_LABEL = 'text-label-lg toggle-label-color';
|
|
@@ -1,37 +1,139 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { useRef, useState, useLayoutEffect } from 'react';
|
|
4
5
|
import type { PropsWithChildren } from 'react';
|
|
6
|
+
import { createPortal } from 'react-dom';
|
|
5
7
|
import cx from 'classnames';
|
|
6
8
|
import { TooltipPosition } from './tooltip.enums';
|
|
7
|
-
import { TOOLTIP_POSITION } from './tooltip.classes';
|
|
8
9
|
|
|
9
10
|
interface TooltipProps {
|
|
10
11
|
text: string;
|
|
11
12
|
position?: TooltipPosition;
|
|
12
13
|
maxWidth?: string;
|
|
14
|
+
offset?: number;
|
|
15
|
+
openDelay?: number;
|
|
16
|
+
closeDelay?: number;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export function Tooltip({
|
|
16
20
|
text,
|
|
17
21
|
position = TooltipPosition.Top,
|
|
18
22
|
maxWidth = 'max-w-[200px]',
|
|
23
|
+
offset = 8,
|
|
24
|
+
openDelay = 0,
|
|
25
|
+
closeDelay = 100,
|
|
19
26
|
children,
|
|
20
|
-
}: PropsWithChildren<TooltipProps>)
|
|
21
|
-
const
|
|
27
|
+
}: PropsWithChildren<TooltipProps>) {
|
|
28
|
+
const triggerRef = useRef<HTMLDivElement>(null);
|
|
29
|
+
const tooltipRef = useRef<HTMLDivElement>(null);
|
|
30
|
+
|
|
31
|
+
const [visible, setVisible] = useState(false);
|
|
32
|
+
const [coords, setCoords] = useState<{ top: number; left: number }>({ top: 0, left: 0 });
|
|
33
|
+
|
|
34
|
+
const openTimer = useRef<ReturnType<typeof setTimeout>>();
|
|
35
|
+
const closeTimer = useRef<ReturnType<typeof setTimeout>>();
|
|
36
|
+
|
|
37
|
+
const clearTimers = () => {
|
|
38
|
+
clearTimeout(openTimer.current);
|
|
39
|
+
clearTimeout(closeTimer.current);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const open = () => {
|
|
43
|
+
clearTimers();
|
|
44
|
+
openTimer.current = setTimeout(() => setVisible(true), openDelay);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const close = () => {
|
|
48
|
+
clearTimers();
|
|
49
|
+
closeTimer.current = setTimeout(() => setVisible(false), closeDelay);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
if (!visible) return;
|
|
54
|
+
|
|
55
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
56
|
+
if (!rect) return;
|
|
57
|
+
|
|
58
|
+
const pos = {
|
|
59
|
+
[TooltipPosition.Top]: {
|
|
60
|
+
top: rect.top - offset,
|
|
61
|
+
left: rect.left + rect.width / 2,
|
|
62
|
+
transform: 'translate(-50%, -100%)',
|
|
63
|
+
},
|
|
64
|
+
[TooltipPosition.Bottom]: {
|
|
65
|
+
top: rect.bottom + offset,
|
|
66
|
+
left: rect.left + rect.width / 2,
|
|
67
|
+
transform: 'translate(-50%, 0)',
|
|
68
|
+
},
|
|
69
|
+
[TooltipPosition.Left]: {
|
|
70
|
+
top: rect.top + rect.height / 2,
|
|
71
|
+
left: rect.left - offset,
|
|
72
|
+
transform: 'translate(-100%, -50%)',
|
|
73
|
+
},
|
|
74
|
+
[TooltipPosition.Right]: {
|
|
75
|
+
top: rect.top + rect.height / 2,
|
|
76
|
+
left: rect.right + offset,
|
|
77
|
+
transform: 'translate(0, -50%)',
|
|
78
|
+
},
|
|
79
|
+
}[position];
|
|
80
|
+
|
|
81
|
+
setCoords({ top: pos.top, left: pos.left });
|
|
82
|
+
tooltipRef.current!.style.transform = pos.transform;
|
|
83
|
+
}, [visible, position, offset]);
|
|
84
|
+
|
|
85
|
+
useLayoutEffect(() => {
|
|
86
|
+
if (!visible) return;
|
|
87
|
+
const update = () => {
|
|
88
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
89
|
+
if (!rect) return;
|
|
90
|
+
setCoords((prev) => ({ ...prev, left: rect.left + rect.width / 2 }));
|
|
91
|
+
};
|
|
92
|
+
window.addEventListener('scroll', update, true);
|
|
93
|
+
window.addEventListener('resize', update);
|
|
94
|
+
return () => {
|
|
95
|
+
window.removeEventListener('scroll', update, true);
|
|
96
|
+
window.removeEventListener('resize', update);
|
|
97
|
+
};
|
|
98
|
+
}, [visible]);
|
|
99
|
+
|
|
100
|
+
// z-[9999999999]: needed because we must exceed the popup’s ≈2 147 483 647 z-index;
|
|
101
|
+
// otherwise the tooltip renders but stays invisible inside a Chrome extension
|
|
102
|
+
const base = 'z-[9999999999] w-max rounded p-xs tooltip-bg tooltip-text-color';
|
|
103
|
+
|
|
22
104
|
return (
|
|
23
|
-
|
|
24
|
-
{children}
|
|
105
|
+
<>
|
|
25
106
|
<div
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
107
|
+
ref={triggerRef}
|
|
108
|
+
className="inline-block cursor-pointer"
|
|
109
|
+
onMouseEnter={open}
|
|
110
|
+
onFocus={open}
|
|
111
|
+
onMouseLeave={close}
|
|
112
|
+
onBlur={close}
|
|
32
113
|
>
|
|
33
|
-
|
|
114
|
+
{children}
|
|
34
115
|
</div>
|
|
35
|
-
|
|
116
|
+
|
|
117
|
+
{visible &&
|
|
118
|
+
createPortal(
|
|
119
|
+
<div
|
|
120
|
+
ref={tooltipRef}
|
|
121
|
+
role="tooltip"
|
|
122
|
+
style={{
|
|
123
|
+
position: 'fixed',
|
|
124
|
+
top: coords.top,
|
|
125
|
+
left: coords.left,
|
|
126
|
+
transition: 'opacity .15s ease',
|
|
127
|
+
opacity: 1,
|
|
128
|
+
}}
|
|
129
|
+
className={cx(base, maxWidth)}
|
|
130
|
+
onMouseEnter={open}
|
|
131
|
+
onMouseLeave={close}
|
|
132
|
+
>
|
|
133
|
+
<p className="w-full break-words">{text}</p>
|
|
134
|
+
</div>,
|
|
135
|
+
document.body,
|
|
136
|
+
)}
|
|
137
|
+
</>
|
|
36
138
|
);
|
|
37
139
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright (c) 2025 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { VIDEO_AUTOPLAY_FLAGS, VIDEO_AUTOPLAY_FLAGS_NO_CONTROLS } from './video.constants';
|
|
6
|
+
|
|
7
|
+
export interface VideoProps {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the video should autoplay.
|
|
10
|
+
*/
|
|
11
|
+
isAutoPlayEnabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* If the video controls should be disabled.
|
|
14
|
+
*/
|
|
15
|
+
disableControls?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Video = forwardRef<
|
|
19
|
+
HTMLVideoElement,
|
|
20
|
+
React.ComponentPropsWithoutRef<'video'> & VideoProps
|
|
21
|
+
>(({ width = '100%', height = 'auto', isAutoPlayEnabled, disableControls, ...props }, ref) => {
|
|
22
|
+
const videoProps = isAutoPlayEnabled
|
|
23
|
+
? disableControls
|
|
24
|
+
? VIDEO_AUTOPLAY_FLAGS_NO_CONTROLS
|
|
25
|
+
: VIDEO_AUTOPLAY_FLAGS
|
|
26
|
+
: { preload: 'metadata', autoPlay: false };
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<video ref={ref} width={width} height={height} {...videoProps} {...props}>
|
|
30
|
+
Your browser does not support the video tag.
|
|
31
|
+
</video>
|
|
32
|
+
);
|
|
33
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright (c) 2025 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export const VIDEO_AUTOPLAY_FLAGS: Partial<
|
|
5
|
+
Omit<React.VideoHTMLAttributes<HTMLVideoElement>, 'src'>
|
|
6
|
+
> = {
|
|
7
|
+
autoPlay: true,
|
|
8
|
+
muted: true,
|
|
9
|
+
playsInline: true,
|
|
10
|
+
controls: true,
|
|
11
|
+
controlsList: 'nodownload',
|
|
12
|
+
disablePictureInPicture: true,
|
|
13
|
+
preload: 'auto',
|
|
14
|
+
loop: true,
|
|
15
|
+
width: '100%',
|
|
16
|
+
height: 'auto',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const VIDEO_AUTOPLAY_FLAGS_NO_CONTROLS: Partial<
|
|
20
|
+
Omit<React.VideoHTMLAttributes<HTMLVideoElement>, 'src'>
|
|
21
|
+
> = {
|
|
22
|
+
autoPlay: true,
|
|
23
|
+
muted: true,
|
|
24
|
+
playsInline: true,
|
|
25
|
+
controls: false,
|
|
26
|
+
disablePictureInPicture: true,
|
|
27
|
+
preload: 'auto',
|
|
28
|
+
loop: true,
|
|
29
|
+
width: '100%',
|
|
30
|
+
height: 'auto',
|
|
31
|
+
};
|
|
@@ -129,7 +129,7 @@ export function Account({
|
|
|
129
129
|
<Avatar isLocked={isLocked} />
|
|
130
130
|
<div className="flex flex-col items-start py-xs">
|
|
131
131
|
<div className="flex items-center space-x-2">
|
|
132
|
-
<span className="font-inter text-title-md
|
|
132
|
+
<span className="account-title-color font-inter text-title-md">
|
|
133
133
|
{title}
|
|
134
134
|
</span>
|
|
135
135
|
{badgeText && badgeType ? (
|
|
@@ -153,7 +153,7 @@ export function Account({
|
|
|
153
153
|
</div>
|
|
154
154
|
</div>
|
|
155
155
|
<div className="z-10 ml-auto flex items-center space-x-2 [&_button]:h-5 [&_button]:w-5 [&_svg]:h-5 [&_svg]:w-5">
|
|
156
|
-
<div className="flex items-center space-x-2 [&_button:not(.locked)]:hidden group-hover:[&_button:not(.locked)]:flex
|
|
156
|
+
<div className="account-icon-color flex items-center space-x-2 [&_button:not(.locked)]:hidden group-hover:[&_button:not(.locked)]:flex">
|
|
157
157
|
{onOptionsClick && (
|
|
158
158
|
<ButtonUnstyled onClick={onOptionsClick}>
|
|
159
159
|
<MoreHoriz />
|
|
@@ -180,9 +180,9 @@ export function Account({
|
|
|
180
180
|
{showSelected && (
|
|
181
181
|
<ButtonUnstyled>
|
|
182
182
|
{isSelected ? (
|
|
183
|
-
<CheckmarkFilled className="h-5 w-5
|
|
183
|
+
<CheckmarkFilled className="account-check-active-color h-5 w-5" />
|
|
184
184
|
) : (
|
|
185
|
-
<RadioOff className="h-5 w-5
|
|
185
|
+
<RadioOff className="account-check-inactive-color h-5 w-5" />
|
|
186
186
|
)}
|
|
187
187
|
</ButtonUnstyled>
|
|
188
188
|
)}
|
|
@@ -78,7 +78,7 @@ export function Address({
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
return (
|
|
81
|
-
<div className="group flex flex-row items-center gap-1
|
|
81
|
+
<div className="address-text-color group flex flex-row items-center gap-1">
|
|
82
82
|
<span className={cx('font-inter text-body-sm')}>{text}</span>
|
|
83
83
|
{isCopyable && (
|
|
84
84
|
<ButtonUnstyled
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { VisualAssetType } from '../visual-asset-card/visualAssetCard.enums';
|
|
5
|
+
import { Video, ImageWithFallback, Image } from '../../atoms';
|
|
6
|
+
import type { VideoProps } from '../../atoms';
|
|
7
|
+
|
|
8
|
+
export interface AssetMediaRendererProps extends VideoProps {
|
|
9
|
+
/**
|
|
10
|
+
* The source of the media to be displayed.
|
|
11
|
+
*/
|
|
12
|
+
src: string;
|
|
13
|
+
/**
|
|
14
|
+
* The type of the asset to be displayed.
|
|
15
|
+
*/
|
|
16
|
+
assetType: VisualAssetType;
|
|
17
|
+
/**
|
|
18
|
+
* Alt text for the image..
|
|
19
|
+
*/
|
|
20
|
+
altText?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Whether to show a fallback image if the main image fails to load.
|
|
23
|
+
*/
|
|
24
|
+
showFallback?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function AssetMediaRenderer({
|
|
28
|
+
src,
|
|
29
|
+
isAutoPlayEnabled,
|
|
30
|
+
assetType,
|
|
31
|
+
altText: alt,
|
|
32
|
+
showFallback,
|
|
33
|
+
disableControls,
|
|
34
|
+
}: AssetMediaRendererProps): React.JSX.Element {
|
|
35
|
+
if (assetType === VisualAssetType.Video) {
|
|
36
|
+
return (
|
|
37
|
+
<Video
|
|
38
|
+
src={src}
|
|
39
|
+
isAutoPlayEnabled={isAutoPlayEnabled}
|
|
40
|
+
disableControls={disableControls}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (showFallback) {
|
|
46
|
+
return <ImageWithFallback src={src} alt={alt} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return <Image src={src} alt={alt} />;
|
|
50
|
+
}
|
|
@@ -37,7 +37,7 @@ export function CardAction({
|
|
|
37
37
|
return (
|
|
38
38
|
<div
|
|
39
39
|
onClick={handleActionClick}
|
|
40
|
-
className="
|
|
40
|
+
className="card-action-link-color shrink-0 [&_svg]:h-5 [&_svg]:w-5"
|
|
41
41
|
>
|
|
42
42
|
{icon ? icon : <ArrowRight />}
|
|
43
43
|
</div>
|
|
@@ -48,12 +48,10 @@ export function CardAction({
|
|
|
48
48
|
return (
|
|
49
49
|
<div className="shrink-0 text-right">
|
|
50
50
|
{title && (
|
|
51
|
-
<div className="font-inter text-label-md
|
|
52
|
-
{title}
|
|
53
|
-
</div>
|
|
51
|
+
<div className="card-action-title-color font-inter text-label-md">{title}</div>
|
|
54
52
|
)}
|
|
55
53
|
{subtitle && (
|
|
56
|
-
<div className="font-inter text-label-sm
|
|
54
|
+
<div className="card-action-subtitle-color font-inter text-label-sm">
|
|
57
55
|
{subtitle}
|
|
58
56
|
</div>
|
|
59
57
|
)}
|
|
@@ -39,12 +39,13 @@ export function CardBody({
|
|
|
39
39
|
})}
|
|
40
40
|
>
|
|
41
41
|
<div
|
|
42
|
-
className={cx('
|
|
42
|
+
className={cx('card-body-title-color font-inter text-title-md', {
|
|
43
43
|
truncate: isTextTruncated,
|
|
44
44
|
})}
|
|
45
45
|
>
|
|
46
46
|
{title}
|
|
47
47
|
</div>
|
|
48
|
+
|
|
48
49
|
{tooltipText ? (
|
|
49
50
|
<Tooltip text={tooltipText} position={tooltipPosition}>
|
|
50
51
|
{icon}
|
|
@@ -60,7 +61,7 @@ export function CardBody({
|
|
|
60
61
|
</div>
|
|
61
62
|
{subtitle && (
|
|
62
63
|
<div
|
|
63
|
-
className={cx('font-inter text-body-md
|
|
64
|
+
className={cx('card-body-subtitle-color font-inter text-body-md', {
|
|
64
65
|
truncate: isTextTruncated,
|
|
65
66
|
})}
|
|
66
67
|
>
|
|
@@ -14,8 +14,8 @@ export const IMAGE_VARIANT_CLASSES: { [key in ImageShape]: string } = {
|
|
|
14
14
|
|
|
15
15
|
export const IMAGE_BG_CLASSES: { [key in ImageType]: string } = {
|
|
16
16
|
[ImageType.Placeholder]: '',
|
|
17
|
-
[ImageType.BgSolid]: '
|
|
18
|
-
[ImageType.BgWhite]: 'bg-white
|
|
17
|
+
[ImageType.BgSolid]: 'card-image-bg-solid',
|
|
18
|
+
[ImageType.BgWhite]: 'card-image-bg-white',
|
|
19
19
|
[ImageType.BgTransparent]: '',
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -23,5 +23,5 @@ export const CARD_TYPE_CLASSES: Record<CardType, string> = {
|
|
|
23
23
|
[CardType.Default]: 'border border-transparent',
|
|
24
24
|
[CardType.Outlined]:
|
|
25
25
|
'border border-shader-neutral-light-8 dark:border-shader-primary-dark-8 p-xs',
|
|
26
|
-
[CardType.Filled]: 'border border-transparent
|
|
26
|
+
[CardType.Filled]: 'border border-transparent card-filled-bg p-xs',
|
|
27
27
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
-
import { ChipState } from './chip.enums';
|
|
5
|
+
import { ChipSize, ChipState } from './chip.enums';
|
|
6
6
|
import {
|
|
7
7
|
BORDER_CLASSES,
|
|
8
8
|
BACKGROUND_CLASSES,
|
|
@@ -51,6 +51,10 @@ interface ChipProps {
|
|
|
51
51
|
* The button is disabled or not.
|
|
52
52
|
*/
|
|
53
53
|
disabled?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The size of the chip.
|
|
56
|
+
*/
|
|
57
|
+
size?: ChipSize;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
export function Chip({
|
|
@@ -63,6 +67,7 @@ export function Chip({
|
|
|
63
67
|
leadingElement,
|
|
64
68
|
trailingElement,
|
|
65
69
|
disabled,
|
|
70
|
+
size = ChipSize.Default,
|
|
66
71
|
}: ChipProps) {
|
|
67
72
|
const chipState = selected ? ChipState.Selected : ChipState.Default;
|
|
68
73
|
return (
|
|
@@ -89,7 +94,9 @@ export function Chip({
|
|
|
89
94
|
)}
|
|
90
95
|
>
|
|
91
96
|
{avatar ?? leadingElement}
|
|
92
|
-
<span className=
|
|
97
|
+
<span className={cx(size === ChipSize.Small ? 'text-label-md' : 'text-body-md')}>
|
|
98
|
+
{label}
|
|
99
|
+
</span>
|
|
93
100
|
{trailingElement}
|
|
94
101
|
{showClose && (
|
|
95
102
|
<ButtonUnstyled
|
|
@@ -7,7 +7,7 @@ export const ROUNDED_CLASS = 'rounded-full';
|
|
|
7
7
|
|
|
8
8
|
export const BACKGROUND_CLASSES: Record<ChipState, string> = {
|
|
9
9
|
[ChipState.Default]: 'bg-transparent',
|
|
10
|
-
[ChipState.Selected]: '
|
|
10
|
+
[ChipState.Selected]: 'chip-bg-selected',
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const STATE_LAYER_OUTLINE =
|
|
@@ -19,14 +19,14 @@ const STATE_LAYER_BG_CLASSES =
|
|
|
19
19
|
export const STATE_LAYER_CLASSES = `${STATE_LAYER_OUTLINE} ${STATE_LAYER_BG_CLASSES}`;
|
|
20
20
|
|
|
21
21
|
export const BORDER_CLASSES: Record<ChipState, string> = {
|
|
22
|
-
[ChipState.Default]: '
|
|
22
|
+
[ChipState.Default]: 'chip-border-default',
|
|
23
23
|
[ChipState.Selected]: 'border-transparent',
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export const TEXT_COLOR: Record<ChipState, string> = {
|
|
27
|
-
[ChipState.Default]: '
|
|
28
|
-
[ChipState.Selected]: '
|
|
27
|
+
[ChipState.Default]: 'chip-text-default',
|
|
28
|
+
[ChipState.Selected]: 'chip-text-selected',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export const FOCUS_CLASSES =
|
|
32
|
-
'focus-visible:shadow-[0_0_0_2px] focus-visible:
|
|
32
|
+
'focus-visible:shadow-[0_0_0_2px] focus-visible:chip-focus-ring focus-visible:outline-none';
|
|
@@ -120,7 +120,7 @@ export function DisplayStats({
|
|
|
120
120
|
</Tooltip>
|
|
121
121
|
)}
|
|
122
122
|
</div>
|
|
123
|
-
{icon && <span className="
|
|
123
|
+
{icon && <span className="display-stats-icon-color">{icon}</span>}
|
|
124
124
|
</div>
|
|
125
125
|
<div className="flex w-full flex-row items-baseline gap-xxs">
|
|
126
126
|
<span className={cx('break-all', valueClass)}>{value}</span>
|
|
@@ -132,7 +132,7 @@ export function DisplayStats({
|
|
|
132
132
|
{copyText && (
|
|
133
133
|
<div className="self-center">
|
|
134
134
|
<ButtonUnstyled onClick={handleCopyClick}>
|
|
135
|
-
<Copy className="
|
|
135
|
+
<Copy className="display-stats-copy-icon-color" />
|
|
136
136
|
</ButtonUnstyled>
|
|
137
137
|
</div>
|
|
138
138
|
)}
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
import { DisplayStatsType, DisplayStatsSize } from './displayStats.enums';
|
|
5
5
|
|
|
6
6
|
export const BACKGROUND_CLASSES: Record<DisplayStatsType, string> = {
|
|
7
|
-
[DisplayStatsType.Default]: '
|
|
8
|
-
[DisplayStatsType.Highlight]: '
|
|
9
|
-
[DisplayStatsType.Secondary]: '
|
|
7
|
+
[DisplayStatsType.Default]: 'display-stats-bg-default',
|
|
8
|
+
[DisplayStatsType.Highlight]: 'display-stats-bg-highlight',
|
|
9
|
+
[DisplayStatsType.Secondary]: 'display-stats-bg-secondary',
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export const TEXT_CLASSES: Record<DisplayStatsType, string> = {
|
|
13
|
-
[DisplayStatsType.Default]: '
|
|
14
|
-
[DisplayStatsType.Highlight]: '
|
|
15
|
-
[DisplayStatsType.Secondary]: '
|
|
13
|
+
[DisplayStatsType.Default]: 'display-stats-text-default',
|
|
14
|
+
[DisplayStatsType.Highlight]: 'display-stats-text-highlight',
|
|
15
|
+
[DisplayStatsType.Secondary]: 'display-stats-text-secondary',
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const SIZE_CLASSES: Record<DisplayStatsSize, string> = {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
export function Dropdown({ children }: React.PropsWithChildren): React.JSX.Element {
|
|
5
5
|
return (
|
|
6
|
-
<ul className="list-none rounded-lg border
|
|
6
|
+
<ul className="dropdown-bg dropdown-border-color list-none rounded-lg border py-xs">
|
|
7
7
|
{children}
|
|
8
8
|
</ul>
|
|
9
9
|
);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
export * from './address';
|
|
5
|
+
export * from './asset-media-renderer';
|
|
5
6
|
export * from './chip';
|
|
6
7
|
export * from './segmented-button';
|
|
7
8
|
export * from './title';
|
|
@@ -15,3 +16,4 @@ export * from './table-header-cell';
|
|
|
15
16
|
export * from './search';
|
|
16
17
|
export * from './card';
|
|
17
18
|
export * from './display-stats';
|
|
19
|
+
export * from './visual-asset-card';
|
|
@@ -115,9 +115,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function InputComp
|
|
|
115
115
|
onClick={focusOnInput}
|
|
116
116
|
ref={inputWrapperRef}
|
|
117
117
|
>
|
|
118
|
-
{leadingIcon &&
|
|
119
|
-
<span className="text-neutral-10 dark:text-neutral-92">{leadingIcon}</span>
|
|
120
|
-
)}
|
|
118
|
+
{leadingIcon && <span className="input-icon-color">{leadingIcon}</span>}
|
|
121
119
|
<InputElement
|
|
122
120
|
{...inputProps}
|
|
123
121
|
inputRef={forwardRef}
|
|
@@ -223,7 +221,7 @@ function InputTrailingElement({
|
|
|
223
221
|
if (showClearInput) {
|
|
224
222
|
return (
|
|
225
223
|
<ButtonUnstyled
|
|
226
|
-
className="
|
|
224
|
+
className="input-icon-color [&_svg]:h-5 [&_svg]:w-5"
|
|
227
225
|
onClick={onClearInput}
|
|
228
226
|
tabIndex={-1}
|
|
229
227
|
>
|
|
@@ -234,7 +232,7 @@ function InputTrailingElement({
|
|
|
234
232
|
return (
|
|
235
233
|
<ButtonUnstyled
|
|
236
234
|
onClick={onToggleButtonClick}
|
|
237
|
-
className="
|
|
235
|
+
className="input-icon-color [&_svg]:h-5 [&_svg]:w-5"
|
|
238
236
|
tabIndex={-1}
|
|
239
237
|
>
|
|
240
238
|
{isContentVisible ? <VisibilityOn /> : <VisibilityOff />}
|