@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,109 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { PropsWithChildren } from 'react';
5
+ import cx from 'classnames';
6
+ import { ArrowDown } from '@iota/apps-ui-icons';
7
+ import { Button, ButtonType } from '@/components/atoms';
8
+ import { ICON_STYLE } from './accordion.classes';
9
+
10
+ export interface AccordionHeaderProps {
11
+ /**
12
+ * Flag for show/hide content
13
+ */
14
+ isExpanded: boolean;
15
+
16
+ /**
17
+ * Action on toggle show/hide content
18
+ */
19
+ onToggle: () => void;
20
+
21
+ /**
22
+ * The type of the badge.
23
+ */
24
+ badge?: React.ReactNode;
25
+ /**
26
+ * Flag for hiding arrow.
27
+ */
28
+ hideArrow?: boolean;
29
+ /**
30
+ * Flag for hiding border.
31
+ */
32
+ hideBorder?: boolean;
33
+ }
34
+
35
+ interface AccordionContentProps {
36
+ /**
37
+ * Flag for show/hide content
38
+ */
39
+ isExpanded: boolean;
40
+ }
41
+
42
+ export function AccordionHeader({
43
+ onToggle,
44
+ children,
45
+ isExpanded,
46
+ hideArrow,
47
+ }: PropsWithChildren<AccordionHeaderProps>) {
48
+ return (
49
+ <div
50
+ onClick={onToggle}
51
+ className={cx(
52
+ 'state-layer relative flex cursor-pointer items-center justify-between gap-md overflow-hidden rounded-xl py-sm--rs',
53
+ {
54
+ 'pr-md--rs': !hideArrow,
55
+ },
56
+ )}
57
+ >
58
+ {children}
59
+ {!hideArrow && (
60
+ <div className="[&_svg]:h-5 [&_svg]:w-5">
61
+ <Button
62
+ type={ButtonType.Ghost}
63
+ icon={
64
+ <ArrowDown
65
+ className={cx(ICON_STYLE, {
66
+ 'rotate-180': isExpanded,
67
+ })}
68
+ />
69
+ }
70
+ />
71
+ </div>
72
+ )}
73
+ </div>
74
+ );
75
+ }
76
+
77
+ export function AccordionContent({
78
+ isExpanded,
79
+ children,
80
+ }: PropsWithChildren<AccordionContentProps>) {
81
+ return (
82
+ <div
83
+ className={cx({
84
+ hidden: !isExpanded,
85
+ })}
86
+ >
87
+ {children}
88
+ </div>
89
+ );
90
+ }
91
+
92
+ export function Accordion({
93
+ children,
94
+ hideBorder,
95
+ }: {
96
+ children: React.ReactNode;
97
+ hideBorder?: boolean;
98
+ }): React.JSX.Element {
99
+ return (
100
+ <div
101
+ className={cx('rounded-xl bg-neutral-100 dark:bg-neutral-6', {
102
+ 'border border-shader-neutral-light-8 dark:border-shader-neutral-dark-8':
103
+ !hideBorder,
104
+ })}
105
+ >
106
+ {children}
107
+ </div>
108
+ );
109
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export const ICON_STYLE = 'text-neutral-10 dark:text-neutral-92 transition-transform ease-linear';
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Accordion';
@@ -0,0 +1,142 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import * as RadixDialog from '@radix-ui/react-dialog';
5
+ import * as VisuallyHidden from '@radix-ui/react-visually-hidden';
6
+ import cx from 'classnames';
7
+ import * as React from 'react';
8
+ import { Close } from '@iota/apps-ui-icons';
9
+ import { useEffect, useState } from 'react';
10
+ import { DialogPosition } from './dialog.enums';
11
+
12
+ const Dialog = ({
13
+ open,
14
+ onOpenChange,
15
+ children,
16
+ ...props
17
+ }: React.ComponentPropsWithoutRef<typeof RadixDialog.Root>) => {
18
+ const handleOpenChange = (isOpen: boolean) => {
19
+ const isMouseOverToast = document.querySelector('.toast-layer:hover');
20
+ if (!isOpen && isMouseOverToast) {
21
+ return;
22
+ }
23
+ onOpenChange?.(isOpen);
24
+ };
25
+
26
+ return (
27
+ <RadixDialog.Root open={open} onOpenChange={handleOpenChange} {...props}>
28
+ {children}
29
+ </RadixDialog.Root>
30
+ );
31
+ };
32
+ const DialogTrigger = RadixDialog.Trigger;
33
+ const DialogClose = RadixDialog.Close;
34
+
35
+ const DialogOverlay = React.forwardRef<
36
+ React.ElementRef<typeof RadixDialog.Overlay>,
37
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Overlay> & {
38
+ showCloseIcon?: boolean;
39
+ position?: DialogPosition;
40
+ }
41
+ >(({ showCloseIcon, position, ...props }, ref) => (
42
+ <RadixDialog.Overlay
43
+ ref={ref}
44
+ className={cx('inset-0 z-[99998] bg-shader-neutral-light-48 backdrop-blur-md', {
45
+ fixed: position === DialogPosition.Right,
46
+ absolute: position === DialogPosition.Center,
47
+ })}
48
+ {...props}
49
+ >
50
+ <DialogClose className={cx('fixed right-3 top-3', { hidden: !showCloseIcon })}>
51
+ <Close />
52
+ </DialogClose>
53
+ </RadixDialog.Overlay>
54
+ ));
55
+ DialogOverlay.displayName = RadixDialog.Overlay.displayName;
56
+
57
+ const DialogContent = React.forwardRef<
58
+ React.ElementRef<typeof RadixDialog.Content>,
59
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Content> & {
60
+ containerId?: string;
61
+ showCloseOnOverlay?: boolean;
62
+ position?: DialogPosition;
63
+ customWidth?: string;
64
+ }
65
+ >(
66
+ (
67
+ {
68
+ className,
69
+ containerId,
70
+ showCloseOnOverlay,
71
+ children,
72
+ position = DialogPosition.Center,
73
+ customWidth = 'w-80 max-w-[85vw] md:w-96',
74
+ ...props
75
+ },
76
+ ref,
77
+ ) => {
78
+ const [containerElement, setContainerElement] = useState<HTMLElement | undefined>(
79
+ undefined,
80
+ );
81
+
82
+ useEffect(() => {
83
+ // This ensures document.getElementById is called in the client-side environment only.
84
+ // note. containerElement cant be null
85
+ const element = containerId ? document.getElementById(containerId) : undefined;
86
+ setContainerElement(element ?? undefined);
87
+ }, [containerId]);
88
+ const positionClass =
89
+ position === DialogPosition.Right
90
+ ? 'overflow-hidden right-0 h-screen top-0 w-full'
91
+ : 'overflow-y-auto overflow-x-hidden left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-xl';
92
+ const widthClass =
93
+ position === DialogPosition.Right ? 'md:w-96 max-w-[500px]' : customWidth;
94
+ const heightClass = position === DialogPosition.Right ? 'h-screen' : 'max-h-[80vh] h-full';
95
+ return (
96
+ <RadixDialog.Portal container={containerElement}>
97
+ <DialogOverlay showCloseIcon={showCloseOnOverlay} position={position} />
98
+ <RadixDialog.Content
99
+ ref={ref}
100
+ className={cx(
101
+ 'fixed z-[99999] flex flex-col justify-center bg-primary-100 dark:bg-neutral-6',
102
+ positionClass,
103
+ widthClass,
104
+ )}
105
+ {...props}
106
+ >
107
+ <VisuallyHidden.Root>
108
+ <RadixDialog.Title />
109
+ <RadixDialog.Description />
110
+ </VisuallyHidden.Root>
111
+ <div className={cx('flex flex-1 flex-col', heightClass)}>{children}</div>
112
+ </RadixDialog.Content>
113
+ </RadixDialog.Portal>
114
+ );
115
+ },
116
+ );
117
+ DialogContent.displayName = RadixDialog.Content.displayName;
118
+
119
+ const DialogTitle = React.forwardRef<
120
+ React.ElementRef<typeof RadixDialog.Title>,
121
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Title>
122
+ >((props, ref) => (
123
+ <RadixDialog.Title
124
+ ref={ref}
125
+ className="font-inter text-title-lg text-neutral-10 dark:text-neutral-92"
126
+ {...props}
127
+ />
128
+ ));
129
+ DialogTitle.displayName = RadixDialog.Title.displayName;
130
+
131
+ const DialogBody = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(
132
+ (props, ref) => (
133
+ <div
134
+ ref={ref}
135
+ className="flex-1 overflow-y-auto p-md--rs text-body-sm text-neutral-40 dark:text-neutral-60"
136
+ {...props}
137
+ />
138
+ ),
139
+ );
140
+ DialogBody.displayName = 'DialogBody';
141
+
142
+ export { Dialog, DialogClose, DialogTrigger, DialogContent, DialogTitle, DialogBody };
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum DialogPosition {
5
+ Center = 'center',
6
+ Right = 'right',
7
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Dialog';
5
+ export * from './dialog.enums';
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './dialog';
5
+ export * from './table';
6
+ export * from './navbar';
7
+ export * from './accordion';
@@ -0,0 +1,101 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import { IotaLogoMark, MenuIcon } from '@iota/apps-ui-icons';
6
+ import type { NavbarItemProps } from '@/components/molecules/navbar-item/NavbarItem';
7
+ import { NavbarItem } from '@/components/molecules/navbar-item/NavbarItem';
8
+
9
+ export type NavbarItemWithId = NavbarItemProps & { id: string };
10
+
11
+ export interface NavbarProps {
12
+ /**
13
+ * If this flag is true we need to leave only the icon and collapsible button
14
+ */
15
+ isCollapsible?: boolean;
16
+
17
+ /**
18
+ * List of elements to be displayed in the navbar.
19
+ */
20
+ items: NavbarItemWithId[];
21
+
22
+ /**
23
+ * The id of the active element.
24
+ */
25
+ activeId: string;
26
+
27
+ /**
28
+ * Callback when an element is clicked.
29
+ */
30
+ onClickItem: (id: string) => void;
31
+
32
+ /**
33
+ * If the navbar is collapsible, this flag indicates if it is open or not.
34
+ */
35
+ isOpen?: boolean;
36
+
37
+ /**
38
+ * Callback when the navbar is toggled.
39
+ */
40
+ onToggleNavbar?: () => void;
41
+ }
42
+
43
+ export function Navbar({
44
+ items,
45
+ activeId,
46
+ onClickItem,
47
+ isCollapsible = false,
48
+ onToggleNavbar,
49
+ }: NavbarProps) {
50
+ return (
51
+ <div
52
+ className={cx('flex h-fit w-full', {
53
+ 'flex-col px-md py-xs sm:h-full sm:w-auto sm:px-none sm:py-xl': isCollapsible,
54
+ })}
55
+ >
56
+ {isCollapsible && (
57
+ <div className="flex w-full items-center justify-between sm:mb-[48px] sm:flex-col">
58
+ <div className="flex justify-center [&_svg]:h-[38px] [&_svg]:w-[38px]">
59
+ <IotaLogoMark className="text-neutral-10 dark:text-neutral-92" />
60
+ </div>
61
+ <div
62
+ className="state-layer relative rounded-full p-xs hover:cursor-pointer dark:text-neutral-92 sm:hidden [&_svg]:h-6 [&_svg]:w-6"
63
+ onClick={onToggleNavbar}
64
+ >
65
+ <MenuIcon />
66
+ </div>
67
+ </div>
68
+ )}
69
+ <div
70
+ className={cx({
71
+ 'flex w-full justify-between px-sm py-xxs': !isCollapsible,
72
+ 'hidden sm:flex sm:flex-col sm:gap-2': isCollapsible,
73
+ })}
74
+ >
75
+ {items.map((item) => (
76
+ <div
77
+ key={item.id}
78
+ className={cx('flex items-center', {
79
+ 'px-xs py-xxs': !isCollapsible,
80
+ 'py-xxs pl-xs pr-sm': isCollapsible,
81
+ })}
82
+ data-testid={`nav-${item.id}`}
83
+ >
84
+ <NavbarItem
85
+ {...item}
86
+ isSelected={item.id === activeId}
87
+ onClick={(e) => {
88
+ if (item.onClick) {
89
+ item.onClick(e);
90
+ }
91
+ if (!item.isDisabled) {
92
+ onClickItem(item.id);
93
+ }
94
+ }}
95
+ />
96
+ </div>
97
+ ))}
98
+ </div>
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,59 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ArrowBack } from '@iota/apps-ui-icons';
5
+ import cx from 'classnames';
6
+ import { Button, ButtonType } from '@/components/atoms';
7
+ import { NavbarItem, NavbarItemType } from '@/components/molecules';
8
+ import type { NavbarProps } from './Navbar';
9
+
10
+ export function NavbarSlideout({
11
+ items,
12
+ activeId,
13
+ onClickItem,
14
+ isOpen,
15
+ onToggleNavbar,
16
+ }: NavbarProps) {
17
+ return (
18
+ <>
19
+ <div
20
+ onClick={onToggleNavbar}
21
+ className={cx('duration-800 transition-opacity ease-out', {
22
+ 'opacity-1 fixed left-0 top-0 h-full w-full bg-shader-neutral-light-72': isOpen,
23
+ '-translate-x-full opacity-0': !isOpen,
24
+ })}
25
+ />
26
+ <div
27
+ className={cx(
28
+ 'z-999 rounded-tb-3xl fixed left-0 top-0 h-full w-11/12 rounded-tr-3xl bg-white px-lg py-lg transition-transform duration-300 ease-out dark:bg-neutral-6',
29
+ {
30
+ 'translate-x-0': isOpen,
31
+ '-translate-x-full': !isOpen,
32
+ },
33
+ )}
34
+ >
35
+ <div className="flex flex-col gap-2">
36
+ <div className="[&_svg]:h-5 [&_svg]:w-5">
37
+ <Button
38
+ type={ButtonType.Ghost}
39
+ onClick={onToggleNavbar}
40
+ icon={<ArrowBack />}
41
+ />
42
+ </div>
43
+ {items.map((item) => (
44
+ <NavbarItem
45
+ key={item.id}
46
+ {...item}
47
+ type={NavbarItemType.Vertical}
48
+ isSelected={item.id === activeId}
49
+ onClick={() => {
50
+ onClickItem(item.id);
51
+ onToggleNavbar && onToggleNavbar();
52
+ }}
53
+ />
54
+ ))}
55
+ </div>
56
+ </div>
57
+ </>
58
+ );
59
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Navbar';
5
+ export * from './NavbarSlideout';
@@ -0,0 +1,234 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { PropsWithChildren, ReactNode } from 'react';
5
+ import cx from 'classnames';
6
+ import { TableProvider, useTableContext } from './TableContext';
7
+ import type { ButtonProps } from '@/components/atoms';
8
+ import { Button, ButtonSize, ButtonType, Checkbox } from '@/components/atoms';
9
+ import { TableCellBase, TableHeaderCell } from '@/components/molecules';
10
+ import { ArrowLeft, DoubleArrowLeft, ArrowRight, DoubleArrowRight } from '@iota/apps-ui-icons';
11
+
12
+ export interface TablePaginationOptions {
13
+ /**
14
+ * On Next page button click.
15
+ */
16
+ onNext?: () => void;
17
+ /**
18
+ * On Previous page button click.
19
+ */
20
+ onPrev?: () => void;
21
+ /**
22
+ * On First page button click.
23
+ */
24
+ onFirst?: () => void;
25
+ /**
26
+ * On Last page button click.
27
+ */
28
+ onLast?: () => void;
29
+ /**
30
+ * Has Next button.
31
+ */
32
+ hasNext?: boolean;
33
+ /**
34
+ * Has Previous button.
35
+ */
36
+ hasPrev?: boolean;
37
+ /**
38
+ * Has First button.
39
+ */
40
+ hasFirst?: boolean;
41
+ /**
42
+ * Has Last button.
43
+ */
44
+ hasLast?: boolean;
45
+ }
46
+
47
+ export type TableProps = {
48
+ /**
49
+ * Options for the table pagination.
50
+ */
51
+ paginationOptions?: TablePaginationOptions;
52
+ /**
53
+ * The action component.
54
+ */
55
+ action?: ReactNode;
56
+ /**
57
+ * The supporting label of the table.
58
+ */
59
+ supportingLabel?: string;
60
+ /**
61
+ * Numeric indexes of the selected rows.
62
+ */
63
+ selectedRowIndexes?: Set<number>;
64
+ /**
65
+ * Numeric indexes of all the rows.
66
+ */
67
+ rowIndexes: number[];
68
+ /**
69
+ * The page size selector component.
70
+ */
71
+ pageSizeSelector?: ReactNode;
72
+
73
+ /**
74
+ * If the table should take the full height of the parent.
75
+ */
76
+ heightFull?: boolean;
77
+ };
78
+
79
+ export function Table({
80
+ paginationOptions,
81
+ action,
82
+ supportingLabel,
83
+ selectedRowIndexes = new Set(),
84
+ rowIndexes,
85
+ children,
86
+ pageSizeSelector,
87
+ heightFull = false,
88
+ }: PropsWithChildren<TableProps>): JSX.Element {
89
+ return (
90
+ <TableProvider selectedRowIndexes={selectedRowIndexes} rowIndexes={rowIndexes}>
91
+ <div className={cx('w-full', { 'h-full': heightFull })}>
92
+ <div
93
+ className={cx('overflow-auto', {
94
+ 'h-full': heightFull,
95
+ })}
96
+ >
97
+ <table
98
+ className={cx('w-full table-auto', {
99
+ 'h-full': heightFull,
100
+ })}
101
+ >
102
+ {children}
103
+ </table>
104
+ </div>
105
+ <div
106
+ className={cx('flex w-full items-center gap-sm pt-md', {
107
+ hidden: !supportingLabel && !paginationOptions && !action,
108
+ 'flex-col justify-between sm:flex-row': paginationOptions,
109
+ 'justify-end': !paginationOptions && action,
110
+ })}
111
+ >
112
+ {(paginationOptions || action) && (
113
+ <div className="flex gap-2">
114
+ {paginationOptions && (
115
+ <>
116
+ <Button
117
+ type={ButtonType.Secondary}
118
+ size={ButtonSize.Small}
119
+ icon={<DoubleArrowLeft />}
120
+ disabled={!paginationOptions.hasFirst}
121
+ onClick={paginationOptions.onFirst}
122
+ />
123
+ <Button
124
+ type={ButtonType.Secondary}
125
+ size={ButtonSize.Small}
126
+ icon={<ArrowLeft />}
127
+ disabled={!paginationOptions.hasPrev}
128
+ onClick={paginationOptions.onPrev}
129
+ />
130
+ <Button
131
+ type={ButtonType.Secondary}
132
+ size={ButtonSize.Small}
133
+ icon={<ArrowRight />}
134
+ disabled={!paginationOptions.hasNext}
135
+ onClick={paginationOptions.onNext}
136
+ />
137
+ <Button
138
+ type={ButtonType.Secondary}
139
+ size={ButtonSize.Small}
140
+ icon={<DoubleArrowRight />}
141
+ disabled={!paginationOptions.hasLast}
142
+ onClick={paginationOptions.onLast}
143
+ />
144
+ </>
145
+ )}
146
+ {action && action}
147
+ </div>
148
+ )}
149
+ {supportingLabel || pageSizeSelector ? (
150
+ <div className="flex flex-row items-center gap-x-sm">
151
+ {supportingLabel && (
152
+ <span className=" text-label-md text-neutral-40 dark:text-neutral-60">
153
+ {supportingLabel}
154
+ </span>
155
+ )}
156
+ {pageSizeSelector && <div className="ml-2">{pageSizeSelector}</div>}
157
+ </div>
158
+ ) : null}
159
+ </div>
160
+ </div>
161
+ </TableProvider>
162
+ );
163
+ }
164
+
165
+ export function TableActionButton(props: PropsWithChildren<ButtonProps>) {
166
+ return <Button type={ButtonType.Secondary} size={ButtonSize.Small} {...props} />;
167
+ }
168
+
169
+ export function TableHeader({ children }: PropsWithChildren): JSX.Element {
170
+ return <thead>{children}</thead>;
171
+ }
172
+
173
+ export function TableRow({
174
+ children,
175
+ leading,
176
+ }: PropsWithChildren<{ leading?: React.ReactNode }>): JSX.Element {
177
+ return (
178
+ <tr>
179
+ {leading}
180
+ {children}
181
+ </tr>
182
+ );
183
+ }
184
+
185
+ const TEXT_COLOR_CLASS = 'text-neutral-40 dark:text-neutral-60';
186
+ const TEXT_SIZE_CLASS = 'text-body-md';
187
+
188
+ export function TableBody({ children }: PropsWithChildren): JSX.Element {
189
+ return <tbody className={cx(TEXT_COLOR_CLASS, TEXT_SIZE_CLASS)}>{children}</tbody>;
190
+ }
191
+
192
+ export interface TableRowCheckboxProps {
193
+ rowIndex: number;
194
+ onCheckboxChange: (checked: boolean) => void;
195
+ }
196
+
197
+ export function TableRowCheckbox({
198
+ rowIndex,
199
+ onCheckboxChange,
200
+ }: TableRowCheckboxProps): React.JSX.Element {
201
+ const { selectedRowIndexes } = useTableContext();
202
+
203
+ return (
204
+ <TableCellBase isContentCentered>
205
+ <Checkbox
206
+ onCheckedChange={(event) => {
207
+ onCheckboxChange(event.target.checked);
208
+ }}
209
+ isChecked={selectedRowIndexes.has(rowIndex)}
210
+ />
211
+ </TableCellBase>
212
+ );
213
+ }
214
+
215
+ export interface TableHeaderCheckboxProps {
216
+ onCheckboxChange: (checked: boolean) => void;
217
+ }
218
+
219
+ export function TableHeaderCheckbox({ onCheckboxChange }: TableHeaderCheckboxProps): JSX.Element {
220
+ const { isHeaderChecked, isHeaderIndeterminate } = useTableContext();
221
+
222
+ return (
223
+ <TableHeaderCell
224
+ isContentCentered
225
+ hasCheckbox
226
+ onCheckboxChange={(event) => {
227
+ onCheckboxChange(event.target.checked);
228
+ }}
229
+ isChecked={isHeaderChecked}
230
+ columnKey={1}
231
+ isIndeterminate={isHeaderIndeterminate}
232
+ />
233
+ );
234
+ }