@iota/apps-ui-kit 0.7.2 → 0.8.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.
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "@iota/apps-ui-kit",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "sideEffects": false,
5
- "repository": {
6
- "type": "git",
7
- "url": "github.com:iotaledger/iota.git"
8
- },
5
+ "repository": "https://github.com/iotaledger/iota",
9
6
  "license": "Apache-2.0",
10
7
  "files": [
11
8
  "CHANGELOG.md",
@@ -30,7 +27,7 @@
30
27
  "classnames": "^2.5.1",
31
28
  "lodash.merge": "^4.6.2",
32
29
  "react-number-format": "^5.2.2",
33
- "@iota/apps-ui-icons": "0.4.1"
30
+ "@iota/apps-ui-icons": "0.6.0"
34
31
  },
35
32
  "peerDependencies": {
36
33
  "react": "^18 || ^19",
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { ButtonHtmlType, ButtonSize, ButtonType } from './button.enums';
5
+ import { forwardRef } from 'react';
5
6
  import {
6
7
  PADDINGS,
7
8
  PADDINGS_ONLY_ICON,
@@ -60,41 +61,50 @@ export interface ButtonProps {
60
61
  testId?: string;
61
62
  }
62
63
 
63
- export function Button({
64
- icon,
65
- text,
66
- disabled,
67
- onClick,
68
- fullWidth,
69
- htmlType = ButtonHtmlType.Button,
70
- size = ButtonSize.Medium,
71
- type = ButtonType.Primary,
72
- iconAfterText = false,
73
- tabIndex = 0,
74
- testId,
75
- }: ButtonProps): React.JSX.Element {
76
- const paddingClasses = icon && !text ? PADDINGS_ONLY_ICON[size] : PADDINGS[size];
77
- const textSizes = TEXT_CLASSES[size];
78
- const backgroundColors = disabled ? DISABLED_BACKGROUND_COLORS[type] : BACKGROUND_COLORS[type];
79
- const textColors = disabled ? TEXT_COLOR_DISABLED[type] : TEXT_COLORS[type];
80
- return (
81
- <button
82
- onClick={onClick}
83
- type={htmlType}
84
- className={cx(
85
- 'state-layer relative flex items-center justify-center gap-2 rounded-full transition-all duration-150 ease-in disabled:cursor-not-allowed disabled:opacity-40',
86
- paddingClasses,
87
- backgroundColors,
88
- fullWidth && 'w-full',
89
- !iconAfterText ? 'flex-row' : 'flex-row-reverse',
90
- `btn btn-${type}`,
91
- )}
92
- disabled={disabled}
93
- tabIndex={tabIndex}
94
- data-testid={testId}
95
- >
96
- {icon && <span className={cx(textColors)}>{icon}</span>}
97
- {text && <span className={cx('font-inter', textColors, textSizes)}>{text}</span>}
98
- </button>
99
- );
100
- }
64
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
65
+ (
66
+ {
67
+ icon,
68
+ text,
69
+ disabled,
70
+ onClick,
71
+ fullWidth,
72
+ htmlType = ButtonHtmlType.Button,
73
+ size = ButtonSize.Medium,
74
+ type = ButtonType.Primary,
75
+ iconAfterText = false,
76
+ tabIndex = 0,
77
+ testId,
78
+ },
79
+ ref,
80
+ ): React.JSX.Element => {
81
+ const paddingClasses = icon && !text ? PADDINGS_ONLY_ICON[size] : PADDINGS[size];
82
+ const textSizes = TEXT_CLASSES[size];
83
+ const backgroundColors = disabled
84
+ ? DISABLED_BACKGROUND_COLORS[type]
85
+ : BACKGROUND_COLORS[type];
86
+ const textColors = disabled ? TEXT_COLOR_DISABLED[type] : TEXT_COLORS[type];
87
+
88
+ return (
89
+ <button
90
+ ref={ref}
91
+ onClick={onClick}
92
+ type={htmlType}
93
+ className={cx(
94
+ 'state-layer relative flex items-center justify-center gap-2 rounded-full transition-all duration-150 ease-in disabled:cursor-not-allowed disabled:opacity-40',
95
+ paddingClasses,
96
+ backgroundColors,
97
+ fullWidth && 'w-full',
98
+ !iconAfterText ? 'flex-row' : 'flex-row-reverse',
99
+ `btn btn-${type}`,
100
+ )}
101
+ disabled={disabled}
102
+ tabIndex={tabIndex}
103
+ data-testid={testId}
104
+ >
105
+ {icon && <span className={cx(textColors)}>{icon}</span>}
106
+ {text && <span className={cx('font-inter', textColors, textSizes)}>{text}</span>}
107
+ </button>
108
+ );
109
+ },
110
+ );
@@ -5,10 +5,26 @@ import cx from 'classnames';
5
5
  import { RadioOn, RadioOff } from '@iota/apps-ui-icons';
6
6
 
7
7
  interface RadioButtonProps {
8
+ /**
9
+ * The id of the radio button.
10
+ */
11
+ id?: string;
12
+ /**
13
+ * The name of the radio button.
14
+ */
15
+ name?: string;
8
16
  /**
9
17
  * The label of the radio button.
10
18
  */
11
19
  label: string;
20
+ /**
21
+ * Supporting text for the label.
22
+ */
23
+ supportingLabel?: string;
24
+ /**
25
+ * The body text of the radio button.
26
+ */
27
+ body?: string;
12
28
  /**
13
29
  * The state of the radio button.
14
30
  */
@@ -24,7 +40,11 @@ interface RadioButtonProps {
24
40
  }
25
41
 
26
42
  function RadioButton({
43
+ id,
44
+ name,
27
45
  label,
46
+ supportingLabel,
47
+ body,
28
48
  isChecked,
29
49
  isDisabled,
30
50
  onChange,
@@ -33,30 +53,50 @@ function RadioButton({
33
53
 
34
54
  return (
35
55
  <label
36
- className={cx('flex flex-row gap-x-1 text-center has-[:disabled]:opacity-40', {
37
- disabled: isDisabled,
38
- 'cursor-pointer': !isDisabled,
39
- })}
56
+ className={cx(
57
+ 'flex flex-row items-center gap-x-1 text-center has-[:disabled]:opacity-40',
58
+ {
59
+ disabled: isDisabled,
60
+ 'cursor-pointer': !isDisabled,
61
+ },
62
+ )}
40
63
  >
41
64
  <div
42
- className={cx('relative flex h-10 w-10 items-center justify-center rounded-full', {
43
- 'state-layer-secondary': !isDisabled,
44
- })}
65
+ className={cx(
66
+ 'relative flex h-10 w-10 shrink-0 items-center justify-center rounded-full',
67
+ {
68
+ 'state-layer-secondary': !isDisabled,
69
+ },
70
+ )}
45
71
  >
46
72
  <input
73
+ id={id}
74
+ name={name}
47
75
  type="radio"
48
76
  checked={isChecked}
49
77
  onChange={onChange}
50
78
  disabled={isDisabled}
51
79
  className={cx('peer appearance-none')}
52
80
  />
53
- <span className="radio-icon-color peer-checked:radio-icon-checked-color peer-checked:peer-disabled:radio-icon-checked-disabled-color absolute [&_svg]:h-6 [&_svg]:w-6">
54
- <RadioIcon />
81
+ <span className="radio-icon-color peer-checked:radio-icon-checked-color peer-checked:peer-disabled:radio-icon-checked-disabled-color absolute size-6">
82
+ <RadioIcon className="size-full" />
83
+ </span>
84
+ </div>
85
+ <div className="flex flex-col items-start gap-xxs text-start">
86
+ <span className="radio-label-color inline-flex items-center justify-center gap-1 text-label-lg">
87
+ {label}
88
+ {supportingLabel && (
89
+ <span className="text-iota-neutral-60 dark:text-iota-neutral-40">
90
+ {supportingLabel}
91
+ </span>
92
+ )}
55
93
  </span>
94
+ {body && (
95
+ <p className="text-body-sm text-iota-neutral-40 dark:text-iota-neutral-60">
96
+ {body}
97
+ </p>
98
+ )}
56
99
  </div>
57
- <span className="radio-label-color inline-flex items-center justify-center text-label-lg ">
58
- {label}
59
- </span>
60
100
  </label>
61
101
  );
62
102
  }
@@ -125,13 +125,15 @@ export function Account({
125
125
  },
126
126
  )}
127
127
  >
128
- <div className="flex items-center space-x-3">
129
- <Avatar isLocked={isLocked} />
130
- <div className="flex flex-col items-start py-xs">
131
- <div className="flex items-center space-x-2">
132
- <span className="account-title-color font-inter text-title-md">
128
+ <div className="flex w-full items-center gap-x-3">
129
+ <div>
130
+ <Avatar isLocked={isLocked} />
131
+ </div>
132
+ <div className="flex w-full min-w-0 flex-col items-start py-xs">
133
+ <div className="flex w-full min-w-0 items-center space-x-2">
134
+ <p className="account-title-color min-w-0 max-w-full truncate font-inter text-title-md">
133
135
  {title}
134
- </span>
136
+ </p>
135
137
  {badgeText && badgeType ? (
136
138
  badgeTooltipText ? (
137
139
  <Tooltip text={badgeTooltipText} position={badgeTooltipPosition}>
@@ -151,41 +153,42 @@ export function Account({
151
153
  isExternal={isExternal}
152
154
  />
153
155
  </div>
154
- </div>
155
- <div className="z-10 ml-auto flex items-center space-x-2 [&_button]:h-5 [&_button]:w-5 [&_svg]:h-5 [&_svg]:w-5">
156
- <div className="account-icon-color flex items-center space-x-2 [&_button:not(.locked)]:hidden group-hover:[&_button:not(.locked)]:flex">
157
- {onOptionsClick && (
158
- <ButtonUnstyled onClick={onOptionsClick}>
159
- <MoreHoriz />
156
+
157
+ <div className="ml-auto flex items-center space-x-2 [&_button]:h-5 [&_button]:w-5 [&_svg]:h-5 [&_svg]:w-5">
158
+ <div className="account-icon-color flex items-center space-x-2 [&_button:not(.locked)]:invisible group-hover:[&_button:not(.locked)]:visible">
159
+ {onOptionsClick && (
160
+ <ButtonUnstyled onClick={onOptionsClick}>
161
+ <MoreHoriz />
162
+ </ButtonUnstyled>
163
+ )}
164
+ {onLockAccountClick &&
165
+ onUnlockAccountClick &&
166
+ (isLocked ? (
167
+ <div className="flex items-center">
168
+ <ButtonUnstyled
169
+ onClick={onUnlockAccountClick}
170
+ testId="account-unlock"
171
+ className="locked"
172
+ >
173
+ <LockLocked />
174
+ </ButtonUnstyled>
175
+ </div>
176
+ ) : (
177
+ <ButtonUnstyled onClick={onLockAccountClick} testId="account-lock">
178
+ <LockUnlocked />
179
+ </ButtonUnstyled>
180
+ ))}
181
+ </div>
182
+ {showSelected && (
183
+ <ButtonUnstyled>
184
+ {isSelected ? (
185
+ <CheckmarkFilled className="account-check-active-color h-5 w-5" />
186
+ ) : (
187
+ <RadioOff className="account-check-inactive-color h-5 w-5" />
188
+ )}
160
189
  </ButtonUnstyled>
161
190
  )}
162
- {onLockAccountClick &&
163
- onUnlockAccountClick &&
164
- (isLocked ? (
165
- <div className="flex items-center">
166
- <ButtonUnstyled
167
- onClick={onUnlockAccountClick}
168
- testId="account-unlock"
169
- className="locked"
170
- >
171
- <LockLocked />
172
- </ButtonUnstyled>
173
- </div>
174
- ) : (
175
- <ButtonUnstyled onClick={onLockAccountClick} testId="account-lock">
176
- <LockUnlocked />
177
- </ButtonUnstyled>
178
- ))}
179
191
  </div>
180
- {showSelected && (
181
- <ButtonUnstyled>
182
- {isSelected ? (
183
- <CheckmarkFilled className="account-check-active-color h-5 w-5" />
184
- ) : (
185
- <RadioOff className="account-check-inactive-color h-5 w-5" />
186
- )}
187
- </ButtonUnstyled>
188
- )}
189
192
  </div>
190
193
  </div>
191
194
  );
@@ -71,15 +71,17 @@ export function VisualAssetCard({
71
71
  )}
72
72
  {isHoverable && onIconClick && (
73
73
  <ButtonUnstyled
74
- className="visual-asset-icon-color absolute right-2 top-2 h-9 w-9 cursor-pointer rounded-full p-xs opacity-0 transition-opacity duration-300 group-hover:bg-shader-neutral-light-72 group-hover:opacity-100 [&_svg]:h-5 [&_svg]:w-5"
74
+ className="visual-asset-icon-color absolute right-2 top-2 z-10 h-9 w-9 cursor-pointer rounded-full p-xs opacity-0 transition-opacity duration-300 group-hover:bg-shader-neutral-light-72 group-hover:opacity-100 [&_svg]:h-5 [&_svg]:w-5"
75
75
  onClick={handleIconClick}
76
76
  >
77
77
  {icon}
78
78
  </ButtonUnstyled>
79
79
  )}
80
80
  {isHoverable && assetTitle && (
81
- <div className="absolute bottom-0 flex items-center justify-center p-xs opacity-0 transition-opacity duration-300 group-hover:opacity-100">
82
- <span className="visual-asset-title-color text-title-md">{assetTitle}</span>
81
+ <div className="absolute bottom-0 w-full p-xs opacity-0 transition-opacity duration-300 group-hover:opacity-100">
82
+ <span className="visual-asset-title-color break-words text-title-md">
83
+ {assetTitle}
84
+ </span>
83
85
  </div>
84
86
  )}
85
87
  </div>
package/src/lib/index.ts CHANGED
@@ -7,4 +7,3 @@ export * from './tailwind';
7
7
  export * from './components';
8
8
  export * from './constants';
9
9
  export * from './enums';
10
- export * from './utils';
@@ -114,6 +114,7 @@
114
114
  @supports selector(::-webkit-scrollbar) {
115
115
  *::-webkit-scrollbar {
116
116
  width: 0.875rem;
117
+ height: 0.875rem;
117
118
  }
118
119
 
119
120
  *::-webkit-scrollbar-track {
@@ -134,4 +135,10 @@
134
135
  .names *::-webkit-scrollbar-thumb {
135
136
  box-shadow: inset 0 0 10px 10px #3c4656;
136
137
  }
138
+
139
+ *::-webkit-scrollbar-corner,
140
+ .dark *::-webkit-scrollbar-corner,
141
+ .names *::-webkit-scrollbar-corner {
142
+ background: transparent;
143
+ }
137
144
  }
@@ -49,3 +49,22 @@ export const Default: Story = {
49
49
  },
50
50
  },
51
51
  };
52
+
53
+ export const ExtendedRadioButton: Story = {
54
+ args: {
55
+ label: 'Label',
56
+ supportingLabel: '(Supporting label)',
57
+ body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
58
+ },
59
+ argTypes: {
60
+ label: {
61
+ control: 'text',
62
+ },
63
+ isChecked: {
64
+ control: 'boolean',
65
+ },
66
+ isDisabled: {
67
+ control: 'boolean',
68
+ },
69
+ },
70
+ };
@@ -1,8 +0,0 @@
1
- // Copyright (c) 2024 IOTA Stiftung
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- export function truncate(value: string, startLength: number = 6, endLength: number = 6): string {
5
- return value.length > startLength + endLength
6
- ? `${value.slice(0, startLength)}...${value.slice(-endLength)}`
7
- : value;
8
- }
@@ -1,4 +0,0 @@
1
- // Copyright (c) 2024 IOTA Stiftung
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- export * from './format';