@iota/apps-ui-kit 0.2.0 → 0.3.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 +45 -0
- package/dist/index.d.ts +1636 -0
- package/dist/index.es.js +8909 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +198 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +6 -3
- package/src/lib/components/atoms/badge/Badge.tsx +37 -0
- package/src/lib/components/atoms/badge/badge.classes.ts +24 -0
- package/src/lib/components/atoms/badge/badge.enums.ts +8 -0
- package/src/lib/components/atoms/badge/index.ts +6 -0
- package/src/lib/components/atoms/button/Button.tsx +99 -0
- package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +23 -0
- package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +27 -0
- package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +11 -0
- package/src/lib/components/atoms/button/button-variants/index.ts +5 -0
- package/src/lib/components/atoms/button/button.classes.ts +53 -0
- package/src/lib/components/atoms/button/button.enums.ts +21 -0
- package/src/lib/components/atoms/button/index.ts +7 -0
- package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +86 -0
- package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +45 -0
- package/src/lib/components/atoms/button-segment/buttonSegment.enums.ts +7 -0
- package/src/lib/components/atoms/button-segment/index.ts +5 -0
- package/src/lib/components/atoms/checkbox/Checkbox.tsx +114 -0
- package/src/lib/components/atoms/checkbox/index.ts +4 -0
- package/src/lib/components/atoms/divider/Divider.tsx +48 -0
- package/src/lib/components/atoms/divider/divider.classes.ts +11 -0
- package/src/lib/components/atoms/divider/divider.enums.ts +7 -0
- package/src/lib/components/atoms/divider/index.ts +6 -0
- package/src/lib/components/atoms/header/Header.tsx +73 -0
- package/src/lib/components/atoms/header/index.ts +4 -0
- package/src/lib/components/atoms/index.ts +22 -0
- package/src/lib/components/atoms/info-box/InfoBox.tsx +73 -0
- package/src/lib/components/atoms/info-box/index.ts +5 -0
- package/src/lib/components/atoms/info-box/infoBox.classes.ts +19 -0
- package/src/lib/components/atoms/info-box/infoBox.enums.ts +14 -0
- package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +156 -0
- package/src/lib/components/atoms/key-value-info/index.ts +6 -0
- package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
- package/src/lib/components/atoms/label-text/LabelText.tsx +93 -0
- package/src/lib/components/atoms/label-text/index.ts +5 -0
- package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
- package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
- package/src/lib/components/atoms/list-item/ListItem.tsx +89 -0
- package/src/lib/components/atoms/list-item/index.ts +4 -0
- package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
- package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
- package/src/lib/components/atoms/panel/Panel.tsx +30 -0
- package/src/lib/components/atoms/panel/index.ts +4 -0
- package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
- package/src/lib/components/atoms/placeholder/index.ts +4 -0
- package/src/lib/components/atoms/radio-button/RadioButton.tsx +68 -0
- package/src/lib/components/atoms/radio-button/index.ts +4 -0
- package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +28 -0
- package/src/lib/components/atoms/secondary-text/index.ts +4 -0
- package/src/lib/components/atoms/skeleton/Skeleton.tsx +47 -0
- package/src/lib/components/atoms/skeleton/index.ts +4 -0
- package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
- package/src/lib/components/atoms/snackbar/index.ts +5 -0
- package/src/lib/components/atoms/snackbar/snackbar.classes.ts +18 -0
- package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +9 -0
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +37 -0
- package/src/lib/components/atoms/tooltip/index.ts +5 -0
- package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
- package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
- package/src/lib/components/atoms/visual-asset-card/VisualAssetCard.tsx +101 -0
- package/src/lib/components/atoms/visual-asset-card/index.ts +5 -0
- package/src/lib/components/atoms/visual-asset-card/visualAssetCard.enums.ts +7 -0
- package/src/lib/components/index.ts +8 -0
- package/src/lib/components/molecules/account/Account.tsx +174 -0
- package/src/lib/components/molecules/account/index.ts +4 -0
- package/src/lib/components/molecules/address/Address.tsx +101 -0
- package/src/lib/components/molecules/address/index.ts +4 -0
- package/src/lib/components/molecules/card/Card.tsx +70 -0
- package/src/lib/components/molecules/card/CardAction.tsx +80 -0
- package/src/lib/components/molecules/card/CardBody.tsx +61 -0
- package/src/lib/components/molecules/card/CardImage.tsx +43 -0
- package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
- package/src/lib/components/molecules/card/card.classes.ts +26 -0
- package/src/lib/components/molecules/card/card.enums.ts +25 -0
- package/src/lib/components/molecules/card/index.ts +8 -0
- package/src/lib/components/molecules/chip/Chip.tsx +105 -0
- package/src/lib/components/molecules/chip/chip.classes.ts +32 -0
- package/src/lib/components/molecules/chip/chip.enums.ts +7 -0
- package/src/lib/components/molecules/chip/index.ts +4 -0
- package/src/lib/components/molecules/display-stats/DisplayStats.tsx +104 -0
- package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
- package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
- package/src/lib/components/molecules/display-stats/index.ts +5 -0
- package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
- package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
- package/src/lib/components/molecules/dropdown/index.ts +5 -0
- package/src/lib/components/molecules/index.ts +17 -0
- package/src/lib/components/molecules/input/Input.tsx +245 -0
- package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
- package/src/lib/components/molecules/input/TextArea.tsx +149 -0
- package/src/lib/components/molecules/input/index.ts +8 -0
- package/src/lib/components/molecules/input/input.classes.ts +14 -0
- package/src/lib/components/molecules/input/input.enums.ts +14 -0
- package/src/lib/components/molecules/input/input.types.ts +29 -0
- package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +48 -0
- package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
- package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
- package/src/lib/components/molecules/navbar-item/index.ts +5 -0
- package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
- package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
- package/src/lib/components/molecules/search/Search.tsx +220 -0
- package/src/lib/components/molecules/search/index.ts +5 -0
- package/src/lib/components/molecules/search/search.classes.ts +20 -0
- package/src/lib/components/molecules/search/search.enums.ts +7 -0
- package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +34 -0
- package/src/lib/components/molecules/segmented-button/index.ts +6 -0
- package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
- package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
- package/src/lib/components/molecules/select/Select.tsx +223 -0
- package/src/lib/components/molecules/select/index.ts +5 -0
- package/src/lib/components/molecules/select/select.enums.ts +7 -0
- package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
- package/src/lib/components/molecules/table-cell/index.ts +4 -0
- package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +140 -0
- package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
- package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
- package/src/lib/components/molecules/title/Title.tsx +69 -0
- package/src/lib/components/molecules/title/index.ts +5 -0
- package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
- package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
- package/src/lib/components/organisms/accordion/Accordion.tsx +109 -0
- package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
- package/src/lib/components/organisms/accordion/index.ts +4 -0
- package/src/lib/components/organisms/dialog/Dialog.tsx +123 -0
- package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
- package/src/lib/components/organisms/dialog/index.ts +5 -0
- package/src/lib/components/organisms/index.ts +7 -0
- package/src/lib/components/organisms/navbar/Navbar.tsx +100 -0
- package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +58 -0
- package/src/lib/components/organisms/navbar/index.ts +5 -0
- package/src/lib/components/organisms/table/Table.tsx +224 -0
- package/src/lib/components/organisms/table/TableContext.tsx +55 -0
- package/src/lib/components/organisms/table/index.ts +4 -0
- package/src/lib/constants/colors.constants.ts +132 -0
- package/src/lib/constants/index.ts +4 -0
- package/src/lib/enums/index.ts +4 -0
- package/src/lib/enums/screenSize.enums.ts +9 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/styles/fonts.css +5 -0
- package/src/lib/styles/index.css +149 -0
- package/src/lib/tailwind/base.presets.ts +49 -0
- package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
- package/src/lib/tailwind/constants/index.ts +6 -0
- package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
- package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
- package/src/lib/tailwind/helpers.ts +20 -0
- package/src/lib/tailwind/index.ts +5 -0
- package/src/lib/tailwind/plugins.ts +8 -0
- package/src/lib/tailwind/responsive.presets.ts +36 -0
- package/src/lib/tailwind/static.presets.ts +25 -0
- package/src/lib/tailwind/types.ts +6 -0
- package/src/lib/utils/format.ts +8 -0
- package/src/lib/utils/index.ts +4 -0
- package/src/storybook/blocks/Showcase.tsx +20 -0
- package/src/storybook/blocks/TypeSet.tsx +34 -0
- package/src/storybook/blocks/TypeSetItem.tsx +74 -0
- package/src/storybook/blocks/index.ts +6 -0
- package/src/storybook/constants/index.ts +5 -0
- package/src/storybook/constants/typeset.constants.ts +39 -0
- package/src/storybook/constants/variableSpacing.constants.ts +6 -0
- package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
- package/src/storybook/helpers/index.ts +4 -0
- package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
- package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
- package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
- package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
- package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
- package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
- package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
- package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
- package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
- package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
- package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
- package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
- package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
- package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
- package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
- package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
- package/src/storybook/stories/atoms/Snackbar.stories.tsx +42 -0
- package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
- package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
- package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
- package/src/storybook/stories/components/index.ts +4 -0
- package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
- package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
- package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
- package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
- package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
- package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
- package/src/storybook/stories/molecules/Card.stories.tsx +115 -0
- package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
- package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
- package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
- package/src/storybook/stories/molecules/Input.stories.tsx +161 -0
- package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
- package/src/storybook/stories/molecules/Search.stories.tsx +100 -0
- package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +107 -0
- package/src/storybook/stories/molecules/Select.stories.tsx +102 -0
- package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
- package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
- package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
- package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
- package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
- package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
- package/src/storybook/stories/organisms/Navbar.stories.tsx +77 -0
- package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import { ButtonUnstyled } from '../../atoms/button';
|
|
6
|
+
import { Badge, BadgeType } from '../../atoms';
|
|
7
|
+
import {
|
|
8
|
+
LockLocked,
|
|
9
|
+
LockUnlocked,
|
|
10
|
+
MoreHoriz,
|
|
11
|
+
CheckmarkFilled,
|
|
12
|
+
RadioOff,
|
|
13
|
+
} from '@iota/apps-ui-icons';
|
|
14
|
+
import { Address } from '../address';
|
|
15
|
+
|
|
16
|
+
interface AccountProps {
|
|
17
|
+
/**
|
|
18
|
+
* The title of the account.
|
|
19
|
+
*/
|
|
20
|
+
title: string;
|
|
21
|
+
/**
|
|
22
|
+
* The subtitle of the account.
|
|
23
|
+
*/
|
|
24
|
+
subtitle: string;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the account is unlocked.
|
|
27
|
+
*/
|
|
28
|
+
isLocked?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Handler for more options click.
|
|
31
|
+
*/
|
|
32
|
+
onOptionsClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Handler for the lock account icon click.
|
|
35
|
+
*/
|
|
36
|
+
onLockAccountClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Handle for the unlock account icon click.
|
|
39
|
+
*/
|
|
40
|
+
onUnlockAccountClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Function to render avatar content.
|
|
43
|
+
*/
|
|
44
|
+
avatarContent: ({ isLocked }: { isLocked?: boolean }) => React.JSX.Element;
|
|
45
|
+
/**
|
|
46
|
+
* The onCopy event of the Address (optional).
|
|
47
|
+
*/
|
|
48
|
+
onCopy?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Text that need to be copied (optional).
|
|
51
|
+
*/
|
|
52
|
+
copyText?: string;
|
|
53
|
+
/**
|
|
54
|
+
* The onOpen event of the Address (optional).
|
|
55
|
+
*/
|
|
56
|
+
onOpen?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Has copy icon (optional).
|
|
59
|
+
*/
|
|
60
|
+
isCopyable?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Has open icon (optional).
|
|
63
|
+
*/
|
|
64
|
+
isExternal?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The account is selected.
|
|
67
|
+
*/
|
|
68
|
+
isSelected?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Show the selected checkbox.
|
|
71
|
+
*/
|
|
72
|
+
showSelected?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Show background if account active (optional).
|
|
75
|
+
*/
|
|
76
|
+
isActive?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The type of the badge.
|
|
79
|
+
*/
|
|
80
|
+
badgeType?: BadgeType;
|
|
81
|
+
/**
|
|
82
|
+
* The text of the badge.
|
|
83
|
+
*/
|
|
84
|
+
badgeText?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function Account({
|
|
88
|
+
title,
|
|
89
|
+
subtitle,
|
|
90
|
+
badgeType,
|
|
91
|
+
badgeText,
|
|
92
|
+
isLocked,
|
|
93
|
+
avatarContent,
|
|
94
|
+
onOptionsClick,
|
|
95
|
+
onLockAccountClick,
|
|
96
|
+
onUnlockAccountClick,
|
|
97
|
+
onCopy,
|
|
98
|
+
copyText,
|
|
99
|
+
onOpen,
|
|
100
|
+
isCopyable,
|
|
101
|
+
isExternal,
|
|
102
|
+
isSelected,
|
|
103
|
+
isActive,
|
|
104
|
+
showSelected,
|
|
105
|
+
}: AccountProps): React.JSX.Element {
|
|
106
|
+
const Avatar = avatarContent;
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
className={cx(
|
|
111
|
+
'state-layer group relative flex w-full items-center justify-between space-x-3 rounded-xl px-sm py-xs hover:cursor-pointer',
|
|
112
|
+
isActive && 'state-active',
|
|
113
|
+
{
|
|
114
|
+
'opacity-60': isLocked && showSelected,
|
|
115
|
+
},
|
|
116
|
+
)}
|
|
117
|
+
>
|
|
118
|
+
<div className="flex items-center space-x-3">
|
|
119
|
+
<Avatar isLocked={isLocked} />
|
|
120
|
+
<div className="flex flex-col items-start py-xs">
|
|
121
|
+
<div className="flex items-center space-x-2">
|
|
122
|
+
<span className="font-inter text-title-md text-neutral-10 dark:text-neutral-92">
|
|
123
|
+
{title}
|
|
124
|
+
</span>
|
|
125
|
+
{badgeType && badgeText && <Badge type={badgeType} label={badgeText} />}
|
|
126
|
+
</div>
|
|
127
|
+
<Address
|
|
128
|
+
text={subtitle}
|
|
129
|
+
onCopySuccess={onCopy}
|
|
130
|
+
copyText={copyText}
|
|
131
|
+
onOpen={onOpen}
|
|
132
|
+
isCopyable={isCopyable}
|
|
133
|
+
isExternal={isExternal}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
<div className="z-10 ml-auto flex items-center space-x-2 [&_button]:h-5 [&_button]:w-5 [&_svg]:h-5 [&_svg]:w-5">
|
|
138
|
+
<div className="flex items-center space-x-2 [&_button:not(.locked)]:hidden group-hover:[&_button:not(.locked)]:flex [&_svg]:text-neutral-40 [&_svg]:dark:text-neutral-60">
|
|
139
|
+
{onOptionsClick && (
|
|
140
|
+
<ButtonUnstyled onClick={onOptionsClick}>
|
|
141
|
+
<MoreHoriz />
|
|
142
|
+
</ButtonUnstyled>
|
|
143
|
+
)}
|
|
144
|
+
{onLockAccountClick &&
|
|
145
|
+
onUnlockAccountClick &&
|
|
146
|
+
(isLocked ? (
|
|
147
|
+
<div className="flex items-center">
|
|
148
|
+
<ButtonUnstyled
|
|
149
|
+
onClick={onUnlockAccountClick}
|
|
150
|
+
testId="account-unlock"
|
|
151
|
+
className="locked"
|
|
152
|
+
>
|
|
153
|
+
<LockLocked />
|
|
154
|
+
</ButtonUnstyled>
|
|
155
|
+
</div>
|
|
156
|
+
) : (
|
|
157
|
+
<ButtonUnstyled onClick={onLockAccountClick} testId="account-lock">
|
|
158
|
+
<LockUnlocked />
|
|
159
|
+
</ButtonUnstyled>
|
|
160
|
+
))}
|
|
161
|
+
</div>
|
|
162
|
+
{showSelected && (
|
|
163
|
+
<ButtonUnstyled>
|
|
164
|
+
{isSelected ? (
|
|
165
|
+
<CheckmarkFilled className="h-5 w-5 text-primary-30 dark:text-primary-80" />
|
|
166
|
+
) : (
|
|
167
|
+
<RadioOff className="h-5 w-5 text-neutral-40 dark:text-neutral-60" />
|
|
168
|
+
)}
|
|
169
|
+
</ButtonUnstyled>
|
|
170
|
+
)}
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import { Copy, ArrowTopRight } from '@iota/apps-ui-icons';
|
|
6
|
+
import { ButtonUnstyled } from '../../atoms/button';
|
|
7
|
+
|
|
8
|
+
interface AddressProps {
|
|
9
|
+
/**
|
|
10
|
+
* The text of the address.
|
|
11
|
+
*/
|
|
12
|
+
text: string;
|
|
13
|
+
/**
|
|
14
|
+
* Has copy icon (optional).
|
|
15
|
+
*/
|
|
16
|
+
isCopyable?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Has open icon (optional).
|
|
19
|
+
*/
|
|
20
|
+
isExternal?: boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The link for external resource (optional).
|
|
24
|
+
*/
|
|
25
|
+
externalLink?: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Text that need to be copied (optional).
|
|
29
|
+
*/
|
|
30
|
+
copyText?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The onCopySuccess event of the Address (optional).
|
|
33
|
+
*/
|
|
34
|
+
onCopySuccess?: (e: React.MouseEvent<HTMLButtonElement>, text: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* The onCopyError event of the Address (optional).
|
|
37
|
+
*/
|
|
38
|
+
onCopyError?: (e: unknown, text: string) => void;
|
|
39
|
+
/**
|
|
40
|
+
* The onOpen event of the Address (optional).
|
|
41
|
+
*/
|
|
42
|
+
onOpen?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function Address({
|
|
46
|
+
text,
|
|
47
|
+
isCopyable,
|
|
48
|
+
isExternal,
|
|
49
|
+
externalLink,
|
|
50
|
+
copyText = text,
|
|
51
|
+
onCopySuccess,
|
|
52
|
+
onCopyError,
|
|
53
|
+
onOpen,
|
|
54
|
+
}: AddressProps): React.JSX.Element {
|
|
55
|
+
async function handleCopyClick(event: React.MouseEvent<HTMLButtonElement>) {
|
|
56
|
+
if (!navigator.clipboard) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
event?.stopPropagation();
|
|
61
|
+
try {
|
|
62
|
+
await navigator.clipboard.writeText(copyText);
|
|
63
|
+
onCopySuccess?.(event, copyText);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('Failed to copy:', error);
|
|
66
|
+
onCopyError?.(error, copyText);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function handleOpenClick(event: React.MouseEvent<HTMLButtonElement>) {
|
|
71
|
+
event?.stopPropagation();
|
|
72
|
+
if (externalLink) {
|
|
73
|
+
const newWindow = window.open(externalLink, '_blank', 'noopener noreferrer');
|
|
74
|
+
if (newWindow) newWindow.opener = null;
|
|
75
|
+
} else {
|
|
76
|
+
onOpen?.(event);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div className="group flex flex-row items-center gap-1 text-neutral-40 dark:text-neutral-60">
|
|
82
|
+
<span className={cx('font-inter text-body-sm')}>{text}</span>
|
|
83
|
+
{isCopyable && (
|
|
84
|
+
<ButtonUnstyled
|
|
85
|
+
onClick={handleCopyClick}
|
|
86
|
+
className="opacity-0 group-hover:opacity-100"
|
|
87
|
+
>
|
|
88
|
+
<Copy />
|
|
89
|
+
</ButtonUnstyled>
|
|
90
|
+
)}
|
|
91
|
+
{isExternal && (
|
|
92
|
+
<ButtonUnstyled
|
|
93
|
+
onClick={handleOpenClick}
|
|
94
|
+
className="opacity-0 group-hover:opacity-100"
|
|
95
|
+
>
|
|
96
|
+
<ArrowTopRight />
|
|
97
|
+
</ButtonUnstyled>
|
|
98
|
+
)}
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import { CARD_DISABLED_CLASSES, CARD_TYPE_CLASSES } from './card.classes';
|
|
6
|
+
import { CardType } from './card.enums';
|
|
7
|
+
|
|
8
|
+
export interface CardProps {
|
|
9
|
+
/**
|
|
10
|
+
* If `true`, the card will be disabled.
|
|
11
|
+
*/
|
|
12
|
+
isDisabled?: boolean;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Handler on click to the card.
|
|
16
|
+
*/
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* UI variant of the card.
|
|
21
|
+
*/
|
|
22
|
+
type?: CardType;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Passing composable Card components like: CardImage, CardText, CardAction.
|
|
26
|
+
*/
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Indicates whether the state-layer should be shown on the card anyway.
|
|
31
|
+
* Use case: When the card is wrapped with a Link component
|
|
32
|
+
*/
|
|
33
|
+
isHoverable?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The 'data-testid' attribute value (used in e2e tests)
|
|
36
|
+
*/
|
|
37
|
+
testId?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function Card({
|
|
41
|
+
isDisabled = false,
|
|
42
|
+
type = CardType.Default,
|
|
43
|
+
isHoverable,
|
|
44
|
+
onClick,
|
|
45
|
+
children,
|
|
46
|
+
testId,
|
|
47
|
+
}: CardProps) {
|
|
48
|
+
function handleOnClick() {
|
|
49
|
+
if (!isDisabled) {
|
|
50
|
+
onClick?.();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
onClick={handleOnClick}
|
|
56
|
+
className={cx(
|
|
57
|
+
'relative inline-flex w-full items-center gap-3 rounded-xl px-sm py-xs',
|
|
58
|
+
CARD_TYPE_CLASSES[type],
|
|
59
|
+
{
|
|
60
|
+
'state-layer': isHoverable || (!isDisabled && onClick),
|
|
61
|
+
[CARD_DISABLED_CLASSES]: isDisabled,
|
|
62
|
+
'cursor-pointer': onClick,
|
|
63
|
+
},
|
|
64
|
+
)}
|
|
65
|
+
data-testid={testId}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { ArrowRight } from '@iota/apps-ui-icons';
|
|
5
|
+
import { CardActionType } from './card.enums';
|
|
6
|
+
import { Button, ButtonSize, ButtonType } from '../../atoms/button';
|
|
7
|
+
|
|
8
|
+
export type CardActionProps = {
|
|
9
|
+
title?: string;
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
type: CardActionType;
|
|
12
|
+
onClick?: () => void;
|
|
13
|
+
icon?: React.ReactNode;
|
|
14
|
+
iconAfterText?: boolean;
|
|
15
|
+
buttonType?: ButtonType;
|
|
16
|
+
buttonDisabled?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function CardAction({
|
|
20
|
+
type,
|
|
21
|
+
onClick,
|
|
22
|
+
subtitle,
|
|
23
|
+
title,
|
|
24
|
+
icon,
|
|
25
|
+
iconAfterText,
|
|
26
|
+
buttonType,
|
|
27
|
+
buttonDisabled,
|
|
28
|
+
}: CardActionProps) {
|
|
29
|
+
function handleActionClick(event: React.MouseEvent) {
|
|
30
|
+
if (onClick) {
|
|
31
|
+
event.stopPropagation();
|
|
32
|
+
onClick();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (type === CardActionType.Link) {
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
onClick={handleActionClick}
|
|
40
|
+
className="shrink-0 text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"
|
|
41
|
+
>
|
|
42
|
+
{icon ? icon : <ArrowRight />}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (type === CardActionType.SupportingText) {
|
|
48
|
+
return (
|
|
49
|
+
<div className="shrink-0 text-right">
|
|
50
|
+
{title && (
|
|
51
|
+
<div className="font-inter text-label-md text-neutral-10 dark:text-neutral-92">
|
|
52
|
+
{title}
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
{subtitle && (
|
|
56
|
+
<div className="font-inter text-label-sm text-neutral-60 dark:text-neutral-40">
|
|
57
|
+
{subtitle}
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (type === CardActionType.Button) {
|
|
64
|
+
return (
|
|
65
|
+
<div className="shrink-0">
|
|
66
|
+
<Button
|
|
67
|
+
type={buttonType || ButtonType.Outlined}
|
|
68
|
+
size={ButtonSize.Small}
|
|
69
|
+
text={title}
|
|
70
|
+
onClick={handleActionClick}
|
|
71
|
+
icon={icon}
|
|
72
|
+
iconAfterText={iconAfterText}
|
|
73
|
+
disabled={buttonDisabled}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
|
|
5
|
+
import { ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
export type CardBodyProps = {
|
|
8
|
+
title: string;
|
|
9
|
+
subtitle?: string | ReactNode;
|
|
10
|
+
clickableAction?: React.ReactNode;
|
|
11
|
+
icon?: React.ReactNode;
|
|
12
|
+
isTextTruncated?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function CardBody({
|
|
16
|
+
title,
|
|
17
|
+
subtitle,
|
|
18
|
+
clickableAction,
|
|
19
|
+
icon,
|
|
20
|
+
isTextTruncated,
|
|
21
|
+
}: CardBodyProps) {
|
|
22
|
+
const handleActionCardBodyClick = (event: React.MouseEvent) => {
|
|
23
|
+
event?.stopPropagation();
|
|
24
|
+
};
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
className={cx('flex w-full flex-col', {
|
|
28
|
+
truncate: isTextTruncated,
|
|
29
|
+
})}
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
className={cx('flex flex-row items-center gap-x-xxs', {
|
|
33
|
+
'grow-1': isTextTruncated,
|
|
34
|
+
})}
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
className={cx('font-inter text-title-md text-neutral-10 dark:text-neutral-92', {
|
|
38
|
+
truncate: isTextTruncated,
|
|
39
|
+
})}
|
|
40
|
+
>
|
|
41
|
+
{title}
|
|
42
|
+
</div>
|
|
43
|
+
{icon && <div className="flex items-center">{icon}</div>}
|
|
44
|
+
{clickableAction && (
|
|
45
|
+
<div onClick={handleActionCardBodyClick} className="flex items-center">
|
|
46
|
+
{clickableAction}
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
{subtitle && (
|
|
51
|
+
<div
|
|
52
|
+
className={cx('font-inter text-body-md text-neutral-40 dark:text-neutral-60', {
|
|
53
|
+
truncate: isTextTruncated,
|
|
54
|
+
})}
|
|
55
|
+
>
|
|
56
|
+
{subtitle}
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import { ImageType, ImageShape } from './card.enums';
|
|
6
|
+
import { IMAGE_BG_CLASSES, IMAGE_VARIANT_CLASSES } from './card.classes';
|
|
7
|
+
import { CardImagePlaceholder } from './CardImagePlaceholder';
|
|
8
|
+
|
|
9
|
+
export interface CardImageProps {
|
|
10
|
+
type?: ImageType;
|
|
11
|
+
shape?: ImageShape;
|
|
12
|
+
url?: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function CardImage({
|
|
17
|
+
type = ImageType.BgSolid,
|
|
18
|
+
shape = ImageShape.Rounded,
|
|
19
|
+
url,
|
|
20
|
+
children,
|
|
21
|
+
}: CardImageProps) {
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
className={cx(
|
|
25
|
+
IMAGE_VARIANT_CLASSES[shape],
|
|
26
|
+
IMAGE_BG_CLASSES[type],
|
|
27
|
+
'flex shrink-0 items-center justify-center overflow-hidden',
|
|
28
|
+
)}
|
|
29
|
+
>
|
|
30
|
+
{type === ImageType.Placeholder && !children && (
|
|
31
|
+
<CardImagePlaceholder variant={shape} />
|
|
32
|
+
)}
|
|
33
|
+
{url && !children && (
|
|
34
|
+
<img
|
|
35
|
+
src={url}
|
|
36
|
+
className={cx(IMAGE_VARIANT_CLASSES[shape], 'object-cover')}
|
|
37
|
+
alt="Card Image"
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
{children}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { ImageShape } from './card.enums';
|
|
4
|
+
|
|
5
|
+
export interface ImagePlaceholderProps {
|
|
6
|
+
/**
|
|
7
|
+
* The variant of the image placeholder.
|
|
8
|
+
*/
|
|
9
|
+
variant?: ImageShape;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function CardImagePlaceholder({ variant = ImageShape.Rounded }: ImagePlaceholderProps) {
|
|
13
|
+
if (variant === ImageShape.Rounded) {
|
|
14
|
+
return <ImagePlaceholderRounded />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return <ImagePlaceholderSquareRounded />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ImagePlaceholderRounded() {
|
|
21
|
+
return (
|
|
22
|
+
<svg
|
|
23
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
24
|
+
width="40"
|
|
25
|
+
height="40"
|
|
26
|
+
viewBox="0 0 40 40"
|
|
27
|
+
fill="none"
|
|
28
|
+
>
|
|
29
|
+
<g clip-path="url(#clip0_880_55185)">
|
|
30
|
+
<path
|
|
31
|
+
d="M0 20C0 8.95431 8.95431 0 20 0C31.0457 0 40 8.95431 40 20C40 31.0457 31.0457 40 20 40C8.95431 40 0 31.0457 0 20Z"
|
|
32
|
+
fill="#5B9CFE"
|
|
33
|
+
/>
|
|
34
|
+
<path
|
|
35
|
+
d="M0 20C0 8.95431 8.95431 0 20 0C31.0457 0 40 8.95431 40 20C40 31.0457 31.0457 40 20 40C8.95431 40 0 31.0457 0 20Z"
|
|
36
|
+
fill="url(#paint0_linear_880_55185)"
|
|
37
|
+
fill-opacity="0.2"
|
|
38
|
+
/>
|
|
39
|
+
<path
|
|
40
|
+
d="M0 20C0 8.95431 8.95431 0 20 0C31.0457 0 40 8.95431 40 20C40 31.0457 31.0457 40 20 40C8.95431 40 0 31.0457 0 20Z"
|
|
41
|
+
fill="url(#paint1_linear_880_55185)"
|
|
42
|
+
fill-opacity="0.2"
|
|
43
|
+
/>
|
|
44
|
+
<path
|
|
45
|
+
d="M0.5 20C0.5 9.23045 9.23045 0.5 20 0.5C30.7696 0.5 39.5 9.23045 39.5 20C39.5 30.7696 30.7696 39.5 20 39.5C9.23045 39.5 0.5 30.7696 0.5 20Z"
|
|
46
|
+
stroke="#002F6D"
|
|
47
|
+
stroke-opacity="0.08"
|
|
48
|
+
/>
|
|
49
|
+
</g>
|
|
50
|
+
<defs>
|
|
51
|
+
<linearGradient
|
|
52
|
+
id="paint0_linear_880_55185"
|
|
53
|
+
x1="20"
|
|
54
|
+
y1="0"
|
|
55
|
+
x2="29.5238"
|
|
56
|
+
y2="22.381"
|
|
57
|
+
gradientUnits="userSpaceOnUse"
|
|
58
|
+
>
|
|
59
|
+
<stop offset="0.990135" stop-opacity="0" />
|
|
60
|
+
<stop offset="1" />
|
|
61
|
+
</linearGradient>
|
|
62
|
+
<linearGradient
|
|
63
|
+
id="paint1_linear_880_55185"
|
|
64
|
+
x1="20"
|
|
65
|
+
y1="0"
|
|
66
|
+
x2="11.4286"
|
|
67
|
+
y2="9.04762"
|
|
68
|
+
gradientUnits="userSpaceOnUse"
|
|
69
|
+
>
|
|
70
|
+
<stop offset="0.9999" stop-opacity="0" />
|
|
71
|
+
<stop offset="1" />
|
|
72
|
+
</linearGradient>
|
|
73
|
+
<clipPath id="clip0_880_55185">
|
|
74
|
+
<path
|
|
75
|
+
d="M0 20C0 8.95431 8.95431 0 20 0C31.0457 0 40 8.95431 40 20C40 31.0457 31.0457 40 20 40C8.95431 40 0 31.0457 0 20Z"
|
|
76
|
+
fill="white"
|
|
77
|
+
/>
|
|
78
|
+
</clipPath>
|
|
79
|
+
</defs>
|
|
80
|
+
</svg>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ImagePlaceholderSquareRounded() {
|
|
85
|
+
return (
|
|
86
|
+
<svg
|
|
87
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
88
|
+
width="40"
|
|
89
|
+
height="40"
|
|
90
|
+
viewBox="0 0 40 40"
|
|
91
|
+
fill="none"
|
|
92
|
+
>
|
|
93
|
+
<g clip-path="url(#clip0_880_55190)">
|
|
94
|
+
<path
|
|
95
|
+
d="M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z"
|
|
96
|
+
fill="#5B9CFE"
|
|
97
|
+
/>
|
|
98
|
+
<path
|
|
99
|
+
d="M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z"
|
|
100
|
+
fill="url(#paint0_linear_880_55190)"
|
|
101
|
+
fill-opacity="0.2"
|
|
102
|
+
/>
|
|
103
|
+
<path
|
|
104
|
+
d="M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z"
|
|
105
|
+
fill="url(#paint1_linear_880_55190)"
|
|
106
|
+
fill-opacity="0.2"
|
|
107
|
+
/>
|
|
108
|
+
<path
|
|
109
|
+
d="M0.5 8C0.5 3.85786 3.85786 0.5 8 0.5H32C36.1421 0.5 39.5 3.85786 39.5 8V32C39.5 36.1421 36.1421 39.5 32 39.5H8C3.85786 39.5 0.5 36.1421 0.5 32V8Z"
|
|
110
|
+
stroke="#002F6D"
|
|
111
|
+
stroke-opacity="0.08"
|
|
112
|
+
/>
|
|
113
|
+
</g>
|
|
114
|
+
<defs>
|
|
115
|
+
<linearGradient
|
|
116
|
+
id="paint0_linear_880_55190"
|
|
117
|
+
x1="20"
|
|
118
|
+
y1="0"
|
|
119
|
+
x2="29.5238"
|
|
120
|
+
y2="22.381"
|
|
121
|
+
gradientUnits="userSpaceOnUse"
|
|
122
|
+
>
|
|
123
|
+
<stop offset="0.990135" stop-opacity="0" />
|
|
124
|
+
<stop offset="1" />
|
|
125
|
+
</linearGradient>
|
|
126
|
+
<linearGradient
|
|
127
|
+
id="paint1_linear_880_55190"
|
|
128
|
+
x1="20"
|
|
129
|
+
y1="0"
|
|
130
|
+
x2="11.4286"
|
|
131
|
+
y2="9.04762"
|
|
132
|
+
gradientUnits="userSpaceOnUse"
|
|
133
|
+
>
|
|
134
|
+
<stop offset="0.9999" stop-opacity="0" />
|
|
135
|
+
<stop offset="1" />
|
|
136
|
+
</linearGradient>
|
|
137
|
+
<clipPath id="clip0_880_55190">
|
|
138
|
+
<path
|
|
139
|
+
d="M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z"
|
|
140
|
+
fill="white"
|
|
141
|
+
/>
|
|
142
|
+
</clipPath>
|
|
143
|
+
</defs>
|
|
144
|
+
</svg>
|
|
145
|
+
);
|
|
146
|
+
}
|