@iota/apps-ui-kit 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/index.d.ts +1636 -0
  3. package/dist/index.es.js +8909 -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 +6 -3
  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 +19 -0
  37. package/src/lib/components/atoms/info-box/infoBox.enums.ts +14 -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 +18 -0
  62. package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +9 -0
  63. package/src/lib/components/atoms/tooltip/Tooltip.tsx +37 -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 +101 -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 +80 -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 +220 -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 +140 -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 +109 -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 +123 -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 +132 -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 +149 -0
  148. package/src/lib/tailwind/base.presets.ts +49 -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/plugins.ts +8 -0
  156. package/src/lib/tailwind/responsive.presets.ts +36 -0
  157. package/src/lib/tailwind/static.presets.ts +25 -0
  158. package/src/lib/tailwind/types.ts +6 -0
  159. package/src/lib/utils/format.ts +8 -0
  160. package/src/lib/utils/index.ts +4 -0
  161. package/src/storybook/blocks/Showcase.tsx +20 -0
  162. package/src/storybook/blocks/TypeSet.tsx +34 -0
  163. package/src/storybook/blocks/TypeSetItem.tsx +74 -0
  164. package/src/storybook/blocks/index.ts +6 -0
  165. package/src/storybook/constants/index.ts +5 -0
  166. package/src/storybook/constants/typeset.constants.ts +39 -0
  167. package/src/storybook/constants/variableSpacing.constants.ts +6 -0
  168. package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
  169. package/src/storybook/helpers/index.ts +4 -0
  170. package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
  171. package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
  172. package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
  173. package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
  174. package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
  175. package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
  176. package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
  177. package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
  178. package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
  179. package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
  180. package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
  181. package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
  182. package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
  183. package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
  184. package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
  185. package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
  186. package/src/storybook/stories/atoms/Snackbar.stories.tsx +42 -0
  187. package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
  188. package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
  189. package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
  190. package/src/storybook/stories/components/index.ts +4 -0
  191. package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
  192. package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
  193. package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
  194. package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
  195. package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
  196. package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
  197. package/src/storybook/stories/molecules/Card.stories.tsx +115 -0
  198. package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
  199. package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
  200. package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
  201. package/src/storybook/stories/molecules/Input.stories.tsx +161 -0
  202. package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
  203. package/src/storybook/stories/molecules/Search.stories.tsx +100 -0
  204. package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +107 -0
  205. package/src/storybook/stories/molecules/Select.stories.tsx +102 -0
  206. package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
  207. package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
  208. package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
  209. package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
  210. package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
  211. package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
  212. package/src/storybook/stories/organisms/Navbar.stories.tsx +77 -0
  213. package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
@@ -0,0 +1,89 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { PropsWithChildren } from 'react';
5
+ import cx from 'classnames';
6
+ import { ArrowRight } from '@iota/apps-ui-icons';
7
+ import { Button, ButtonSize, ButtonType } from '@/components';
8
+
9
+ export interface ListItemProps {
10
+ /**
11
+ * Has right icon (optional).
12
+ */
13
+ showRightIcon?: boolean;
14
+ /**
15
+ * Hide bottom border (optional).
16
+ */
17
+ hideBottomBorder?: boolean;
18
+ /**
19
+ * On click handler (optional).
20
+ */
21
+ onClick?: () => void;
22
+ /**
23
+ * The list item is disabled or not.
24
+ */
25
+ isDisabled?: boolean;
26
+ /**
27
+ * The list item is highlighted.
28
+ */
29
+ isHighlighted?: boolean;
30
+ }
31
+
32
+ export function ListItem({
33
+ showRightIcon,
34
+ hideBottomBorder,
35
+ onClick,
36
+ isDisabled,
37
+ children,
38
+ isHighlighted,
39
+ }: PropsWithChildren<ListItemProps>): React.JSX.Element {
40
+ function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
41
+ if ((event.key === 'Enter' || event.key === ' ') && !isDisabled && onClick) {
42
+ onClick();
43
+ }
44
+ }
45
+
46
+ function handleClick() {
47
+ if (!isDisabled && onClick) {
48
+ onClick();
49
+ }
50
+ }
51
+
52
+ return (
53
+ <div
54
+ className={cx(
55
+ 'w-full',
56
+ {
57
+ 'border-b border-shader-neutral-light-8 pb-xs dark:border-shader-neutral-dark-8':
58
+ !hideBottomBorder,
59
+ },
60
+ { 'opacity-40': isDisabled },
61
+ )}
62
+ >
63
+ <div
64
+ onClick={handleClick}
65
+ role="button"
66
+ tabIndex={0}
67
+ onKeyDown={handleKeyDown}
68
+ className={cx(
69
+ 'relative flex flex-row items-center justify-between px-md py-sm text-neutral-10 dark:text-neutral-92',
70
+ !isDisabled && onClick ? 'cursor-pointer' : 'cursor-default',
71
+ {
72
+ 'bg-shader-primary-dark-16 dark:bg-shader-inverted-dark-16': isHighlighted,
73
+ 'state-layer': !isDisabled,
74
+ },
75
+ )}
76
+ >
77
+ {children}
78
+ {showRightIcon && (
79
+ <Button
80
+ size={ButtonSize.Small}
81
+ type={ButtonType.Ghost}
82
+ disabled={isDisabled}
83
+ icon={<ArrowRight />}
84
+ />
85
+ )}
86
+ </div>
87
+ </div>
88
+ );
89
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './ListItem';
@@ -0,0 +1,38 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import { Loader } from '@iota/apps-ui-icons';
6
+
7
+ export interface LoadingIndicatorProps {
8
+ /**
9
+ * The color of the loading indicator.
10
+ */
11
+ color?: string;
12
+ /**
13
+ * The size of the loading indicator.
14
+ */
15
+ size?: string;
16
+ /**
17
+ * The text to display next to the loading indicator.
18
+ */
19
+ text?: string;
20
+ /**
21
+ * The 'data-testid' attribute value (used in e2e tests)
22
+ */
23
+ testId?: string;
24
+ }
25
+
26
+ export function LoadingIndicator({
27
+ color = 'text-primary-30 dark:text-primary-80',
28
+ size = 'w-5 h-5',
29
+ text,
30
+ testId,
31
+ }: LoadingIndicatorProps): React.JSX.Element {
32
+ return (
33
+ <div className="flex items-center justify-center gap-xs">
34
+ <Loader className={cx('animate-spin', color, size)} data-testid={testId} />
35
+ {text && <span className={cx('text-body-sm', color)}>{text}</span>}
36
+ </div>
37
+ );
38
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './LoadingIndicator';
@@ -0,0 +1,30 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+
6
+ interface PanelProps {
7
+ /**
8
+ * Show or hide border around the panel.
9
+ */
10
+ hasBorder?: boolean;
11
+ /**
12
+ * Background color of the panel.
13
+ */
14
+ bgColor?: string;
15
+ }
16
+
17
+ export function Panel({
18
+ children,
19
+ hasBorder,
20
+ bgColor = 'bg-neutral-100 dark:bg-neutral-6',
21
+ }: React.PropsWithChildren<PanelProps>): React.JSX.Element {
22
+ const borderClass = hasBorder
23
+ ? 'border border-shader-neutral-light-8 dark:border-shader-neutral-dark-8'
24
+ : 'border border-transparent';
25
+ return (
26
+ <div className={cx('flex w-full flex-col rounded-xl', bgColor, borderClass)}>
27
+ {children}
28
+ </div>
29
+ );
30
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Panel';
@@ -0,0 +1,27 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+
6
+ interface PlaceholderProps {
7
+ /**
8
+ * The width of the placeholder.
9
+ */
10
+ width?: string;
11
+ /**
12
+ * The height of the placeholder.
13
+ */
14
+ height?: string;
15
+ }
16
+
17
+ export function Placeholder({ width = 'w-full', height = 'h-4' }: PlaceholderProps) {
18
+ return (
19
+ <div
20
+ className={cx(
21
+ 'animate-pulse rounded-md bg-gradient-to-r from-shader-primary-light-8 bg-[length:1000px_100%] dark:from-shader-primary-dark-8',
22
+ width,
23
+ height,
24
+ )}
25
+ />
26
+ );
27
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { Placeholder } from './Placeholder';
@@ -0,0 +1,68 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import { RadioOn, RadioOff } from '@iota/apps-ui-icons';
6
+
7
+ interface RadioButtonProps {
8
+ /**
9
+ * The label of the radio button.
10
+ */
11
+ label: string;
12
+ /**
13
+ * The state of the radio button.
14
+ */
15
+ isChecked?: boolean;
16
+ /**
17
+ * If radio button disabled.
18
+ */
19
+ isDisabled?: boolean;
20
+ /**
21
+ * The callback to call when the radio button is clicked.
22
+ */
23
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
24
+ }
25
+
26
+ function RadioButton({
27
+ label,
28
+ isChecked,
29
+ isDisabled,
30
+ onChange,
31
+ }: RadioButtonProps): React.JSX.Element {
32
+ const RadioIcon = isChecked ? RadioOn : RadioOff;
33
+
34
+ return (
35
+ <label
36
+ className={cx('group flex flex-row gap-x-1 text-center', {
37
+ disabled: isDisabled,
38
+ 'cursor-pointer': !isDisabled,
39
+ })}
40
+ >
41
+ <div
42
+ className={cx('relative flex h-10 w-10 items-center justify-center rounded-full', {
43
+ 'state-layer': !isDisabled,
44
+ })}
45
+ >
46
+ <input
47
+ type="radio"
48
+ checked={isChecked}
49
+ onChange={onChange}
50
+ disabled={isDisabled}
51
+ className={cx('peer appearance-none disabled:opacity-40')}
52
+ />
53
+ <span
54
+ className="absolute
55
+ text-neutral-40 peer-checked:text-primary-30 peer-disabled:opacity-40 peer-checked:peer-disabled:text-neutral-40 dark:text-neutral-60 dark:peer-checked:peer-disabled:text-neutral-40 [&_svg]:h-6 [&_svg]:w-6
56
+ "
57
+ >
58
+ <RadioIcon />
59
+ </span>
60
+ </div>
61
+ <span className="inline-flex items-center justify-center text-label-lg text-neutral-40 group-[.disabled]:text-opacity-40 dark:text-neutral-60 group-[.disabled]:dark:text-opacity-40">
62
+ {label}
63
+ </span>
64
+ </label>
65
+ );
66
+ }
67
+
68
+ export { RadioButton };
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './RadioButton';
@@ -0,0 +1,28 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+
6
+ interface SecondaryTextProps {
7
+ /**
8
+ * The children to render.
9
+ */
10
+ children: React.ReactNode;
11
+ /**
12
+ * Should the text have error styles.
13
+ */
14
+ hasErrorStyles?: boolean;
15
+ }
16
+
17
+ export function SecondaryText({ children, hasErrorStyles }: SecondaryTextProps) {
18
+ const ERROR_STYLES = 'group-[.errored]:text-error-30 dark:group-[.errored]:text-error-80';
19
+ return (
20
+ <p
21
+ className={cx('text-label-lg text-neutral-40 dark:text-neutral-60 ', {
22
+ [ERROR_STYLES]: hasErrorStyles,
23
+ })}
24
+ >
25
+ {children}
26
+ </p>
27
+ );
28
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './SecondaryText';
@@ -0,0 +1,47 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+
6
+ interface SkeletonLoaderProps {
7
+ /**
8
+ * Width class for the skeleton div.
9
+ */
10
+ widthClass?: string;
11
+ /**
12
+ * Height class for the skeleton div.
13
+ */
14
+ heightClass?: string;
15
+ /**
16
+ * If true, the skeleton will use darker neutral colors.
17
+ */
18
+ hasSecondaryColors?: boolean;
19
+ /**
20
+ * Whether the class `rounded-full` should be applied. Defaults to true.
21
+ */
22
+ isRounded?: boolean;
23
+ }
24
+
25
+ export function Skeleton({
26
+ children,
27
+ widthClass = 'w-full',
28
+ heightClass = 'h-3',
29
+ hasSecondaryColors,
30
+ isRounded = true,
31
+ }: React.PropsWithChildren<SkeletonLoaderProps>): React.JSX.Element {
32
+ return (
33
+ <div
34
+ className={cx(
35
+ 'animate-pulse rounded-full',
36
+ widthClass,
37
+ heightClass,
38
+ isRounded && 'rounded-full',
39
+ hasSecondaryColors
40
+ ? 'bg-neutral-80 dark:bg-neutral-10'
41
+ : 'bg-neutral-90 dark:bg-neutral-12',
42
+ )}
43
+ >
44
+ {children}
45
+ </div>
46
+ );
47
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Skeleton';
@@ -0,0 +1,69 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { useEffect } from 'react';
5
+ import cx from 'classnames';
6
+ import { Close } from '@iota/apps-ui-icons';
7
+ import { SnackbarType } from './snackbar.enums';
8
+ import { BACKGROUND_COLOR, TEXT_COLOR } from '@/components/atoms/snackbar/snackbar.classes';
9
+
10
+ type Renderable = JSX.Element | string | null;
11
+ export interface SnackbarProps {
12
+ /**
13
+ * The message to display in the snackbar.
14
+ */
15
+ text: Renderable;
16
+ /**
17
+ * Type of the snackbar.
18
+ */
19
+ type: SnackbarType;
20
+
21
+ /**
22
+ * Duration in milliseconds for the snackbar to auto close. `0` will make the component not close automatically.
23
+ */
24
+ duration?: number;
25
+
26
+ /**
27
+ * Callback to close the snackbar.
28
+ */
29
+ onClose: () => void;
30
+
31
+ /**
32
+ * Show the close button.
33
+ */
34
+ showClose?: boolean;
35
+ }
36
+
37
+ export function Snackbar({
38
+ text,
39
+ duration = 2000,
40
+ onClose,
41
+ showClose,
42
+ type = SnackbarType.Default,
43
+ }: SnackbarProps) {
44
+ useEffect(() => {
45
+ if (duration) {
46
+ const timer = setTimeout(onClose, duration);
47
+ return () => clearTimeout(timer);
48
+ }
49
+ }, [duration, onClose]);
50
+
51
+ return (
52
+ <div
53
+ className={cx(
54
+ 'transition-all duration-300 ease-out',
55
+ 'z-99 bottom-0',
56
+ 'flex w-full items-center justify-between gap-xxs rounded-md py-sm pl-md pr-sm',
57
+ BACKGROUND_COLOR[type],
58
+ )}
59
+ >
60
+ <div className={cx('w-full text-left text-body-md', TEXT_COLOR[type])}>{text}</div>
61
+ {showClose && (
62
+ <Close
63
+ className={cx('h-5 w-5 cursor-pointer', TEXT_COLOR[type])}
64
+ onClick={onClose}
65
+ />
66
+ )}
67
+ </div>
68
+ );
69
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Snackbar';
5
+ export { SnackbarType } from './snackbar.enums';
@@ -0,0 +1,18 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { SnackbarType } from './snackbar.enums';
5
+
6
+ export const TEXT_COLOR: Record<SnackbarType, string> = {
7
+ [SnackbarType.Default]: 'text-neutral-10 dark:text-neutral-92',
8
+ [SnackbarType.Error]: 'text-error-20 dark:text-error-90',
9
+ [SnackbarType.Warning]: 'text-warning-10 dark:text-warning-90',
10
+ [SnackbarType.Success]: 'text-tertiary-20 dark:text-tertiary-90',
11
+ };
12
+
13
+ export const BACKGROUND_COLOR: Record<SnackbarType, string> = {
14
+ [SnackbarType.Default]: 'bg-primary-90 dark:bg-primary-10',
15
+ [SnackbarType.Error]: 'bg-error-90 dark:bg-error-10',
16
+ [SnackbarType.Warning]: 'bg-warning-90 dark:bg-warning-20',
17
+ [SnackbarType.Success]: 'bg-tertiary-90 dark:bg-tertiary-10',
18
+ };
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum SnackbarType {
5
+ Default = 'default',
6
+ Error = 'error',
7
+ Warning = 'warning',
8
+ Success = 'success',
9
+ }
@@ -0,0 +1,37 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { PropsWithChildren } from 'react';
5
+ import cx from 'classnames';
6
+ import { TooltipPosition } from './tooltip.enums';
7
+ import { TOOLTIP_POSITION } from './tooltip.classes';
8
+
9
+ interface TooltipProps {
10
+ text: string;
11
+ position?: TooltipPosition;
12
+ maxWidth?: string;
13
+ }
14
+
15
+ export function Tooltip({
16
+ text,
17
+ position = TooltipPosition.Top,
18
+ maxWidth = 'max-w-[200px]',
19
+ children,
20
+ }: PropsWithChildren<TooltipProps>): React.JSX.Element {
21
+ const tooltipPositionClass = TOOLTIP_POSITION[position];
22
+ return (
23
+ <div className="group relative inline-block">
24
+ {children}
25
+ <div
26
+ className={cx(
27
+ 'absolute z-[999] hidden w-max rounded bg-neutral-80 p-xs text-neutral-10 opacity-0 transition-opacity duration-300 group-hover:block group-hover:opacity-100 group-focus:opacity-100 dark:bg-neutral-30 dark:text-neutral-92',
28
+ tooltipPositionClass,
29
+ maxWidth,
30
+ )}
31
+ role="tooltip"
32
+ >
33
+ <p className="w-full break-words">{text}</p>
34
+ </div>
35
+ </div>
36
+ );
37
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Tooltip';
5
+ export * from './tooltip.enums';
@@ -0,0 +1,11 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { TooltipPosition } from './tooltip.enums';
5
+
6
+ export const TOOLTIP_POSITION: Record<TooltipPosition, string> = {
7
+ [TooltipPosition.Top]: 'bottom-full left-1/2 transform -translate-x-1/2 mb-1',
8
+ [TooltipPosition.Bottom]: 'top-full left-1/2 transform -translate-x-1/2 mt-1',
9
+ [TooltipPosition.Left]: 'top-1/2 right-full transform -translate-y-1/2 mr-1',
10
+ [TooltipPosition.Right]: 'top-1/2 left-full transform -translate-y-1/2 ml-1',
11
+ };
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum TooltipPosition {
5
+ Top = 'top',
6
+ Bottom = 'bottom',
7
+ Left = 'left',
8
+ Right = 'right',
9
+ }
@@ -0,0 +1,101 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { VisualAssetType } from './visualAssetCard.enums';
5
+ import { ButtonUnstyled } from '../button';
6
+ import { MoreHoriz, PlaceholderReplace } from '@iota/apps-ui-icons';
7
+ import cx from 'classnames';
8
+ import { useState } from 'react';
9
+
10
+ export interface VisualAssetCardProps {
11
+ /**
12
+ * The type of the asset to be displayed.
13
+ */
14
+ assetType?: VisualAssetType;
15
+ /**
16
+ * The source of the image to be displayed.
17
+ */
18
+ assetSrc: string;
19
+ /**
20
+ * Alt text for the image.
21
+ */
22
+ altText: string;
23
+ /**
24
+ * The onClick event for the icon.
25
+ */
26
+ onIconClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
27
+ /**
28
+ * The onClick event for the card.
29
+ */
30
+ onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
31
+ /**
32
+ * The icon to be displayed.
33
+ */
34
+ icon?: React.ReactNode;
35
+ /**
36
+ * The title text to be displayed on hover.
37
+ */
38
+ assetTitle?: string;
39
+ /**
40
+ * Whether the card is hoverable.
41
+ */
42
+ isHoverable?: boolean;
43
+ }
44
+
45
+ export function VisualAssetCard({
46
+ assetType = VisualAssetType.Image,
47
+ assetSrc,
48
+ altText,
49
+ onIconClick,
50
+ onClick,
51
+ icon = <MoreHoriz />,
52
+ assetTitle,
53
+ isHoverable = true,
54
+ }: VisualAssetCardProps): React.JSX.Element {
55
+ const [imageError, setImageError] = useState(false);
56
+
57
+ const handleIconClick = (event: React.MouseEvent<HTMLButtonElement>) => {
58
+ onIconClick?.(event);
59
+ event?.stopPropagation();
60
+ };
61
+
62
+ return (
63
+ <div
64
+ className={cx('relative aspect-square w-full overflow-hidden rounded-xl', {
65
+ 'group cursor-pointer': isHoverable,
66
+ })}
67
+ onClick={onClick}
68
+ >
69
+ {assetType === VisualAssetType.Video ? (
70
+ <video src={assetSrc} className="h-full w-full object-cover" autoPlay loop muted />
71
+ ) : imageError ? (
72
+ <div className="flex h-full w-full items-center justify-center bg-neutral-96 dark:bg-neutral-10">
73
+ <PlaceholderReplace className="h-4 w-4 text-neutral-40 dark:text-neutral-60" />
74
+ </div>
75
+ ) : (
76
+ <img
77
+ src={assetSrc}
78
+ alt={altText}
79
+ className="h-full w-full object-cover"
80
+ onError={() => setImageError(true)}
81
+ />
82
+ )}
83
+ {isHoverable && (
84
+ <div className="absolute left-0 top-0 h-full w-full bg-cover bg-center bg-no-repeat group-hover:bg-shader-neutral-light-48 group-hover:transition group-hover:duration-300 group-hover:ease-in-out group-hover:dark:bg-shader-primary-dark-48" />
85
+ )}
86
+ {isHoverable && onIconClick && (
87
+ <ButtonUnstyled
88
+ className="absolute right-2 top-2 h-9 w-9 cursor-pointer rounded-full p-xs opacity-0 transition-opacity duration-300 group-hover:bg-shader-neutral-light-72 group-hover:opacity-100 [&_svg]:h-5 [&_svg]:w-5 [&_svg]:text-primary-100"
89
+ onClick={handleIconClick}
90
+ >
91
+ {icon}
92
+ </ButtonUnstyled>
93
+ )}
94
+ {isHoverable && assetTitle && (
95
+ <div className="absolute bottom-0 flex items-center justify-center p-xs opacity-0 transition-opacity duration-300 group-hover:opacity-100">
96
+ <span className="text-title-md text-neutral-100">{assetTitle}</span>
97
+ </div>
98
+ )}
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './VisualAssetCard';
5
+ export * from './visualAssetCard.enums';
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum VisualAssetType {
5
+ Image = 'image',
6
+ Video = 'video',
7
+ }
@@ -0,0 +1,8 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import '../styles/index.css';
5
+
6
+ export * from './atoms';
7
+ export * from './molecules';
8
+ export * from './organisms';