@iota/apps-ui-kit 0.0.0-experimental-20250613144451

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 (220) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/LICENSE +201 -0
  3. package/README.md +16 -0
  4. package/dist/index.d.ts +1726 -0
  5. package/dist/index.es.js +6923 -0
  6. package/dist/index.es.js.map +1 -0
  7. package/dist/index.umd.js +118 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/style.css +1 -0
  10. package/package.json +75 -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 +99 -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 +45 -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 +114 -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/index.ts +23 -0
  36. package/src/lib/components/atoms/info-box/InfoBox.tsx +74 -0
  37. package/src/lib/components/atoms/info-box/index.ts +5 -0
  38. package/src/lib/components/atoms/info-box/infoBox.classes.ts +19 -0
  39. package/src/lib/components/atoms/info-box/infoBox.enums.ts +14 -0
  40. package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +157 -0
  41. package/src/lib/components/atoms/key-value-info/index.ts +6 -0
  42. package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
  43. package/src/lib/components/atoms/label-text/LabelText.tsx +94 -0
  44. package/src/lib/components/atoms/label-text/index.ts +5 -0
  45. package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
  46. package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
  47. package/src/lib/components/atoms/list-item/ListItem.tsx +89 -0
  48. package/src/lib/components/atoms/list-item/index.ts +4 -0
  49. package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
  50. package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
  51. package/src/lib/components/atoms/panel/Panel.tsx +30 -0
  52. package/src/lib/components/atoms/panel/index.ts +4 -0
  53. package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
  54. package/src/lib/components/atoms/placeholder/index.ts +4 -0
  55. package/src/lib/components/atoms/radio-button/RadioButton.tsx +68 -0
  56. package/src/lib/components/atoms/radio-button/index.ts +4 -0
  57. package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +28 -0
  58. package/src/lib/components/atoms/secondary-text/index.ts +4 -0
  59. package/src/lib/components/atoms/skeleton/Skeleton.tsx +47 -0
  60. package/src/lib/components/atoms/skeleton/index.ts +4 -0
  61. package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
  62. package/src/lib/components/atoms/snackbar/index.ts +5 -0
  63. package/src/lib/components/atoms/snackbar/snackbar.classes.ts +18 -0
  64. package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +9 -0
  65. package/src/lib/components/atoms/toggle/Toggle.tsx +140 -0
  66. package/src/lib/components/atoms/toggle/index.ts +6 -0
  67. package/src/lib/components/atoms/toggle/toggle.classes.ts +41 -0
  68. package/src/lib/components/atoms/toggle/toggle.enums.ts +12 -0
  69. package/src/lib/components/atoms/tooltip/Tooltip.tsx +138 -0
  70. package/src/lib/components/atoms/tooltip/index.ts +5 -0
  71. package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
  72. package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
  73. package/src/lib/components/atoms/visual-asset-card/VisualAssetCard.tsx +101 -0
  74. package/src/lib/components/atoms/visual-asset-card/index.ts +5 -0
  75. package/src/lib/components/atoms/visual-asset-card/visualAssetCard.enums.ts +7 -0
  76. package/src/lib/components/index.ts +8 -0
  77. package/src/lib/components/molecules/account/Account.tsx +192 -0
  78. package/src/lib/components/molecules/account/index.ts +4 -0
  79. package/src/lib/components/molecules/address/Address.tsx +101 -0
  80. package/src/lib/components/molecules/address/index.ts +4 -0
  81. package/src/lib/components/molecules/card/Card.tsx +70 -0
  82. package/src/lib/components/molecules/card/CardAction.tsx +80 -0
  83. package/src/lib/components/molecules/card/CardBody.tsx +72 -0
  84. package/src/lib/components/molecules/card/CardImage.tsx +43 -0
  85. package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
  86. package/src/lib/components/molecules/card/card.classes.ts +27 -0
  87. package/src/lib/components/molecules/card/card.enums.ts +26 -0
  88. package/src/lib/components/molecules/card/index.ts +8 -0
  89. package/src/lib/components/molecules/chip/Chip.tsx +105 -0
  90. package/src/lib/components/molecules/chip/chip.classes.ts +32 -0
  91. package/src/lib/components/molecules/chip/chip.enums.ts +7 -0
  92. package/src/lib/components/molecules/chip/index.ts +4 -0
  93. package/src/lib/components/molecules/display-stats/DisplayStats.tsx +142 -0
  94. package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
  95. package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
  96. package/src/lib/components/molecules/display-stats/index.ts +5 -0
  97. package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
  98. package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
  99. package/src/lib/components/molecules/dropdown/index.ts +5 -0
  100. package/src/lib/components/molecules/index.ts +17 -0
  101. package/src/lib/components/molecules/input/Input.tsx +246 -0
  102. package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
  103. package/src/lib/components/molecules/input/TextArea.tsx +150 -0
  104. package/src/lib/components/molecules/input/index.ts +8 -0
  105. package/src/lib/components/molecules/input/input.classes.ts +14 -0
  106. package/src/lib/components/molecules/input/input.enums.ts +14 -0
  107. package/src/lib/components/molecules/input/input.types.ts +29 -0
  108. package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +48 -0
  109. package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
  110. package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
  111. package/src/lib/components/molecules/navbar-item/index.ts +5 -0
  112. package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
  113. package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
  114. package/src/lib/components/molecules/search/Search.tsx +216 -0
  115. package/src/lib/components/molecules/search/index.ts +5 -0
  116. package/src/lib/components/molecules/search/search.classes.ts +20 -0
  117. package/src/lib/components/molecules/search/search.enums.ts +7 -0
  118. package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +38 -0
  119. package/src/lib/components/molecules/segmented-button/index.ts +6 -0
  120. package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
  121. package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
  122. package/src/lib/components/molecules/select/Select.tsx +222 -0
  123. package/src/lib/components/molecules/select/index.ts +5 -0
  124. package/src/lib/components/molecules/select/select.enums.ts +7 -0
  125. package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
  126. package/src/lib/components/molecules/table-cell/index.ts +4 -0
  127. package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +140 -0
  128. package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
  129. package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
  130. package/src/lib/components/molecules/title/Title.tsx +78 -0
  131. package/src/lib/components/molecules/title/index.ts +5 -0
  132. package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
  133. package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
  134. package/src/lib/components/organisms/accordion/Accordion.tsx +109 -0
  135. package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
  136. package/src/lib/components/organisms/accordion/index.ts +4 -0
  137. package/src/lib/components/organisms/dialog/Dialog.tsx +142 -0
  138. package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
  139. package/src/lib/components/organisms/dialog/index.ts +5 -0
  140. package/src/lib/components/organisms/index.ts +7 -0
  141. package/src/lib/components/organisms/navbar/Navbar.tsx +101 -0
  142. package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +59 -0
  143. package/src/lib/components/organisms/navbar/index.ts +5 -0
  144. package/src/lib/components/organisms/table/Table.tsx +234 -0
  145. package/src/lib/components/organisms/table/TableContext.tsx +56 -0
  146. package/src/lib/components/organisms/table/index.ts +4 -0
  147. package/src/lib/constants/colors.constants.ts +133 -0
  148. package/src/lib/constants/index.ts +4 -0
  149. package/src/lib/enums/index.ts +4 -0
  150. package/src/lib/enums/screenSize.enums.ts +9 -0
  151. package/src/lib/index.ts +8 -0
  152. package/src/lib/styles/fonts.css +5 -0
  153. package/src/lib/styles/index.css +149 -0
  154. package/src/lib/tailwind/base.presets.ts +49 -0
  155. package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
  156. package/src/lib/tailwind/constants/index.ts +6 -0
  157. package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
  158. package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
  159. package/src/lib/tailwind/helpers.ts +20 -0
  160. package/src/lib/tailwind/index.ts +5 -0
  161. package/src/lib/tailwind/plugins.ts +8 -0
  162. package/src/lib/tailwind/responsive.presets.ts +36 -0
  163. package/src/lib/tailwind/static.presets.ts +25 -0
  164. package/src/lib/tailwind/types.ts +6 -0
  165. package/src/lib/utils/format.ts +8 -0
  166. package/src/lib/utils/index.ts +4 -0
  167. package/src/storybook/blocks/Showcase.tsx +20 -0
  168. package/src/storybook/blocks/TypeSet.tsx +34 -0
  169. package/src/storybook/blocks/TypeSetItem.tsx +74 -0
  170. package/src/storybook/blocks/index.ts +6 -0
  171. package/src/storybook/constants/index.ts +5 -0
  172. package/src/storybook/constants/typeset.constants.ts +39 -0
  173. package/src/storybook/constants/variableSpacing.constants.ts +6 -0
  174. package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
  175. package/src/storybook/helpers/index.ts +4 -0
  176. package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
  177. package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
  178. package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
  179. package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
  180. package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
  181. package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
  182. package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
  183. package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
  184. package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
  185. package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
  186. package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
  187. package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
  188. package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
  189. package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
  190. package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
  191. package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
  192. package/src/storybook/stories/atoms/Snackbar.stories.tsx +43 -0
  193. package/src/storybook/stories/atoms/Toggle.stories.tsx +59 -0
  194. package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
  195. package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
  196. package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
  197. package/src/storybook/stories/components/index.ts +4 -0
  198. package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
  199. package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
  200. package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
  201. package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
  202. package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
  203. package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
  204. package/src/storybook/stories/molecules/Card.stories.tsx +112 -0
  205. package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
  206. package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
  207. package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
  208. package/src/storybook/stories/molecules/Input.stories.tsx +162 -0
  209. package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
  210. package/src/storybook/stories/molecules/Search.stories.tsx +101 -0
  211. package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +108 -0
  212. package/src/storybook/stories/molecules/Select.stories.tsx +103 -0
  213. package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
  214. package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
  215. package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
  216. package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
  217. package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
  218. package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
  219. package/src/storybook/stories/organisms/Navbar.stories.tsx +78 -0
  220. package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
@@ -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 '@/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="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,72 @@
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('font-inter text-title-md text-neutral-10 dark:text-neutral-92', {
43
+ truncate: isTextTruncated,
44
+ })}
45
+ >
46
+ {title}
47
+ </div>
48
+ {tooltipText ? (
49
+ <Tooltip text={tooltipText} position={tooltipPosition}>
50
+ {icon}
51
+ </Tooltip>
52
+ ) : (
53
+ <div className="flex items-center">{icon}</div>
54
+ )}
55
+ {clickableAction && (
56
+ <div onClick={handleActionCardBodyClick} className="flex items-center">
57
+ {clickableAction}
58
+ </div>
59
+ )}
60
+ </div>
61
+ {subtitle && (
62
+ <div
63
+ className={cx('font-inter text-body-md text-neutral-40 dark:text-neutral-60', {
64
+ truncate: isTextTruncated,
65
+ })}
66
+ >
67
+ {subtitle}
68
+ </div>
69
+ )}
70
+ </div>
71
+ );
72
+ }
@@ -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]: 'bg-neutral-96 dark:bg-neutral-10',
18
+ [ImageType.BgWhite]: 'bg-white dark:bg-neutral-6',
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 bg-neutral-96 dark:bg-neutral-10 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';
@@ -0,0 +1,105 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import { ChipState } from './chip.enums';
6
+ import {
7
+ BORDER_CLASSES,
8
+ BACKGROUND_CLASSES,
9
+ ROUNDED_CLASS,
10
+ STATE_LAYER_CLASSES,
11
+ TEXT_COLOR,
12
+ FOCUS_CLASSES,
13
+ } from './chip.classes';
14
+ import { ButtonUnstyled } from '@/components/atoms/button';
15
+ import { Close } from '@iota/apps-ui-icons';
16
+
17
+ interface ChipProps {
18
+ /**
19
+ * The label of the chip
20
+ */
21
+ label: string;
22
+ /**
23
+ * Whether to show the close icon
24
+ */
25
+ showClose?: boolean;
26
+ /**
27
+ * Whether the chip is selected
28
+ */
29
+ selected?: boolean;
30
+ /**
31
+ * Callback when the close icon is clicked
32
+ */
33
+ onClose?: () => void;
34
+ /**
35
+ * On Click handler for the chip
36
+ */
37
+ onClick?: () => void;
38
+ /**
39
+ * Avatar to show in the chip.
40
+ */
41
+ avatar?: React.JSX.Element;
42
+ /**
43
+ * Leading element to show in the chip.
44
+ */
45
+ leadingElement?: React.JSX.Element;
46
+ /**
47
+ * Trailing element to show in the chip.
48
+ */
49
+ trailingElement?: React.JSX.Element;
50
+ /**
51
+ * The button is disabled or not.
52
+ */
53
+ disabled?: boolean;
54
+ }
55
+
56
+ export function Chip({
57
+ label,
58
+ showClose,
59
+ selected,
60
+ onClose,
61
+ onClick,
62
+ avatar,
63
+ leadingElement,
64
+ trailingElement,
65
+ disabled,
66
+ }: ChipProps) {
67
+ const chipState = selected ? ChipState.Selected : ChipState.Default;
68
+ return (
69
+ <ButtonUnstyled
70
+ onClick={onClick}
71
+ className={cx(
72
+ 'border transition-all duration-500 ease-in-out disabled:opacity-40',
73
+ ROUNDED_CLASS,
74
+ BACKGROUND_CLASSES[chipState],
75
+ BORDER_CLASSES[chipState],
76
+ FOCUS_CLASSES,
77
+ )}
78
+ disabled={disabled}
79
+ >
80
+ <span
81
+ className={cx(
82
+ 'flex h-full w-full flex-row items-center gap-x-2',
83
+ avatar ? 'py-xxs' : 'py-[6px]',
84
+ avatar ? 'pl-xxs' : leadingElement ? 'pl-xs' : 'pl-sm',
85
+ ROUNDED_CLASS,
86
+ !disabled && STATE_LAYER_CLASSES,
87
+ showClose ? 'pr-xs' : 'pr-sm',
88
+ TEXT_COLOR[chipState],
89
+ )}
90
+ >
91
+ {avatar ?? leadingElement}
92
+ <span className="text-body-md">{label}</span>
93
+ {trailingElement}
94
+ {showClose && (
95
+ <ButtonUnstyled
96
+ onClick={onClose}
97
+ className="cursor-pointer [&_svg]:h-4 [&_svg]:w-4"
98
+ >
99
+ <Close />
100
+ </ButtonUnstyled>
101
+ )}
102
+ </span>
103
+ </ButtonUnstyled>
104
+ );
105
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ChipState } from './chip.enums';
5
+
6
+ export const ROUNDED_CLASS = 'rounded-full';
7
+
8
+ export const BACKGROUND_CLASSES: Record<ChipState, string> = {
9
+ [ChipState.Default]: 'bg-transparent',
10
+ [ChipState.Selected]: 'bg-primary-90 dark:bg-primary-10',
11
+ };
12
+
13
+ const STATE_LAYER_OUTLINE =
14
+ 'outline outline-1 outline-transparent hover:outline-shader-primary-light-8 active:outline-shader-primary-light-12 dark:hover:outline-shader-primary-dark-8 dark:active:outline-shader-primary-dark-12';
15
+
16
+ const STATE_LAYER_BG_CLASSES =
17
+ 'hover:bg-shader-primary-light-8 active:bg-shader-primary-light-12 dark:hover:bg-shader-primary-dark-8 dark:active:bg-shader-primary-dark-12 focus:bg-shader-primary-light-12 dark:focus:bg-shader-primary-dark-12';
18
+
19
+ export const STATE_LAYER_CLASSES = `${STATE_LAYER_OUTLINE} ${STATE_LAYER_BG_CLASSES}`;
20
+
21
+ export const BORDER_CLASSES: Record<ChipState, string> = {
22
+ [ChipState.Default]: 'border-neutral-70 dark:border-neutral-40',
23
+ [ChipState.Selected]: 'border-transparent',
24
+ };
25
+
26
+ export const TEXT_COLOR: Record<ChipState, string> = {
27
+ [ChipState.Default]: 'text-neutral-40 dark:text-neutral-60',
28
+ [ChipState.Selected]: 'text-neutral-10 dark:text-neutral-92',
29
+ };
30
+
31
+ export const FOCUS_CLASSES =
32
+ 'focus-visible:shadow-[0_0_0_2px] focus-visible:shadow-primary-30 focus-visible:outline-none dark:focus-visible:shadow-primary-80';
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum ChipState {
5
+ Default = 'default',
6
+ Selected = 'selected',
7
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Chip';