@iota/apps-ui-kit 0.2.0 → 0.2.1

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.
Files changed (212) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/index.d.ts +1622 -0
  3. package/dist/index.es.js +8805 -0
  4. package/dist/index.es.js.map +1 -0
  5. package/dist/index.umd.js +198 -0
  6. package/dist/index.umd.js.map +1 -0
  7. package/dist/style.css +1 -0
  8. package/package.json +5 -2
  9. package/src/lib/components/atoms/badge/Badge.tsx +37 -0
  10. package/src/lib/components/atoms/badge/badge.classes.ts +24 -0
  11. package/src/lib/components/atoms/badge/badge.enums.ts +8 -0
  12. package/src/lib/components/atoms/badge/index.ts +6 -0
  13. package/src/lib/components/atoms/button/Button.tsx +99 -0
  14. package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +23 -0
  15. package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +27 -0
  16. package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +11 -0
  17. package/src/lib/components/atoms/button/button-variants/index.ts +5 -0
  18. package/src/lib/components/atoms/button/button.classes.ts +53 -0
  19. package/src/lib/components/atoms/button/button.enums.ts +21 -0
  20. package/src/lib/components/atoms/button/index.ts +7 -0
  21. package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +86 -0
  22. package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +45 -0
  23. package/src/lib/components/atoms/button-segment/buttonSegment.enums.ts +7 -0
  24. package/src/lib/components/atoms/button-segment/index.ts +5 -0
  25. package/src/lib/components/atoms/checkbox/Checkbox.tsx +114 -0
  26. package/src/lib/components/atoms/checkbox/index.ts +4 -0
  27. package/src/lib/components/atoms/divider/Divider.tsx +48 -0
  28. package/src/lib/components/atoms/divider/divider.classes.ts +11 -0
  29. package/src/lib/components/atoms/divider/divider.enums.ts +7 -0
  30. package/src/lib/components/atoms/divider/index.ts +6 -0
  31. package/src/lib/components/atoms/header/Header.tsx +73 -0
  32. package/src/lib/components/atoms/header/index.ts +4 -0
  33. package/src/lib/components/atoms/index.ts +22 -0
  34. package/src/lib/components/atoms/info-box/InfoBox.tsx +73 -0
  35. package/src/lib/components/atoms/info-box/index.ts +5 -0
  36. package/src/lib/components/atoms/info-box/infoBox.classes.ts +14 -0
  37. package/src/lib/components/atoms/info-box/infoBox.enums.ts +12 -0
  38. package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +156 -0
  39. package/src/lib/components/atoms/key-value-info/index.ts +6 -0
  40. package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
  41. package/src/lib/components/atoms/label-text/LabelText.tsx +93 -0
  42. package/src/lib/components/atoms/label-text/index.ts +5 -0
  43. package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
  44. package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
  45. package/src/lib/components/atoms/list-item/ListItem.tsx +89 -0
  46. package/src/lib/components/atoms/list-item/index.ts +4 -0
  47. package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
  48. package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
  49. package/src/lib/components/atoms/panel/Panel.tsx +30 -0
  50. package/src/lib/components/atoms/panel/index.ts +4 -0
  51. package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
  52. package/src/lib/components/atoms/placeholder/index.ts +4 -0
  53. package/src/lib/components/atoms/radio-button/RadioButton.tsx +68 -0
  54. package/src/lib/components/atoms/radio-button/index.ts +4 -0
  55. package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +28 -0
  56. package/src/lib/components/atoms/secondary-text/index.ts +4 -0
  57. package/src/lib/components/atoms/skeleton/Skeleton.tsx +47 -0
  58. package/src/lib/components/atoms/skeleton/index.ts +4 -0
  59. package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
  60. package/src/lib/components/atoms/snackbar/index.ts +5 -0
  61. package/src/lib/components/atoms/snackbar/snackbar.classes.ts +14 -0
  62. package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +7 -0
  63. package/src/lib/components/atoms/tooltip/Tooltip.tsx +34 -0
  64. package/src/lib/components/atoms/tooltip/index.ts +5 -0
  65. package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
  66. package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
  67. package/src/lib/components/atoms/visual-asset-card/VisualAssetCard.tsx +93 -0
  68. package/src/lib/components/atoms/visual-asset-card/index.ts +5 -0
  69. package/src/lib/components/atoms/visual-asset-card/visualAssetCard.enums.ts +7 -0
  70. package/src/lib/components/index.ts +8 -0
  71. package/src/lib/components/molecules/account/Account.tsx +174 -0
  72. package/src/lib/components/molecules/account/index.ts +4 -0
  73. package/src/lib/components/molecules/address/Address.tsx +101 -0
  74. package/src/lib/components/molecules/address/index.ts +4 -0
  75. package/src/lib/components/molecules/card/Card.tsx +70 -0
  76. package/src/lib/components/molecules/card/CardAction.tsx +78 -0
  77. package/src/lib/components/molecules/card/CardBody.tsx +61 -0
  78. package/src/lib/components/molecules/card/CardImage.tsx +43 -0
  79. package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
  80. package/src/lib/components/molecules/card/card.classes.ts +26 -0
  81. package/src/lib/components/molecules/card/card.enums.ts +25 -0
  82. package/src/lib/components/molecules/card/index.ts +8 -0
  83. package/src/lib/components/molecules/chip/Chip.tsx +105 -0
  84. package/src/lib/components/molecules/chip/chip.classes.ts +32 -0
  85. package/src/lib/components/molecules/chip/chip.enums.ts +7 -0
  86. package/src/lib/components/molecules/chip/index.ts +4 -0
  87. package/src/lib/components/molecules/display-stats/DisplayStats.tsx +104 -0
  88. package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
  89. package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
  90. package/src/lib/components/molecules/display-stats/index.ts +5 -0
  91. package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
  92. package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
  93. package/src/lib/components/molecules/dropdown/index.ts +5 -0
  94. package/src/lib/components/molecules/index.ts +17 -0
  95. package/src/lib/components/molecules/input/Input.tsx +245 -0
  96. package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
  97. package/src/lib/components/molecules/input/TextArea.tsx +149 -0
  98. package/src/lib/components/molecules/input/index.ts +8 -0
  99. package/src/lib/components/molecules/input/input.classes.ts +14 -0
  100. package/src/lib/components/molecules/input/input.enums.ts +14 -0
  101. package/src/lib/components/molecules/input/input.types.ts +29 -0
  102. package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +48 -0
  103. package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
  104. package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
  105. package/src/lib/components/molecules/navbar-item/index.ts +5 -0
  106. package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
  107. package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
  108. package/src/lib/components/molecules/search/Search.tsx +189 -0
  109. package/src/lib/components/molecules/search/index.ts +5 -0
  110. package/src/lib/components/molecules/search/search.classes.ts +20 -0
  111. package/src/lib/components/molecules/search/search.enums.ts +7 -0
  112. package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +34 -0
  113. package/src/lib/components/molecules/segmented-button/index.ts +6 -0
  114. package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
  115. package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
  116. package/src/lib/components/molecules/select/Select.tsx +223 -0
  117. package/src/lib/components/molecules/select/index.ts +5 -0
  118. package/src/lib/components/molecules/select/select.enums.ts +7 -0
  119. package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
  120. package/src/lib/components/molecules/table-cell/index.ts +4 -0
  121. package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +126 -0
  122. package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
  123. package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
  124. package/src/lib/components/molecules/title/Title.tsx +69 -0
  125. package/src/lib/components/molecules/title/index.ts +5 -0
  126. package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
  127. package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
  128. package/src/lib/components/organisms/accordion/Accordion.tsx +111 -0
  129. package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
  130. package/src/lib/components/organisms/accordion/index.ts +4 -0
  131. package/src/lib/components/organisms/dialog/Dialog.tsx +122 -0
  132. package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
  133. package/src/lib/components/organisms/dialog/index.ts +5 -0
  134. package/src/lib/components/organisms/index.ts +7 -0
  135. package/src/lib/components/organisms/navbar/Navbar.tsx +100 -0
  136. package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +58 -0
  137. package/src/lib/components/organisms/navbar/index.ts +5 -0
  138. package/src/lib/components/organisms/table/Table.tsx +224 -0
  139. package/src/lib/components/organisms/table/TableContext.tsx +55 -0
  140. package/src/lib/components/organisms/table/index.ts +4 -0
  141. package/src/lib/constants/colors.constants.ts +127 -0
  142. package/src/lib/constants/index.ts +4 -0
  143. package/src/lib/enums/index.ts +4 -0
  144. package/src/lib/enums/screenSize.enums.ts +9 -0
  145. package/src/lib/index.ts +8 -0
  146. package/src/lib/styles/fonts.css +5 -0
  147. package/src/lib/styles/index.css +136 -0
  148. package/src/lib/tailwind/base.presets.ts +47 -0
  149. package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
  150. package/src/lib/tailwind/constants/index.ts +6 -0
  151. package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
  152. package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
  153. package/src/lib/tailwind/helpers.ts +20 -0
  154. package/src/lib/tailwind/index.ts +5 -0
  155. package/src/lib/tailwind/responsive.presets.ts +36 -0
  156. package/src/lib/tailwind/static.presets.ts +25 -0
  157. package/src/lib/tailwind/types.ts +6 -0
  158. package/src/lib/utils/format.ts +8 -0
  159. package/src/lib/utils/index.ts +4 -0
  160. package/src/storybook/blocks/Showcase.tsx +20 -0
  161. package/src/storybook/blocks/TypeSet.tsx +34 -0
  162. package/src/storybook/blocks/TypeSetItem.tsx +74 -0
  163. package/src/storybook/blocks/index.ts +6 -0
  164. package/src/storybook/constants/index.ts +5 -0
  165. package/src/storybook/constants/typeset.constants.ts +39 -0
  166. package/src/storybook/constants/variableSpacing.constants.ts +6 -0
  167. package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
  168. package/src/storybook/helpers/index.ts +4 -0
  169. package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
  170. package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
  171. package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
  172. package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
  173. package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
  174. package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
  175. package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
  176. package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
  177. package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
  178. package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
  179. package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
  180. package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
  181. package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
  182. package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
  183. package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
  184. package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
  185. package/src/storybook/stories/atoms/Snackbar.stories.tsx +42 -0
  186. package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
  187. package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
  188. package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
  189. package/src/storybook/stories/components/index.ts +4 -0
  190. package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
  191. package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
  192. package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
  193. package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
  194. package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
  195. package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
  196. package/src/storybook/stories/molecules/Card.stories.tsx +115 -0
  197. package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
  198. package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
  199. package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
  200. package/src/storybook/stories/molecules/Input.stories.tsx +161 -0
  201. package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
  202. package/src/storybook/stories/molecules/Search.stories.tsx +100 -0
  203. package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +107 -0
  204. package/src/storybook/stories/molecules/Select.stories.tsx +102 -0
  205. package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
  206. package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
  207. package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
  208. package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
  209. package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
  210. package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
  211. package/src/storybook/stories/organisms/Navbar.stories.tsx +77 -0
  212. 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,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { Account } from './Account';
@@ -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,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Address';
@@ -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,78 @@
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
+ event?.stopPropagation();
31
+ onClick?.();
32
+ }
33
+
34
+ if (type === CardActionType.Link) {
35
+ return (
36
+ <div
37
+ onClick={handleActionClick}
38
+ className="shrink-0 text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"
39
+ >
40
+ {icon ? icon : <ArrowRight />}
41
+ </div>
42
+ );
43
+ }
44
+
45
+ if (type === CardActionType.SupportingText) {
46
+ return (
47
+ <div className="shrink-0 text-right">
48
+ {title && (
49
+ <div className="font-inter text-label-md text-neutral-10 dark:text-neutral-92">
50
+ {title}
51
+ </div>
52
+ )}
53
+ {subtitle && (
54
+ <div className="font-inter text-label-sm text-neutral-60 dark:text-neutral-40">
55
+ {subtitle}
56
+ </div>
57
+ )}
58
+ </div>
59
+ );
60
+ }
61
+ if (type === CardActionType.Button) {
62
+ return (
63
+ <div className="shrink-0">
64
+ <Button
65
+ type={buttonType || ButtonType.Outlined}
66
+ size={ButtonSize.Small}
67
+ text={title}
68
+ onClick={handleActionClick}
69
+ icon={icon}
70
+ iconAfterText={iconAfterText}
71
+ disabled={buttonDisabled}
72
+ />
73
+ </div>
74
+ );
75
+ }
76
+
77
+ return null;
78
+ }
@@ -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
+ }