@iota/apps-ui-kit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/index.d.ts +1622 -0
  3. package/dist/index.es.js +8805 -0
  4. package/dist/index.es.js.map +1 -0
  5. package/dist/index.umd.js +198 -0
  6. package/dist/index.umd.js.map +1 -0
  7. package/dist/style.css +1 -0
  8. package/package.json +5 -2
  9. package/src/lib/components/atoms/badge/Badge.tsx +37 -0
  10. package/src/lib/components/atoms/badge/badge.classes.ts +24 -0
  11. package/src/lib/components/atoms/badge/badge.enums.ts +8 -0
  12. package/src/lib/components/atoms/badge/index.ts +6 -0
  13. package/src/lib/components/atoms/button/Button.tsx +99 -0
  14. package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +23 -0
  15. package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +27 -0
  16. package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +11 -0
  17. package/src/lib/components/atoms/button/button-variants/index.ts +5 -0
  18. package/src/lib/components/atoms/button/button.classes.ts +53 -0
  19. package/src/lib/components/atoms/button/button.enums.ts +21 -0
  20. package/src/lib/components/atoms/button/index.ts +7 -0
  21. package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +86 -0
  22. package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +45 -0
  23. package/src/lib/components/atoms/button-segment/buttonSegment.enums.ts +7 -0
  24. package/src/lib/components/atoms/button-segment/index.ts +5 -0
  25. package/src/lib/components/atoms/checkbox/Checkbox.tsx +114 -0
  26. package/src/lib/components/atoms/checkbox/index.ts +4 -0
  27. package/src/lib/components/atoms/divider/Divider.tsx +48 -0
  28. package/src/lib/components/atoms/divider/divider.classes.ts +11 -0
  29. package/src/lib/components/atoms/divider/divider.enums.ts +7 -0
  30. package/src/lib/components/atoms/divider/index.ts +6 -0
  31. package/src/lib/components/atoms/header/Header.tsx +73 -0
  32. package/src/lib/components/atoms/header/index.ts +4 -0
  33. package/src/lib/components/atoms/index.ts +22 -0
  34. package/src/lib/components/atoms/info-box/InfoBox.tsx +73 -0
  35. package/src/lib/components/atoms/info-box/index.ts +5 -0
  36. package/src/lib/components/atoms/info-box/infoBox.classes.ts +14 -0
  37. package/src/lib/components/atoms/info-box/infoBox.enums.ts +12 -0
  38. package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +156 -0
  39. package/src/lib/components/atoms/key-value-info/index.ts +6 -0
  40. package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
  41. package/src/lib/components/atoms/label-text/LabelText.tsx +93 -0
  42. package/src/lib/components/atoms/label-text/index.ts +5 -0
  43. package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
  44. package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
  45. package/src/lib/components/atoms/list-item/ListItem.tsx +89 -0
  46. package/src/lib/components/atoms/list-item/index.ts +4 -0
  47. package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
  48. package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
  49. package/src/lib/components/atoms/panel/Panel.tsx +30 -0
  50. package/src/lib/components/atoms/panel/index.ts +4 -0
  51. package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
  52. package/src/lib/components/atoms/placeholder/index.ts +4 -0
  53. package/src/lib/components/atoms/radio-button/RadioButton.tsx +68 -0
  54. package/src/lib/components/atoms/radio-button/index.ts +4 -0
  55. package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +28 -0
  56. package/src/lib/components/atoms/secondary-text/index.ts +4 -0
  57. package/src/lib/components/atoms/skeleton/Skeleton.tsx +47 -0
  58. package/src/lib/components/atoms/skeleton/index.ts +4 -0
  59. package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
  60. package/src/lib/components/atoms/snackbar/index.ts +5 -0
  61. package/src/lib/components/atoms/snackbar/snackbar.classes.ts +14 -0
  62. package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +7 -0
  63. package/src/lib/components/atoms/tooltip/Tooltip.tsx +34 -0
  64. package/src/lib/components/atoms/tooltip/index.ts +5 -0
  65. package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
  66. package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
  67. package/src/lib/components/atoms/visual-asset-card/VisualAssetCard.tsx +93 -0
  68. package/src/lib/components/atoms/visual-asset-card/index.ts +5 -0
  69. package/src/lib/components/atoms/visual-asset-card/visualAssetCard.enums.ts +7 -0
  70. package/src/lib/components/index.ts +8 -0
  71. package/src/lib/components/molecules/account/Account.tsx +174 -0
  72. package/src/lib/components/molecules/account/index.ts +4 -0
  73. package/src/lib/components/molecules/address/Address.tsx +101 -0
  74. package/src/lib/components/molecules/address/index.ts +4 -0
  75. package/src/lib/components/molecules/card/Card.tsx +70 -0
  76. package/src/lib/components/molecules/card/CardAction.tsx +78 -0
  77. package/src/lib/components/molecules/card/CardBody.tsx +61 -0
  78. package/src/lib/components/molecules/card/CardImage.tsx +43 -0
  79. package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
  80. package/src/lib/components/molecules/card/card.classes.ts +26 -0
  81. package/src/lib/components/molecules/card/card.enums.ts +25 -0
  82. package/src/lib/components/molecules/card/index.ts +8 -0
  83. package/src/lib/components/molecules/chip/Chip.tsx +105 -0
  84. package/src/lib/components/molecules/chip/chip.classes.ts +32 -0
  85. package/src/lib/components/molecules/chip/chip.enums.ts +7 -0
  86. package/src/lib/components/molecules/chip/index.ts +4 -0
  87. package/src/lib/components/molecules/display-stats/DisplayStats.tsx +104 -0
  88. package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
  89. package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
  90. package/src/lib/components/molecules/display-stats/index.ts +5 -0
  91. package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
  92. package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
  93. package/src/lib/components/molecules/dropdown/index.ts +5 -0
  94. package/src/lib/components/molecules/index.ts +17 -0
  95. package/src/lib/components/molecules/input/Input.tsx +245 -0
  96. package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
  97. package/src/lib/components/molecules/input/TextArea.tsx +149 -0
  98. package/src/lib/components/molecules/input/index.ts +8 -0
  99. package/src/lib/components/molecules/input/input.classes.ts +14 -0
  100. package/src/lib/components/molecules/input/input.enums.ts +14 -0
  101. package/src/lib/components/molecules/input/input.types.ts +29 -0
  102. package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +48 -0
  103. package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
  104. package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
  105. package/src/lib/components/molecules/navbar-item/index.ts +5 -0
  106. package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
  107. package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
  108. package/src/lib/components/molecules/search/Search.tsx +189 -0
  109. package/src/lib/components/molecules/search/index.ts +5 -0
  110. package/src/lib/components/molecules/search/search.classes.ts +20 -0
  111. package/src/lib/components/molecules/search/search.enums.ts +7 -0
  112. package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +34 -0
  113. package/src/lib/components/molecules/segmented-button/index.ts +6 -0
  114. package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
  115. package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
  116. package/src/lib/components/molecules/select/Select.tsx +223 -0
  117. package/src/lib/components/molecules/select/index.ts +5 -0
  118. package/src/lib/components/molecules/select/select.enums.ts +7 -0
  119. package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
  120. package/src/lib/components/molecules/table-cell/index.ts +4 -0
  121. package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +126 -0
  122. package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
  123. package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
  124. package/src/lib/components/molecules/title/Title.tsx +69 -0
  125. package/src/lib/components/molecules/title/index.ts +5 -0
  126. package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
  127. package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
  128. package/src/lib/components/organisms/accordion/Accordion.tsx +111 -0
  129. package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
  130. package/src/lib/components/organisms/accordion/index.ts +4 -0
  131. package/src/lib/components/organisms/dialog/Dialog.tsx +122 -0
  132. package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
  133. package/src/lib/components/organisms/dialog/index.ts +5 -0
  134. package/src/lib/components/organisms/index.ts +7 -0
  135. package/src/lib/components/organisms/navbar/Navbar.tsx +100 -0
  136. package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +58 -0
  137. package/src/lib/components/organisms/navbar/index.ts +5 -0
  138. package/src/lib/components/organisms/table/Table.tsx +224 -0
  139. package/src/lib/components/organisms/table/TableContext.tsx +55 -0
  140. package/src/lib/components/organisms/table/index.ts +4 -0
  141. package/src/lib/constants/colors.constants.ts +127 -0
  142. package/src/lib/constants/index.ts +4 -0
  143. package/src/lib/enums/index.ts +4 -0
  144. package/src/lib/enums/screenSize.enums.ts +9 -0
  145. package/src/lib/index.ts +8 -0
  146. package/src/lib/styles/fonts.css +5 -0
  147. package/src/lib/styles/index.css +136 -0
  148. package/src/lib/tailwind/base.presets.ts +47 -0
  149. package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
  150. package/src/lib/tailwind/constants/index.ts +6 -0
  151. package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
  152. package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
  153. package/src/lib/tailwind/helpers.ts +20 -0
  154. package/src/lib/tailwind/index.ts +5 -0
  155. package/src/lib/tailwind/responsive.presets.ts +36 -0
  156. package/src/lib/tailwind/static.presets.ts +25 -0
  157. package/src/lib/tailwind/types.ts +6 -0
  158. package/src/lib/utils/format.ts +8 -0
  159. package/src/lib/utils/index.ts +4 -0
  160. package/src/storybook/blocks/Showcase.tsx +20 -0
  161. package/src/storybook/blocks/TypeSet.tsx +34 -0
  162. package/src/storybook/blocks/TypeSetItem.tsx +74 -0
  163. package/src/storybook/blocks/index.ts +6 -0
  164. package/src/storybook/constants/index.ts +5 -0
  165. package/src/storybook/constants/typeset.constants.ts +39 -0
  166. package/src/storybook/constants/variableSpacing.constants.ts +6 -0
  167. package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
  168. package/src/storybook/helpers/index.ts +4 -0
  169. package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
  170. package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
  171. package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
  172. package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
  173. package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
  174. package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
  175. package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
  176. package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
  177. package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
  178. package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
  179. package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
  180. package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
  181. package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
  182. package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
  183. package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
  184. package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
  185. package/src/storybook/stories/atoms/Snackbar.stories.tsx +42 -0
  186. package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
  187. package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
  188. package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
  189. package/src/storybook/stories/components/index.ts +4 -0
  190. package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
  191. package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
  192. package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
  193. package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
  194. package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
  195. package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
  196. package/src/storybook/stories/molecules/Card.stories.tsx +115 -0
  197. package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
  198. package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
  199. package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
  200. package/src/storybook/stories/molecules/Input.stories.tsx +161 -0
  201. package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
  202. package/src/storybook/stories/molecules/Search.stories.tsx +100 -0
  203. package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +107 -0
  204. package/src/storybook/stories/molecules/Select.stories.tsx +102 -0
  205. package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
  206. package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
  207. package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
  208. package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
  209. package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
  210. package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
  211. package/src/storybook/stories/organisms/Navbar.stories.tsx +77 -0
  212. package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
@@ -0,0 +1,26 @@
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.BgTransparent]: '',
19
+ };
20
+
21
+ export const CARD_TYPE_CLASSES: Record<CardType, string> = {
22
+ [CardType.Default]: 'border border-transparent',
23
+ [CardType.Outlined]:
24
+ 'border border-shader-neutral-light-8 dark:border-shader-primary-dark-8 p-xs',
25
+ [CardType.Filled]: 'border border-transparent bg-neutral-96 dark:bg-neutral-10 p-xs',
26
+ };
@@ -0,0 +1,25 @@
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
+ BgTransparent = 'bg-transparent',
14
+ }
15
+
16
+ export enum ImageShape {
17
+ Rounded = 'rounded',
18
+ SquareRounded = 'square-rounded',
19
+ }
20
+
21
+ export enum CardActionType {
22
+ Link = 'link',
23
+ SupportingText = 'supporting-text',
24
+ Button = 'button',
25
+ }
@@ -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 '../../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';
@@ -0,0 +1,104 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ReactNode } from 'react';
5
+ import { Tooltip, TooltipPosition } from '../../atoms';
6
+ import { Info } from '@iota/apps-ui-icons';
7
+ import { DisplayStatsType, DisplayStatsSize } from './displayStats.enums';
8
+ import cx from 'classnames';
9
+ import {
10
+ BACKGROUND_CLASSES,
11
+ SIZE_CLASSES,
12
+ TEXT_CLASSES,
13
+ VALUE_TEXT_CLASSES,
14
+ SUPPORTING_LABEL_TEXT_CLASSES,
15
+ LABEL_TEXT_CLASSES,
16
+ } from './displayStats.classes';
17
+
18
+ interface DisplayStatsProps {
19
+ /**
20
+ * The label of the stats.
21
+ */
22
+ label: ReactNode;
23
+ /**
24
+ * The tooltip position.
25
+ */
26
+ tooltipPosition?: TooltipPosition;
27
+ /**
28
+ * The tooltip text.
29
+ */
30
+ tooltipText?: string;
31
+ /**
32
+ * The value of the stats.
33
+ */
34
+ value: ReactNode;
35
+ /**
36
+ * The supporting label of the stats (optional).
37
+ */
38
+ supportingLabel?: string;
39
+ /**
40
+ * The background color of the stats.
41
+ */
42
+ type?: DisplayStatsType;
43
+ /**
44
+ * The size of the stats.
45
+ */
46
+ size?: DisplayStatsSize;
47
+ /**
48
+ * Add icon to the right of the label.
49
+ */
50
+ icon?: React.ReactNode;
51
+ }
52
+
53
+ export function DisplayStats({
54
+ label,
55
+ tooltipPosition,
56
+ tooltipText,
57
+ value,
58
+ supportingLabel,
59
+ type = DisplayStatsType.Default,
60
+ size = DisplayStatsSize.Default,
61
+ icon,
62
+ }: DisplayStatsProps): React.JSX.Element {
63
+ const backgroundClass = BACKGROUND_CLASSES[type];
64
+ const sizeClass = SIZE_CLASSES[size];
65
+ const textClass = TEXT_CLASSES[type];
66
+ const valueClass = VALUE_TEXT_CLASSES[size];
67
+ const labelClass = LABEL_TEXT_CLASSES[size];
68
+ const supportingLabelTextClass = SUPPORTING_LABEL_TEXT_CLASSES[size];
69
+
70
+ return (
71
+ <div
72
+ className={cx(
73
+ 'flex h-full w-full flex-col justify-between rounded-2xl p-md--rs',
74
+ backgroundClass,
75
+ sizeClass,
76
+ textClass,
77
+ )}
78
+ >
79
+ <div
80
+ className={cx('flex flex-row items-center', {
81
+ 'w-full justify-between': icon,
82
+ })}
83
+ >
84
+ <div className="flex flex-row items-center gap-xxs">
85
+ <span className={cx(labelClass, 'whitespace-pre-line')}>{label}</span>
86
+ {tooltipText && (
87
+ <Tooltip text={tooltipText} position={tooltipPosition}>
88
+ <Info className="opacity-40" />
89
+ </Tooltip>
90
+ )}
91
+ </div>
92
+ {icon && <span className="text-neutral-10 dark:text-neutral-92">{icon}</span>}
93
+ </div>
94
+ <div className="flex w-full flex-row items-baseline gap-xxs">
95
+ <span className={cx('break-all', valueClass)}>{value}</span>
96
+ {supportingLabel && (
97
+ <span className={cx('opacity-40', supportingLabelTextClass)}>
98
+ {supportingLabel}
99
+ </span>
100
+ )}
101
+ </div>
102
+ </div>
103
+ );
104
+ }
@@ -0,0 +1,36 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { DisplayStatsType, DisplayStatsSize } from './displayStats.enums';
5
+
6
+ export const BACKGROUND_CLASSES: Record<DisplayStatsType, string> = {
7
+ [DisplayStatsType.Default]: 'bg-neutral-96 dark:bg-neutral-10',
8
+ [DisplayStatsType.Highlight]: 'bg-primary-30 dark:bg-primary-80',
9
+ [DisplayStatsType.Secondary]: 'bg-secondary-90 dark:bg-secondary-10',
10
+ };
11
+
12
+ export const TEXT_CLASSES: Record<DisplayStatsType, string> = {
13
+ [DisplayStatsType.Default]: 'text-neutral-10 dark:text-neutral-92',
14
+ [DisplayStatsType.Highlight]: 'text-neutral-100 dark:text-primary-10',
15
+ [DisplayStatsType.Secondary]: 'text-neutral-10 dark:text-neutral-92',
16
+ };
17
+
18
+ export const SIZE_CLASSES: Record<DisplayStatsSize, string> = {
19
+ [DisplayStatsSize.Default]: 'gap-y-sm',
20
+ [DisplayStatsSize.Large]: 'gap-y-md',
21
+ };
22
+
23
+ export const VALUE_TEXT_CLASSES: Record<DisplayStatsSize, string> = {
24
+ [DisplayStatsSize.Default]: 'text-title-md',
25
+ [DisplayStatsSize.Large]: 'text-headline-sm',
26
+ };
27
+
28
+ export const SUPPORTING_LABEL_TEXT_CLASSES: Record<DisplayStatsSize, string> = {
29
+ [DisplayStatsSize.Default]: 'text-label-md',
30
+ [DisplayStatsSize.Large]: 'text-label-lg',
31
+ };
32
+
33
+ export const LABEL_TEXT_CLASSES: Record<DisplayStatsSize, string> = {
34
+ [DisplayStatsSize.Default]: 'text-label-sm',
35
+ [DisplayStatsSize.Large]: 'text-label-md',
36
+ };
@@ -0,0 +1,13 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum DisplayStatsType {
5
+ Default = 'default',
6
+ Highlight = 'highlight',
7
+ Secondary = 'secondary',
8
+ }
9
+
10
+ export enum DisplayStatsSize {
11
+ Default = 'default',
12
+ Large = 'large',
13
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './DisplayStats';
5
+ export * from './displayStats.enums';
@@ -0,0 +1,10 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export function Dropdown({ children }: React.PropsWithChildren): React.JSX.Element {
5
+ return (
6
+ <ul className="list-none rounded-lg border border-neutral-80 bg-neutral-100 py-xs dark:border-neutral-20 dark:bg-neutral-6">
7
+ {children}
8
+ </ul>
9
+ );
10
+ }
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum DropdownPosition {
5
+ Top = 'top',
6
+ Bottom = 'bottom',
7
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Dropdown';
5
+ export * from './dropdownPosition.enums';
@@ -0,0 +1,17 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './address';
5
+ export * from './chip';
6
+ export * from './segmented-button';
7
+ export * from './title';
8
+ export * from './input';
9
+ export * from './navbar-item';
10
+ export * from './account';
11
+ export * from './dropdown';
12
+ export * from './table-cell';
13
+ export * from './select';
14
+ export * from './table-header-cell';
15
+ export * from './search';
16
+ export * from './card';
17
+ export * from './display-stats';
@@ -0,0 +1,245 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { forwardRef, Fragment, useEffect, useRef, useState } from 'react';
5
+ import cx from 'classnames';
6
+ import { InputWrapper, InputWrapperProps } from './InputWrapper';
7
+ import {
8
+ BORDER_CLASSES,
9
+ INPUT_CLASSES,
10
+ INPUT_TEXT_CLASSES,
11
+ INPUT_NUMBER_CLASSES,
12
+ INPUT_PLACEHOLDER_CLASSES,
13
+ } from './input.classes';
14
+ import { InputType } from './input.enums';
15
+ import { SecondaryText } from '../../atoms/secondary-text';
16
+ import { Close, VisibilityOff, VisibilityOn } from '@iota/apps-ui-icons';
17
+ import { ButtonUnstyled } from '../../atoms/button';
18
+ import { InputPropsByType, NumericFormatInputProps } from './input.types';
19
+ import { NumericFormat } from 'react-number-format';
20
+
21
+ export interface BaseInputProps extends InputWrapperProps {
22
+ /**
23
+ * A leading icon that is shown before the input
24
+ */
25
+ leadingIcon?: React.JSX.Element;
26
+ /**
27
+ * Supporting text that is shown at the end of the input component.
28
+ */
29
+ supportingText?: string;
30
+ /**
31
+ * Amount counter that is shown at the side of the caption text.
32
+ */
33
+ amountCounter?: string | number;
34
+ /**
35
+ * Trailing element that is shown after the input
36
+ */
37
+ trailingElement?: React.JSX.Element;
38
+ /**
39
+ * Is the content of the input visible
40
+ */
41
+ isContentVisible?: boolean;
42
+ /**
43
+ * Value of the input
44
+ */
45
+ value?: string | number;
46
+ /**
47
+ * Default value of the input
48
+ */
49
+ defaultValue?: string | number;
50
+ /**
51
+ * onClearInput function that is called when the clear button is clicked
52
+ */
53
+ onClearInput?: () => void;
54
+ /**
55
+ * Shows toggle button to show/hide the content of the input field
56
+ */
57
+ isVisibilityToggleEnabled?: boolean;
58
+ }
59
+
60
+ export type InputProps = BaseInputProps & InputPropsByType;
61
+
62
+ export const Input = forwardRef<HTMLInputElement, InputProps>(function InputComponent(
63
+ {
64
+ label,
65
+ caption,
66
+ disabled,
67
+ errorMessage,
68
+ leadingIcon,
69
+ supportingText,
70
+ amountCounter,
71
+ trailingElement,
72
+ isContentVisible,
73
+ value,
74
+ defaultValue,
75
+ onClearInput,
76
+ isVisibilityToggleEnabled,
77
+ type,
78
+ ...inputProps
79
+ },
80
+ forwardRef,
81
+ ) {
82
+ isVisibilityToggleEnabled ??= type === InputType.Password;
83
+ const inputWrapperRef = useRef<HTMLDivElement | null>(null);
84
+
85
+ const [isInputContentVisible, setIsInputContentVisible] = useState<boolean>(
86
+ isContentVisible ?? type !== InputType.Password,
87
+ );
88
+
89
+ useEffect(() => {
90
+ setIsInputContentVisible(isContentVisible ?? type !== InputType.Password);
91
+ }, [type, isContentVisible]);
92
+
93
+ function onToggleButtonClick() {
94
+ setIsInputContentVisible((prev) => !prev);
95
+ }
96
+
97
+ function focusOnInput() {
98
+ if (inputWrapperRef.current) {
99
+ inputWrapperRef.current.querySelector('input')?.focus();
100
+ }
101
+ }
102
+
103
+ return (
104
+ <InputWrapper
105
+ label={label}
106
+ caption={caption}
107
+ disabled={disabled}
108
+ errorMessage={errorMessage}
109
+ amountCounter={amountCounter}
110
+ required={inputProps.required}
111
+ >
112
+ <div
113
+ className={cx('relative flex flex-row items-center gap-x-3', BORDER_CLASSES)}
114
+ onClick={focusOnInput}
115
+ ref={inputWrapperRef}
116
+ >
117
+ {leadingIcon && (
118
+ <span className="text-neutral-10 dark:text-neutral-92">{leadingIcon}</span>
119
+ )}
120
+ <InputElement
121
+ {...inputProps}
122
+ inputRef={forwardRef}
123
+ value={value}
124
+ type={
125
+ type === InputType.Password && isInputContentVisible ? InputType.Text : type
126
+ }
127
+ disabled={disabled}
128
+ className={cx(
129
+ INPUT_CLASSES,
130
+ INPUT_TEXT_CLASSES,
131
+ INPUT_PLACEHOLDER_CLASSES,
132
+ INPUT_NUMBER_CLASSES,
133
+ )}
134
+ />
135
+
136
+ {supportingText && <SecondaryText>{supportingText}</SecondaryText>}
137
+ <InputTrailingElement
138
+ value={value}
139
+ type={type}
140
+ onClearInput={onClearInput}
141
+ isContentVisible={isInputContentVisible}
142
+ trailingElement={trailingElement}
143
+ isVisibilityToggleEnabled={isVisibilityToggleEnabled}
144
+ onToggleButtonClick={onToggleButtonClick}
145
+ />
146
+ </div>
147
+ </InputWrapper>
148
+ );
149
+ });
150
+
151
+ function InputElement({
152
+ type,
153
+ inputRef,
154
+ ...inputProps
155
+ }: InputProps & {
156
+ inputRef: React.ForwardedRef<HTMLInputElement>;
157
+ className: string;
158
+ }) {
159
+ function preventScrollInputChange(e: React.WheelEvent<HTMLInputElement>) {
160
+ if (type === InputType.Number) {
161
+ const input = e.currentTarget;
162
+
163
+ input.blur();
164
+ e.stopPropagation();
165
+ setTimeout(() => {
166
+ input.focus({ preventScroll: true });
167
+ }, 0);
168
+ }
169
+ }
170
+ return type === InputType.NumericFormat ? (
171
+ <NumericFormatInput inputRef={inputRef} {...inputProps} type={type} />
172
+ ) : (
173
+ <input
174
+ ref={inputRef}
175
+ {...inputProps}
176
+ type={type}
177
+ onWheel={(e) => {
178
+ preventScrollInputChange(e);
179
+ inputProps.onWheel?.(e);
180
+ }}
181
+ />
182
+ );
183
+ }
184
+
185
+ function NumericFormatInput({
186
+ inputRef,
187
+ className,
188
+ type,
189
+ ...inputProps
190
+ }: NumericFormatInputProps &
191
+ InputProps & {
192
+ inputRef: React.ForwardedRef<HTMLInputElement>;
193
+ className: string;
194
+ value?: string | number;
195
+ }) {
196
+ return (
197
+ <NumericFormat
198
+ className={className}
199
+ valueIsNumericString
200
+ getInputRef={inputRef}
201
+ {...inputProps}
202
+ />
203
+ );
204
+ }
205
+
206
+ function InputTrailingElement({
207
+ value,
208
+ type,
209
+ onClearInput,
210
+ isContentVisible,
211
+ trailingElement,
212
+ onToggleButtonClick,
213
+ isVisibilityToggleEnabled,
214
+ }: BaseInputProps & {
215
+ onToggleButtonClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
216
+ type: InputPropsByType['type'];
217
+ }) {
218
+ const showClearInput = Boolean(type === InputType.Text && value && onClearInput);
219
+ const showPasswordToggle = Boolean(type === InputType.Password && isVisibilityToggleEnabled);
220
+ const showTrailingElement = Boolean(trailingElement && !showClearInput && !showPasswordToggle);
221
+
222
+ if (showClearInput) {
223
+ return (
224
+ <ButtonUnstyled
225
+ className="text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"
226
+ onClick={onClearInput}
227
+ tabIndex={-1}
228
+ >
229
+ <Close />
230
+ </ButtonUnstyled>
231
+ );
232
+ } else if (showPasswordToggle) {
233
+ return (
234
+ <ButtonUnstyled
235
+ onClick={onToggleButtonClick}
236
+ className="text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"
237
+ tabIndex={-1}
238
+ >
239
+ {isContentVisible ? <VisibilityOn /> : <VisibilityOff />}
240
+ </ButtonUnstyled>
241
+ );
242
+ } else if (showTrailingElement) {
243
+ return <Fragment>{trailingElement}</Fragment>;
244
+ }
245
+ }