adnbn-ui 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +3 -0
- package/.prettierrc +28 -0
- package/.storybook/main.ts +22 -0
- package/.storybook/preview.tsx +100 -0
- package/.storybook/styles/custom.scss +59 -0
- package/.storybook/styles/preview.css +58 -0
- package/.storybook/vitest.setup.ts +9 -0
- package/eslint.config.js +39 -0
- package/package.json +77 -2
- package/src/components/Avatar/Avatar.stories.tsx +118 -0
- package/src/components/Avatar/Avatar.tsx +65 -0
- package/src/components/Avatar/avatar.module.scss +77 -0
- package/src/components/Avatar/index.ts +2 -0
- package/src/components/BaseButton/BaseButton.tsx +36 -0
- package/src/components/BaseButton/base-button.module.scss +24 -0
- package/src/components/BaseButton/index.ts +2 -0
- package/src/components/Button/Button.stories.tsx +148 -0
- package/src/components/Button/Button.tsx +73 -0
- package/src/components/Button/button.module.scss +140 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +180 -0
- package/src/components/Checkbox/Checkbox.tsx +71 -0
- package/src/components/Checkbox/checkbox.module.scss +82 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/Dialog/Dialog.tsx +125 -0
- package/src/components/Dialog/dialog.module.scss +55 -0
- package/src/components/Dialog/index.ts +2 -0
- package/src/components/Drawer/Drawer.stories.tsx +89 -0
- package/src/components/Drawer/Drawer.tsx +57 -0
- package/src/components/Drawer/drawer.module.scss +170 -0
- package/src/components/Drawer/index.ts +2 -0
- package/src/components/Footer/Footer.stories.tsx +118 -0
- package/src/components/Footer/Footer.tsx +58 -0
- package/src/components/Footer/footer.module.scss +44 -0
- package/src/components/Footer/index.ts +2 -0
- package/src/components/Header/Header.stories.tsx +49 -0
- package/src/components/Header/Header.tsx +73 -0
- package/src/components/Header/header.module.scss +56 -0
- package/src/components/Header/index.ts +2 -0
- package/src/components/Highlight/Highlight.stories.tsx +83 -0
- package/src/components/Highlight/Highlight.tsx +40 -0
- package/src/components/Highlight/highlight.module.scss +47 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/Icon/Icon.tsx +46 -0
- package/src/components/Icon/icon.module.scss +17 -0
- package/src/components/Icon/index.ts +2 -0
- package/src/components/IconButton/IconButton.stories.tsx +179 -0
- package/src/components/IconButton/IconButton.tsx +65 -0
- package/src/components/IconButton/icon-button.module.scss +86 -0
- package/src/components/IconButton/index.ts +2 -0
- package/src/components/Layout/Layout.stories.tsx +88 -0
- package/src/components/Layout/Provider.tsx +47 -0
- package/src/components/Layout/context.ts +24 -0
- package/src/components/Layout/index.ts +2 -0
- package/src/components/Layout/layout.module.scss +17 -0
- package/src/components/List/List.stories.tsx +81 -0
- package/src/components/List/List.tsx +24 -0
- package/src/components/List/index.ts +2 -0
- package/src/components/List/list.module.scss +8 -0
- package/src/components/ListItem/ListItem.tsx +75 -0
- package/src/components/ListItem/index.ts +2 -0
- package/src/components/ListItem/list-item.module.scss +36 -0
- package/src/components/Modal/Modal.stories.tsx +95 -0
- package/src/components/Modal/Modal.tsx +94 -0
- package/src/components/Modal/index.ts +2 -0
- package/src/components/Modal/modal.module.scss +97 -0
- package/src/components/Odometer/Odometer.stories.tsx +66 -0
- package/src/components/Odometer/Odometer.tsx +45 -0
- package/src/components/Odometer/hooks/useOdometer.tsx +24 -0
- package/src/components/Odometer/index.ts +3 -0
- package/src/components/Odometer/odometer.module.scss +81 -0
- package/src/components/Odometer/odometr.d.ts +9 -0
- package/src/components/ScrollArea/ScrollArea.stories.tsx +58 -0
- package/src/components/ScrollArea/ScrollArea.tsx +63 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/ScrollArea/scroll-area.module.scss +54 -0
- package/src/components/SvgSprite/SvgSprite.tsx +21 -0
- package/src/components/SvgSprite/index.ts +2 -0
- package/src/components/Switch/Switch.stories.tsx +25 -0
- package/src/components/Switch/Switch.tsx +23 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Switch/switch.module.scss +65 -0
- package/src/components/Tag/Tag.stories.tsx +157 -0
- package/src/components/Tag/Tag.tsx +71 -0
- package/src/components/Tag/index.ts +2 -0
- package/src/components/Tag/tag.module.scss +118 -0
- package/src/components/TextArea/TextArea.stories.tsx +145 -0
- package/src/components/TextArea/TextArea.tsx +143 -0
- package/src/components/TextArea/index.ts +2 -0
- package/src/components/TextArea/text-area.module.scss +88 -0
- package/src/components/TextField/TextField.stories.tsx +177 -0
- package/src/components/TextField/TextField.tsx +162 -0
- package/src/components/TextField/index.ts +2 -0
- package/src/components/TextField/text-field.module.scss +129 -0
- package/src/components/Toast/Toast.stories.tsx +209 -0
- package/src/components/Toast/Toast.tsx +142 -0
- package/src/components/Toast/index.ts +2 -0
- package/src/components/Toast/toast.module.scss +267 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +80 -0
- package/src/components/Tooltip/Tooltip.tsx +79 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/Tooltip/tooltip.module.scss +93 -0
- package/src/components/View/View.stories.tsx +47 -0
- package/src/components/View/View.tsx +68 -0
- package/src/components/View/index.ts +2 -0
- package/src/components/View/view.module.scss +38 -0
- package/src/components/ViewDrawer/ViewDrawer.stories.tsx +75 -0
- package/src/components/ViewDrawer/ViewDrawer.tsx +24 -0
- package/src/components/ViewDrawer/index.ts +2 -0
- package/src/components/ViewModal/ViewModal.stories.tsx +68 -0
- package/src/components/ViewModal/ViewModal.tsx +24 -0
- package/src/components/ViewModal/index.ts +2 -0
- package/src/components/index.ts +29 -0
- package/src/components/types.ts +65 -0
- package/src/config/default.ts +3 -0
- package/src/config/index.ts +26 -0
- package/src/declaration.d.ts +8 -0
- package/src/index.ts +3 -0
- package/src/plugin/builder/ConfigBuilder.ts +32 -0
- package/src/plugin/builder/StyleBuilder.ts +34 -0
- package/src/plugin/builder/virtual.config.ts +7 -0
- package/src/plugin/finder/ConfigFinder.ts +26 -0
- package/src/plugin/finder/Finder.ts +76 -0
- package/src/plugin/finder/StyleFinder.ts +23 -0
- package/src/plugin/index.ts +70 -0
- package/src/plugin/types.ts +8 -0
- package/src/providers/UIProvider.tsx +26 -0
- package/src/providers/icons/IconsProvider.tsx +34 -0
- package/src/providers/icons/context.ts +22 -0
- package/src/providers/icons/index.ts +3 -0
- package/src/providers/index.ts +3 -0
- package/src/providers/theme/ThemeProvider.tsx +39 -0
- package/src/providers/theme/context.ts +30 -0
- package/src/providers/theme/index.ts +2 -0
- package/src/providers/theme/styles/default.scss +95 -0
- package/src/providers/theme/styles/reset.css +111 -0
- package/src/styles/mixins.scss +23 -0
- package/src/types/theme.ts +4 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/react.ts +21 -0
- package/src/utils/utils.ts +12 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +11 -0
- package/vitest.workspace.ts +19 -0
- package/components/Button/index.ts +0 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
import {useState} from "react";
|
2
|
+
import {Meta} from "@storybook/react";
|
3
|
+
|
4
|
+
import {hideInTable} from "../../utils";
|
5
|
+
|
6
|
+
import {Button, DrawerSide} from "../index";
|
7
|
+
|
8
|
+
import ViewDrawerComponent, {ViewDrawerProps} from "./ViewDrawer";
|
9
|
+
|
10
|
+
const sides: DrawerSide[] = [DrawerSide.Left, DrawerSide.Top, DrawerSide.Bottom, DrawerSide.Right];
|
11
|
+
|
12
|
+
const meta: Meta<typeof ViewDrawerComponent> = {
|
13
|
+
title: "Components/ViewDrawer",
|
14
|
+
component: ViewDrawerComponent,
|
15
|
+
tags: ["autodocs"],
|
16
|
+
argTypes: {
|
17
|
+
side: {
|
18
|
+
options: sides,
|
19
|
+
control: {type: "select"},
|
20
|
+
},
|
21
|
+
title: {
|
22
|
+
type: "string",
|
23
|
+
},
|
24
|
+
subtitle: {
|
25
|
+
type: "string",
|
26
|
+
},
|
27
|
+
after: {
|
28
|
+
type: "string",
|
29
|
+
},
|
30
|
+
before: {
|
31
|
+
type: "string",
|
32
|
+
},
|
33
|
+
fullscreen: {
|
34
|
+
type: "boolean",
|
35
|
+
},
|
36
|
+
speed: {
|
37
|
+
type: "number",
|
38
|
+
},
|
39
|
+
children: hideInTable,
|
40
|
+
className: hideInTable,
|
41
|
+
wrapClassName: hideInTable,
|
42
|
+
titleClassName: hideInTable,
|
43
|
+
bodyClassName: hideInTable,
|
44
|
+
headerClassName: hideInTable,
|
45
|
+
beforeClassName: hideInTable,
|
46
|
+
afterClassName: hideInTable,
|
47
|
+
subtitleClassName: hideInTable,
|
48
|
+
childrenClassName: hideInTable,
|
49
|
+
},
|
50
|
+
};
|
51
|
+
|
52
|
+
export default meta;
|
53
|
+
|
54
|
+
export const ViewDrawer = (props: ViewDrawerProps) => {
|
55
|
+
const [open, setOpen] = useState(false);
|
56
|
+
return (
|
57
|
+
<div>
|
58
|
+
<Button onClick={() => setOpen(true)}>Open</Button>
|
59
|
+
<ViewDrawerComponent
|
60
|
+
open={open}
|
61
|
+
onOpenChange={setOpen}
|
62
|
+
title="Volume Up Plus"
|
63
|
+
side={DrawerSide.Right}
|
64
|
+
fullscreen={false}
|
65
|
+
subtitle="Adjust the current tab's volume with the slider. Switch to any audio tab in one click."
|
66
|
+
after="❤️"
|
67
|
+
{...props}
|
68
|
+
>
|
69
|
+
<Button style={{margin: "50px auto", maxWidth: "max-content"}} onClick={() => setOpen(false)}>
|
70
|
+
Close ViewDrawer
|
71
|
+
</Button>
|
72
|
+
</ViewDrawerComponent>
|
73
|
+
</div>
|
74
|
+
);
|
75
|
+
};
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import React, {FC, memo} from "react";
|
2
|
+
|
3
|
+
import {splitProps} from "../../utils";
|
4
|
+
import {useComponentProps} from "../../providers";
|
5
|
+
|
6
|
+
import {Drawer, DrawerProps, drawerPropsKeys} from "../Drawer";
|
7
|
+
import {View, ViewProps, viewPropsKeys} from "../View";
|
8
|
+
|
9
|
+
export type ViewDrawerProps = Omit<DrawerProps, "title"> & ViewProps;
|
10
|
+
|
11
|
+
const ViewDrawer: FC<ViewDrawerProps> = props => {
|
12
|
+
const mergedProps = {...useComponentProps("viewDrawer"), ...props};
|
13
|
+
|
14
|
+
const drawerProps = splitProps<DrawerProps>(mergedProps, drawerPropsKeys);
|
15
|
+
const viewProps = splitProps<ViewProps>(mergedProps, viewPropsKeys);
|
16
|
+
|
17
|
+
return (
|
18
|
+
<Drawer {...drawerProps}>
|
19
|
+
<View {...viewProps} />
|
20
|
+
</Drawer>
|
21
|
+
);
|
22
|
+
};
|
23
|
+
|
24
|
+
export default memo(ViewDrawer);
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import {useState} from "react";
|
2
|
+
import {Meta} from "@storybook/react";
|
3
|
+
|
4
|
+
import {hideInTable} from "../../utils";
|
5
|
+
|
6
|
+
import {Button} from "../index";
|
7
|
+
|
8
|
+
import ViewModalComponent, {ViewModalProps} from "./ViewModal";
|
9
|
+
|
10
|
+
const meta: Meta<typeof ViewModalComponent> = {
|
11
|
+
title: "Components/ViewModal",
|
12
|
+
component: ViewModalComponent,
|
13
|
+
tags: ["autodocs"],
|
14
|
+
argTypes: {
|
15
|
+
title: {
|
16
|
+
type: "string",
|
17
|
+
},
|
18
|
+
subtitle: {
|
19
|
+
type: "string",
|
20
|
+
},
|
21
|
+
after: {
|
22
|
+
type: "string",
|
23
|
+
},
|
24
|
+
before: {
|
25
|
+
type: "string",
|
26
|
+
},
|
27
|
+
fullscreen: {
|
28
|
+
type: "boolean",
|
29
|
+
},
|
30
|
+
speed: {
|
31
|
+
type: "number",
|
32
|
+
},
|
33
|
+
children: hideInTable,
|
34
|
+
className: hideInTable,
|
35
|
+
wrapClassName: hideInTable,
|
36
|
+
titleClassName: hideInTable,
|
37
|
+
bodyClassName: hideInTable,
|
38
|
+
headerClassName: hideInTable,
|
39
|
+
beforeClassName: hideInTable,
|
40
|
+
afterClassName: hideInTable,
|
41
|
+
subtitleClassName: hideInTable,
|
42
|
+
childrenClassName: hideInTable,
|
43
|
+
},
|
44
|
+
};
|
45
|
+
|
46
|
+
export default meta;
|
47
|
+
|
48
|
+
export const ViewModal = (props: ViewModalProps) => {
|
49
|
+
const [open, setOpen] = useState(false);
|
50
|
+
return (
|
51
|
+
<div>
|
52
|
+
<Button onClick={() => setOpen(true)}>Open</Button>
|
53
|
+
<ViewModalComponent
|
54
|
+
open={open}
|
55
|
+
onOpenChange={setOpen}
|
56
|
+
title="Volume Up Plus"
|
57
|
+
fullscreen={false}
|
58
|
+
subtitle="Adjust the current tab's volume with the slider. Switch to any audio tab in one click."
|
59
|
+
after="❤️"
|
60
|
+
{...props}
|
61
|
+
>
|
62
|
+
<Button style={{margin: "50px auto", maxWidth: "max-content"}} onClick={() => setOpen(false)}>
|
63
|
+
Close ViewModal
|
64
|
+
</Button>
|
65
|
+
</ViewModalComponent>
|
66
|
+
</div>
|
67
|
+
);
|
68
|
+
};
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import React, {FC, memo} from "react";
|
2
|
+
|
3
|
+
import {splitProps} from "../../utils";
|
4
|
+
import {useComponentProps} from "../../providers";
|
5
|
+
|
6
|
+
import {Modal, ModalProps, modalPropsKeys} from "../Modal";
|
7
|
+
import {View, ViewProps, viewPropsKeys} from "../View";
|
8
|
+
|
9
|
+
export type ViewModalProps = Omit<ModalProps, "title"> & ViewProps;
|
10
|
+
|
11
|
+
const ViewModal: FC<ViewModalProps> = props => {
|
12
|
+
const mergedProps = {...useComponentProps("viewModal"), ...props};
|
13
|
+
|
14
|
+
const modalProps = splitProps<ModalProps>(mergedProps, modalPropsKeys);
|
15
|
+
const viewProps = splitProps<ViewProps>(mergedProps, viewPropsKeys);
|
16
|
+
|
17
|
+
return (
|
18
|
+
<Modal {...modalProps}>
|
19
|
+
<View {...viewProps} />
|
20
|
+
</Modal>
|
21
|
+
);
|
22
|
+
};
|
23
|
+
|
24
|
+
export default memo(ViewModal);
|
@@ -0,0 +1,29 @@
|
|
1
|
+
export * from "./Avatar";
|
2
|
+
export * from "./BaseButton";
|
3
|
+
export * from "./Button";
|
4
|
+
export * from "./Checkbox";
|
5
|
+
export * from "./Dialog";
|
6
|
+
export * from "./Drawer";
|
7
|
+
export * from "./Footer";
|
8
|
+
export * from "./Header";
|
9
|
+
export * from "./Highlight";
|
10
|
+
export * from "./Icon";
|
11
|
+
export * from "./IconButton";
|
12
|
+
export * from "./Layout";
|
13
|
+
export * from "./List";
|
14
|
+
export * from "./ListItem";
|
15
|
+
export * from "./Modal";
|
16
|
+
export * from "./Odometer";
|
17
|
+
export * from "./ScrollArea";
|
18
|
+
export * from "./SvgSprite";
|
19
|
+
export * from "./Switch";
|
20
|
+
export * from "./Tag";
|
21
|
+
export * from "./TextArea";
|
22
|
+
export * from "./TextField";
|
23
|
+
export * from "./Toast";
|
24
|
+
export * from "./Tooltip";
|
25
|
+
export * from "./View";
|
26
|
+
export * from "./ViewDrawer";
|
27
|
+
export * from "./ViewModal";
|
28
|
+
|
29
|
+
export type {ComponentsProps} from "./types";
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import type {
|
2
|
+
AvatarProps,
|
3
|
+
ButtonProps,
|
4
|
+
CheckboxProps,
|
5
|
+
DialogProps,
|
6
|
+
DrawerProps,
|
7
|
+
FooterProps,
|
8
|
+
HeaderProps,
|
9
|
+
HighlightProps,
|
10
|
+
IconProps,
|
11
|
+
IconButtonProps,
|
12
|
+
ListProps,
|
13
|
+
ListItemProps,
|
14
|
+
ModalProps,
|
15
|
+
OdometerProps,
|
16
|
+
ScrollAreaProps,
|
17
|
+
SwitchProps,
|
18
|
+
TagProps,
|
19
|
+
TextAreaProps,
|
20
|
+
TextFieldProps,
|
21
|
+
ToastProps,
|
22
|
+
TooltipProps,
|
23
|
+
ViewProps,
|
24
|
+
ViewDrawerProps,
|
25
|
+
ViewModalProps,
|
26
|
+
} from "../components";
|
27
|
+
|
28
|
+
export interface ComponentsProps {
|
29
|
+
avatar?: Pick<AvatarProps, "size" | "radius" | "cursorPointer" | "delayMs">;
|
30
|
+
button?: Pick<ButtonProps, "variant" | "color" | "size" | "radius">;
|
31
|
+
checkbox?: Pick<CheckboxProps, "variant" | "size" | "radius" | "checkedIcon" | "indeterminateIcon">;
|
32
|
+
dialog?: DialogProps;
|
33
|
+
drawer?: DrawerProps;
|
34
|
+
footer?: FooterProps;
|
35
|
+
header?: Pick<HeaderProps, "alignCenter" | "before" | "after">;
|
36
|
+
highlight?: HighlightProps;
|
37
|
+
icon?: Omit<IconProps, "name">;
|
38
|
+
iconButton?: Pick<IconButtonProps, "variant" | "size" | "radius">;
|
39
|
+
list?: ListProps;
|
40
|
+
listItem?: ListItemProps;
|
41
|
+
modal?: ModalProps;
|
42
|
+
odometer?: Pick<OdometerProps, "auto" | "format" | "duration">;
|
43
|
+
scrollArea?: ScrollAreaProps;
|
44
|
+
switch?: SwitchProps;
|
45
|
+
tag?: Pick<TagProps, "variant" | "size" | "color" | "radius" | "clickable">;
|
46
|
+
textArea?: TextAreaProps;
|
47
|
+
textField?: TextFieldProps;
|
48
|
+
toast?: Pick<
|
49
|
+
ToastProps,
|
50
|
+
| "side"
|
51
|
+
| "duration"
|
52
|
+
| "swipeDirection"
|
53
|
+
| "swipeThreshold"
|
54
|
+
| "closeProps"
|
55
|
+
| "closeIcon"
|
56
|
+
| "fullWidth"
|
57
|
+
| "sticky"
|
58
|
+
| "radius"
|
59
|
+
| "color"
|
60
|
+
>;
|
61
|
+
tooltip?: Pick<TooltipProps, "side" | "align" | "delayDuration" | "arrowHeight" | "arrowWidth">;
|
62
|
+
view?: ViewProps;
|
63
|
+
viewDrawer?: ViewDrawerProps;
|
64
|
+
viewModal?: ViewModalProps;
|
65
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import type {ComponentsProps} from "../components";
|
2
|
+
import type {Icons} from "../providers";
|
3
|
+
|
4
|
+
export {AvatarSize, AvatarRadius} from "../components/Avatar";
|
5
|
+
export {ButtonColor, ButtonSize, ButtonRadius, ButtonVariant} from "../components/Button";
|
6
|
+
export {CheckboxVariant, CheckboxRadius, CheckboxSize} from "../components/Checkbox";
|
7
|
+
export {DrawerSide} from "../components/Drawer";
|
8
|
+
export {HighlightColor} from "../components/Highlight";
|
9
|
+
export {IconButtonSize, IconButtonVariant, IconButtonRadius} from "../components/IconButton";
|
10
|
+
export {ModalRadius} from "../components/Modal";
|
11
|
+
export {TagVariant, TagColor, TagRadius, TagSize} from "../components/Tag";
|
12
|
+
export {TextAreaSize, TextAreaVariant} from "../components/TextArea";
|
13
|
+
export {TextFieldAccent, TextFieldSize, TextFieldVariant} from "../components/TextField";
|
14
|
+
export {ToastColor, ToastRadius, ToastSide} from "../components/Toast";
|
15
|
+
|
16
|
+
export type {ComponentsProps} from "../components";
|
17
|
+
|
18
|
+
export interface Config {
|
19
|
+
props: ComponentsProps;
|
20
|
+
icons: Icons;
|
21
|
+
}
|
22
|
+
|
23
|
+
export const defineConfig = (config: Partial<Config>): Config => {
|
24
|
+
const {props = {}, icons = {}} = config;
|
25
|
+
return {props, icons};
|
26
|
+
};
|
package/src/index.ts
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import fs from "fs";
|
2
|
+
import path from "path";
|
3
|
+
import Finder from "../finder/Finder";
|
4
|
+
|
5
|
+
import type {BuilderContract} from "../types";
|
6
|
+
|
7
|
+
export default class ConfigBuilder implements BuilderContract {
|
8
|
+
protected template: string;
|
9
|
+
|
10
|
+
public constructor(protected finder: Finder) {
|
11
|
+
this.template = fs.readFileSync(path.resolve(__dirname, "virtual.config.ts"), "utf8");
|
12
|
+
}
|
13
|
+
|
14
|
+
public build(): string {
|
15
|
+
const files = this.finder.getFiles();
|
16
|
+
|
17
|
+
const imports = files.map(file => {
|
18
|
+
return file.name ? `import ${file.name} from "${file.import}"` : `import "${file.import}"`;
|
19
|
+
});
|
20
|
+
|
21
|
+
// Elements must be reversed for correct merging of configs by priority
|
22
|
+
const names = files
|
23
|
+
.map(file => file.name)
|
24
|
+
.filter(Boolean)
|
25
|
+
.reverse();
|
26
|
+
|
27
|
+
// prettier-ignore
|
28
|
+
return this.template
|
29
|
+
.replace("//configs imports", imports.join("\n"))
|
30
|
+
.replace("{}", names.join(", "));
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import fs from "fs";
|
2
|
+
import path from "path";
|
3
|
+
import Finder from "../finder/Finder";
|
4
|
+
|
5
|
+
import type {BuilderContract} from "../types";
|
6
|
+
|
7
|
+
export default class StyleBuilder implements BuilderContract {
|
8
|
+
public constructor(protected finder: Finder) {}
|
9
|
+
|
10
|
+
public build(): string {
|
11
|
+
const files = this.finder.getFiles();
|
12
|
+
|
13
|
+
const usesLines = new Set<string>();
|
14
|
+
const stylesLines: string[] = [];
|
15
|
+
|
16
|
+
const lines = files
|
17
|
+
.map(file => file.import)
|
18
|
+
.reduce((lines, filePath) => {
|
19
|
+
return lines + "\n" + fs.readFileSync(path.resolve(filePath), "utf8");
|
20
|
+
}, "")
|
21
|
+
.split("\n");
|
22
|
+
|
23
|
+
for (const line of lines) {
|
24
|
+
const trimmed = line.trim();
|
25
|
+
if (trimmed.startsWith("@use")) {
|
26
|
+
usesLines.add(trimmed);
|
27
|
+
} else {
|
28
|
+
stylesLines.push(line);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
return [...usesLines].join("\n") + "\n" + stylesLines.join("\n");
|
33
|
+
}
|
34
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import Finder from "./Finder";
|
3
|
+
|
4
|
+
import type {ReadonlyConfig} from "adnbn";
|
5
|
+
import type {FileImportInfo} from "../types";
|
6
|
+
|
7
|
+
export default class ConfigFinder extends Finder {
|
8
|
+
protected getAllowedExtensions(): string[] {
|
9
|
+
return ["tsx", "ts"];
|
10
|
+
}
|
11
|
+
|
12
|
+
constructor(fileName: string, config: ReadonlyConfig) {
|
13
|
+
super(fileName, config);
|
14
|
+
}
|
15
|
+
|
16
|
+
protected getFile(dirPath: string): FileImportInfo | undefined {
|
17
|
+
const filePath = this.resolveFileWithExtensions(dirPath, this.fileName);
|
18
|
+
|
19
|
+
if (!filePath) return;
|
20
|
+
|
21
|
+
return {
|
22
|
+
name: dirPath.replaceAll(path.sep, "").replaceAll("-", ""),
|
23
|
+
import: this.toImportPath(filePath),
|
24
|
+
};
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import fs from "fs";
|
2
|
+
import path from "path";
|
3
|
+
|
4
|
+
import type {ReadonlyConfig} from "adnbn";
|
5
|
+
|
6
|
+
import type {FileImportInfo} from "../types";
|
7
|
+
|
8
|
+
export interface FinderOptions {
|
9
|
+
searchDirs: string[];
|
10
|
+
fileName: string;
|
11
|
+
canMerge: boolean;
|
12
|
+
}
|
13
|
+
|
14
|
+
export default abstract class Finder {
|
15
|
+
protected abstract getAllowedExtensions(): string[];
|
16
|
+
|
17
|
+
protected abstract getFile(dirPath: string): FileImportInfo | undefined;
|
18
|
+
|
19
|
+
protected searchDirs: string[] = [];
|
20
|
+
protected canMerge: boolean = true;
|
21
|
+
|
22
|
+
protected constructor(
|
23
|
+
protected readonly fileName: string,
|
24
|
+
protected readonly config: ReadonlyConfig
|
25
|
+
) {}
|
26
|
+
|
27
|
+
public setCanMerge(canMerge: boolean): this {
|
28
|
+
this.canMerge = canMerge;
|
29
|
+
return this;
|
30
|
+
}
|
31
|
+
|
32
|
+
public setSearchDirs(searchDirs: string[]): this {
|
33
|
+
this.searchDirs = searchDirs;
|
34
|
+
return this;
|
35
|
+
}
|
36
|
+
|
37
|
+
public getFiles(): FileImportInfo[] {
|
38
|
+
const files: FileImportInfo[] = [];
|
39
|
+
|
40
|
+
let isFound = false;
|
41
|
+
|
42
|
+
this.searchDirs.forEach(dirPath => {
|
43
|
+
const file = this.getFile(dirPath);
|
44
|
+
|
45
|
+
if (file && (this.canMerge || !isFound)) {
|
46
|
+
files.push(file);
|
47
|
+
isFound = true;
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
return files;
|
52
|
+
}
|
53
|
+
|
54
|
+
protected resolveFileWithExtensions(basePath: string, fileName: string): string | undefined {
|
55
|
+
const extname = path.extname(fileName);
|
56
|
+
|
57
|
+
const baseName = this.getAllowedExtensions().includes(extname.slice(1))
|
58
|
+
? path.basename(fileName, extname)
|
59
|
+
: fileName;
|
60
|
+
|
61
|
+
for (const ext of this.getAllowedExtensions()) {
|
62
|
+
const fullPath = path.resolve(basePath, `${baseName}.${ext}`);
|
63
|
+
if (fs.existsSync(fullPath)) {
|
64
|
+
return fullPath;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
return undefined;
|
69
|
+
}
|
70
|
+
|
71
|
+
protected toImportPath(fullPath: string, withExt: boolean = false): string {
|
72
|
+
const importPath = path.relative(this.config.inputDir, fullPath).split(path.sep).join("/");
|
73
|
+
|
74
|
+
return withExt ? importPath : importPath.replace(path.extname(importPath), "");
|
75
|
+
}
|
76
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import type {ReadonlyConfig} from "adnbn";
|
2
|
+
|
3
|
+
import Finder from "./Finder";
|
4
|
+
|
5
|
+
import type {FileImportInfo} from "../types";
|
6
|
+
|
7
|
+
export default class StyleFinder extends Finder {
|
8
|
+
protected getAllowedExtensions(): string[] {
|
9
|
+
return ["scss", "css"];
|
10
|
+
}
|
11
|
+
|
12
|
+
constructor(fileName: string, config: ReadonlyConfig) {
|
13
|
+
super(fileName, config);
|
14
|
+
}
|
15
|
+
|
16
|
+
protected getFile(dirPath: string): FileImportInfo | undefined {
|
17
|
+
const filePath = this.resolveFileWithExtensions(dirPath, this.fileName);
|
18
|
+
|
19
|
+
if (!filePath) return;
|
20
|
+
|
21
|
+
return {name: "", import: this.toImportPath(filePath, true)};
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import {definePlugin} from "adnbn";
|
3
|
+
import {Configuration as Rspack} from "@rspack/core";
|
4
|
+
import {RspackVirtualModulePlugin} from "rspack-plugin-virtual-module";
|
5
|
+
|
6
|
+
import StyleBuilder from "./builder/StyleBuilder";
|
7
|
+
import ConfigBuilder from "./builder/ConfigBuilder";
|
8
|
+
|
9
|
+
import Finder from "./finder/Finder";
|
10
|
+
import StyleFinder from "./finder/StyleFinder";
|
11
|
+
import ConfigFinder from "./finder/ConfigFinder";
|
12
|
+
|
13
|
+
import type {BuilderContract} from "./types";
|
14
|
+
|
15
|
+
export interface PluginOptions {
|
16
|
+
themeDir?: string;
|
17
|
+
configFileName?: string;
|
18
|
+
styleFileName?: string;
|
19
|
+
mergeConfig?: boolean;
|
20
|
+
mergeStyles?: boolean;
|
21
|
+
}
|
22
|
+
|
23
|
+
export default definePlugin((options: PluginOptions = {}) => {
|
24
|
+
const {
|
25
|
+
themeDir = ".",
|
26
|
+
configFileName = "ui.config",
|
27
|
+
styleFileName = "ui.style",
|
28
|
+
mergeConfig = true,
|
29
|
+
mergeStyles = true,
|
30
|
+
} = options;
|
31
|
+
|
32
|
+
let configFinder: Finder;
|
33
|
+
let styleFinder: Finder;
|
34
|
+
|
35
|
+
let configBuilder: BuilderContract;
|
36
|
+
let styleBuilder: BuilderContract;
|
37
|
+
|
38
|
+
return {
|
39
|
+
name: "adnbn-ui",
|
40
|
+
startup: ({config}) => {
|
41
|
+
const {srcDir, appsDir, sharedDir, app, appSrcDir} = config;
|
42
|
+
const normalizeThemeDir = path.normalize(themeDir).split(path.sep);
|
43
|
+
|
44
|
+
// Elements should be arranged in descending order of priority
|
45
|
+
const searchDirs = [
|
46
|
+
path.join(srcDir, appsDir, app, appSrcDir, ...normalizeThemeDir),
|
47
|
+
path.join(srcDir, sharedDir, ...normalizeThemeDir),
|
48
|
+
];
|
49
|
+
|
50
|
+
configFinder = new ConfigFinder(configFileName, config).setCanMerge(mergeConfig).setSearchDirs(searchDirs);
|
51
|
+
styleFinder = new StyleFinder(styleFileName, config).setCanMerge(mergeStyles).setSearchDirs(searchDirs);
|
52
|
+
|
53
|
+
configBuilder = new ConfigBuilder(configFinder);
|
54
|
+
styleBuilder = new StyleBuilder(styleFinder);
|
55
|
+
},
|
56
|
+
bundler: () => {
|
57
|
+
return {
|
58
|
+
plugins: [
|
59
|
+
new RspackVirtualModulePlugin(
|
60
|
+
{
|
61
|
+
"adnbn-ui-config": configBuilder.build(),
|
62
|
+
"adnbn-ui-style.scss": styleBuilder.build(),
|
63
|
+
},
|
64
|
+
"adnbn-ui-virtual"
|
65
|
+
),
|
66
|
+
],
|
67
|
+
} satisfies Rspack;
|
68
|
+
},
|
69
|
+
};
|
70
|
+
});
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import React, {PropsWithChildren, useMemo} from "react";
|
2
|
+
import {merge} from "ts-deepmerge";
|
3
|
+
|
4
|
+
import ThemeProvider from "./theme/ThemeProvider";
|
5
|
+
import {IconsProvider, Icons} from "./icons";
|
6
|
+
import {ComponentsProps} from "../components";
|
7
|
+
|
8
|
+
import config from "adnbn-ui-config";
|
9
|
+
|
10
|
+
import type {Config} from "../config";
|
11
|
+
|
12
|
+
const UIProvider = ({children, props = {}, icons = {}}: PropsWithChildren<Partial<Config>>) => {
|
13
|
+
const componentsProps: ComponentsProps = useMemo(() => merge(config.props || {}, props), [props]);
|
14
|
+
|
15
|
+
const svgIcons: Icons = useMemo(() => merge(config.icons || {}, icons), [icons]);
|
16
|
+
|
17
|
+
return (
|
18
|
+
<ThemeProvider {...componentsProps}>
|
19
|
+
<IconsProvider icons={svgIcons}>{children}</IconsProvider>
|
20
|
+
</ThemeProvider>
|
21
|
+
);
|
22
|
+
};
|
23
|
+
|
24
|
+
UIProvider.displayName = "UIProvider";
|
25
|
+
|
26
|
+
export default UIProvider;
|