@iota/apps-ui-kit 0.7.0 → 0.7.2
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/CHANGELOG.md +21 -0
- package/dist/index.d.ts +51 -25
- package/dist/index.es.js +2213 -2151
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +10 -10
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -2
- package/src/lib/components/atoms/button/Button.tsx +1 -0
- package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +1 -1
- package/src/lib/components/atoms/checkbox/Checkbox.tsx +0 -1
- package/src/lib/components/atoms/index.ts +1 -0
- package/src/lib/components/atoms/list-item/ListItem.tsx +1 -1
- package/src/lib/components/atoms/radio-button/RadioButton.tsx +1 -1
- package/src/lib/components/atoms/skeleton/Skeleton.tsx +5 -20
- package/src/lib/components/index.ts +0 -2
- package/src/lib/components/molecules/chip/Chip.tsx +51 -17
- package/src/lib/components/molecules/chip/chip.classes.ts +36 -14
- package/src/lib/components/molecules/chip/chip.enums.ts +6 -3
- package/src/lib/components/molecules/input/Input.tsx +34 -17
- package/src/lib/components/molecules/input/TextArea.tsx +5 -4
- package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +0 -1
- package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +1 -1
- package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +1 -1
- package/src/lib/components/molecules/select/Select.tsx +24 -4
- package/src/lib/components/organisms/dialog/Dialog.tsx +37 -22
- package/src/lib/constants/colors.constants.ts +12 -5
- package/src/lib/enums/index.ts +1 -0
- package/src/lib/enums/theme.enums.ts +8 -0
- package/src/lib/index.ts +2 -0
- package/src/lib/styles/base.css +40 -0
- package/src/lib/styles/components.css +52 -4
- package/src/lib/styles/index.css +4 -753
- package/src/lib/styles/utilities.css +11 -3
- package/src/lib/styles/variables/dark-variables.css +262 -0
- package/src/lib/styles/variables/general-variables.css +9 -0
- package/src/lib/styles/variables/light-variables.css +276 -0
- package/src/lib/styles/variables/names-variables.css +270 -0
- package/src/lib/tailwind/base.presets.ts +4 -0
- package/src/lib/tailwind/constants/gradients.constants.ts +6 -0
- package/src/storybook/blocks/TypeSet.tsx +3 -3
- package/src/storybook/constants/gradients.constants.ts +8 -0
- package/src/storybook/helpers/formatGradientNames.ts +15 -0
- package/src/storybook/stories/atoms/Skeleton.stories.tsx +5 -5
- package/src/storybook/stories/components/DocsSyncTheme.tsx +20 -0
- package/src/storybook/stories/components/index.ts +1 -0
- package/src/storybook/stories/design-tokens/colors.stories.mdx +12 -0
- package/src/storybook/stories/design-tokens/icons.stories.mdx +2 -0
- package/src/storybook/stories/design-tokens/typeset.stories.mdx +2 -0
- package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +2 -1
- package/src/storybook/stories/molecules/Chip.stories.tsx +5 -0
- package/src/storybook/stories/molecules/Input.stories.tsx +79 -2
- package/src/storybook/stories/organisms/Dialog.stories.tsx +54 -28
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iota/apps-ui-kit",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
|
+
"sideEffects": false,
|
|
4
5
|
"repository": {
|
|
5
6
|
"type": "git",
|
|
6
7
|
"url": "github.com:iotaledger/iota.git"
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"classnames": "^2.5.1",
|
|
30
31
|
"lodash.merge": "^4.6.2",
|
|
31
32
|
"react-number-format": "^5.2.2",
|
|
32
|
-
"@iota/apps-ui-icons": "0.4.
|
|
33
|
+
"@iota/apps-ui-icons": "0.4.1"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
36
|
"react": "^18 || ^19",
|
|
@@ -77,7 +77,7 @@ export function ButtonSegment({
|
|
|
77
77
|
<ButtonUnstyled
|
|
78
78
|
onClick={onClick}
|
|
79
79
|
className={cx(
|
|
80
|
-
'enabled:state-layer relative flex items-center disabled:opacity-40',
|
|
80
|
+
'enabled:state-layer-secondary relative flex items-center disabled:opacity-40',
|
|
81
81
|
backgroundColors,
|
|
82
82
|
textColors,
|
|
83
83
|
padding,
|
|
@@ -101,7 +101,6 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
101
101
|
'peer-[&:is(:checked,:indeterminate)]:checkbox-border-checked',
|
|
102
102
|
'peer-[&:is(:checked,:indeterminate)]:checkbox-bg-checked',
|
|
103
103
|
'peer-[&:is(:checked,:indeterminate)]:checkbox-text-checked',
|
|
104
|
-
'peer-disabled:peer-[&:is(:checked,:indeterminate)]:[&_svg]:hidden',
|
|
105
104
|
'peer-disabled:peer-[&:not(:checked,:indeterminate)]:checkbox-border-color-disabled',
|
|
106
105
|
'peer-disabled:peer-[&:is(:checked,:indeterminate)]:checkbox-border-color-disabled-checked',
|
|
107
106
|
'peer-disabled:peer-[&:is(:checked,:indeterminate)]:checkbox-bg-color-disabled-checked',
|
|
@@ -2,41 +2,26 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
|
+
import React from 'react';
|
|
5
6
|
|
|
6
|
-
interface SkeletonLoaderProps {
|
|
7
|
-
/**
|
|
8
|
-
* Width class for the skeleton div.
|
|
9
|
-
*/
|
|
10
|
-
widthClass?: string;
|
|
11
|
-
/**
|
|
12
|
-
* Height class for the skeleton div.
|
|
13
|
-
*/
|
|
14
|
-
heightClass?: string;
|
|
7
|
+
interface SkeletonLoaderProps extends Pick<React.HTMLAttributes<HTMLDivElement>, 'className'> {
|
|
15
8
|
/**
|
|
16
9
|
* If true, the skeleton will use darker neutral colors.
|
|
17
10
|
*/
|
|
18
11
|
hasSecondaryColors?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Whether the class `rounded-full` should be applied. Defaults to true.
|
|
21
|
-
*/
|
|
22
|
-
isRounded?: boolean;
|
|
23
12
|
}
|
|
24
13
|
|
|
25
14
|
export function Skeleton({
|
|
26
15
|
children,
|
|
27
|
-
|
|
28
|
-
heightClass = 'h-3',
|
|
16
|
+
className,
|
|
29
17
|
hasSecondaryColors,
|
|
30
|
-
isRounded = true,
|
|
31
18
|
}: React.PropsWithChildren<SkeletonLoaderProps>): React.JSX.Element {
|
|
32
19
|
return (
|
|
33
20
|
<div
|
|
34
21
|
className={cx(
|
|
35
|
-
'animate-pulse rounded-full',
|
|
36
|
-
widthClass,
|
|
37
|
-
heightClass,
|
|
38
|
-
isRounded && 'rounded-full',
|
|
22
|
+
'h-3 w-full animate-pulse rounded-full',
|
|
39
23
|
hasSecondaryColors ? 'skeleton-secondary-bg' : 'skeleton-bg',
|
|
24
|
+
className,
|
|
40
25
|
)}
|
|
41
26
|
>
|
|
42
27
|
{children}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { ButtonUnstyled } from '@/components/atoms/button';
|
|
5
|
+
import { Close } from '@iota/apps-ui-icons';
|
|
4
6
|
import cx from 'classnames';
|
|
5
|
-
import { ChipSize, ChipState } from './chip.enums';
|
|
6
7
|
import {
|
|
7
|
-
BORDER_CLASSES,
|
|
8
8
|
BACKGROUND_CLASSES,
|
|
9
|
+
BG_SELECTED_OUTLINE,
|
|
10
|
+
BG_SELECTED_OVERLAY,
|
|
11
|
+
BORDER_CLASSES,
|
|
12
|
+
CLOSE_ICON_INTERACTIVE,
|
|
13
|
+
FOCUS_CLASSES,
|
|
9
14
|
ROUNDED_CLASS,
|
|
10
15
|
STATE_LAYER_CLASSES,
|
|
11
16
|
TEXT_COLOR,
|
|
12
|
-
|
|
17
|
+
TEXT_COLOR_SELECTED_OUTLINE,
|
|
13
18
|
} from './chip.classes';
|
|
14
|
-
import {
|
|
15
|
-
import { Close } from '@iota/apps-ui-icons';
|
|
19
|
+
import { ChipSize, ChipType } from './chip.enums';
|
|
16
20
|
|
|
17
21
|
interface ChipProps {
|
|
18
22
|
/**
|
|
@@ -51,6 +55,10 @@ interface ChipProps {
|
|
|
51
55
|
* The button is disabled or not.
|
|
52
56
|
*/
|
|
53
57
|
disabled?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The type of the Chip
|
|
60
|
+
*/
|
|
61
|
+
type?: ChipType;
|
|
54
62
|
/**
|
|
55
63
|
* The size of the chip.
|
|
56
64
|
*/
|
|
@@ -59,8 +67,9 @@ interface ChipProps {
|
|
|
59
67
|
|
|
60
68
|
export function Chip({
|
|
61
69
|
label,
|
|
62
|
-
|
|
70
|
+
type = ChipType.Outline,
|
|
63
71
|
selected,
|
|
72
|
+
showClose,
|
|
64
73
|
onClose,
|
|
65
74
|
onClick,
|
|
66
75
|
avatar,
|
|
@@ -69,16 +78,30 @@ export function Chip({
|
|
|
69
78
|
disabled,
|
|
70
79
|
size = ChipSize.Default,
|
|
71
80
|
}: ChipProps) {
|
|
72
|
-
const
|
|
81
|
+
const isOutlineSelected = type === ChipType.Outline && selected;
|
|
82
|
+
const outlineStyle = selected
|
|
83
|
+
? type === ChipType.Outline
|
|
84
|
+
? 'outline-transparent names:outline-names-neutral-20'
|
|
85
|
+
: 'chip-outline-color'
|
|
86
|
+
: 'outline-transparent';
|
|
87
|
+
|
|
88
|
+
const focusOutlineStyle = cx(
|
|
89
|
+
'group-focus:chip-outline-color-active',
|
|
90
|
+
type === ChipType.Outline && 'names:group-focus:outline-transparent',
|
|
91
|
+
);
|
|
92
|
+
const selectedOverlayBg =
|
|
93
|
+
selected && !disabled && type !== ChipType.Outline ? BG_SELECTED_OVERLAY : '';
|
|
94
|
+
|
|
73
95
|
return (
|
|
74
96
|
<ButtonUnstyled
|
|
75
97
|
onClick={onClick}
|
|
76
98
|
className={cx(
|
|
77
|
-
'border
|
|
99
|
+
'group border disabled:opacity-40',
|
|
78
100
|
ROUNDED_CLASS,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
101
|
+
isOutlineSelected
|
|
102
|
+
? BG_SELECTED_OUTLINE[ChipType.Outline]
|
|
103
|
+
: BACKGROUND_CLASSES[type],
|
|
104
|
+
selected ? 'border-transparent' : BORDER_CLASSES[type],
|
|
82
105
|
)}
|
|
83
106
|
disabled={disabled}
|
|
84
107
|
>
|
|
@@ -87,10 +110,16 @@ export function Chip({
|
|
|
87
110
|
'flex h-full w-full flex-row items-center gap-x-2',
|
|
88
111
|
avatar ? 'py-xxs' : 'py-[6px]',
|
|
89
112
|
avatar ? 'pl-xxs' : leadingElement ? 'pl-xs' : 'pl-sm',
|
|
113
|
+
showClose ? 'pr-xs' : 'pr-sm',
|
|
90
114
|
ROUNDED_CLASS,
|
|
115
|
+
isOutlineSelected
|
|
116
|
+
? TEXT_COLOR_SELECTED_OUTLINE[ChipType.Outline]
|
|
117
|
+
: TEXT_COLOR[type],
|
|
118
|
+
outlineStyle,
|
|
119
|
+
!disabled && focusOutlineStyle,
|
|
91
120
|
!disabled && STATE_LAYER_CLASSES,
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
FOCUS_CLASSES,
|
|
122
|
+
selectedOverlayBg,
|
|
94
123
|
)}
|
|
95
124
|
>
|
|
96
125
|
{avatar ?? leadingElement}
|
|
@@ -99,12 +128,17 @@ export function Chip({
|
|
|
99
128
|
</span>
|
|
100
129
|
{trailingElement}
|
|
101
130
|
{showClose && (
|
|
102
|
-
<
|
|
131
|
+
<div
|
|
103
132
|
onClick={onClose}
|
|
104
|
-
className=
|
|
133
|
+
className={cx(disabled ? 'cursor-default' : 'cursor-pointer')}
|
|
105
134
|
>
|
|
106
|
-
<Close
|
|
107
|
-
|
|
135
|
+
<Close
|
|
136
|
+
className={cx(
|
|
137
|
+
'h-4 w-4 transition-opacity duration-150',
|
|
138
|
+
disabled ? '' : selected ? 'opacity-100' : CLOSE_ICON_INTERACTIVE,
|
|
139
|
+
)}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
108
142
|
)}
|
|
109
143
|
</span>
|
|
110
144
|
</ButtonUnstyled>
|
|
@@ -1,32 +1,54 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ChipType } from './chip.enums';
|
|
5
5
|
|
|
6
6
|
export const ROUNDED_CLASS = 'rounded-full';
|
|
7
7
|
|
|
8
|
-
export const BACKGROUND_CLASSES: Record<
|
|
9
|
-
[
|
|
10
|
-
[
|
|
8
|
+
export const BACKGROUND_CLASSES: Record<ChipType, string> = {
|
|
9
|
+
[ChipType.Outline]: 'bg-transparent',
|
|
10
|
+
[ChipType.Elevated]: 'chip-bg-elevated',
|
|
11
|
+
[ChipType.Success]: 'bg-success-surface',
|
|
12
|
+
[ChipType.Brand]: 'chip-bg-brand',
|
|
13
|
+
[ChipType.Error]: 'bg-error-surface',
|
|
11
14
|
};
|
|
12
15
|
|
|
13
|
-
const STATE_LAYER_OUTLINE =
|
|
14
|
-
'outline outline-1
|
|
16
|
+
export const STATE_LAYER_OUTLINE =
|
|
17
|
+
'outline outline-1 hover:chip-outline-color-hover active:chip-outline-color-active';
|
|
15
18
|
|
|
16
|
-
const STATE_LAYER_BG_CLASSES =
|
|
17
|
-
'hover:bg-
|
|
19
|
+
export const STATE_LAYER_BG_CLASSES =
|
|
20
|
+
'hover:chip-bg-color-hover active:chip-bg-color-active group-focus:chip-bg-color-focus';
|
|
18
21
|
|
|
19
22
|
export const STATE_LAYER_CLASSES = `${STATE_LAYER_OUTLINE} ${STATE_LAYER_BG_CLASSES}`;
|
|
20
23
|
|
|
21
|
-
export const
|
|
22
|
-
[
|
|
23
|
-
[ChipState.Selected]: 'border-transparent',
|
|
24
|
+
export const BG_SELECTED_OUTLINE: Partial<Record<ChipType, string>> = {
|
|
25
|
+
[ChipType.Outline]: 'chip-bg-selected-outline',
|
|
24
26
|
};
|
|
25
27
|
|
|
26
|
-
export const
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
export const BG_SELECTED_OVERLAY = 'chip-bg-selected-overlay';
|
|
29
|
+
|
|
30
|
+
export const TEXT_COLOR_SELECTED_OUTLINE: Partial<Record<ChipType, string>> = {
|
|
31
|
+
[ChipType.Outline]: 'chip-text-secondary',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const BORDER_CLASSES: Record<ChipType, string> = {
|
|
35
|
+
[ChipType.Outline]: 'chip-border-default',
|
|
36
|
+
[ChipType.Elevated]: 'border-transparent',
|
|
37
|
+
[ChipType.Success]: 'border-success-surface',
|
|
38
|
+
[ChipType.Brand]: 'chip-border-color-brand',
|
|
39
|
+
[ChipType.Error]: 'border-error-surface',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const TEXT_COLOR: Record<ChipType, string> = {
|
|
43
|
+
[ChipType.Outline]: 'chip-text-default',
|
|
44
|
+
[ChipType.Elevated]: 'chip-text-secondary',
|
|
45
|
+
[ChipType.Success]: 'chip-text-secondary',
|
|
46
|
+
[ChipType.Brand]: 'chip-text-brand',
|
|
47
|
+
[ChipType.Error]: 'chip-text-secondary',
|
|
29
48
|
};
|
|
30
49
|
|
|
31
50
|
export const FOCUS_CLASSES =
|
|
32
51
|
'focus-visible:shadow-[0_0_0_2px] focus-visible:chip-focus-ring focus-visible:outline-none';
|
|
52
|
+
|
|
53
|
+
export const CLOSE_ICON_INTERACTIVE =
|
|
54
|
+
'chip-close-icon-opacity group-hover:opacity-100 group-focus:opacity-100 group-active:opacity-100';
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Copyright (c) 2024 IOTA Stiftung
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
export enum
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export enum ChipType {
|
|
5
|
+
Outline = 'outline',
|
|
6
|
+
Elevated = 'elevated',
|
|
7
|
+
Success = 'success',
|
|
8
|
+
Brand = 'brand',
|
|
9
|
+
Error = 'error',
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export enum ChipSize {
|
|
@@ -23,7 +23,7 @@ export interface BaseInputProps extends InputWrapperProps {
|
|
|
23
23
|
/**
|
|
24
24
|
* A leading icon that is shown before the input
|
|
25
25
|
*/
|
|
26
|
-
leadingIcon?: React.
|
|
26
|
+
leadingIcon?: React.ReactNode;
|
|
27
27
|
/**
|
|
28
28
|
* Supporting text that is shown at the end of the input component.
|
|
29
29
|
*/
|
|
@@ -35,7 +35,7 @@ export interface BaseInputProps extends InputWrapperProps {
|
|
|
35
35
|
/**
|
|
36
36
|
* Trailing element that is shown after the input
|
|
37
37
|
*/
|
|
38
|
-
trailingElement?: React.
|
|
38
|
+
trailingElement?: React.ReactNode;
|
|
39
39
|
/**
|
|
40
40
|
* Is the content of the input visible
|
|
41
41
|
*/
|
|
@@ -44,6 +44,10 @@ export interface BaseInputProps extends InputWrapperProps {
|
|
|
44
44
|
* Value of the input
|
|
45
45
|
*/
|
|
46
46
|
value?: string | number;
|
|
47
|
+
/**
|
|
48
|
+
* Text that is shown below the value of the input.
|
|
49
|
+
*/
|
|
50
|
+
supportingValue?: string | null;
|
|
47
51
|
/**
|
|
48
52
|
* Default value of the input
|
|
49
53
|
*/
|
|
@@ -72,6 +76,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function InputComp
|
|
|
72
76
|
trailingElement,
|
|
73
77
|
isContentVisible,
|
|
74
78
|
value,
|
|
79
|
+
supportingValue,
|
|
75
80
|
defaultValue,
|
|
76
81
|
onClearInput,
|
|
77
82
|
isVisibilityToggleEnabled,
|
|
@@ -111,26 +116,38 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function InputComp
|
|
|
111
116
|
required={inputProps.required}
|
|
112
117
|
>
|
|
113
118
|
<div
|
|
114
|
-
className={cx(
|
|
119
|
+
className={cx(
|
|
120
|
+
'input-container relative flex flex-row items-center gap-x-3',
|
|
121
|
+
BORDER_CLASSES,
|
|
122
|
+
)}
|
|
115
123
|
onClick={focusOnInput}
|
|
116
124
|
ref={inputWrapperRef}
|
|
117
125
|
>
|
|
118
126
|
{leadingIcon && <span className="input-icon-color">{leadingIcon}</span>}
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
type
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
<div className="flex flex-1 flex-col items-start">
|
|
128
|
+
<InputElement
|
|
129
|
+
{...inputProps}
|
|
130
|
+
inputRef={forwardRef}
|
|
131
|
+
value={value}
|
|
132
|
+
type={
|
|
133
|
+
type === InputType.Password && isInputContentVisible
|
|
134
|
+
? InputType.Text
|
|
135
|
+
: type
|
|
136
|
+
}
|
|
137
|
+
disabled={disabled}
|
|
138
|
+
className={cx(
|
|
139
|
+
INPUT_CLASSES,
|
|
140
|
+
INPUT_TEXT_CLASSES,
|
|
141
|
+
INPUT_PLACEHOLDER_CLASSES,
|
|
142
|
+
INPUT_NUMBER_CLASSES,
|
|
143
|
+
)}
|
|
144
|
+
/>
|
|
145
|
+
{supportingValue && (
|
|
146
|
+
<span className="text-label-md text-iota-neutral-60 names:text-iota-neutral-60 dark:text-iota-neutral-40">
|
|
147
|
+
{supportingValue}
|
|
148
|
+
</span>
|
|
132
149
|
)}
|
|
133
|
-
|
|
150
|
+
</div>
|
|
134
151
|
|
|
135
152
|
{supportingText && <SecondaryText>{supportingText}</SecondaryText>}
|
|
136
153
|
<InputTrailingElement
|
|
@@ -62,6 +62,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextFieldBaseProps>(func
|
|
|
62
62
|
isResizeEnabled,
|
|
63
63
|
required,
|
|
64
64
|
isContentVisible,
|
|
65
|
+
defaultValue,
|
|
65
66
|
...textareaProps
|
|
66
67
|
},
|
|
67
68
|
ref,
|
|
@@ -93,16 +94,16 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextFieldBaseProps>(func
|
|
|
93
94
|
required={required}
|
|
94
95
|
ref={ref}
|
|
95
96
|
className={cx(
|
|
96
|
-
'peer block min-h-[50px]',
|
|
97
|
+
'text-area-container peer block min-h-[50px]',
|
|
97
98
|
BORDER_CLASSES,
|
|
98
99
|
INPUT_CLASSES,
|
|
99
100
|
INPUT_TEXT_CLASSES,
|
|
100
101
|
INPUT_PLACEHOLDER_CLASSES,
|
|
101
102
|
isInputContentVisible && isResizeEnabled ? 'resize-y' : 'resize-none',
|
|
102
|
-
!isInputContentVisible &&
|
|
103
|
-
'not-visible select-none text-transparent dark:text-transparent',
|
|
103
|
+
!isInputContentVisible && 'not-visible select-none text-transparent',
|
|
104
104
|
)}
|
|
105
|
-
|
|
105
|
+
defaultValue={isInputContentVisible && defaultValue ? defaultValue : undefined}
|
|
106
|
+
value={isInputContentVisible && value ? value : undefined}
|
|
106
107
|
{...textareaProps}
|
|
107
108
|
/>
|
|
108
109
|
{!isInputContentVisible && (
|
|
@@ -29,7 +29,7 @@ export function NavbarItemHorizontal({
|
|
|
29
29
|
const backgroundColors = isSelected && SELECTED_BACKGROUND;
|
|
30
30
|
const badgePositionClasses = text ? BADGE_WITH_TEXT : BADGE_WITHOUT_TEXT;
|
|
31
31
|
const textClasses = isSelected ? SELECTED_TEXT : UNSELECTED_TEXT;
|
|
32
|
-
const disabledClasses = isDisabled ? 'cursor-not-allowed opacity-60' : 'state-layer';
|
|
32
|
+
const disabledClasses = isDisabled ? 'cursor-not-allowed opacity-60' : 'state-layer-secondary';
|
|
33
33
|
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
34
34
|
if (isDisabled) {
|
|
35
35
|
e.preventDefault();
|
|
@@ -25,7 +25,7 @@ export function NavbarItemVertical({
|
|
|
25
25
|
const textClasses = isSelected ? SELECTED_TEXT : UNSELECTED_TEXT;
|
|
26
26
|
const disabledClasses = isDisabled
|
|
27
27
|
? 'cursor-not-allowed opacity-60'
|
|
28
|
-
: 'state-layer cursor-pointer ';
|
|
28
|
+
: 'state-layer-secondary cursor-pointer ';
|
|
29
29
|
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
30
30
|
if (isDisabled) {
|
|
31
31
|
e.preventDefault();
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { TriangleDown } from '@iota/apps-ui-icons';
|
|
5
5
|
import cx from 'classnames';
|
|
6
|
-
import { forwardRef, useEffect, useState } from 'react';
|
|
6
|
+
import { forwardRef, useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { Dropdown } from '../dropdown/Dropdown';
|
|
8
8
|
import { SecondaryText } from '@/components/atoms/secondary-text';
|
|
9
9
|
import { InputWrapper, LabelHtmlTag } from '../input/InputWrapper';
|
|
@@ -88,16 +88,35 @@ export const Select = forwardRef<HTMLButtonElement, SelectProps>(
|
|
|
88
88
|
) => {
|
|
89
89
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
90
90
|
const selectedValue = findValueByProps(value, options);
|
|
91
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
91
92
|
|
|
92
93
|
const selectorText = selectedValue || placeholder;
|
|
93
94
|
const selectPadding = size === SelectSize.Small ? 'px-sm' : 'px-md';
|
|
94
95
|
const textSize = size === SelectSize.Small ? 'text-body-md' : 'text-body-lg';
|
|
96
|
+
|
|
95
97
|
useEffect(() => {
|
|
96
98
|
if (disabled && isOpen) {
|
|
97
99
|
closeDropdown();
|
|
98
100
|
}
|
|
99
101
|
}, [disabled, isOpen]);
|
|
100
102
|
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (!isOpen) return;
|
|
105
|
+
|
|
106
|
+
const handleClickOutside = (e: MouseEvent) => {
|
|
107
|
+
const target = e.target as Node;
|
|
108
|
+
if (wrapperRef.current && !wrapperRef.current.contains(target)) {
|
|
109
|
+
closeDropdown();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
117
|
+
};
|
|
118
|
+
}, [isOpen]);
|
|
119
|
+
|
|
101
120
|
function findValueByProps(value: SelectProps['value'], options: SelectOption[] = []) {
|
|
102
121
|
return (
|
|
103
122
|
options.find((option) =>
|
|
@@ -123,6 +142,7 @@ export const Select = forwardRef<HTMLButtonElement, SelectProps>(
|
|
|
123
142
|
function closeDropdown() {
|
|
124
143
|
setIsOpen(false);
|
|
125
144
|
}
|
|
145
|
+
|
|
126
146
|
return (
|
|
127
147
|
<InputWrapper
|
|
128
148
|
label={label}
|
|
@@ -131,13 +151,13 @@ export const Select = forwardRef<HTMLButtonElement, SelectProps>(
|
|
|
131
151
|
errorMessage={errorMessage}
|
|
132
152
|
labelHtmlTag={LabelHtmlTag.Div}
|
|
133
153
|
>
|
|
134
|
-
<div className="relative flex w-full flex-col">
|
|
154
|
+
<div className="relative flex w-full flex-col" ref={wrapperRef}>
|
|
135
155
|
<ButtonUnstyled
|
|
136
156
|
ref={ref}
|
|
137
157
|
onClick={onSelectorClick}
|
|
138
158
|
disabled={disabled}
|
|
139
159
|
className={cx(
|
|
140
|
-
'select-border-color focus-visible:enabled:select-border-focus-color active:enabled:select-border-focus-color group-[.errored]:select-border-error-color group-[.opened]:select-border-focus-color [&:is(:focus,_:focus-visible,_:active)]:enabled:select-border-focus-color hover:enabled:select-border-hover-color flex flex-row items-center gap-x-3 rounded-lg border py-sm disabled:cursor-not-allowed [&_svg]:h-5 [&_svg]:w-5',
|
|
160
|
+
'select-container select-border-color focus-visible:enabled:select-border-focus-color active:enabled:select-border-focus-color group-[.errored]:select-border-error-color group-[.opened]:select-border-focus-color [&:is(:focus,_:focus-visible,_:active)]:enabled:select-border-focus-color hover:enabled:select-border-hover-color flex flex-row items-center gap-x-3 rounded-lg border py-sm disabled:cursor-not-allowed [&_svg]:h-5 [&_svg]:w-5',
|
|
141
161
|
selectPadding,
|
|
142
162
|
)}
|
|
143
163
|
>
|
|
@@ -171,7 +191,7 @@ export const Select = forwardRef<HTMLButtonElement, SelectProps>(
|
|
|
171
191
|
|
|
172
192
|
{isOpen && (
|
|
173
193
|
<div
|
|
174
|
-
className="fixed left-0 top-0 z-[49]
|
|
194
|
+
className="fixed left-0 top-0 z-[49] bg-transparent"
|
|
175
195
|
onClick={closeDropdown}
|
|
176
196
|
/>
|
|
177
197
|
)}
|