@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,140 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { SortByDown, SortByUp } from '@iota/apps-ui-icons';
5
+ import cx from 'classnames';
6
+ import { Checkbox } from '@/lib';
7
+ import { TableHeaderCellSortOrder } from './tableHeaderCell.enums';
8
+
9
+ export interface TableHeaderCellProps {
10
+ /**
11
+ * The column key.
12
+ */
13
+ columnKey: string | number;
14
+ /**
15
+ * The label of the Header cell.
16
+ */
17
+ label?: string;
18
+ /**
19
+ * Action component to be rendered on the left side.
20
+ */
21
+ actionLeft?: React.ReactNode;
22
+ /**
23
+ * Action component to be rendered on the right side.
24
+ */
25
+ actionRight?: React.ReactNode;
26
+ /**
27
+ * Has Sort icon.
28
+ */
29
+ hasSort?: boolean;
30
+ /**
31
+ * On Sort icon click.
32
+ */
33
+ onSortClick?: (columnKey: string | number, sortOrder: TableHeaderCellSortOrder) => void;
34
+ /**
35
+ * Has Checkbox.
36
+ */
37
+ hasCheckbox?: boolean;
38
+ /**
39
+ * Is Checkbox checked.
40
+ */
41
+ isChecked?: boolean;
42
+ /**
43
+ * Is Checkbox indeterminate.
44
+ */
45
+ isIndeterminate?: boolean;
46
+ /**
47
+ * On Checkbox change.
48
+ */
49
+ onCheckboxChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
50
+ /**
51
+ * Whether the cell content should be centered.
52
+ */
53
+ isContentCentered?: boolean;
54
+ /**
55
+ * Sort order when cell is initialized
56
+ */
57
+ sortOrder?: TableHeaderCellSortOrder;
58
+ }
59
+
60
+ export function TableHeaderCell({
61
+ label,
62
+ columnKey,
63
+ hasSort,
64
+ hasCheckbox,
65
+ isChecked,
66
+ isIndeterminate,
67
+ isContentCentered,
68
+ onSortClick,
69
+ onCheckboxChange,
70
+ sortOrder,
71
+ }: TableHeaderCellProps): JSX.Element {
72
+ const handleSort = () => {
73
+ const newSortOrder =
74
+ sortOrder === TableHeaderCellSortOrder.Asc
75
+ ? TableHeaderCellSortOrder.Desc
76
+ : TableHeaderCellSortOrder.Asc;
77
+ if (onSortClick) {
78
+ onSortClick(columnKey, newSortOrder);
79
+ }
80
+ };
81
+
82
+ const textColorClass = 'text-neutral-10 dark:text-neutral-92';
83
+ const textSizeClass = 'text-label-lg';
84
+
85
+ const sortElement = (() => {
86
+ if (!hasSort) {
87
+ return null;
88
+ }
89
+
90
+ if (sortOrder === TableHeaderCellSortOrder.Asc) {
91
+ return <SortByUp className="shrink-0" />;
92
+ }
93
+
94
+ if (sortOrder === TableHeaderCellSortOrder.Desc) {
95
+ return <SortByDown className="shrink-0" />;
96
+ }
97
+
98
+ return <SortByUp className="invisible shrink-0 group-hover:visible" />;
99
+ })();
100
+
101
+ return (
102
+ <th
103
+ onClick={hasSort ? handleSort : undefined}
104
+ className={cx(
105
+ 'state-layer group relative h-14 border-b border-shader-neutral-light-8 px-md after:pointer-events-none dark:border-shader-neutral-dark-8',
106
+ {
107
+ 'cursor-pointer': hasSort,
108
+ },
109
+ )}
110
+ >
111
+ <div
112
+ className={cx(
113
+ 'flex flex-row items-center gap-1 [&_svg]:h-4 [&_svg]:w-4',
114
+ textColorClass,
115
+ textSizeClass,
116
+ {
117
+ 'justify-center': isContentCentered,
118
+ },
119
+ )}
120
+ >
121
+ {hasCheckbox ? (
122
+ <Checkbox
123
+ isChecked={isChecked}
124
+ isIndeterminate={isIndeterminate}
125
+ onCheckedChange={onCheckboxChange}
126
+ />
127
+ ) : (
128
+ <span
129
+ className={cx({
130
+ 'text-left': !isContentCentered,
131
+ })}
132
+ >
133
+ {label}
134
+ </span>
135
+ )}
136
+ {sortElement}
137
+ </div>
138
+ </th>
139
+ );
140
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './TableHeaderCell';
5
+ export * from './tableHeaderCell.enums';
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum TableHeaderCellSortOrder {
5
+ Asc = 'asc',
6
+ Desc = 'desc',
7
+ }
@@ -0,0 +1,69 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Tooltip, TooltipPosition } from '../../atoms';
5
+ import { Info } from '@iota/apps-ui-icons';
6
+ import { TitleSize } from './titleSize.enums';
7
+ import cx from 'classnames';
8
+ import { TITLE_PADDINGS, TITLE_SIZE } from './titleClasses.constants';
9
+
10
+ interface TitleProps {
11
+ /**
12
+ * The title of the component.
13
+ */
14
+ title: string;
15
+ /**
16
+ * The subtitle of the component.
17
+ */
18
+ subtitle?: string;
19
+ /**
20
+ * The trailing element.
21
+ */
22
+ trailingElement?: React.ReactNode;
23
+ /**
24
+ * The tooltip position.
25
+ */
26
+ tooltipPosition?: TooltipPosition;
27
+ /**
28
+ * The tooltip text.
29
+ */
30
+ tooltipText?: string;
31
+ /**
32
+ * Supporting Element
33
+ */
34
+ supportingElement?: React.ReactNode;
35
+ /**
36
+ * The size of the component
37
+ */
38
+ size?: TitleSize;
39
+ }
40
+
41
+ export function Title({
42
+ title,
43
+ subtitle,
44
+ trailingElement,
45
+ tooltipText,
46
+ supportingElement,
47
+ tooltipPosition,
48
+ size = TitleSize.Medium,
49
+ }: TitleProps) {
50
+ return (
51
+ <div className={cx('flex flex-row items-center justify-between', TITLE_PADDINGS[size])}>
52
+ <div className="flex flex-row items-center gap-x-xxxs">
53
+ <div className="flex flex-col justify-start">
54
+ <div className="flex flex-row items-center gap-x-0.5 text-neutral-10 dark:text-neutral-92">
55
+ <h4 className={cx(TITLE_SIZE[size])}>{title}</h4>
56
+ {tooltipText && (
57
+ <Tooltip text={tooltipText} position={tooltipPosition}>
58
+ <Info />
59
+ </Tooltip>
60
+ )}
61
+ </div>
62
+ <p className="text-label-md text-neutral-60 dark:text-neutral-40">{subtitle}</p>
63
+ </div>
64
+ {supportingElement}
65
+ </div>
66
+ {trailingElement}
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 './Title';
5
+ export { TitleSize } from './titleSize.enums';
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { TitleSize } from './titleSize.enums';
5
+
6
+ export const TITLE_PADDINGS: Record<TitleSize, string> = {
7
+ [TitleSize.Small]: 'px-md py-sm--rs',
8
+ [TitleSize.Medium]: 'px-md--rs py-sm--rs',
9
+ };
10
+
11
+ export const TITLE_SIZE: Record<TitleSize, string> = {
12
+ [TitleSize.Small]: 'text-title-md',
13
+ [TitleSize.Medium]: 'text-title-lg',
14
+ };
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum TitleSize {
5
+ Small = 'small',
6
+ Medium = 'medium',
7
+ }
@@ -0,0 +1,109 @@
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 { ArrowDown } from '@iota/apps-ui-icons';
7
+ import { Button, ButtonType } from '@/lib';
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,123 @@
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 = RadixDialog.Root;
13
+ const DialogTrigger = RadixDialog.Trigger;
14
+ const DialogClose = RadixDialog.Close;
15
+
16
+ const DialogOverlay = React.forwardRef<
17
+ React.ElementRef<typeof RadixDialog.Overlay>,
18
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Overlay> & {
19
+ showCloseIcon?: boolean;
20
+ position?: DialogPosition;
21
+ }
22
+ >(({ showCloseIcon, position, ...props }, ref) => (
23
+ <RadixDialog.Overlay
24
+ ref={ref}
25
+ className={cx('inset-0 z-[99998] bg-shader-neutral-light-48 backdrop-blur-md', {
26
+ fixed: position === DialogPosition.Right,
27
+ absolute: position === DialogPosition.Center,
28
+ })}
29
+ {...props}
30
+ >
31
+ <DialogClose className={cx('fixed right-3 top-3', { hidden: !showCloseIcon })}>
32
+ <Close />
33
+ </DialogClose>
34
+ </RadixDialog.Overlay>
35
+ ));
36
+ DialogOverlay.displayName = RadixDialog.Overlay.displayName;
37
+
38
+ const DialogContent = React.forwardRef<
39
+ React.ElementRef<typeof RadixDialog.Content>,
40
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Content> & {
41
+ containerId?: string;
42
+ showCloseOnOverlay?: boolean;
43
+ position?: DialogPosition;
44
+ customWidth?: string;
45
+ }
46
+ >(
47
+ (
48
+ {
49
+ className,
50
+ containerId,
51
+ showCloseOnOverlay,
52
+ children,
53
+ position = DialogPosition.Center,
54
+ customWidth = 'w-80 max-w-[85vw] md:w-96',
55
+ ...props
56
+ },
57
+ ref,
58
+ ) => {
59
+ const [containerElement, setContainerElement] = useState<HTMLElement | undefined>(
60
+ undefined,
61
+ );
62
+
63
+ useEffect(() => {
64
+ // This ensures document.getElementById is called in the client-side environment only.
65
+ // note. containerElement cant be null
66
+ const element = containerId ? document.getElementById(containerId) : undefined;
67
+ setContainerElement(element ?? undefined);
68
+ }, [containerId]);
69
+ const positionClass =
70
+ position === DialogPosition.Right
71
+ ? 'overflow-hidden right-0 h-screen top-0 w-full'
72
+ : 'overflow-y-auto overflow-x-hidden left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-xl';
73
+ const widthClass =
74
+ position === DialogPosition.Right ? 'md:w-96 max-w-[500px]' : customWidth;
75
+ const heightClass = position === DialogPosition.Right ? 'h-screen' : 'max-h-[80vh] h-full';
76
+ return (
77
+ <RadixDialog.Portal container={containerElement}>
78
+ <DialogOverlay showCloseIcon={showCloseOnOverlay} position={position} />
79
+ <RadixDialog.Content
80
+ ref={ref}
81
+ className={cx(
82
+ 'fixed z-[99999] flex flex-col justify-center bg-primary-100 dark:bg-neutral-6',
83
+ positionClass,
84
+ widthClass,
85
+ )}
86
+ {...props}
87
+ >
88
+ <VisuallyHidden.Root>
89
+ <RadixDialog.Title />
90
+ <RadixDialog.Description />
91
+ </VisuallyHidden.Root>
92
+ <div className={cx('flex flex-1 flex-col', heightClass)}>{children}</div>
93
+ </RadixDialog.Content>
94
+ </RadixDialog.Portal>
95
+ );
96
+ },
97
+ );
98
+ DialogContent.displayName = RadixDialog.Content.displayName;
99
+
100
+ const DialogTitle = React.forwardRef<
101
+ React.ElementRef<typeof RadixDialog.Title>,
102
+ React.ComponentPropsWithoutRef<typeof RadixDialog.Title>
103
+ >((props, ref) => (
104
+ <RadixDialog.Title
105
+ ref={ref}
106
+ className="font-inter text-title-lg text-neutral-10 dark:text-neutral-92"
107
+ {...props}
108
+ />
109
+ ));
110
+ DialogTitle.displayName = RadixDialog.Title.displayName;
111
+
112
+ const DialogBody = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(
113
+ (props, ref) => (
114
+ <div
115
+ ref={ref}
116
+ className="flex-1 overflow-y-auto p-md--rs text-body-sm text-neutral-40 dark:text-neutral-60"
117
+ {...props}
118
+ />
119
+ ),
120
+ );
121
+ DialogBody.displayName = 'DialogBody';
122
+
123
+ 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,100 @@
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 { NavbarItem, NavbarItemProps } from '@/components/molecules/navbar-item/NavbarItem';
7
+
8
+ export type NavbarItemWithId = NavbarItemProps & { id: string };
9
+
10
+ export interface NavbarProps {
11
+ /**
12
+ * If this flag is true we need to leave only the icon and collapsible button
13
+ */
14
+ isCollapsible?: boolean;
15
+
16
+ /**
17
+ * List of elements to be displayed in the navbar.
18
+ */
19
+ items: NavbarItemWithId[];
20
+
21
+ /**
22
+ * The id of the active element.
23
+ */
24
+ activeId: string;
25
+
26
+ /**
27
+ * Callback when an element is clicked.
28
+ */
29
+ onClickItem: (id: string) => void;
30
+
31
+ /**
32
+ * If the navbar is collapsible, this flag indicates if it is open or not.
33
+ */
34
+ isOpen?: boolean;
35
+
36
+ /**
37
+ * Callback when the navbar is toggled.
38
+ */
39
+ onToggleNavbar?: () => void;
40
+ }
41
+
42
+ export function Navbar({
43
+ items,
44
+ activeId,
45
+ onClickItem,
46
+ isCollapsible = false,
47
+ onToggleNavbar,
48
+ }: NavbarProps) {
49
+ return (
50
+ <div
51
+ className={cx('flex h-fit w-full', {
52
+ 'flex-col px-md py-xs sm:h-full sm:w-auto sm:px-none sm:py-xl': isCollapsible,
53
+ })}
54
+ >
55
+ {isCollapsible && (
56
+ <div className="flex w-full items-center justify-between sm:mb-[48px] sm:flex-col">
57
+ <div className="flex justify-center [&_svg]:h-[38px] [&_svg]:w-[38px]">
58
+ <IotaLogoMark className="text-neutral-10 dark:text-neutral-92" />
59
+ </div>
60
+ <div
61
+ className="state-layer relative rounded-full p-xs hover:cursor-pointer dark:text-neutral-92 sm:hidden [&_svg]:h-6 [&_svg]:w-6"
62
+ onClick={onToggleNavbar}
63
+ >
64
+ <MenuIcon />
65
+ </div>
66
+ </div>
67
+ )}
68
+ <div
69
+ className={cx({
70
+ 'flex w-full justify-between px-sm py-xxs': !isCollapsible,
71
+ 'hidden sm:flex sm:flex-col sm:gap-2': isCollapsible,
72
+ })}
73
+ >
74
+ {items.map((item) => (
75
+ <div
76
+ key={item.id}
77
+ className={cx('flex items-center', {
78
+ 'px-xs py-xxs': !isCollapsible,
79
+ 'py-xxs pl-xs pr-sm': isCollapsible,
80
+ })}
81
+ data-testid={`nav-${item.id}`}
82
+ >
83
+ <NavbarItem
84
+ {...item}
85
+ isSelected={item.id === activeId}
86
+ onClick={(e) => {
87
+ if (item.onClick) {
88
+ item.onClick(e);
89
+ }
90
+ if (!item.isDisabled) {
91
+ onClickItem(item.id);
92
+ }
93
+ }}
94
+ />
95
+ </div>
96
+ ))}
97
+ </div>
98
+ </div>
99
+ );
100
+ }
@@ -0,0 +1,58 @@
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, NavbarItem, NavbarItemType } from '@/components';
7
+ import { NavbarProps } from './Navbar';
8
+
9
+ export function NavbarSlideout({
10
+ items,
11
+ activeId,
12
+ onClickItem,
13
+ isOpen,
14
+ onToggleNavbar,
15
+ }: NavbarProps) {
16
+ return (
17
+ <>
18
+ <div
19
+ onClick={onToggleNavbar}
20
+ className={cx('duration-800 transition-opacity ease-out', {
21
+ 'opacity-1 fixed left-0 top-0 h-full w-full bg-shader-neutral-light-72': isOpen,
22
+ '-translate-x-full opacity-0': !isOpen,
23
+ })}
24
+ />
25
+ <div
26
+ className={cx(
27
+ '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',
28
+ {
29
+ 'translate-x-0': isOpen,
30
+ '-translate-x-full': !isOpen,
31
+ },
32
+ )}
33
+ >
34
+ <div className="flex flex-col gap-2">
35
+ <div className="[&_svg]:h-5 [&_svg]:w-5">
36
+ <Button
37
+ type={ButtonType.Ghost}
38
+ onClick={onToggleNavbar}
39
+ icon={<ArrowBack />}
40
+ />
41
+ </div>
42
+ {items.map((item) => (
43
+ <NavbarItem
44
+ key={item.id}
45
+ {...item}
46
+ type={NavbarItemType.Vertical}
47
+ isSelected={item.id === activeId}
48
+ onClick={() => {
49
+ onClickItem(item.id);
50
+ onToggleNavbar && onToggleNavbar();
51
+ }}
52
+ />
53
+ ))}
54
+ </div>
55
+ </div>
56
+ </>
57
+ );
58
+ }
@@ -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';