@iota/apps-ui-kit 0.0.0-dev-20251015065834
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 +145 -0
- package/LICENSE +201 -0
- package/README.md +16 -0
- package/dist/index.d.ts +1911 -0
- package/dist/index.es.js +6486 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +66 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +80 -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 +110 -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 +24 -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 +124 -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/image/Image.tsx +32 -0
- package/src/lib/components/atoms/image/index.ts +4 -0
- package/src/lib/components/atoms/index.ts +26 -0
- package/src/lib/components/atoms/info-box/InfoBox.tsx +68 -0
- package/src/lib/components/atoms/info-box/index.ts +5 -0
- package/src/lib/components/atoms/info-box/infoBox.classes.ts +18 -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 +92 -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 +88 -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/media-fallback/MediaFallback.tsx +12 -0
- package/src/lib/components/atoms/media-fallback/index.ts +4 -0
- package/src/lib/components/atoms/panel/Panel.tsx +28 -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 +64 -0
- package/src/lib/components/atoms/radio-button/index.ts +4 -0
- package/src/lib/components/atoms/secondary-text/SecondaryText.tsx +29 -0
- package/src/lib/components/atoms/secondary-text/index.ts +4 -0
- package/src/lib/components/atoms/skeleton/Skeleton.tsx +30 -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 +139 -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/video/Video.tsx +33 -0
- package/src/lib/components/atoms/video/index.ts +4 -0
- package/src/lib/components/atoms/video/video.constants.ts +31 -0
- package/src/lib/components/index.ts +6 -0
- package/src/lib/components/molecules/account/Account.tsx +195 -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/asset-media-renderer/AssetMediaRenderer.tsx +50 -0
- package/src/lib/components/molecules/asset-media-renderer/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 +73 -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 +146 -0
- package/src/lib/components/molecules/chip/chip.classes.ts +54 -0
- package/src/lib/components/molecules/chip/chip.enums.ts +15 -0
- package/src/lib/components/molecules/chip/index.ts +5 -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 +19 -0
- package/src/lib/components/molecules/input/Input.tsx +261 -0
- package/src/lib/components/molecules/input/InputWrapper.tsx +97 -0
- package/src/lib/components/molecules/input/TextArea.tsx +148 -0
- package/src/lib/components/molecules/input/index.ts +8 -0
- package/src/lib/components/molecules/input/input.classes.ts +13 -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 +47 -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 +219 -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 +235 -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/molecules/visual-asset-card/VisualAssetCard.tsx +89 -0
- package/src/lib/components/molecules/visual-asset-card/index.ts +5 -0
- package/src/lib/components/molecules/visual-asset-card/visualAssetCard.enums.ts +7 -0
- package/src/lib/components/organisms/accordion/Accordion.tsx +108 -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 +157 -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 +239 -0
- package/src/lib/constants/index.ts +4 -0
- package/src/lib/enums/index.ts +5 -0
- package/src/lib/enums/screenSize.enums.ts +9 -0
- package/src/lib/enums/theme.enums.ts +8 -0
- package/src/lib/index.ts +10 -0
- package/src/lib/styles/base.css +144 -0
- package/src/lib/styles/components.css +735 -0
- package/src/lib/styles/fonts.css +7 -0
- package/src/lib/styles/index.css +18 -0
- package/src/lib/styles/utilities.css +61 -0
- package/src/lib/styles/variables/dark-variables.css +262 -0
- package/src/lib/styles/variables/general-variables.css +9 -0
- package/src/lib/styles/variables/light-variables.css +276 -0
- package/src/lib/styles/variables/names-variables.css +270 -0
- package/src/lib/tailwind/base.presets.ts +58 -0
- package/src/lib/tailwind/constants/customColors.constants.ts +13 -0
- package/src/lib/tailwind/constants/fontFamily.constants.ts +8 -0
- package/src/lib/tailwind/constants/fontSizes.constants.ts +201 -0
- package/src/lib/tailwind/constants/gradients.constants.ts +6 -0
- package/src/lib/tailwind/constants/index.ts +7 -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 +12 -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/gradients.constants.ts +8 -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/formatGradientNames.ts +15 -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 +59 -0
- package/src/storybook/stories/atoms/VisualAssetCard.stories.tsx +57 -0
- package/src/storybook/stories/components/DocsSyncTheme.tsx +20 -0
- package/src/storybook/stories/components/VariableSpacingShowcase.tsx +46 -0
- package/src/storybook/stories/components/index.ts +5 -0
- package/src/storybook/stories/design-tokens/colors.stories.mdx +44 -0
- package/src/storybook/stories/design-tokens/icons.stories.mdx +19 -0
- package/src/storybook/stories/design-tokens/typeset.stories.mdx +17 -0
- package/src/storybook/stories/design-tokens/variable-spacing.stories.mdx +11 -0
- package/src/storybook/stories/molecules/Account.stories.tsx +71 -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 +127 -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 +239 -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 +129 -0
- package/src/storybook/stories/organisms/Navbar.stories.tsx +78 -0
- package/src/storybook/stories/organisms/Table.stories.tsx +154 -0
|
@@ -0,0 +1,157 @@
|
|
|
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(
|
|
45
|
+
' dialog-overlay-bg absolute h-full w-full backdrop-blur-md names:backdrop-blur-lg',
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<DialogClose className={cx('fixed right-3 top-3', { hidden: !showCloseIcon })}>
|
|
50
|
+
<Close className="button-text-color-neutral" />
|
|
51
|
+
</DialogClose>
|
|
52
|
+
</RadixDialog.Overlay>
|
|
53
|
+
));
|
|
54
|
+
DialogOverlay.displayName = RadixDialog.Overlay.displayName;
|
|
55
|
+
|
|
56
|
+
const DialogContainer = React.forwardRef<
|
|
57
|
+
HTMLDivElement,
|
|
58
|
+
React.PropsWithChildren<{ isFixedPosition: boolean }>
|
|
59
|
+
>((props, ref) => (
|
|
60
|
+
<div
|
|
61
|
+
className={cx('inset-0 z-[99999]', props.isFixedPosition ? 'fixed' : 'absolute')}
|
|
62
|
+
ref={ref}
|
|
63
|
+
>
|
|
64
|
+
<div className="relative h-full w-full">{props.children}</div>
|
|
65
|
+
</div>
|
|
66
|
+
));
|
|
67
|
+
|
|
68
|
+
const DialogContent = React.forwardRef<
|
|
69
|
+
React.ElementRef<typeof RadixDialog.Content>,
|
|
70
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Content> & {
|
|
71
|
+
containerId?: string;
|
|
72
|
+
showCloseOnOverlay?: boolean;
|
|
73
|
+
position?: DialogPosition;
|
|
74
|
+
customWidth?: string;
|
|
75
|
+
isFixedPosition?: boolean;
|
|
76
|
+
}
|
|
77
|
+
>(
|
|
78
|
+
(
|
|
79
|
+
{
|
|
80
|
+
className,
|
|
81
|
+
containerId,
|
|
82
|
+
showCloseOnOverlay,
|
|
83
|
+
children,
|
|
84
|
+
position = DialogPosition.Center,
|
|
85
|
+
customWidth = 'w-80 max-w-[85vw] md:w-96',
|
|
86
|
+
isFixedPosition = position === DialogPosition.Right,
|
|
87
|
+
...props
|
|
88
|
+
},
|
|
89
|
+
ref,
|
|
90
|
+
) => {
|
|
91
|
+
const [containerElement, setContainerElement] = useState<HTMLElement | undefined>(
|
|
92
|
+
undefined,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
// This ensures document.getElementById is called in the client-side environment only.
|
|
97
|
+
// note. containerElement cant be null
|
|
98
|
+
const element = containerId ? document.getElementById(containerId) : undefined;
|
|
99
|
+
setContainerElement(element ?? undefined);
|
|
100
|
+
}, [containerId]);
|
|
101
|
+
const dialogPositioning =
|
|
102
|
+
position === DialogPosition.Right
|
|
103
|
+
? 'overflow-hidden right-0 h-screen top-0 w-full'
|
|
104
|
+
: 'overflow-y-auto overflow-x-hidden left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-xl';
|
|
105
|
+
const widthClass =
|
|
106
|
+
position === DialogPosition.Right ? 'md:w-96 max-w-[500px]' : customWidth;
|
|
107
|
+
const heightClass = position === DialogPosition.Right ? 'h-screen' : 'max-h-[80vh] h-full';
|
|
108
|
+
return (
|
|
109
|
+
<RadixDialog.Portal container={containerElement}>
|
|
110
|
+
<DialogContainer isFixedPosition={isFixedPosition}>
|
|
111
|
+
<DialogOverlay showCloseIcon={showCloseOnOverlay} position={position} />
|
|
112
|
+
<RadixDialog.Content
|
|
113
|
+
ref={ref}
|
|
114
|
+
className={cx(
|
|
115
|
+
'dialog-content-bg dialog-outline absolute flex flex-col justify-center',
|
|
116
|
+
dialogPositioning,
|
|
117
|
+
widthClass,
|
|
118
|
+
)}
|
|
119
|
+
{...props}
|
|
120
|
+
>
|
|
121
|
+
<VisuallyHidden.Root>
|
|
122
|
+
<RadixDialog.Title />
|
|
123
|
+
<RadixDialog.Description />
|
|
124
|
+
</VisuallyHidden.Root>
|
|
125
|
+
<div className={cx('flex flex-1 flex-col', heightClass)}>{children}</div>
|
|
126
|
+
</RadixDialog.Content>
|
|
127
|
+
</DialogContainer>
|
|
128
|
+
</RadixDialog.Portal>
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
DialogContent.displayName = RadixDialog.Content.displayName;
|
|
133
|
+
|
|
134
|
+
const DialogTitle = React.forwardRef<
|
|
135
|
+
React.ElementRef<typeof RadixDialog.Title>,
|
|
136
|
+
React.ComponentPropsWithoutRef<typeof RadixDialog.Title>
|
|
137
|
+
>((props, ref) => (
|
|
138
|
+
<RadixDialog.Title
|
|
139
|
+
ref={ref}
|
|
140
|
+
className="dialog-title-color font-inter text-title-lg"
|
|
141
|
+
{...props}
|
|
142
|
+
/>
|
|
143
|
+
));
|
|
144
|
+
DialogTitle.displayName = RadixDialog.Title.displayName;
|
|
145
|
+
|
|
146
|
+
const DialogBody = React.forwardRef<React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'>>(
|
|
147
|
+
(props, ref) => (
|
|
148
|
+
<div
|
|
149
|
+
ref={ref}
|
|
150
|
+
className="dialog-body-color flex-1 overflow-y-auto p-md--rs text-body-sm"
|
|
151
|
+
{...props}
|
|
152
|
+
/>
|
|
153
|
+
),
|
|
154
|
+
);
|
|
155
|
+
DialogBody.displayName = 'DialogBody';
|
|
156
|
+
|
|
157
|
+
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="navbar-icon-color" />
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
className="state-layer navbar-icon-color relative rounded-full p-xs hover:cursor-pointer 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 navbar-slideout-bg fixed left-0 top-0 h-full w-11/12 rounded-tr-3xl px-lg py-lg transition-transform duration-300 ease-out',
|
|
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="table-text-color text-label-md">
|
|
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 = 'table-text-color';
|
|
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
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Copyright (c) 2024 IOTA Stiftung
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { PropsWithChildren } from 'react';
|
|
5
|
+
import { createContext, useContext } from 'react';
|
|
6
|
+
|
|
7
|
+
export interface TableProviderProps {
|
|
8
|
+
/**
|
|
9
|
+
* Numeric indexes of the selected rows.
|
|
10
|
+
*/
|
|
11
|
+
selectedRowIndexes: Set<number>;
|
|
12
|
+
/**
|
|
13
|
+
* Numeric indexes of all the rows.
|
|
14
|
+
*/
|
|
15
|
+
rowIndexes: number[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type TableContextProps = {
|
|
19
|
+
isHeaderChecked: boolean;
|
|
20
|
+
selectedRowIndexes: Set<number>;
|
|
21
|
+
isHeaderIndeterminate: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const TableContext = createContext<TableContextProps>({
|
|
25
|
+
isHeaderChecked: false,
|
|
26
|
+
selectedRowIndexes: new Set(),
|
|
27
|
+
isHeaderIndeterminate: false,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const useTableContext = () => {
|
|
31
|
+
const context = useContext(TableContext);
|
|
32
|
+
return context;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function TableProvider({
|
|
36
|
+
children,
|
|
37
|
+
selectedRowIndexes,
|
|
38
|
+
rowIndexes,
|
|
39
|
+
...props
|
|
40
|
+
}: PropsWithChildren<TableProviderProps>) {
|
|
41
|
+
const isHeaderChecked = rowIndexes.length === selectedRowIndexes.size;
|
|
42
|
+
const isHeaderIndeterminate = !isHeaderChecked && selectedRowIndexes.size > 0;
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<TableContext.Provider
|
|
46
|
+
value={{
|
|
47
|
+
...props,
|
|
48
|
+
isHeaderChecked,
|
|
49
|
+
selectedRowIndexes,
|
|
50
|
+
isHeaderIndeterminate,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</TableContext.Provider>
|
|
55
|
+
);
|
|
56
|
+
}
|