@iota/apps-ui-kit 0.2.0 → 0.2.1
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 +20 -0
- package/dist/index.d.ts +1622 -0
- package/dist/index.es.js +8805 -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 +5 -2
- 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 +14 -0
- package/src/lib/components/atoms/info-box/infoBox.enums.ts +12 -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 +14 -0
- package/src/lib/components/atoms/snackbar/snackbar.enums.tsx +7 -0
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +34 -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 +93 -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 +78 -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 +189 -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 +126 -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 +111 -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 +122 -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 +127 -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 +136 -0
- package/src/lib/tailwind/base.presets.ts +47 -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/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,126 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { SortByDown, SortByUp } from '@iota/apps-ui-icons';
|
|
6
|
+
import cx from 'classnames';
|
|
7
|
+
import { Checkbox } from '@/lib';
|
|
8
|
+
import { TableHeaderCellSortOrder } from './tableHeaderCell.enums';
|
|
9
|
+
|
|
10
|
+
export interface TableHeaderCellProps {
|
|
11
|
+
/**
|
|
12
|
+
* The column key.
|
|
13
|
+
*/
|
|
14
|
+
columnKey: string | number;
|
|
15
|
+
/**
|
|
16
|
+
* The label of the Header cell.
|
|
17
|
+
*/
|
|
18
|
+
label?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Action component to be rendered on the left side.
|
|
21
|
+
*/
|
|
22
|
+
actionLeft?: React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Action component to be rendered on the right side.
|
|
25
|
+
*/
|
|
26
|
+
actionRight?: React.ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Has Sort icon.
|
|
29
|
+
*/
|
|
30
|
+
hasSort?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* On Sort icon click.
|
|
33
|
+
*/
|
|
34
|
+
onSortClick?: (columnKey: string | number, sortOrder: TableHeaderCellSortOrder) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Has Checkbox.
|
|
37
|
+
*/
|
|
38
|
+
hasCheckbox?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Is Checkbox checked.
|
|
41
|
+
*/
|
|
42
|
+
isChecked?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Is Checkbox indeterminate.
|
|
45
|
+
*/
|
|
46
|
+
isIndeterminate?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* On Checkbox change.
|
|
49
|
+
*/
|
|
50
|
+
onCheckboxChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the cell content should be centered.
|
|
53
|
+
*/
|
|
54
|
+
isContentCentered?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function TableHeaderCell({
|
|
58
|
+
label,
|
|
59
|
+
columnKey,
|
|
60
|
+
hasSort,
|
|
61
|
+
hasCheckbox,
|
|
62
|
+
isChecked,
|
|
63
|
+
isIndeterminate,
|
|
64
|
+
isContentCentered,
|
|
65
|
+
onSortClick,
|
|
66
|
+
onCheckboxChange,
|
|
67
|
+
}: TableHeaderCellProps): JSX.Element {
|
|
68
|
+
const [sortOrder, setSortOrder] = useState<TableHeaderCellSortOrder | null>(
|
|
69
|
+
TableHeaderCellSortOrder.Asc,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const handleSort = () => {
|
|
73
|
+
const newSortOrder =
|
|
74
|
+
sortOrder === TableHeaderCellSortOrder.Asc
|
|
75
|
+
? TableHeaderCellSortOrder.Desc
|
|
76
|
+
: TableHeaderCellSortOrder.Asc;
|
|
77
|
+
setSortOrder(newSortOrder);
|
|
78
|
+
if (onSortClick) {
|
|
79
|
+
onSortClick(columnKey, newSortOrder);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const textColorClass = 'text-neutral-10 dark:text-neutral-92';
|
|
84
|
+
const textSizeClass = 'text-label-lg';
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<th
|
|
88
|
+
className={cx(
|
|
89
|
+
'state-layer relative h-14 border-b border-shader-neutral-light-8 px-md after:pointer-events-none dark:border-shader-neutral-dark-8',
|
|
90
|
+
)}
|
|
91
|
+
>
|
|
92
|
+
<div
|
|
93
|
+
className={cx(
|
|
94
|
+
'flex flex-row items-center gap-1 [&_svg]:h-4 [&_svg]:w-4',
|
|
95
|
+
textColorClass,
|
|
96
|
+
textSizeClass,
|
|
97
|
+
{
|
|
98
|
+
'justify-center': isContentCentered,
|
|
99
|
+
},
|
|
100
|
+
)}
|
|
101
|
+
>
|
|
102
|
+
{hasCheckbox ? (
|
|
103
|
+
<Checkbox
|
|
104
|
+
isChecked={isChecked}
|
|
105
|
+
isIndeterminate={isIndeterminate}
|
|
106
|
+
onCheckedChange={onCheckboxChange}
|
|
107
|
+
/>
|
|
108
|
+
) : (
|
|
109
|
+
<span
|
|
110
|
+
className={cx({
|
|
111
|
+
'text-left': !isContentCentered,
|
|
112
|
+
})}
|
|
113
|
+
>
|
|
114
|
+
{label}
|
|
115
|
+
</span>
|
|
116
|
+
)}
|
|
117
|
+
{hasSort && sortOrder === TableHeaderCellSortOrder.Asc && (
|
|
118
|
+
<SortByUp className="cursor-pointer" onClick={handleSort} />
|
|
119
|
+
)}
|
|
120
|
+
{hasSort && sortOrder === TableHeaderCellSortOrder.Desc && (
|
|
121
|
+
<SortByDown className="cursor-pointer" onClick={handleSort} />
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
</th>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -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,111 @@
|
|
|
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
|
+
hideBorder,
|
|
48
|
+
}: PropsWithChildren<AccordionHeaderProps>) {
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
onClick={onToggle}
|
|
52
|
+
className={cx(
|
|
53
|
+
'state-layer relative flex cursor-pointer items-center justify-between gap-md py-sm--rs',
|
|
54
|
+
{
|
|
55
|
+
'pr-md--rs': !hideArrow,
|
|
56
|
+
'rounded-xl': hideBorder,
|
|
57
|
+
},
|
|
58
|
+
)}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
{!hideArrow && (
|
|
62
|
+
<div className="[&_svg]:h-5 [&_svg]:w-5">
|
|
63
|
+
<Button
|
|
64
|
+
type={ButtonType.Ghost}
|
|
65
|
+
icon={
|
|
66
|
+
<ArrowDown
|
|
67
|
+
className={cx(ICON_STYLE, {
|
|
68
|
+
'rotate-180': isExpanded,
|
|
69
|
+
})}
|
|
70
|
+
/>
|
|
71
|
+
}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
)}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function AccordionContent({
|
|
80
|
+
isExpanded,
|
|
81
|
+
children,
|
|
82
|
+
}: PropsWithChildren<AccordionContentProps>) {
|
|
83
|
+
return (
|
|
84
|
+
<div
|
|
85
|
+
className={cx({
|
|
86
|
+
hidden: !isExpanded,
|
|
87
|
+
})}
|
|
88
|
+
>
|
|
89
|
+
{children}
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function Accordion({
|
|
95
|
+
children,
|
|
96
|
+
hideBorder,
|
|
97
|
+
}: {
|
|
98
|
+
children: React.ReactNode;
|
|
99
|
+
hideBorder?: boolean;
|
|
100
|
+
}): React.JSX.Element {
|
|
101
|
+
return (
|
|
102
|
+
<div
|
|
103
|
+
className={cx('overflow-hidden rounded-xl bg-neutral-100 dark:bg-neutral-6', {
|
|
104
|
+
' border border-shader-neutral-light-8 dark:border-shader-neutral-dark-8':
|
|
105
|
+
!hideBorder,
|
|
106
|
+
})}
|
|
107
|
+
>
|
|
108
|
+
{children}
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
? 'right-0 h-screen top-0 w-full'
|
|
72
|
+
: 'max-h-[60vh] 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
|
+
return (
|
|
76
|
+
<RadixDialog.Portal container={containerElement}>
|
|
77
|
+
<DialogOverlay showCloseIcon={showCloseOnOverlay} position={position} />
|
|
78
|
+
<RadixDialog.Content
|
|
79
|
+
ref={ref}
|
|
80
|
+
className={cx(
|
|
81
|
+
'fixed z-[99999] flex flex-col justify-center overflow-hidden bg-primary-100 dark:bg-neutral-6',
|
|
82
|
+
positionClass,
|
|
83
|
+
widthClass,
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
<VisuallyHidden.Root>
|
|
88
|
+
<RadixDialog.Title />
|
|
89
|
+
<RadixDialog.Description />
|
|
90
|
+
</VisuallyHidden.Root>
|
|
91
|
+
{children}
|
|
92
|
+
</RadixDialog.Content>
|
|
93
|
+
</RadixDialog.Portal>
|
|
94
|
+
);
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
DialogContent.displayName = RadixDialog.Content.displayName;
|
|
98
|
+
|
|
99
|
+
const DialogTitle = React.forwardRef<
|
|
100
|
+
React.ElementRef<typeof RadixDialog.Title>,
|
|
101
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Title>
|
|
102
|
+
>((props, ref) => (
|
|
103
|
+
<RadixDialog.Title
|
|
104
|
+
ref={ref}
|
|
105
|
+
className="font-inter text-title-lg text-neutral-10 dark:text-neutral-92"
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
));
|
|
109
|
+
DialogTitle.displayName = RadixDialog.Title.displayName;
|
|
110
|
+
|
|
111
|
+
const DialogBody = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(
|
|
112
|
+
(props, ref) => (
|
|
113
|
+
<div
|
|
114
|
+
ref={ref}
|
|
115
|
+
className="p-md--rs text-body-sm text-neutral-40 dark:text-neutral-60"
|
|
116
|
+
{...props}
|
|
117
|
+
/>
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
DialogBody.displayName = 'DialogBody';
|
|
121
|
+
|
|
122
|
+
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 collapsable button
|
|
13
|
+
*/
|
|
14
|
+
isCollapsable?: 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 collapsable, 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
|
+
isCollapsable = 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': isCollapsable,
|
|
53
|
+
})}
|
|
54
|
+
>
|
|
55
|
+
{isCollapsable && (
|
|
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': !isCollapsable,
|
|
71
|
+
'hidden sm:flex sm:flex-col sm:gap-2': isCollapsable,
|
|
72
|
+
})}
|
|
73
|
+
>
|
|
74
|
+
{items.map((item) => (
|
|
75
|
+
<div
|
|
76
|
+
key={item.id}
|
|
77
|
+
className={cx('flex items-center', {
|
|
78
|
+
'px-xs py-xxs': !isCollapsable,
|
|
79
|
+
'py-xxs pl-xs pr-sm': isCollapsable,
|
|
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
|
+
}
|