@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,97 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import { SecondaryText } from '../../atoms/secondary-text';
6
+ import { LABEL_CLASSES } from './input.classes';
7
+ import { createElement } from 'react';
8
+
9
+ export enum LabelHtmlTag {
10
+ Label = 'label',
11
+ Div = 'div',
12
+ }
13
+
14
+ export interface InputWrapperProps {
15
+ /**
16
+ * Shows a label with the text above the input.
17
+ */
18
+ label?: string;
19
+ /**
20
+ * Shows a caption with the text below the input.
21
+ */
22
+ caption?: string;
23
+ /**
24
+ * Error Message. Overrides the caption.
25
+ */
26
+ errorMessage?: string;
27
+ /**
28
+ * Amount counter that is shown at the side of the caption text.
29
+ */
30
+ amountCounter?: string | number;
31
+ /**
32
+ * Is the input required
33
+ */
34
+ required?: boolean;
35
+ /**
36
+ * Is the input disabled
37
+ */
38
+ disabled?: boolean;
39
+ /**
40
+ * Use a div as a label instead of a label element
41
+ */
42
+ labelHtmlTag?: LabelHtmlTag;
43
+ }
44
+
45
+ export function InputWrapper({
46
+ label,
47
+ caption,
48
+ disabled,
49
+ errorMessage,
50
+ amountCounter,
51
+ required,
52
+ labelHtmlTag = LabelHtmlTag.Label,
53
+ children,
54
+ }: React.PropsWithChildren<InputWrapperProps>) {
55
+ return (
56
+ <div
57
+ className={cx('group flex w-full flex-col gap-y-2', {
58
+ 'cursor-not-allowed opacity-40': disabled,
59
+ errored: errorMessage,
60
+ enabled: !disabled,
61
+ required: required,
62
+ })}
63
+ >
64
+ {label ? (
65
+ <LabelWrapper labelHtmlTag={labelHtmlTag}>
66
+ {label}
67
+ {children}
68
+ </LabelWrapper>
69
+ ) : (
70
+ children
71
+ )}
72
+
73
+ {(errorMessage || caption || amountCounter) && (
74
+ <div
75
+ className={cx(
76
+ 'flex flex-row items-center',
77
+ caption || errorMessage ? 'justify-between' : 'justify-end',
78
+ )}
79
+ >
80
+ {(errorMessage || caption) && (
81
+ <SecondaryText hasErrorStyles>{errorMessage || caption}</SecondaryText>
82
+ )}
83
+ {amountCounter && <SecondaryText>{amountCounter}</SecondaryText>}
84
+ </div>
85
+ )}
86
+ </div>
87
+ );
88
+ }
89
+
90
+ function LabelWrapper({
91
+ labelHtmlTag,
92
+ children,
93
+ }: Required<Pick<InputWrapperProps, 'labelHtmlTag'>> & {
94
+ children: React.ReactNode;
95
+ }) {
96
+ return createElement(labelHtmlTag, { className: LABEL_CLASSES }, children);
97
+ }
@@ -0,0 +1,149 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { forwardRef, useEffect, useState } from 'react';
5
+ import { InputWrapper, InputWrapperProps } from './InputWrapper';
6
+ import {
7
+ BORDER_CLASSES,
8
+ INPUT_CLASSES,
9
+ INPUT_TEXT_CLASSES,
10
+ INPUT_PLACEHOLDER_CLASSES,
11
+ } from './input.classes';
12
+ import cx from 'classnames';
13
+ import { ButtonUnstyled } from '../../atoms/button';
14
+ import { VisibilityOff, VisibilityOn } from '@iota/apps-ui-icons';
15
+
16
+ type TextAreaProps = Omit<
17
+ React.TextareaHTMLAttributes<HTMLTextAreaElement>,
18
+ 'cols' | 'resize' | 'className'
19
+ >;
20
+
21
+ interface TextFieldBaseProps extends TextAreaProps, InputWrapperProps {
22
+ /**
23
+ * Shows a label with the text above the input field.
24
+ */
25
+ label?: string;
26
+ /**
27
+ * Shows a caption with the text below the input field.
28
+ */
29
+ caption?: string;
30
+ /**
31
+ * Error Message. Overrides the caption.
32
+ */
33
+ errorMessage?: string;
34
+ /**
35
+ * Amount counter that is shown at the side of the caption text.
36
+ */
37
+ amountCounter?: string | number;
38
+ /**
39
+ * Shows toggle button to show/hide the content of the input field
40
+ */
41
+ isVisibilityToggleEnabled?: boolean;
42
+ /**
43
+ * Is the content of the input visible
44
+ */
45
+ isContentVisible?: boolean;
46
+ /**
47
+ * If true the textarea is resizable vertically
48
+ */
49
+ isResizeEnabled?: boolean;
50
+ }
51
+
52
+ export const TextArea = forwardRef<HTMLTextAreaElement, TextFieldBaseProps>(function TextArea(
53
+ {
54
+ label,
55
+ caption,
56
+ disabled,
57
+ errorMessage,
58
+ value,
59
+ amountCounter,
60
+ isVisibilityToggleEnabled,
61
+ isResizeEnabled,
62
+ required,
63
+ isContentVisible,
64
+ ...textareaProps
65
+ },
66
+ ref,
67
+ ) {
68
+ const [isInputContentVisible, setIsInputContentVisible] = useState<boolean>(
69
+ isContentVisible ?? true,
70
+ );
71
+
72
+ useEffect(() => {
73
+ setIsInputContentVisible(isContentVisible ?? true);
74
+ }, [isContentVisible]);
75
+
76
+ function onToggleButtonClick() {
77
+ setIsInputContentVisible((prev) => !prev);
78
+ }
79
+
80
+ return (
81
+ <InputWrapper
82
+ label={label}
83
+ caption={caption}
84
+ disabled={disabled || !isInputContentVisible}
85
+ errorMessage={errorMessage}
86
+ amountCounter={amountCounter}
87
+ required={required}
88
+ >
89
+ <div className="relative">
90
+ <textarea
91
+ disabled={disabled || !isInputContentVisible}
92
+ required={required}
93
+ ref={ref}
94
+ className={cx(
95
+ 'peer block min-h-[50px]',
96
+ BORDER_CLASSES,
97
+ INPUT_CLASSES,
98
+ INPUT_TEXT_CLASSES,
99
+ INPUT_PLACEHOLDER_CLASSES,
100
+ isInputContentVisible && isResizeEnabled ? 'resize-y' : 'resize-none',
101
+ !isInputContentVisible &&
102
+ 'not-visible select-none text-transparent dark:text-transparent',
103
+ )}
104
+ value={isInputContentVisible ? value : ''}
105
+ {...textareaProps}
106
+ />
107
+ {!isInputContentVisible && (
108
+ <div className="absolute left-0 top-0 flex h-full w-full flex-col items-stretch gap-y-2 px-md py-sm peer-[.not-visible]:select-none">
109
+ <VisibilityOffBar rows={3} halfWidthRow={3} />
110
+ </div>
111
+ )}
112
+
113
+ {isVisibilityToggleEnabled && (
114
+ <span className="absolute bottom-4 right-4 flex">
115
+ <ButtonUnstyled
116
+ onClick={onToggleButtonClick}
117
+ className="text-neutral-10 dark:text-neutral-92 [&_svg]:h-5 [&_svg]:w-5"
118
+ tabIndex={-1}
119
+ >
120
+ {isInputContentVisible ? <VisibilityOn /> : <VisibilityOff />}
121
+ </ButtonUnstyled>
122
+ </span>
123
+ )}
124
+ </div>
125
+ </InputWrapper>
126
+ );
127
+ });
128
+
129
+ interface VisibilityOffBarProps {
130
+ rows: number;
131
+ halfWidthRow?: number;
132
+ }
133
+
134
+ function VisibilityOffBar({ rows, halfWidthRow }: VisibilityOffBarProps) {
135
+ return (
136
+ <>
137
+ {Array.from({ length: rows }).map((_, index) => {
138
+ const isHalfWidth = halfWidthRow === index + 1;
139
+ const width = isHalfWidth ? 'w-1/2' : 'w-full';
140
+ return (
141
+ <div
142
+ key={index}
143
+ className={`h-2.5 rounded bg-neutral-92/60 dark:bg-neutral-10/60 ${width}`}
144
+ />
145
+ );
146
+ })}
147
+ </>
148
+ );
149
+ }
@@ -0,0 +1,8 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './Input';
5
+ export * from './TextArea';
6
+
7
+ export * from './input.types';
8
+ export * from './input.enums';
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export const INPUT_CLASSES =
5
+ 'w-full bg-transparent text-body-lg caret-primary-30 dark:caret-primary-80 focus:outline-none focus-visible:outline-none disabled:cursor-not-allowed';
6
+ export const INPUT_TEXT_CLASSES = 'text-neutral-10 dark:text-neutral-92';
7
+ export const INPUT_PLACEHOLDER_CLASSES =
8
+ 'enabled:placeholder:text-neutral-40/40 dark:placeholder:text-neutral-60/40 enabled:dark:placeholder:text-neutral-60/40';
9
+ export const BORDER_CLASSES =
10
+ 'px-md py-sm rounded-lg border border-neutral-80 group-[.enabled]:cursor-text group-[.errored]:border-error-30 hover:group-[.enabled]:border-neutral-50 dark:border-neutral-20 dark:hover:border-neutral-60 dark:group-[.errored]:border-error-80 [&:has(input:focus)]:!border-primary-30 [&:has(input:focus)]:dark:!border-primary-80';
11
+ export const INPUT_NUMBER_CLASSES =
12
+ '[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none disabled:cursor-not-allowed';
13
+ export const LABEL_CLASSES =
14
+ 'flex flex-col gap-y-2 text-label-lg text-neutral-40 dark:text-neutral-60';
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum InputType {
5
+ Text = 'text',
6
+ Password = 'password',
7
+ Number = 'number',
8
+ NumericFormat = 'numericFormat',
9
+ }
10
+
11
+ export enum Resize {
12
+ None = 'none',
13
+ Vertical = 'vertical',
14
+ }
@@ -0,0 +1,29 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { ComponentProps } from 'react';
5
+ import { InputType } from '.';
6
+ import { NumericFormat } from 'react-number-format';
7
+
8
+ type InputElementProps = Omit<
9
+ React.ComponentProps<'input'>,
10
+ 'type' | 'className' | 'ref' | 'value' | 'defaultValue'
11
+ >;
12
+
13
+ type GenericInputProps = {
14
+ type: InputType.Text | InputType.Password | InputType.Number;
15
+ };
16
+
17
+ type NumericFormatProps = ComponentProps<typeof NumericFormat>;
18
+
19
+ export type NumericFormatInputProps = {
20
+ type: InputType.NumericFormat;
21
+ suffix?: NumericFormatProps['suffix'];
22
+ prefix?: NumericFormatProps['prefix'];
23
+ decimalScale?: NumericFormatProps['decimalScale'];
24
+ allowNegative?: NumericFormatProps['allowNegative'];
25
+ thousandSeparator?: NumericFormatProps['thousandSeparator'];
26
+ onValueChange?: NumericFormatProps['onValueChange'];
27
+ };
28
+
29
+ export type InputPropsByType = InputElementProps & (NumericFormatInputProps | GenericInputProps);
@@ -0,0 +1,48 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { NavbarItemHorizontal } from './NavbarItemHorizontal';
5
+ import { NavbarItemVertical } from './NavbarItemVertical';
6
+ import { NavbarItemType } from './navbarItem.enums';
7
+
8
+ export interface NavbarItemProps {
9
+ /**
10
+ * The type of the navbar item.
11
+ */
12
+ type?: NavbarItemType;
13
+
14
+ /**
15
+ * The icon of the navbar item.
16
+ */
17
+ icon: React.ReactNode;
18
+ /**
19
+ * The text of the navbar item.
20
+ */
21
+ text?: string;
22
+ /**
23
+ * Indicates if the navbar item is selected.
24
+ */
25
+ isSelected?: boolean;
26
+ /**
27
+ * Indicates if the navbar item has a badge.
28
+ */
29
+ hasBadge?: boolean;
30
+ /**
31
+ * The onClick event of the navbar item.
32
+ */
33
+ onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
34
+ /**
35
+ * Indicates if the navbar item is disabled.
36
+ */
37
+ isDisabled?: boolean;
38
+ }
39
+
40
+ export function NavbarItem(props: NavbarItemProps): React.JSX.Element {
41
+ const { type, text } = props;
42
+
43
+ if (type === NavbarItemType.Vertical && !!text) {
44
+ return <NavbarItemVertical {...props} />;
45
+ }
46
+
47
+ return <NavbarItemHorizontal {...props} />;
48
+ }
@@ -0,0 +1,65 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import {
6
+ BADGE_WITH_TEXT,
7
+ BADGE_WITHOUT_TEXT,
8
+ PADDING_WITH_TEXT,
9
+ PADDING_WITHOUT_TEXT,
10
+ SELECTED_BACKGROUND,
11
+ SELECTED_ICON,
12
+ SELECTED_TEXT,
13
+ UNSELECTED_ICON,
14
+ UNSELECTED_TEXT,
15
+ } from './navbarItem.classes';
16
+ import { Badge, BadgeType } from '../../atoms';
17
+ import { NavbarItemProps } from './NavbarItem';
18
+
19
+ export function NavbarItemHorizontal({
20
+ icon,
21
+ text,
22
+ isSelected,
23
+ hasBadge,
24
+ onClick,
25
+ isDisabled = false,
26
+ }: Omit<NavbarItemProps, 'type'>): React.JSX.Element {
27
+ const fillClasses = isSelected ? SELECTED_ICON : UNSELECTED_ICON;
28
+ const paddingClasses = text ? PADDING_WITH_TEXT : PADDING_WITHOUT_TEXT;
29
+ const backgroundColors = isSelected && SELECTED_BACKGROUND;
30
+ const badgePositionClasses = text ? BADGE_WITH_TEXT : BADGE_WITHOUT_TEXT;
31
+ const textClasses = isSelected ? SELECTED_TEXT : UNSELECTED_TEXT;
32
+ const disabledClasses = isDisabled ? 'cursor-not-allowed opacity-60' : 'state-layer';
33
+ const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
34
+ if (isDisabled) {
35
+ e.preventDefault();
36
+ return;
37
+ }
38
+ onClick?.(e);
39
+ };
40
+ return (
41
+ <div
42
+ onClick={handleClick}
43
+ className={cx(
44
+ 'inline-flex cursor-pointer flex-col items-center justify-center space-y-1',
45
+ )}
46
+ >
47
+ <div
48
+ className={cx(
49
+ 'relative inline-flex rounded-full',
50
+ paddingClasses,
51
+ backgroundColors,
52
+ disabledClasses,
53
+ )}
54
+ >
55
+ <div className={cx('inline-flex [&_svg]:h-6 [&_svg]:w-6', fillClasses)}>{icon}</div>
56
+ {hasBadge && (
57
+ <div className={cx('absolute', badgePositionClasses)}>
58
+ <Badge type={BadgeType.PrimarySolid} />
59
+ </div>
60
+ )}
61
+ </div>
62
+ {text && <span className={cx('text-center text-label-md', textClasses)}>{text}</span>}
63
+ </div>
64
+ );
65
+ }
@@ -0,0 +1,54 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import cx from 'classnames';
5
+ import {
6
+ SELECTED_BACKGROUND,
7
+ SELECTED_ICON,
8
+ SELECTED_TEXT,
9
+ UNSELECTED_ICON,
10
+ UNSELECTED_TEXT,
11
+ } from './navbarItem.classes';
12
+ import { Badge, BadgeType } from '../../atoms';
13
+ import { NavbarItemProps } from './NavbarItem';
14
+
15
+ export function NavbarItemVertical({
16
+ icon,
17
+ text,
18
+ isSelected,
19
+ hasBadge,
20
+ onClick,
21
+ isDisabled = false,
22
+ }: Omit<NavbarItemProps, 'type'>): React.JSX.Element {
23
+ const fillClasses = isSelected ? SELECTED_ICON : UNSELECTED_ICON;
24
+ const backgroundColors = isSelected && SELECTED_BACKGROUND;
25
+ const textClasses = isSelected ? SELECTED_TEXT : UNSELECTED_TEXT;
26
+ const disabledClasses = isDisabled
27
+ ? 'cursor-not-allowed opacity-60'
28
+ : 'state-layer cursor-pointer ';
29
+ const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
30
+ if (isDisabled) {
31
+ e.preventDefault();
32
+ return;
33
+ }
34
+ onClick?.(e);
35
+ };
36
+ return (
37
+ <div
38
+ onClick={handleClick}
39
+ className={cx(
40
+ 'relative inline-flex w-full flex-row items-center justify-between rounded-full p-sm',
41
+ backgroundColors,
42
+ disabledClasses,
43
+ )}
44
+ >
45
+ <div className="flex items-center gap-3">
46
+ <div className={cx('inline-flex [&_svg]:h-6 [&_svg]:w-6', fillClasses)}>{icon}</div>
47
+ {text && (
48
+ <span className={cx('text-center text-label-lg', textClasses)}>{text}</span>
49
+ )}
50
+ </div>
51
+ {hasBadge && <Badge type={BadgeType.PrimarySolid} />}
52
+ </div>
53
+ );
54
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './navbarItem.enums';
5
+ export * from './NavbarItem';
@@ -0,0 +1,16 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export const SELECTED_ICON = 'text-neutral-10 dark:text-neutral-92';
5
+ export const UNSELECTED_ICON = 'text-neutral-40 dark:text-neutral-60';
6
+
7
+ export const PADDING_WITH_TEXT = 'py-xxs px-sm';
8
+ export const PADDING_WITHOUT_TEXT = 'p-sm';
9
+
10
+ export const SELECTED_BACKGROUND = 'bg-shader-primary-light-12 dark:bg-shader-primary-dark-12';
11
+
12
+ export const BADGE_WITH_TEXT = '-top-3 right-3';
13
+ export const BADGE_WITHOUT_TEXT = '-top-1 right-3';
14
+
15
+ export const SELECTED_TEXT = 'text-neutral-10 dark:text-neutral-92';
16
+ export const UNSELECTED_TEXT = 'text-neutral-60 dark:text-neutral-40';
@@ -0,0 +1,7 @@
1
+ // Copyright (c) 2024 IOTA Stiftung
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export enum NavbarItemType {
5
+ Horizontal = 'horizontal',
6
+ Vertical = 'vertical',
7
+ }