@iota/apps-ui-kit 0.0.0-dev-20251015065834

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 (243) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/LICENSE +201 -0
  3. package/README.md +16 -0
  4. package/dist/index.d.ts +1911 -0
  5. package/dist/index.es.js +6486 -0
  6. package/dist/index.es.js.map +1 -0
  7. package/dist/index.umd.js +66 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/style.css +1 -0
  10. package/package.json +80 -0
  11. package/src/lib/components/atoms/badge/Badge.tsx +37 -0
  12. package/src/lib/components/atoms/badge/badge.classes.ts +33 -0
  13. package/src/lib/components/atoms/badge/badge.enums.ts +11 -0
  14. package/src/lib/components/atoms/badge/index.ts +6 -0
  15. package/src/lib/components/atoms/button/Button.tsx +110 -0
  16. package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +23 -0
  17. package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +27 -0
  18. package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +11 -0
  19. package/src/lib/components/atoms/button/button-variants/index.ts +5 -0
  20. package/src/lib/components/atoms/button/button.classes.ts +53 -0
  21. package/src/lib/components/atoms/button/button.enums.ts +21 -0
  22. package/src/lib/components/atoms/button/index.ts +7 -0
  23. package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +98 -0
  24. package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +24 -0
  25. package/src/lib/components/atoms/button-segment/buttonSegment.enums.ts +7 -0
  26. package/src/lib/components/atoms/button-segment/index.ts +5 -0
  27. package/src/lib/components/atoms/checkbox/Checkbox.tsx +124 -0
  28. package/src/lib/components/atoms/checkbox/index.ts +4 -0
  29. package/src/lib/components/atoms/divider/Divider.tsx +48 -0
  30. package/src/lib/components/atoms/divider/divider.classes.ts +11 -0
  31. package/src/lib/components/atoms/divider/divider.enums.ts +7 -0
  32. package/src/lib/components/atoms/divider/index.ts +6 -0
  33. package/src/lib/components/atoms/header/Header.tsx +73 -0
  34. package/src/lib/components/atoms/header/index.ts +4 -0
  35. package/src/lib/components/atoms/image/Image.tsx +32 -0
  36. package/src/lib/components/atoms/image/index.ts +4 -0
  37. package/src/lib/components/atoms/index.ts +26 -0
  38. package/src/lib/components/atoms/info-box/InfoBox.tsx +68 -0
  39. package/src/lib/components/atoms/info-box/index.ts +5 -0
  40. package/src/lib/components/atoms/info-box/infoBox.classes.ts +18 -0
  41. package/src/lib/components/atoms/info-box/infoBox.enums.ts +14 -0
  42. package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +157 -0
  43. package/src/lib/components/atoms/key-value-info/index.ts +6 -0
  44. package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
  45. package/src/lib/components/atoms/label-text/LabelText.tsx +92 -0
  46. package/src/lib/components/atoms/label-text/index.ts +5 -0
  47. package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
  48. package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
  49. package/src/lib/components/atoms/list-item/ListItem.tsx +88 -0
  50. package/src/lib/components/atoms/list-item/index.ts +4 -0
  51. package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
  52. package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
  53. package/src/lib/components/atoms/media-fallback/MediaFallback.tsx +12 -0
  54. package/src/lib/components/atoms/media-fallback/index.ts +4 -0
  55. package/src/lib/components/atoms/panel/Panel.tsx +28 -0
  56. package/src/lib/components/atoms/panel/index.ts +4 -0
  57. package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
  58. package/src/lib/components/atoms/placeholder/index.ts +4 -0
  59. package/src/lib/components/atoms/radio-button/RadioButton.tsx +64 -0
  60. package/src/lib/components/atoms/radio-button/index.ts +4 -0
  61. package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +29 -0
  62. package/src/lib/components/atoms/secondary-text/index.ts +4 -0
  63. package/src/lib/components/atoms/skeleton/Skeleton.tsx +30 -0
  64. package/src/lib/components/atoms/skeleton/index.ts +4 -0
  65. package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
  66. package/src/lib/components/atoms/snackbar/index.ts +5 -0
  67. package/src/lib/components/atoms/snackbar/snackbar.classes.ts +18 -0
  68. package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +9 -0
  69. package/src/lib/components/atoms/toggle/Toggle.tsx +140 -0
  70. package/src/lib/components/atoms/toggle/index.ts +6 -0
  71. package/src/lib/components/atoms/toggle/toggle.classes.ts +41 -0
  72. package/src/lib/components/atoms/toggle/toggle.enums.ts +12 -0
  73. package/src/lib/components/atoms/tooltip/Tooltip.tsx +139 -0
  74. package/src/lib/components/atoms/tooltip/index.ts +5 -0
  75. package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
  76. package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
  77. package/src/lib/components/atoms/video/Video.tsx +33 -0
  78. package/src/lib/components/atoms/video/index.ts +4 -0
  79. package/src/lib/components/atoms/video/video.constants.ts +31 -0
  80. package/src/lib/components/index.ts +6 -0
  81. package/src/lib/components/molecules/account/Account.tsx +195 -0
  82. package/src/lib/components/molecules/account/index.ts +4 -0
  83. package/src/lib/components/molecules/address/Address.tsx +101 -0
  84. package/src/lib/components/molecules/address/index.ts +4 -0
  85. package/src/lib/components/molecules/asset-media-renderer/AssetMediaRenderer.tsx +50 -0
  86. package/src/lib/components/molecules/asset-media-renderer/index.ts +4 -0
  87. package/src/lib/components/molecules/card/Card.tsx +70 -0
  88. package/src/lib/components/molecules/card/CardAction.tsx +78 -0
  89. package/src/lib/components/molecules/card/CardBody.tsx +73 -0
  90. package/src/lib/components/molecules/card/CardImage.tsx +43 -0
  91. package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
  92. package/src/lib/components/molecules/card/card.classes.ts +27 -0
  93. package/src/lib/components/molecules/card/card.enums.ts +26 -0
  94. package/src/lib/components/molecules/card/index.ts +8 -0
  95. package/src/lib/components/molecules/chip/Chip.tsx +146 -0
  96. package/src/lib/components/molecules/chip/chip.classes.ts +54 -0
  97. package/src/lib/components/molecules/chip/chip.enums.ts +15 -0
  98. package/src/lib/components/molecules/chip/index.ts +5 -0
  99. package/src/lib/components/molecules/display-stats/DisplayStats.tsx +142 -0
  100. package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
  101. package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
  102. package/src/lib/components/molecules/display-stats/index.ts +5 -0
  103. package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
  104. package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
  105. package/src/lib/components/molecules/dropdown/index.ts +5 -0
  106. package/src/lib/components/molecules/index.ts +19 -0
  107. package/src/lib/components/molecules/input/Input.tsx +261 -0
  108. package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
  109. package/src/lib/components/molecules/input/TextArea.tsx +148 -0
  110. package/src/lib/components/molecules/input/index.ts +8 -0
  111. package/src/lib/components/molecules/input/input.classes.ts +13 -0
  112. package/src/lib/components/molecules/input/input.enums.ts +14 -0
  113. package/src/lib/components/molecules/input/input.types.ts +29 -0
  114. package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +47 -0
  115. package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
  116. package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
  117. package/src/lib/components/molecules/navbar-item/index.ts +5 -0
  118. package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
  119. package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
  120. package/src/lib/components/molecules/search/Search.tsx +219 -0
  121. package/src/lib/components/molecules/search/index.ts +5 -0
  122. package/src/lib/components/molecules/search/search.classes.ts +20 -0
  123. package/src/lib/components/molecules/search/search.enums.ts +7 -0
  124. package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +38 -0
  125. package/src/lib/components/molecules/segmented-button/index.ts +6 -0
  126. package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
  127. package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
  128. package/src/lib/components/molecules/select/Select.tsx +235 -0
  129. package/src/lib/components/molecules/select/index.ts +5 -0
  130. package/src/lib/components/molecules/select/select.enums.ts +7 -0
  131. package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
  132. package/src/lib/components/molecules/table-cell/index.ts +4 -0
  133. package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +140 -0
  134. package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
  135. package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
  136. package/src/lib/components/molecules/title/Title.tsx +78 -0
  137. package/src/lib/components/molecules/title/index.ts +5 -0
  138. package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
  139. package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
  140. package/src/lib/components/molecules/visual-asset-card/VisualAssetCard.tsx +89 -0
  141. package/src/lib/components/molecules/visual-asset-card/index.ts +5 -0
  142. package/src/lib/components/molecules/visual-asset-card/visualAssetCard.enums.ts +7 -0
  143. package/src/lib/components/organisms/accordion/Accordion.tsx +108 -0
  144. package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
  145. package/src/lib/components/organisms/accordion/index.ts +4 -0
  146. package/src/lib/components/organisms/dialog/Dialog.tsx +157 -0
  147. package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
  148. package/src/lib/components/organisms/dialog/index.ts +5 -0
  149. package/src/lib/components/organisms/index.ts +7 -0
  150. package/src/lib/components/organisms/navbar/Navbar.tsx +101 -0
  151. package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +59 -0
  152. package/src/lib/components/organisms/navbar/index.ts +5 -0
  153. package/src/lib/components/organisms/table/Table.tsx +234 -0
  154. package/src/lib/components/organisms/table/TableContext.tsx +56 -0
  155. package/src/lib/components/organisms/table/index.ts +4 -0
  156. package/src/lib/constants/colors.constants.ts +239 -0
  157. package/src/lib/constants/index.ts +4 -0
  158. package/src/lib/enums/index.ts +5 -0
  159. package/src/lib/enums/screenSize.enums.ts +9 -0
  160. package/src/lib/enums/theme.enums.ts +8 -0
  161. package/src/lib/index.ts +10 -0
  162. package/src/lib/styles/base.css +144 -0
  163. package/src/lib/styles/components.css +735 -0
  164. package/src/lib/styles/fonts.css +7 -0
  165. package/src/lib/styles/index.css +18 -0
  166. package/src/lib/styles/utilities.css +61 -0
  167. package/src/lib/styles/variables/dark-variables.css +262 -0
  168. package/src/lib/styles/variables/general-variables.css +9 -0
  169. package/src/lib/styles/variables/light-variables.css +276 -0
  170. package/src/lib/styles/variables/names-variables.css +270 -0
  171. package/src/lib/tailwind/base.presets.ts +58 -0
  172. package/src/lib/tailwind/constants/customColors.constants.ts +13 -0
  173. package/src/lib/tailwind/constants/fontFamily.constants.ts +8 -0
  174. package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
  175. package/src/lib/tailwind/constants/gradients.constants.ts +6 -0
  176. package/src/lib/tailwind/constants/index.ts +7 -0
  177. package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
  178. package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
  179. package/src/lib/tailwind/helpers.ts +20 -0
  180. package/src/lib/tailwind/index.ts +5 -0
  181. package/src/lib/tailwind/plugins.ts +12 -0
  182. package/src/lib/tailwind/responsive.presets.ts +36 -0
  183. package/src/lib/tailwind/static.presets.ts +25 -0
  184. package/src/lib/tailwind/types.ts +6 -0
  185. package/src/lib/utils/format.ts +8 -0
  186. package/src/lib/utils/index.ts +4 -0
  187. package/src/storybook/blocks/Showcase.tsx +20 -0
  188. package/src/storybook/blocks/TypeSet.tsx +34 -0
  189. package/src/storybook/blocks/TypeSetItem.tsx +74 -0
  190. package/src/storybook/blocks/index.ts +6 -0
  191. package/src/storybook/constants/gradients.constants.ts +8 -0
  192. package/src/storybook/constants/index.ts +5 -0
  193. package/src/storybook/constants/typeset.constants.ts +39 -0
  194. package/src/storybook/constants/variableSpacing.constants.ts +6 -0
  195. package/src/storybook/helpers/formatGradientNames.ts +15 -0
  196. package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
  197. package/src/storybook/helpers/index.ts +4 -0
  198. package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
  199. package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
  200. package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
  201. package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
  202. package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
  203. package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
  204. package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
  205. package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
  206. package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
  207. package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
  208. package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
  209. package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
  210. package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
  211. package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
  212. package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
  213. package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
  214. package/src/storybook/stories/atoms/Snackbar.stories.tsx +43 -0
  215. package/src/storybook/stories/atoms/Toggle.stories.tsx +59 -0
  216. package/src/storybook/stories/atoms/Tooltip.stories.tsx +59 -0
  217. package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +57 -0
  218. package/src/storybook/stories/components/DocsSyncTheme.tsx +20 -0
  219. package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
  220. package/src/storybook/stories/components/index.ts +5 -0
  221. package/src/storybook/stories/design-tokens/colors.stories.mdx +44 -0
  222. package/src/storybook/stories/design-tokens/icons.stories.mdx +19 -0
  223. package/src/storybook/stories/design-tokens/typeset.stories.mdx +17 -0
  224. package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +11 -0
  225. package/src/storybook/stories/molecules/Account.stories.tsx +71 -0
  226. package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
  227. package/src/storybook/stories/molecules/Card.stories.tsx +112 -0
  228. package/src/storybook/stories/molecules/Chip.stories.tsx +127 -0
  229. package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
  230. package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
  231. package/src/storybook/stories/molecules/Input.stories.tsx +239 -0
  232. package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
  233. package/src/storybook/stories/molecules/Search.stories.tsx +101 -0
  234. package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +108 -0
  235. package/src/storybook/stories/molecules/Select.stories.tsx +103 -0
  236. package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
  237. package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
  238. package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
  239. package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
  240. package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
  241. package/src/storybook/stories/organisms/Dialog.stories.tsx +129 -0
  242. package/src/storybook/stories/organisms/Navbar.stories.tsx +78 -0
  243. package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
@@ -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 '@/components/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="address-text-color group flex flex-row items-center gap-1">
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,50 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { VisualAssetType } from '../visual-asset-card/visualAssetCard.enums';
5
+ import { Video, ImageWithFallback, Image } from '../../atoms';
6
+ import type { VideoProps } from '../../atoms';
7
+
8
+ export interface AssetMediaRendererProps extends VideoProps {
9
+ /**
10
+ * The source of the media to be displayed.
11
+ */
12
+ src: string;
13
+ /**
14
+ * The type of the asset to be displayed.
15
+ */
16
+ assetType: VisualAssetType;
17
+ /**
18
+ * Alt text for the image..
19
+ */
20
+ altText?: string;
21
+ /**
22
+ * Whether to show a fallback image if the main image fails to load.
23
+ */
24
+ showFallback?: boolean;
25
+ }
26
+
27
+ export function AssetMediaRenderer({
28
+ src,
29
+ isAutoPlayEnabled,
30
+ assetType,
31
+ altText: alt,
32
+ showFallback,
33
+ disableControls,
34
+ }: AssetMediaRendererProps): React.JSX.Element {
35
+ if (assetType === VisualAssetType.Video) {
36
+ return (
37
+ <Video
38
+ src={src}
39
+ isAutoPlayEnabled={isAutoPlayEnabled}
40
+ disableControls={disableControls}
41
+ />
42
+ );
43
+ }
44
+
45
+ if (showFallback) {
46
+ return <ImageWithFallback src={src} alt={alt} />;
47
+ }
48
+
49
+ return <Image src={src} alt={alt} />;
50
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2025 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './AssetMediaRenderer';
@@ -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 '@/components/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="card-action-link-color shrink-0 [&_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="card-action-title-color font-inter text-label-md">{title}</div>
52
+ )}
53
+ {subtitle && (
54
+ <div className="card-action-subtitle-color font-inter text-label-sm">
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,73 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import cx from 'classnames';
4
+ import type { ReactNode } from 'react';
5
+ import { Tooltip } from '@/components/atoms/tooltip';
6
+ import type { TooltipPosition } from '@/components/atoms/tooltip';
7
+
8
+ export type CardBodyProps = {
9
+ title: string;
10
+ subtitle?: string | ReactNode;
11
+ clickableAction?: React.ReactNode;
12
+ icon?: React.ReactNode;
13
+ isTextTruncated?: boolean;
14
+ tooltipText?: string;
15
+ tooltipPosition?: TooltipPosition;
16
+ };
17
+
18
+ export function CardBody({
19
+ title,
20
+ subtitle,
21
+ clickableAction,
22
+ icon,
23
+ isTextTruncated,
24
+ tooltipText,
25
+ tooltipPosition,
26
+ }: CardBodyProps) {
27
+ const handleActionCardBodyClick = (event: React.MouseEvent) => {
28
+ event?.stopPropagation();
29
+ };
30
+ return (
31
+ <div
32
+ className={cx('flex w-full flex-col', {
33
+ truncate: isTextTruncated,
34
+ })}
35
+ >
36
+ <div
37
+ className={cx('flex flex-row items-center gap-x-xxs', {
38
+ 'grow-1': isTextTruncated,
39
+ })}
40
+ >
41
+ <div
42
+ className={cx('card-body-title-color font-inter text-title-md', {
43
+ truncate: isTextTruncated,
44
+ })}
45
+ >
46
+ {title}
47
+ </div>
48
+
49
+ {tooltipText ? (
50
+ <Tooltip text={tooltipText} position={tooltipPosition}>
51
+ {icon}
52
+ </Tooltip>
53
+ ) : (
54
+ <div className="flex items-center">{icon}</div>
55
+ )}
56
+ {clickableAction && (
57
+ <div onClick={handleActionCardBodyClick} className="flex items-center">
58
+ {clickableAction}
59
+ </div>
60
+ )}
61
+ </div>
62
+ {subtitle && (
63
+ <div
64
+ className={cx('card-body-subtitle-color font-inter text-body-md', {
65
+ truncate: isTextTruncated,
66
+ })}
67
+ >
68
+ {subtitle}
69
+ </div>
70
+ )}
71
+ </div>
72
+ );
73
+ }
@@ -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
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { CardType, ImageType, ImageShape } from './card.enums';
5
+
6
+ export const CARD_DISABLED_CLASSES = `cursor-default opacity-40`;
7
+
8
+ export const IMAGE_SIZE = 'h-10 w-10';
9
+
10
+ export const IMAGE_VARIANT_CLASSES: { [key in ImageShape]: string } = {
11
+ [ImageShape.SquareRounded]: `${IMAGE_SIZE} rounded-md`,
12
+ [ImageShape.Rounded]: `${IMAGE_SIZE} rounded-full`,
13
+ };
14
+
15
+ export const IMAGE_BG_CLASSES: { [key in ImageType]: string } = {
16
+ [ImageType.Placeholder]: '',
17
+ [ImageType.BgSolid]: 'card-image-bg-solid',
18
+ [ImageType.BgWhite]: 'card-image-bg-white',
19
+ [ImageType.BgTransparent]: '',
20
+ };
21
+
22
+ export const CARD_TYPE_CLASSES: Record<CardType, string> = {
23
+ [CardType.Default]: 'border border-transparent',
24
+ [CardType.Outlined]:
25
+ 'border border-shader-neutral-light-8 dark:border-shader-primary-dark-8 p-xs',
26
+ [CardType.Filled]: 'border border-transparent card-filled-bg p-xs',
27
+ };
@@ -0,0 +1,26 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum CardType {
5
+ Default = 'default',
6
+ Outlined = 'outlined',
7
+ Filled = 'filled',
8
+ }
9
+
10
+ export enum ImageType {
11
+ Placeholder = 'placeholder',
12
+ BgSolid = 'bg-solid',
13
+ BgWhite = 'bg-white',
14
+ BgTransparent = 'bg-transparent',
15
+ }
16
+
17
+ export enum ImageShape {
18
+ Rounded = 'rounded',
19
+ SquareRounded = 'square-rounded',
20
+ }
21
+
22
+ export enum CardActionType {
23
+ Link = 'link',
24
+ SupportingText = 'supporting-text',
25
+ Button = 'button',
26
+ }
@@ -0,0 +1,8 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Card';
5
+ export * from './CardAction';
6
+ export * from './CardImage';
7
+ export * from './CardBody';
8
+ export * from './card.enums';