@iota/apps-ui-kit 0.5.0 → 0.6.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 +24 -0
- package/dist/index.d.ts +47 -19
- package/dist/index.es.js +3609 -3516
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +43 -43
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -4
- package/src/lib/components/atoms/badge/Badge.tsx +1 -1
- package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +1 -1
- package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +1 -1
- package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +1 -1
- package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +15 -3
- package/src/lib/components/atoms/info-box/InfoBox.tsx +2 -1
- package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +3 -2
- package/src/lib/components/atoms/label-text/LabelText.tsx +2 -1
- package/src/lib/components/atoms/list-item/ListItem.tsx +2 -2
- package/src/lib/components/atoms/snackbar/Snackbar.tsx +1 -1
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +115 -14
- package/src/lib/components/molecules/account/Account.tsx +21 -3
- package/src/lib/components/molecules/address/Address.tsx +1 -1
- package/src/lib/components/molecules/card/CardAction.tsx +1 -1
- package/src/lib/components/molecules/card/CardBody.tsx +3 -3
- package/src/lib/components/molecules/chip/Chip.tsx +1 -1
- package/src/lib/components/molecules/display-stats/DisplayStats.tsx +41 -3
- package/src/lib/components/molecules/input/Input.tsx +5 -4
- package/src/lib/components/molecules/input/InputWrapper.tsx +1 -1
- package/src/lib/components/molecules/input/TextArea.tsx +3 -2
- package/src/lib/components/molecules/input/input.types.ts +3 -3
- package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +2 -2
- package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +2 -2
- package/src/lib/components/molecules/search/Search.tsx +2 -9
- package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +7 -3
- package/src/lib/components/molecules/select/Select.tsx +2 -3
- package/src/lib/components/molecules/table-cell/TableCell.tsx +2 -2
- package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +1 -1
- package/src/lib/components/molecules/title/Title.tsx +2 -1
- package/src/lib/components/organisms/accordion/Accordion.tsx +2 -2
- package/src/lib/components/organisms/dialog/Dialog.tsx +20 -1
- package/src/lib/components/organisms/navbar/Navbar.tsx +2 -1
- package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +3 -2
- package/src/lib/components/organisms/table/Table.tsx +6 -12
- package/src/lib/components/organisms/table/TableContext.tsx +2 -1
- package/src/lib/tailwind/base.presets.ts +1 -1
- package/src/lib/tailwind/constants/fontSizes.constants.ts +1 -1
- package/src/lib/tailwind/helpers.ts +1 -1
- package/src/lib/tailwind/responsive.presets.ts +1 -1
- package/src/lib/tailwind/types.ts +1 -1
- package/src/storybook/blocks/TypeSet.tsx +1 -1
- package/src/storybook/stories/atoms/Snackbar.stories.tsx +2 -1
- package/src/storybook/stories/molecules/Card.stories.tsx +1 -4
- package/src/storybook/stories/molecules/Dropdown.stories.tsx +1 -1
- package/src/storybook/stories/molecules/Input.stories.tsx +2 -1
- package/src/storybook/stories/molecules/Search.stories.tsx +2 -1
- package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +2 -1
- package/src/storybook/stories/molecules/Select.stories.tsx +2 -1
- package/src/storybook/stories/organisms/Navbar.stories.tsx +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iota/apps-ui-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "github.com:iotaledger/iota.git"
|
|
@@ -30,21 +30,20 @@
|
|
|
30
30
|
"react": "^18.3.1",
|
|
31
31
|
"react-dom": "^18.3.1",
|
|
32
32
|
"react-number-format": "^5.2.2",
|
|
33
|
-
"@iota/apps-ui-icons": "0.3.
|
|
33
|
+
"@iota/apps-ui-icons": "0.3.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@chromatic-com/storybook": "^1.6.0",
|
|
37
37
|
"@storybook/addon-essentials": "^7.1.0",
|
|
38
38
|
"@storybook/addon-interactions": "^7.1.0",
|
|
39
39
|
"@storybook/addon-links": "^7.1.0",
|
|
40
|
-
"@storybook/addon-onboarding": "^8.1.11",
|
|
41
40
|
"@storybook/blocks": "^7.1.0",
|
|
42
41
|
"@storybook/react": "^7.1.0",
|
|
43
42
|
"@storybook/react-vite": "^7.1.0",
|
|
44
|
-
"@storybook/test": "^8.1.11",
|
|
45
43
|
"@types/lodash.merge": "^4.6.9",
|
|
46
44
|
"@types/node": "^20.14.10",
|
|
47
45
|
"@types/react": "^18.3.3",
|
|
46
|
+
"@types/react-dom": "^18.3.0",
|
|
48
47
|
"@vitejs/plugin-react-swc": "^3.3.2",
|
|
49
48
|
"autoprefixer": "^10.4.19",
|
|
50
49
|
"cross-env": "^7.0.3",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
-
import { BadgeType } from './badge.enums';
|
|
5
|
+
import type { BadgeType } from './badge.enums';
|
|
6
6
|
import { BACKGROUND_COLORS, BADGE_TEXT_CLASS, BORDER_COLORS, TEXT_COLORS } from './badge.classes';
|
|
7
7
|
|
|
8
8
|
interface BadgeProps {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { ButtonHtmlType } from '../button.enums';
|
|
5
|
-
import { ButtonVariantProps } from './buttonVariants.types';
|
|
5
|
+
import type { ButtonVariantProps } from './buttonVariants.types';
|
|
6
6
|
|
|
7
7
|
export function ButtonPill({
|
|
8
8
|
htmlType = ButtonHtmlType.Button,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { ButtonHtmlType } from '../button.enums';
|
|
5
|
-
import { ButtonVariantProps } from './buttonVariants.types';
|
|
5
|
+
import type { ButtonVariantProps } from './buttonVariants.types';
|
|
6
6
|
import cx from 'classnames';
|
|
7
7
|
|
|
8
8
|
export function ButtonUnstyled({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { ButtonProps } from '../Button';
|
|
4
|
+
import type { ButtonProps } from '../Button';
|
|
5
5
|
|
|
6
6
|
type ButtonPickedProps = Pick<ButtonProps, 'htmlType' | 'testId'>;
|
|
7
7
|
type PropsFromButtonElement = Omit<React.HTMLProps<HTMLButtonElement>, 'type'>;
|
|
@@ -38,6 +38,10 @@ interface ButtonSegmentProps {
|
|
|
38
38
|
* The type of the button.
|
|
39
39
|
*/
|
|
40
40
|
type?: ButtonSegmentType;
|
|
41
|
+
/**
|
|
42
|
+
* If the button is nested inside a parent button.
|
|
43
|
+
*/
|
|
44
|
+
isNested?: boolean;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
export function ButtonSegment({
|
|
@@ -47,6 +51,7 @@ export function ButtonSegment({
|
|
|
47
51
|
disabled,
|
|
48
52
|
onClick,
|
|
49
53
|
type = ButtonSegmentType.Rounded,
|
|
54
|
+
isNested = false,
|
|
50
55
|
}: ButtonSegmentProps): React.JSX.Element {
|
|
51
56
|
const isUnderlined = type === ButtonSegmentType.Underlined;
|
|
52
57
|
|
|
@@ -58,9 +63,16 @@ export function ButtonSegment({
|
|
|
58
63
|
|
|
59
64
|
const underlined = isUnderlined ? (selected ? UNDERLINED_SELECTED : UNDERLINED) : '';
|
|
60
65
|
const textColors = selected ? TEXT_COLORS_SELECTED : TEXT_COLORS;
|
|
61
|
-
const padding = isUnderlined ? 'px-lg py-md' : 'px-sm py-[6px]';
|
|
66
|
+
const padding = isUnderlined ? (isNested ? 'px-md py-sm' : 'px-lg py-md') : 'px-sm py-[6px]';
|
|
62
67
|
const borderRadius = isUnderlined ? '' : 'rounded-full';
|
|
63
|
-
const textSize =
|
|
68
|
+
const textSize = isNested
|
|
69
|
+
? isUnderlined
|
|
70
|
+
? 'text-title-sm'
|
|
71
|
+
: 'text-label-md'
|
|
72
|
+
: isUnderlined
|
|
73
|
+
? 'text-title-md'
|
|
74
|
+
: 'text-label-lg';
|
|
75
|
+
|
|
64
76
|
return (
|
|
65
77
|
<ButtonUnstyled
|
|
66
78
|
onClick={onClick}
|
|
@@ -79,7 +91,7 @@ export function ButtonSegment({
|
|
|
79
91
|
>
|
|
80
92
|
<div className={cx('flex flex-row items-center justify-center gap-2', textSize)}>
|
|
81
93
|
{icon && <span>{icon}</span>}
|
|
82
|
-
<span className="font-inter">{label}</span>
|
|
94
|
+
<span className="shrink-0 font-inter">{label}</span>
|
|
83
95
|
</div>
|
|
84
96
|
</ButtonUnstyled>
|
|
85
97
|
);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
-
import {
|
|
5
|
+
import type { InfoBoxType } from './infoBox.enums';
|
|
6
|
+
import { InfoBoxStyle } from './infoBox.enums';
|
|
6
7
|
import { BACKGROUND_COLORS, ICON_COLORS } from './infoBox.classes';
|
|
7
8
|
|
|
8
9
|
export interface InfoBoxProps {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { ReactNode } from 'react';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { Copy, Info } from '@iota/apps-ui-icons';
|
|
7
7
|
import { ValueSize } from './keyValue.enums';
|
|
8
|
-
import {
|
|
8
|
+
import type { TooltipPosition } from '../tooltip';
|
|
9
|
+
import { Tooltip } from '../tooltip';
|
|
9
10
|
import { ButtonUnstyled } from '../button';
|
|
10
11
|
|
|
11
12
|
interface KeyValueProps {
|
|
@@ -5,7 +5,8 @@ import cx from 'classnames';
|
|
|
5
5
|
import { LabelTextSize } from './labelText.enums';
|
|
6
6
|
import { LABEL_TEXT_SIZE, SUPPORTING_TEXT_SIZE, TEXT_SIZE } from './labelText.classes';
|
|
7
7
|
import { Info } from '@iota/apps-ui-icons';
|
|
8
|
-
import { TooltipPosition
|
|
8
|
+
import type { TooltipPosition } from '../tooltip';
|
|
9
|
+
import { Tooltip } from '../tooltip';
|
|
9
10
|
|
|
10
11
|
interface LabelTextProps {
|
|
11
12
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { PropsWithChildren } from 'react';
|
|
4
|
+
import type { PropsWithChildren } from 'react';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { ArrowRight } from '@iota/apps-ui-icons';
|
|
7
|
-
import { Button, ButtonSize, ButtonType } from '
|
|
7
|
+
import { Button, ButtonSize, ButtonType } from '../button';
|
|
8
8
|
|
|
9
9
|
export interface ListItemProps {
|
|
10
10
|
/**
|
|
@@ -5,7 +5,7 @@ import { useEffect } from 'react';
|
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { Close } from '@iota/apps-ui-icons';
|
|
7
7
|
import { SnackbarType } from './snackbar.enums';
|
|
8
|
-
import { BACKGROUND_COLOR, TEXT_COLOR } from '
|
|
8
|
+
import { BACKGROUND_COLOR, TEXT_COLOR } from './snackbar.classes';
|
|
9
9
|
|
|
10
10
|
type Renderable = JSX.Element | string | null;
|
|
11
11
|
export interface SnackbarProps {
|
|
@@ -1,37 +1,138 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { useRef, useState, useLayoutEffect } from 'react';
|
|
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
|
+
const base =
|
|
101
|
+
'z-[999] w-max rounded bg-neutral-80 p-xs text-neutral-10 dark:bg-neutral-30 dark:text-neutral-92';
|
|
102
|
+
|
|
22
103
|
return (
|
|
23
|
-
|
|
24
|
-
{children}
|
|
104
|
+
<>
|
|
25
105
|
<div
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
106
|
+
ref={triggerRef}
|
|
107
|
+
className="inline-block cursor-pointer"
|
|
108
|
+
onMouseEnter={open}
|
|
109
|
+
onFocus={open}
|
|
110
|
+
onMouseLeave={close}
|
|
111
|
+
onBlur={close}
|
|
32
112
|
>
|
|
33
|
-
|
|
113
|
+
{children}
|
|
34
114
|
</div>
|
|
35
|
-
|
|
115
|
+
|
|
116
|
+
{visible &&
|
|
117
|
+
createPortal(
|
|
118
|
+
<div
|
|
119
|
+
ref={tooltipRef}
|
|
120
|
+
role="tooltip"
|
|
121
|
+
style={{
|
|
122
|
+
position: 'fixed',
|
|
123
|
+
top: coords.top,
|
|
124
|
+
left: coords.left,
|
|
125
|
+
transition: 'opacity .15s ease',
|
|
126
|
+
opacity: 1,
|
|
127
|
+
}}
|
|
128
|
+
className={cx(base, maxWidth)}
|
|
129
|
+
onMouseEnter={open}
|
|
130
|
+
onMouseLeave={close}
|
|
131
|
+
>
|
|
132
|
+
<p className="w-full break-words">{text}</p>
|
|
133
|
+
</div>,
|
|
134
|
+
document.body,
|
|
135
|
+
)}
|
|
136
|
+
</>
|
|
36
137
|
);
|
|
37
138
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
-
import {
|
|
6
|
-
import { Badge,
|
|
5
|
+
import type { BadgeType } from '@/components/atoms';
|
|
6
|
+
import { Badge, Tooltip, TooltipPosition, ButtonUnstyled } from '@/components/atoms';
|
|
7
7
|
import {
|
|
8
8
|
LockLocked,
|
|
9
9
|
LockUnlocked,
|
|
@@ -82,6 +82,14 @@ interface AccountProps {
|
|
|
82
82
|
* The text of the badge.
|
|
83
83
|
*/
|
|
84
84
|
badgeText?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The tooltip text of the badge.
|
|
87
|
+
*/
|
|
88
|
+
badgeTooltipText?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The tooltip position of the badge.
|
|
91
|
+
*/
|
|
92
|
+
badgeTooltipPosition?: TooltipPosition;
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
export function Account({
|
|
@@ -102,6 +110,8 @@ export function Account({
|
|
|
102
110
|
isSelected,
|
|
103
111
|
isActive,
|
|
104
112
|
showSelected,
|
|
113
|
+
badgeTooltipText,
|
|
114
|
+
badgeTooltipPosition = TooltipPosition.Bottom,
|
|
105
115
|
}: AccountProps): React.JSX.Element {
|
|
106
116
|
const Avatar = avatarContent;
|
|
107
117
|
|
|
@@ -122,7 +132,15 @@ export function Account({
|
|
|
122
132
|
<span className="font-inter text-title-md text-neutral-10 dark:text-neutral-92">
|
|
123
133
|
{title}
|
|
124
134
|
</span>
|
|
125
|
-
{
|
|
135
|
+
{badgeText && badgeType ? (
|
|
136
|
+
badgeTooltipText ? (
|
|
137
|
+
<Tooltip text={badgeTooltipText} position={badgeTooltipPosition}>
|
|
138
|
+
<Badge type={badgeType} label={badgeText} />
|
|
139
|
+
</Tooltip>
|
|
140
|
+
) : (
|
|
141
|
+
<Badge type={badgeType} label={badgeText} />
|
|
142
|
+
)
|
|
143
|
+
) : null}
|
|
126
144
|
</div>
|
|
127
145
|
<Address
|
|
128
146
|
text={subtitle}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { ArrowRight } from '@iota/apps-ui-icons';
|
|
5
5
|
import { CardActionType } from './card.enums';
|
|
6
|
-
import { Button, ButtonSize, ButtonType } from '
|
|
6
|
+
import { Button, ButtonSize, ButtonType } from '@/components/atoms/button';
|
|
7
7
|
|
|
8
8
|
export type CardActionProps = {
|
|
9
9
|
title?: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import cx from 'classnames';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
import { Tooltip } from '@/components/atoms/tooltip';
|
|
6
|
+
import type { TooltipPosition } from '@/components/atoms/tooltip';
|
|
7
7
|
|
|
8
8
|
export type CardBodyProps = {
|
|
9
9
|
title: string;
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
TEXT_COLOR,
|
|
12
12
|
FOCUS_CLASSES,
|
|
13
13
|
} from './chip.classes';
|
|
14
|
-
import { ButtonUnstyled } from '
|
|
14
|
+
import { ButtonUnstyled } from '@/components/atoms/button';
|
|
15
15
|
import { Close } from '@iota/apps-ui-icons';
|
|
16
16
|
|
|
17
17
|
interface ChipProps {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { ReactNode } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
import type { TooltipPosition } from '@/components/atoms';
|
|
6
|
+
import { ButtonUnstyled, Tooltip } from '@/components/atoms';
|
|
7
|
+
import { Copy, Info } from '@iota/apps-ui-icons';
|
|
7
8
|
import { DisplayStatsType, DisplayStatsSize } from './displayStats.enums';
|
|
8
9
|
import cx from 'classnames';
|
|
9
10
|
import {
|
|
@@ -48,6 +49,18 @@ interface DisplayStatsProps {
|
|
|
48
49
|
* Add icon to the right of the label.
|
|
49
50
|
*/
|
|
50
51
|
icon?: React.ReactNode;
|
|
52
|
+
/**
|
|
53
|
+
* Text that need to be copied (optional).
|
|
54
|
+
*/
|
|
55
|
+
copyText?: string;
|
|
56
|
+
/**
|
|
57
|
+
* The onCopySuccess event of the KeyValue (optional).
|
|
58
|
+
*/
|
|
59
|
+
onCopySuccess?: (e: React.MouseEvent<HTMLButtonElement>, text: string) => void;
|
|
60
|
+
/**
|
|
61
|
+
* The onCopyError event of the KeyValue (optional).
|
|
62
|
+
*/
|
|
63
|
+
onCopyError?: (e: unknown, text: string) => void;
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
export function DisplayStats({
|
|
@@ -59,6 +72,9 @@ export function DisplayStats({
|
|
|
59
72
|
type = DisplayStatsType.Default,
|
|
60
73
|
size = DisplayStatsSize.Default,
|
|
61
74
|
icon,
|
|
75
|
+
copyText,
|
|
76
|
+
onCopySuccess,
|
|
77
|
+
onCopyError,
|
|
62
78
|
}: DisplayStatsProps): React.JSX.Element {
|
|
63
79
|
const backgroundClass = BACKGROUND_CLASSES[type];
|
|
64
80
|
const sizeClass = SIZE_CLASSES[size];
|
|
@@ -67,6 +83,21 @@ export function DisplayStats({
|
|
|
67
83
|
const labelClass = LABEL_TEXT_CLASSES[size];
|
|
68
84
|
const supportingLabelTextClass = SUPPORTING_LABEL_TEXT_CLASSES[size];
|
|
69
85
|
|
|
86
|
+
async function handleCopyClick(event: React.MouseEvent<HTMLButtonElement>) {
|
|
87
|
+
if (!navigator.clipboard) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (copyText) {
|
|
92
|
+
try {
|
|
93
|
+
await navigator.clipboard.writeText(copyText);
|
|
94
|
+
onCopySuccess?.(event, copyText);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('Failed to copy:', error);
|
|
97
|
+
onCopyError?.(error, copyText);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
70
101
|
return (
|
|
71
102
|
<div
|
|
72
103
|
className={cx(
|
|
@@ -98,6 +129,13 @@ export function DisplayStats({
|
|
|
98
129
|
{supportingLabel}
|
|
99
130
|
</span>
|
|
100
131
|
)}
|
|
132
|
+
{copyText && (
|
|
133
|
+
<div className="self-center">
|
|
134
|
+
<ButtonUnstyled onClick={handleCopyClick}>
|
|
135
|
+
<Copy className="text-neutral-60 dark:text-neutral-40" />
|
|
136
|
+
</ButtonUnstyled>
|
|
137
|
+
</div>
|
|
138
|
+
)}
|
|
101
139
|
</div>
|
|
102
140
|
</div>
|
|
103
141
|
);
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
import { forwardRef, Fragment, useEffect, useRef, useState } from 'react';
|
|
5
5
|
import cx from 'classnames';
|
|
6
|
-
import {
|
|
6
|
+
import type { InputWrapperProps } from './InputWrapper';
|
|
7
|
+
import { InputWrapper } from './InputWrapper';
|
|
7
8
|
import {
|
|
8
9
|
BORDER_CLASSES,
|
|
9
10
|
INPUT_CLASSES,
|
|
@@ -12,10 +13,10 @@ import {
|
|
|
12
13
|
INPUT_PLACEHOLDER_CLASSES,
|
|
13
14
|
} from './input.classes';
|
|
14
15
|
import { InputType } from './input.enums';
|
|
15
|
-
import { SecondaryText } from '
|
|
16
|
+
import { SecondaryText } from '@/components/atoms/secondary-text';
|
|
16
17
|
import { Close, VisibilityOff, VisibilityOn } from '@iota/apps-ui-icons';
|
|
17
|
-
import { ButtonUnstyled } from '
|
|
18
|
-
import { InputPropsByType, NumericFormatInputProps } from './input.types';
|
|
18
|
+
import { ButtonUnstyled } from '@/components/atoms/button';
|
|
19
|
+
import type { InputPropsByType, NumericFormatInputProps } from './input.types';
|
|
19
20
|
import { NumericFormat } from 'react-number-format';
|
|
20
21
|
|
|
21
22
|
export interface BaseInputProps extends InputWrapperProps {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
-
import { SecondaryText } from '
|
|
5
|
+
import { SecondaryText } from '@/components/atoms/secondary-text';
|
|
6
6
|
import { LABEL_CLASSES } from './input.classes';
|
|
7
7
|
import { createElement } from 'react';
|
|
8
8
|
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { forwardRef, useEffect, useState } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import type { InputWrapperProps } from './InputWrapper';
|
|
6
|
+
import { InputWrapper } from './InputWrapper';
|
|
6
7
|
import {
|
|
7
8
|
BORDER_CLASSES,
|
|
8
9
|
INPUT_CLASSES,
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
INPUT_PLACEHOLDER_CLASSES,
|
|
11
12
|
} from './input.classes';
|
|
12
13
|
import cx from 'classnames';
|
|
13
|
-
import { ButtonUnstyled } from '
|
|
14
|
+
import { ButtonUnstyled } from '@/components/atoms/button';
|
|
14
15
|
import { VisibilityOff, VisibilityOn } from '@iota/apps-ui-icons';
|
|
15
16
|
|
|
16
17
|
type TextAreaProps = Omit<
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { ComponentProps } from 'react';
|
|
5
|
-
import { InputType } from '.';
|
|
6
|
-
import { NumericFormat } from 'react-number-format';
|
|
4
|
+
import type { ComponentProps } from 'react';
|
|
5
|
+
import type { InputType } from '.';
|
|
6
|
+
import type { NumericFormat } from 'react-number-format';
|
|
7
7
|
|
|
8
8
|
type InputElementProps = Omit<
|
|
9
9
|
React.ComponentProps<'input'>,
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
UNSELECTED_ICON,
|
|
14
14
|
UNSELECTED_TEXT,
|
|
15
15
|
} from './navbarItem.classes';
|
|
16
|
-
import { Badge, BadgeType } from '
|
|
17
|
-
import { NavbarItemProps } from './NavbarItem';
|
|
16
|
+
import { Badge, BadgeType } from '@/components/atoms';
|
|
17
|
+
import type { NavbarItemProps } from './NavbarItem';
|
|
18
18
|
|
|
19
19
|
export function NavbarItemHorizontal({
|
|
20
20
|
icon,
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
UNSELECTED_ICON,
|
|
10
10
|
UNSELECTED_TEXT,
|
|
11
11
|
} from './navbarItem.classes';
|
|
12
|
-
import { Badge, BadgeType } from '
|
|
13
|
-
import { NavbarItemProps } from './NavbarItem';
|
|
12
|
+
import { Badge, BadgeType } from '@/components/atoms';
|
|
13
|
+
import type { NavbarItemProps } from './NavbarItem';
|
|
14
14
|
|
|
15
15
|
export function NavbarItemVertical({
|
|
16
16
|
icon,
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { Loader, Search as SearchIcon } from '@iota/apps-ui-icons';
|
|
7
|
-
import { Divider
|
|
7
|
+
import { Divider } from '@/components/atoms';
|
|
8
|
+
import { SearchBarType } from './search.enums';
|
|
8
9
|
import {
|
|
9
10
|
BACKGROUND_COLORS,
|
|
10
11
|
SUGGESTIONS_WRAPPER_STYLE,
|
|
@@ -43,10 +44,6 @@ export interface SearchProps {
|
|
|
43
44
|
* Are the suggestions loading.
|
|
44
45
|
*/
|
|
45
46
|
isLoading: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Callback when a key is pressed.
|
|
48
|
-
*/
|
|
49
|
-
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
50
47
|
/**
|
|
51
48
|
* The type of the search bar. Can be 'outlined' or 'filled'.
|
|
52
49
|
*/
|
|
@@ -64,7 +61,6 @@ export function Search({
|
|
|
64
61
|
onSuggestionClick,
|
|
65
62
|
placeholder,
|
|
66
63
|
isLoading = false,
|
|
67
|
-
onKeyDown,
|
|
68
64
|
type = SearchBarType.Outlined,
|
|
69
65
|
renderSuggestion,
|
|
70
66
|
}: SearchProps): React.JSX.Element {
|
|
@@ -157,9 +153,6 @@ export function Search({
|
|
|
157
153
|
}
|
|
158
154
|
}
|
|
159
155
|
}
|
|
160
|
-
if (onKeyDown) {
|
|
161
|
-
onKeyDown(event);
|
|
162
|
-
}
|
|
163
156
|
};
|
|
164
157
|
|
|
165
158
|
return (
|