@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.
- package/CHANGELOG.md +45 -0
- package/dist/index.d.ts +1636 -0
- package/dist/index.es.js +8909 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +198 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +6 -3
- package/src/lib/components/atoms/badge/Badge.tsx +37 -0
- package/src/lib/components/atoms/badge/badge.classes.ts +24 -0
- package/src/lib/components/atoms/badge/badge.enums.ts +8 -0
- package/src/lib/components/atoms/badge/index.ts +6 -0
- package/src/lib/components/atoms/button/Button.tsx +99 -0
- package/src/lib/components/atoms/button/button-variants/ButtonPill.tsx +23 -0
- package/src/lib/components/atoms/button/button-variants/ButtonUnstyled.tsx +27 -0
- package/src/lib/components/atoms/button/button-variants/buttonVariants.types.ts +11 -0
- package/src/lib/components/atoms/button/button-variants/index.ts +5 -0
- package/src/lib/components/atoms/button/button.classes.ts +53 -0
- package/src/lib/components/atoms/button/button.enums.ts +21 -0
- package/src/lib/components/atoms/button/index.ts +7 -0
- package/src/lib/components/atoms/button-segment/ButtonSegment.tsx +86 -0
- package/src/lib/components/atoms/button-segment/buttonSegment.classes.ts +45 -0
- package/src/lib/components/atoms/button-segment/buttonSegment.enums.ts +7 -0
- package/src/lib/components/atoms/button-segment/index.ts +5 -0
- package/src/lib/components/atoms/checkbox/Checkbox.tsx +114 -0
- package/src/lib/components/atoms/checkbox/index.ts +4 -0
- package/src/lib/components/atoms/divider/Divider.tsx +48 -0
- package/src/lib/components/atoms/divider/divider.classes.ts +11 -0
- package/src/lib/components/atoms/divider/divider.enums.ts +7 -0
- package/src/lib/components/atoms/divider/index.ts +6 -0
- package/src/lib/components/atoms/header/Header.tsx +73 -0
- package/src/lib/components/atoms/header/index.ts +4 -0
- package/src/lib/components/atoms/index.ts +22 -0
- package/src/lib/components/atoms/info-box/InfoBox.tsx +73 -0
- package/src/lib/components/atoms/info-box/index.ts +5 -0
- package/src/lib/components/atoms/info-box/infoBox.classes.ts +19 -0
- package/src/lib/components/atoms/info-box/infoBox.enums.ts +14 -0
- package/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +156 -0
- package/src/lib/components/atoms/key-value-info/index.ts +6 -0
- package/src/lib/components/atoms/key-value-info/keyValue.enums.ts +7 -0
- package/src/lib/components/atoms/label-text/LabelText.tsx +93 -0
- package/src/lib/components/atoms/label-text/index.ts +5 -0
- package/src/lib/components/atoms/label-text/labelText.classes.ts +22 -0
- package/src/lib/components/atoms/label-text/labelText.enums.ts +8 -0
- package/src/lib/components/atoms/list-item/ListItem.tsx +89 -0
- package/src/lib/components/atoms/list-item/index.ts +4 -0
- package/src/lib/components/atoms/loading-indicator/LoadingIndicator.tsx +38 -0
- package/src/lib/components/atoms/loading-indicator/index.ts +4 -0
- package/src/lib/components/atoms/panel/Panel.tsx +30 -0
- package/src/lib/components/atoms/panel/index.ts +4 -0
- package/src/lib/components/atoms/placeholder/Placeholder.tsx +27 -0
- package/src/lib/components/atoms/placeholder/index.ts +4 -0
- package/src/lib/components/atoms/radio-button/RadioButton.tsx +68 -0
- package/src/lib/components/atoms/radio-button/index.ts +4 -0
- package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +28 -0
- package/src/lib/components/atoms/secondary-text/index.ts +4 -0
- package/src/lib/components/atoms/skeleton/Skeleton.tsx +47 -0
- package/src/lib/components/atoms/skeleton/index.ts +4 -0
- package/src/lib/components/atoms/snackbar/Snackbar.tsx +69 -0
- package/src/lib/components/atoms/snackbar/index.ts +5 -0
- package/src/lib/components/atoms/snackbar/snackbar.classes.ts +18 -0
- package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +9 -0
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +37 -0
- package/src/lib/components/atoms/tooltip/index.ts +5 -0
- package/src/lib/components/atoms/tooltip/tooltip.classes.ts +11 -0
- package/src/lib/components/atoms/tooltip/tooltip.enums.ts +9 -0
- package/src/lib/components/atoms/visual-asset-card/VisualAssetCard.tsx +101 -0
- package/src/lib/components/atoms/visual-asset-card/index.ts +5 -0
- package/src/lib/components/atoms/visual-asset-card/visualAssetCard.enums.ts +7 -0
- package/src/lib/components/index.ts +8 -0
- package/src/lib/components/molecules/account/Account.tsx +174 -0
- package/src/lib/components/molecules/account/index.ts +4 -0
- package/src/lib/components/molecules/address/Address.tsx +101 -0
- package/src/lib/components/molecules/address/index.ts +4 -0
- package/src/lib/components/molecules/card/Card.tsx +70 -0
- package/src/lib/components/molecules/card/CardAction.tsx +80 -0
- package/src/lib/components/molecules/card/CardBody.tsx +61 -0
- package/src/lib/components/molecules/card/CardImage.tsx +43 -0
- package/src/lib/components/molecules/card/CardImagePlaceholder.tsx +146 -0
- package/src/lib/components/molecules/card/card.classes.ts +26 -0
- package/src/lib/components/molecules/card/card.enums.ts +25 -0
- package/src/lib/components/molecules/card/index.ts +8 -0
- package/src/lib/components/molecules/chip/Chip.tsx +105 -0
- package/src/lib/components/molecules/chip/chip.classes.ts +32 -0
- package/src/lib/components/molecules/chip/chip.enums.ts +7 -0
- package/src/lib/components/molecules/chip/index.ts +4 -0
- package/src/lib/components/molecules/display-stats/DisplayStats.tsx +104 -0
- package/src/lib/components/molecules/display-stats/displayStats.classes.ts +36 -0
- package/src/lib/components/molecules/display-stats/displayStats.enums.ts +13 -0
- package/src/lib/components/molecules/display-stats/index.ts +5 -0
- package/src/lib/components/molecules/dropdown/Dropdown.tsx +10 -0
- package/src/lib/components/molecules/dropdown/dropdownPosition.enums.ts +7 -0
- package/src/lib/components/molecules/dropdown/index.ts +5 -0
- package/src/lib/components/molecules/index.ts +17 -0
- package/src/lib/components/molecules/input/Input.tsx +245 -0
- package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
- package/src/lib/components/molecules/input/TextArea.tsx +149 -0
- package/src/lib/components/molecules/input/index.ts +8 -0
- package/src/lib/components/molecules/input/input.classes.ts +14 -0
- package/src/lib/components/molecules/input/input.enums.ts +14 -0
- package/src/lib/components/molecules/input/input.types.ts +29 -0
- package/src/lib/components/molecules/navbar-item/NavbarItem.tsx +48 -0
- package/src/lib/components/molecules/navbar-item/NavbarItemHorizontal.tsx +65 -0
- package/src/lib/components/molecules/navbar-item/NavbarItemVertical.tsx +54 -0
- package/src/lib/components/molecules/navbar-item/index.ts +5 -0
- package/src/lib/components/molecules/navbar-item/navbarItem.classes.ts +16 -0
- package/src/lib/components/molecules/navbar-item/navbarItem.enums.ts +7 -0
- package/src/lib/components/molecules/search/Search.tsx +220 -0
- package/src/lib/components/molecules/search/index.ts +5 -0
- package/src/lib/components/molecules/search/search.classes.ts +20 -0
- package/src/lib/components/molecules/search/search.enums.ts +7 -0
- package/src/lib/components/molecules/segmented-button/SegmentedButton.tsx +34 -0
- package/src/lib/components/molecules/segmented-button/index.ts +6 -0
- package/src/lib/components/molecules/segmented-button/segmentedButton.classes.ts +12 -0
- package/src/lib/components/molecules/segmented-button/segmentedButton.enums.ts +8 -0
- package/src/lib/components/molecules/select/Select.tsx +223 -0
- package/src/lib/components/molecules/select/index.ts +5 -0
- package/src/lib/components/molecules/select/select.enums.ts +7 -0
- package/src/lib/components/molecules/table-cell/TableCell.tsx +62 -0
- package/src/lib/components/molecules/table-cell/index.ts +4 -0
- package/src/lib/components/molecules/table-header-cell/TableHeaderCell.tsx +140 -0
- package/src/lib/components/molecules/table-header-cell/index.ts +5 -0
- package/src/lib/components/molecules/table-header-cell/tableHeaderCell.enums.ts +7 -0
- package/src/lib/components/molecules/title/Title.tsx +69 -0
- package/src/lib/components/molecules/title/index.ts +5 -0
- package/src/lib/components/molecules/title/titleClasses.constants.ts +14 -0
- package/src/lib/components/molecules/title/titleSize.enums.ts +7 -0
- package/src/lib/components/organisms/accordion/Accordion.tsx +109 -0
- package/src/lib/components/organisms/accordion/accordion.classes.ts +4 -0
- package/src/lib/components/organisms/accordion/index.ts +4 -0
- package/src/lib/components/organisms/dialog/Dialog.tsx +123 -0
- package/src/lib/components/organisms/dialog/dialog.enums.ts +7 -0
- package/src/lib/components/organisms/dialog/index.ts +5 -0
- package/src/lib/components/organisms/index.ts +7 -0
- package/src/lib/components/organisms/navbar/Navbar.tsx +100 -0
- package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +58 -0
- package/src/lib/components/organisms/navbar/index.ts +5 -0
- package/src/lib/components/organisms/table/Table.tsx +224 -0
- package/src/lib/components/organisms/table/TableContext.tsx +55 -0
- package/src/lib/components/organisms/table/index.ts +4 -0
- package/src/lib/constants/colors.constants.ts +132 -0
- package/src/lib/constants/index.ts +4 -0
- package/src/lib/enums/index.ts +4 -0
- package/src/lib/enums/screenSize.enums.ts +9 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/styles/fonts.css +5 -0
- package/src/lib/styles/index.css +149 -0
- package/src/lib/tailwind/base.presets.ts +49 -0
- package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
- package/src/lib/tailwind/constants/index.ts +6 -0
- package/src/lib/tailwind/constants/scaling.constants.ts +41 -0
- package/src/lib/tailwind/constants/variableSpacing.constants.ts +66 -0
- package/src/lib/tailwind/helpers.ts +20 -0
- package/src/lib/tailwind/index.ts +5 -0
- package/src/lib/tailwind/plugins.ts +8 -0
- package/src/lib/tailwind/responsive.presets.ts +36 -0
- package/src/lib/tailwind/static.presets.ts +25 -0
- package/src/lib/tailwind/types.ts +6 -0
- package/src/lib/utils/format.ts +8 -0
- package/src/lib/utils/index.ts +4 -0
- package/src/storybook/blocks/Showcase.tsx +20 -0
- package/src/storybook/blocks/TypeSet.tsx +34 -0
- package/src/storybook/blocks/TypeSetItem.tsx +74 -0
- package/src/storybook/blocks/index.ts +6 -0
- package/src/storybook/constants/index.ts +5 -0
- package/src/storybook/constants/typeset.constants.ts +39 -0
- package/src/storybook/constants/variableSpacing.constants.ts +6 -0
- package/src/storybook/helpers/getFontSizeLabel.ts +15 -0
- package/src/storybook/helpers/index.ts +4 -0
- package/src/storybook/stories/atoms/Badge.stories.tsx +32 -0
- package/src/storybook/stories/atoms/Button.stories.tsx +45 -0
- package/src/storybook/stories/atoms/ButtonSegment.stories.tsx +45 -0
- package/src/storybook/stories/atoms/Checkbox.stories.tsx +34 -0
- package/src/storybook/stories/atoms/CustomScrollbar.stories.tsx +22 -0
- package/src/storybook/stories/atoms/Divider.stories.tsx +41 -0
- package/src/storybook/stories/atoms/Header.stories.tsx +58 -0
- package/src/storybook/stories/atoms/InfoBox.stories.tsx +67 -0
- package/src/storybook/stories/atoms/KeyValueInfo.stories.tsx +59 -0
- package/src/storybook/stories/atoms/LabelText.stories.tsx +55 -0
- package/src/storybook/stories/atoms/ListItem.stories.tsx +41 -0
- package/src/storybook/stories/atoms/LoadingIndicator.stories.tsx +32 -0
- package/src/storybook/stories/atoms/Panel.stories.tsx +36 -0
- package/src/storybook/stories/atoms/Placeholder.stories.tsx +33 -0
- package/src/storybook/stories/atoms/RadioButton.stories.tsx +51 -0
- package/src/storybook/stories/atoms/Skeleton.stories.tsx +33 -0
- package/src/storybook/stories/atoms/Snackbar.stories.tsx +42 -0
- package/src/storybook/stories/atoms/Tooltip.stories.tsx +57 -0
- package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +56 -0
- package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
- package/src/storybook/stories/components/index.ts +4 -0
- package/src/storybook/stories/design-tokens/colors.stories.mdx +23 -0
- package/src/storybook/stories/design-tokens/icons.stories.mdx +17 -0
- package/src/storybook/stories/design-tokens/typeset.stories.mdx +15 -0
- package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +10 -0
- package/src/storybook/stories/molecules/Account.stories.tsx +69 -0
- package/src/storybook/stories/molecules/Address.stories.tsx +39 -0
- package/src/storybook/stories/molecules/Card.stories.tsx +115 -0
- package/src/storybook/stories/molecules/Chip.stories.tsx +122 -0
- package/src/storybook/stories/molecules/DisplayStats.stories.tsx +63 -0
- package/src/storybook/stories/molecules/Dropdown.stories.tsx +38 -0
- package/src/storybook/stories/molecules/Input.stories.tsx +161 -0
- package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
- package/src/storybook/stories/molecules/Search.stories.tsx +100 -0
- package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +107 -0
- package/src/storybook/stories/molecules/Select.stories.tsx +102 -0
- package/src/storybook/stories/molecules/TableCell.stories.tsx +46 -0
- package/src/storybook/stories/molecules/TableHeaderCell.stories.tsx +34 -0
- package/src/storybook/stories/molecules/TextArea.stories.tsx +80 -0
- package/src/storybook/stories/molecules/Title.stories.tsx +76 -0
- package/src/storybook/stories/organisms/Accordion.stories.tsx +70 -0
- package/src/storybook/stories/organisms/Dialog.stories.tsx +103 -0
- package/src/storybook/stories/organisms/Navbar.stories.tsx +77 -0
- 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,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,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,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,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,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
|
+
}
|