@iota/apps-ui-kit 0.0.0-experimental-20250613144451
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 +106 -0
- package/LICENSE +201 -0
- package/README.md +16 -0
- package/dist/index.d.ts +1726 -0
- package/dist/index.es.js +6923 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +118 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +75 -0
- package/src/lib/components/atoms/badge/Badge.tsx +37 -0
- package/src/lib/components/atoms/badge/badge.classes.ts +33 -0
- package/src/lib/components/atoms/badge/badge.enums.ts +11 -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 +98 -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 +23 -0
- package/src/lib/components/atoms/info-box/InfoBox.tsx +74 -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 +157 -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 +94 -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/toggle/Toggle.tsx +140 -0
- package/src/lib/components/atoms/toggle/index.ts +6 -0
- package/src/lib/components/atoms/toggle/toggle.classes.ts +41 -0
- package/src/lib/components/atoms/toggle/toggle.enums.ts +12 -0
- package/src/lib/components/atoms/tooltip/Tooltip.tsx +138 -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 +192 -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 +72 -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 +27 -0
- package/src/lib/components/molecules/card/card.enums.ts +26 -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 +142 -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 +246 -0
- package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
- package/src/lib/components/molecules/input/TextArea.tsx +150 -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 +216 -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 +38 -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 +222 -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 +78 -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 +142 -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 +101 -0
- package/src/lib/components/organisms/navbar/NavbarSlideout.tsx +59 -0
- package/src/lib/components/organisms/navbar/index.ts +5 -0
- package/src/lib/components/organisms/table/Table.tsx +234 -0
- package/src/lib/components/organisms/table/TableContext.tsx +56 -0
- package/src/lib/components/organisms/table/index.ts +4 -0
- package/src/lib/constants/colors.constants.ts +133 -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 +43 -0
- package/src/storybook/stories/atoms/Toggle.stories.tsx +59 -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 +112 -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 +162 -0
- package/src/storybook/stories/molecules/NavbarItem.stories.tsx +45 -0
- package/src/storybook/stories/molecules/Search.stories.tsx +101 -0
- package/src/storybook/stories/molecules/SegmentedButton.stories.tsx +108 -0
- package/src/storybook/stories/molecules/Select.stories.tsx +103 -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 +78 -0
- package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { PropsWithChildren } from 'react';
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import { ArrowDown } from '@iota/apps-ui-icons';
|
|
7
|
+
import { Button, ButtonType } from '@/components/atoms';
|
|
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,142 @@
|
|
|
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 = ({
|
|
13
|
+
open,
|
|
14
|
+
onOpenChange,
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentPropsWithoutRef<typeof RadixDialog.Root>) => {
|
|
18
|
+
const handleOpenChange = (isOpen: boolean) => {
|
|
19
|
+
const isMouseOverToast = document.querySelector('.toast-layer:hover');
|
|
20
|
+
if (!isOpen && isMouseOverToast) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
onOpenChange?.(isOpen);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<RadixDialog.Root open={open} onOpenChange={handleOpenChange} {...props}>
|
|
28
|
+
{children}
|
|
29
|
+
</RadixDialog.Root>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
const DialogTrigger = RadixDialog.Trigger;
|
|
33
|
+
const DialogClose = RadixDialog.Close;
|
|
34
|
+
|
|
35
|
+
const DialogOverlay = React.forwardRef<
|
|
36
|
+
React.ElementRef<typeof RadixDialog.Overlay>,
|
|
37
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Overlay> & {
|
|
38
|
+
showCloseIcon?: boolean;
|
|
39
|
+
position?: DialogPosition;
|
|
40
|
+
}
|
|
41
|
+
>(({ showCloseIcon, position, ...props }, ref) => (
|
|
42
|
+
<RadixDialog.Overlay
|
|
43
|
+
ref={ref}
|
|
44
|
+
className={cx('inset-0 z-[99998] bg-shader-neutral-light-48 backdrop-blur-md', {
|
|
45
|
+
fixed: position === DialogPosition.Right,
|
|
46
|
+
absolute: position === DialogPosition.Center,
|
|
47
|
+
})}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
<DialogClose className={cx('fixed right-3 top-3', { hidden: !showCloseIcon })}>
|
|
51
|
+
<Close />
|
|
52
|
+
</DialogClose>
|
|
53
|
+
</RadixDialog.Overlay>
|
|
54
|
+
));
|
|
55
|
+
DialogOverlay.displayName = RadixDialog.Overlay.displayName;
|
|
56
|
+
|
|
57
|
+
const DialogContent = React.forwardRef<
|
|
58
|
+
React.ElementRef<typeof RadixDialog.Content>,
|
|
59
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Content> & {
|
|
60
|
+
containerId?: string;
|
|
61
|
+
showCloseOnOverlay?: boolean;
|
|
62
|
+
position?: DialogPosition;
|
|
63
|
+
customWidth?: string;
|
|
64
|
+
}
|
|
65
|
+
>(
|
|
66
|
+
(
|
|
67
|
+
{
|
|
68
|
+
className,
|
|
69
|
+
containerId,
|
|
70
|
+
showCloseOnOverlay,
|
|
71
|
+
children,
|
|
72
|
+
position = DialogPosition.Center,
|
|
73
|
+
customWidth = 'w-80 max-w-[85vw] md:w-96',
|
|
74
|
+
...props
|
|
75
|
+
},
|
|
76
|
+
ref,
|
|
77
|
+
) => {
|
|
78
|
+
const [containerElement, setContainerElement] = useState<HTMLElement | undefined>(
|
|
79
|
+
undefined,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
// This ensures document.getElementById is called in the client-side environment only.
|
|
84
|
+
// note. containerElement cant be null
|
|
85
|
+
const element = containerId ? document.getElementById(containerId) : undefined;
|
|
86
|
+
setContainerElement(element ?? undefined);
|
|
87
|
+
}, [containerId]);
|
|
88
|
+
const positionClass =
|
|
89
|
+
position === DialogPosition.Right
|
|
90
|
+
? 'overflow-hidden right-0 h-screen top-0 w-full'
|
|
91
|
+
: 'overflow-y-auto overflow-x-hidden left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-xl';
|
|
92
|
+
const widthClass =
|
|
93
|
+
position === DialogPosition.Right ? 'md:w-96 max-w-[500px]' : customWidth;
|
|
94
|
+
const heightClass = position === DialogPosition.Right ? 'h-screen' : 'max-h-[80vh] h-full';
|
|
95
|
+
return (
|
|
96
|
+
<RadixDialog.Portal container={containerElement}>
|
|
97
|
+
<DialogOverlay showCloseIcon={showCloseOnOverlay} position={position} />
|
|
98
|
+
<RadixDialog.Content
|
|
99
|
+
ref={ref}
|
|
100
|
+
className={cx(
|
|
101
|
+
'fixed z-[99999] flex flex-col justify-center bg-primary-100 dark:bg-neutral-6',
|
|
102
|
+
positionClass,
|
|
103
|
+
widthClass,
|
|
104
|
+
)}
|
|
105
|
+
{...props}
|
|
106
|
+
>
|
|
107
|
+
<VisuallyHidden.Root>
|
|
108
|
+
<RadixDialog.Title />
|
|
109
|
+
<RadixDialog.Description />
|
|
110
|
+
</VisuallyHidden.Root>
|
|
111
|
+
<div className={cx('flex flex-1 flex-col', heightClass)}>{children}</div>
|
|
112
|
+
</RadixDialog.Content>
|
|
113
|
+
</RadixDialog.Portal>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
DialogContent.displayName = RadixDialog.Content.displayName;
|
|
118
|
+
|
|
119
|
+
const DialogTitle = React.forwardRef<
|
|
120
|
+
React.ElementRef<typeof RadixDialog.Title>,
|
|
121
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Title>
|
|
122
|
+
>((props, ref) => (
|
|
123
|
+
<RadixDialog.Title
|
|
124
|
+
ref={ref}
|
|
125
|
+
className="font-inter text-title-lg text-neutral-10 dark:text-neutral-92"
|
|
126
|
+
{...props}
|
|
127
|
+
/>
|
|
128
|
+
));
|
|
129
|
+
DialogTitle.displayName = RadixDialog.Title.displayName;
|
|
130
|
+
|
|
131
|
+
const DialogBody = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(
|
|
132
|
+
(props, ref) => (
|
|
133
|
+
<div
|
|
134
|
+
ref={ref}
|
|
135
|
+
className="flex-1 overflow-y-auto p-md--rs text-body-sm text-neutral-40 dark:text-neutral-60"
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
DialogBody.displayName = 'DialogBody';
|
|
141
|
+
|
|
142
|
+
export { Dialog, DialogClose, DialogTrigger, DialogContent, DialogTitle, DialogBody };
|
|
@@ -0,0 +1,101 @@
|
|
|
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 type { NavbarItemProps } from '@/components/molecules/navbar-item/NavbarItem';
|
|
7
|
+
import { NavbarItem } from '@/components/molecules/navbar-item/NavbarItem';
|
|
8
|
+
|
|
9
|
+
export type NavbarItemWithId = NavbarItemProps & { id: string };
|
|
10
|
+
|
|
11
|
+
export interface NavbarProps {
|
|
12
|
+
/**
|
|
13
|
+
* If this flag is true we need to leave only the icon and collapsible button
|
|
14
|
+
*/
|
|
15
|
+
isCollapsible?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* List of elements to be displayed in the navbar.
|
|
19
|
+
*/
|
|
20
|
+
items: NavbarItemWithId[];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The id of the active element.
|
|
24
|
+
*/
|
|
25
|
+
activeId: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Callback when an element is clicked.
|
|
29
|
+
*/
|
|
30
|
+
onClickItem: (id: string) => void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* If the navbar is collapsible, this flag indicates if it is open or not.
|
|
34
|
+
*/
|
|
35
|
+
isOpen?: boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Callback when the navbar is toggled.
|
|
39
|
+
*/
|
|
40
|
+
onToggleNavbar?: () => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function Navbar({
|
|
44
|
+
items,
|
|
45
|
+
activeId,
|
|
46
|
+
onClickItem,
|
|
47
|
+
isCollapsible = false,
|
|
48
|
+
onToggleNavbar,
|
|
49
|
+
}: NavbarProps) {
|
|
50
|
+
return (
|
|
51
|
+
<div
|
|
52
|
+
className={cx('flex h-fit w-full', {
|
|
53
|
+
'flex-col px-md py-xs sm:h-full sm:w-auto sm:px-none sm:py-xl': isCollapsible,
|
|
54
|
+
})}
|
|
55
|
+
>
|
|
56
|
+
{isCollapsible && (
|
|
57
|
+
<div className="flex w-full items-center justify-between sm:mb-[48px] sm:flex-col">
|
|
58
|
+
<div className="flex justify-center [&_svg]:h-[38px] [&_svg]:w-[38px]">
|
|
59
|
+
<IotaLogoMark className="text-neutral-10 dark:text-neutral-92" />
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
className="state-layer relative rounded-full p-xs hover:cursor-pointer dark:text-neutral-92 sm:hidden [&_svg]:h-6 [&_svg]:w-6"
|
|
63
|
+
onClick={onToggleNavbar}
|
|
64
|
+
>
|
|
65
|
+
<MenuIcon />
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
<div
|
|
70
|
+
className={cx({
|
|
71
|
+
'flex w-full justify-between px-sm py-xxs': !isCollapsible,
|
|
72
|
+
'hidden sm:flex sm:flex-col sm:gap-2': isCollapsible,
|
|
73
|
+
})}
|
|
74
|
+
>
|
|
75
|
+
{items.map((item) => (
|
|
76
|
+
<div
|
|
77
|
+
key={item.id}
|
|
78
|
+
className={cx('flex items-center', {
|
|
79
|
+
'px-xs py-xxs': !isCollapsible,
|
|
80
|
+
'py-xxs pl-xs pr-sm': isCollapsible,
|
|
81
|
+
})}
|
|
82
|
+
data-testid={`nav-${item.id}`}
|
|
83
|
+
>
|
|
84
|
+
<NavbarItem
|
|
85
|
+
{...item}
|
|
86
|
+
isSelected={item.id === activeId}
|
|
87
|
+
onClick={(e) => {
|
|
88
|
+
if (item.onClick) {
|
|
89
|
+
item.onClick(e);
|
|
90
|
+
}
|
|
91
|
+
if (!item.isDisabled) {
|
|
92
|
+
onClickItem(item.id);
|
|
93
|
+
}
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
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 } from '@/components/atoms';
|
|
7
|
+
import { NavbarItem, NavbarItemType } from '@/components/molecules';
|
|
8
|
+
import type { NavbarProps } from './Navbar';
|
|
9
|
+
|
|
10
|
+
export function NavbarSlideout({
|
|
11
|
+
items,
|
|
12
|
+
activeId,
|
|
13
|
+
onClickItem,
|
|
14
|
+
isOpen,
|
|
15
|
+
onToggleNavbar,
|
|
16
|
+
}: NavbarProps) {
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<div
|
|
20
|
+
onClick={onToggleNavbar}
|
|
21
|
+
className={cx('duration-800 transition-opacity ease-out', {
|
|
22
|
+
'opacity-1 fixed left-0 top-0 h-full w-full bg-shader-neutral-light-72': isOpen,
|
|
23
|
+
'-translate-x-full opacity-0': !isOpen,
|
|
24
|
+
})}
|
|
25
|
+
/>
|
|
26
|
+
<div
|
|
27
|
+
className={cx(
|
|
28
|
+
'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',
|
|
29
|
+
{
|
|
30
|
+
'translate-x-0': isOpen,
|
|
31
|
+
'-translate-x-full': !isOpen,
|
|
32
|
+
},
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
<div className="flex flex-col gap-2">
|
|
36
|
+
<div className="[&_svg]:h-5 [&_svg]:w-5">
|
|
37
|
+
<Button
|
|
38
|
+
type={ButtonType.Ghost}
|
|
39
|
+
onClick={onToggleNavbar}
|
|
40
|
+
icon={<ArrowBack />}
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
{items.map((item) => (
|
|
44
|
+
<NavbarItem
|
|
45
|
+
key={item.id}
|
|
46
|
+
{...item}
|
|
47
|
+
type={NavbarItemType.Vertical}
|
|
48
|
+
isSelected={item.id === activeId}
|
|
49
|
+
onClick={() => {
|
|
50
|
+
onClickItem(item.id);
|
|
51
|
+
onToggleNavbar && onToggleNavbar();
|
|
52
|
+
}}
|
|
53
|
+
/>
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { PropsWithChildren, ReactNode } from 'react';
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import { TableProvider, useTableContext } from './TableContext';
|
|
7
|
+
import type { ButtonProps } from '@/components/atoms';
|
|
8
|
+
import { Button, ButtonSize, ButtonType, Checkbox } from '@/components/atoms';
|
|
9
|
+
import { TableCellBase, TableHeaderCell } from '@/components/molecules';
|
|
10
|
+
import { ArrowLeft, DoubleArrowLeft, ArrowRight, DoubleArrowRight } from '@iota/apps-ui-icons';
|
|
11
|
+
|
|
12
|
+
export interface TablePaginationOptions {
|
|
13
|
+
/**
|
|
14
|
+
* On Next page button click.
|
|
15
|
+
*/
|
|
16
|
+
onNext?: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* On Previous page button click.
|
|
19
|
+
*/
|
|
20
|
+
onPrev?: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* On First page button click.
|
|
23
|
+
*/
|
|
24
|
+
onFirst?: () => void;
|
|
25
|
+
/**
|
|
26
|
+
* On Last page button click.
|
|
27
|
+
*/
|
|
28
|
+
onLast?: () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Has Next button.
|
|
31
|
+
*/
|
|
32
|
+
hasNext?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Has Previous button.
|
|
35
|
+
*/
|
|
36
|
+
hasPrev?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Has First button.
|
|
39
|
+
*/
|
|
40
|
+
hasFirst?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Has Last button.
|
|
43
|
+
*/
|
|
44
|
+
hasLast?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type TableProps = {
|
|
48
|
+
/**
|
|
49
|
+
* Options for the table pagination.
|
|
50
|
+
*/
|
|
51
|
+
paginationOptions?: TablePaginationOptions;
|
|
52
|
+
/**
|
|
53
|
+
* The action component.
|
|
54
|
+
*/
|
|
55
|
+
action?: ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* The supporting label of the table.
|
|
58
|
+
*/
|
|
59
|
+
supportingLabel?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Numeric indexes of the selected rows.
|
|
62
|
+
*/
|
|
63
|
+
selectedRowIndexes?: Set<number>;
|
|
64
|
+
/**
|
|
65
|
+
* Numeric indexes of all the rows.
|
|
66
|
+
*/
|
|
67
|
+
rowIndexes: number[];
|
|
68
|
+
/**
|
|
69
|
+
* The page size selector component.
|
|
70
|
+
*/
|
|
71
|
+
pageSizeSelector?: ReactNode;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* If the table should take the full height of the parent.
|
|
75
|
+
*/
|
|
76
|
+
heightFull?: boolean;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export function Table({
|
|
80
|
+
paginationOptions,
|
|
81
|
+
action,
|
|
82
|
+
supportingLabel,
|
|
83
|
+
selectedRowIndexes = new Set(),
|
|
84
|
+
rowIndexes,
|
|
85
|
+
children,
|
|
86
|
+
pageSizeSelector,
|
|
87
|
+
heightFull = false,
|
|
88
|
+
}: PropsWithChildren<TableProps>): JSX.Element {
|
|
89
|
+
return (
|
|
90
|
+
<TableProvider selectedRowIndexes={selectedRowIndexes} rowIndexes={rowIndexes}>
|
|
91
|
+
<div className={cx('w-full', { 'h-full': heightFull })}>
|
|
92
|
+
<div
|
|
93
|
+
className={cx('overflow-auto', {
|
|
94
|
+
'h-full': heightFull,
|
|
95
|
+
})}
|
|
96
|
+
>
|
|
97
|
+
<table
|
|
98
|
+
className={cx('w-full table-auto', {
|
|
99
|
+
'h-full': heightFull,
|
|
100
|
+
})}
|
|
101
|
+
>
|
|
102
|
+
{children}
|
|
103
|
+
</table>
|
|
104
|
+
</div>
|
|
105
|
+
<div
|
|
106
|
+
className={cx('flex w-full items-center gap-sm pt-md', {
|
|
107
|
+
hidden: !supportingLabel && !paginationOptions && !action,
|
|
108
|
+
'flex-col justify-between sm:flex-row': paginationOptions,
|
|
109
|
+
'justify-end': !paginationOptions && action,
|
|
110
|
+
})}
|
|
111
|
+
>
|
|
112
|
+
{(paginationOptions || action) && (
|
|
113
|
+
<div className="flex gap-2">
|
|
114
|
+
{paginationOptions && (
|
|
115
|
+
<>
|
|
116
|
+
<Button
|
|
117
|
+
type={ButtonType.Secondary}
|
|
118
|
+
size={ButtonSize.Small}
|
|
119
|
+
icon={<DoubleArrowLeft />}
|
|
120
|
+
disabled={!paginationOptions.hasFirst}
|
|
121
|
+
onClick={paginationOptions.onFirst}
|
|
122
|
+
/>
|
|
123
|
+
<Button
|
|
124
|
+
type={ButtonType.Secondary}
|
|
125
|
+
size={ButtonSize.Small}
|
|
126
|
+
icon={<ArrowLeft />}
|
|
127
|
+
disabled={!paginationOptions.hasPrev}
|
|
128
|
+
onClick={paginationOptions.onPrev}
|
|
129
|
+
/>
|
|
130
|
+
<Button
|
|
131
|
+
type={ButtonType.Secondary}
|
|
132
|
+
size={ButtonSize.Small}
|
|
133
|
+
icon={<ArrowRight />}
|
|
134
|
+
disabled={!paginationOptions.hasNext}
|
|
135
|
+
onClick={paginationOptions.onNext}
|
|
136
|
+
/>
|
|
137
|
+
<Button
|
|
138
|
+
type={ButtonType.Secondary}
|
|
139
|
+
size={ButtonSize.Small}
|
|
140
|
+
icon={<DoubleArrowRight />}
|
|
141
|
+
disabled={!paginationOptions.hasLast}
|
|
142
|
+
onClick={paginationOptions.onLast}
|
|
143
|
+
/>
|
|
144
|
+
</>
|
|
145
|
+
)}
|
|
146
|
+
{action && action}
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
{supportingLabel || pageSizeSelector ? (
|
|
150
|
+
<div className="flex flex-row items-center gap-x-sm">
|
|
151
|
+
{supportingLabel && (
|
|
152
|
+
<span className=" text-label-md text-neutral-40 dark:text-neutral-60">
|
|
153
|
+
{supportingLabel}
|
|
154
|
+
</span>
|
|
155
|
+
)}
|
|
156
|
+
{pageSizeSelector && <div className="ml-2">{pageSizeSelector}</div>}
|
|
157
|
+
</div>
|
|
158
|
+
) : null}
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</TableProvider>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function TableActionButton(props: PropsWithChildren<ButtonProps>) {
|
|
166
|
+
return <Button type={ButtonType.Secondary} size={ButtonSize.Small} {...props} />;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function TableHeader({ children }: PropsWithChildren): JSX.Element {
|
|
170
|
+
return <thead>{children}</thead>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function TableRow({
|
|
174
|
+
children,
|
|
175
|
+
leading,
|
|
176
|
+
}: PropsWithChildren<{ leading?: React.ReactNode }>): JSX.Element {
|
|
177
|
+
return (
|
|
178
|
+
<tr>
|
|
179
|
+
{leading}
|
|
180
|
+
{children}
|
|
181
|
+
</tr>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const TEXT_COLOR_CLASS = 'text-neutral-40 dark:text-neutral-60';
|
|
186
|
+
const TEXT_SIZE_CLASS = 'text-body-md';
|
|
187
|
+
|
|
188
|
+
export function TableBody({ children }: PropsWithChildren): JSX.Element {
|
|
189
|
+
return <tbody className={cx(TEXT_COLOR_CLASS, TEXT_SIZE_CLASS)}>{children}</tbody>;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface TableRowCheckboxProps {
|
|
193
|
+
rowIndex: number;
|
|
194
|
+
onCheckboxChange: (checked: boolean) => void;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function TableRowCheckbox({
|
|
198
|
+
rowIndex,
|
|
199
|
+
onCheckboxChange,
|
|
200
|
+
}: TableRowCheckboxProps): React.JSX.Element {
|
|
201
|
+
const { selectedRowIndexes } = useTableContext();
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<TableCellBase isContentCentered>
|
|
205
|
+
<Checkbox
|
|
206
|
+
onCheckedChange={(event) => {
|
|
207
|
+
onCheckboxChange(event.target.checked);
|
|
208
|
+
}}
|
|
209
|
+
isChecked={selectedRowIndexes.has(rowIndex)}
|
|
210
|
+
/>
|
|
211
|
+
</TableCellBase>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface TableHeaderCheckboxProps {
|
|
216
|
+
onCheckboxChange: (checked: boolean) => void;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function TableHeaderCheckbox({ onCheckboxChange }: TableHeaderCheckboxProps): JSX.Element {
|
|
220
|
+
const { isHeaderChecked, isHeaderIndeterminate } = useTableContext();
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<TableHeaderCell
|
|
224
|
+
isContentCentered
|
|
225
|
+
hasCheckbox
|
|
226
|
+
onCheckboxChange={(event) => {
|
|
227
|
+
onCheckboxChange(event.target.checked);
|
|
228
|
+
}}
|
|
229
|
+
isChecked={isHeaderChecked}
|
|
230
|
+
columnKey={1}
|
|
231
|
+
isIndeterminate={isHeaderIndeterminate}
|
|
232
|
+
/>
|
|
233
|
+
);
|
|
234
|
+
}
|