@js-empire/emperor-ui 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.husky/pre-commit +4 -0
- package/.storybook/main.ts +2 -11
- package/.storybook/preview.ts +1 -1
- package/.vscode/extensions.json +3 -0
- package/README.md +68 -1
- package/package.json +16 -4
- package/public/icons/emperor-ui-logo.ico +0 -0
- package/public/images/avatar-female.jpg +0 -0
- package/public/images/avatar-male.jpg +0 -0
- package/public/images/emperor-ui-logo.png +0 -0
- package/src/components/atoms/brand/brand.stories.tsx +27 -0
- package/src/components/atoms/brand/brand.tsx +56 -0
- package/src/components/atoms/brand/index.ts +1 -0
- package/src/components/atoms/brand/styles/classes.ts +9 -0
- package/src/components/atoms/brand/styles/index.ts +2 -0
- package/src/components/atoms/brand/styles/styles.ts +0 -0
- package/src/components/atoms/column/column.stories.tsx +36 -0
- package/src/components/atoms/column/column.tsx +21 -0
- package/src/components/atoms/column/index.ts +1 -0
- package/src/components/atoms/container/column.stories.tsx +36 -0
- package/src/components/atoms/container/container.tsx +28 -0
- package/src/components/atoms/container/index.ts +1 -0
- package/src/components/atoms/index.ts +6 -0
- package/src/components/atoms/portal/index.ts +1 -0
- package/src/components/atoms/portal/portal.stories.tsx +43 -0
- package/src/components/atoms/portal/portal.tsx +23 -0
- package/src/components/atoms/row/index.ts +1 -0
- package/src/components/atoms/row/row.stories.tsx +36 -0
- package/src/components/atoms/row/row.tsx +26 -0
- package/src/components/atoms/uploader/avatar-label.tsx +83 -0
- package/src/components/atoms/uploader/index.ts +7 -0
- package/src/components/atoms/uploader/stories/uploader.stories.tsx +41 -0
- package/src/components/atoms/uploader/upload-file-error-box.tsx +29 -0
- package/src/components/atoms/uploader/upload-file-input.tsx +36 -0
- package/src/components/atoms/uploader/upload-file-label.tsx +74 -0
- package/src/components/atoms/uploader/upload-file-listing.tsx +53 -0
- package/src/components/atoms/uploader/uploader.tsx +55 -0
- package/src/components/atoms/uploader/view-image-modal.tsx +39 -0
- package/src/components/index.ts +4 -8
- package/src/components/molecules/index.ts +5 -0
- package/src/components/molecules/item-card/item-card.tsx +6 -0
- package/src/components/molecules/nav-bar/index.ts +3 -0
- package/src/components/molecules/nav-bar/nav-bar-item.tsx +70 -0
- package/src/components/molecules/nav-bar/nav-bar.tsx +65 -0
- package/src/components/molecules/nav-bar/stories/hover-effect/nav-bar-hover-effect.stories.tsx +52 -0
- package/src/components/molecules/nav-bar/stories/nav-bar.stories.tsx +50 -0
- package/src/components/molecules/nav-bar/styles/classes.ts +68 -0
- package/src/components/molecules/nav-bar/styles/index.ts +2 -0
- package/src/components/molecules/nav-bar/styles/styles.ts +84 -0
- package/src/components/molecules/nav-bar/sub-items-box.tsx +57 -0
- package/src/components/molecules/scaffold/scaffold.stories.tsx +21 -0
- package/src/components/molecules/scaffold/scaffold.tsx +36 -0
- package/src/components/molecules/side-bar/compact-side-bar.tsx +73 -0
- package/src/components/molecules/side-bar/index.ts +1 -0
- package/src/components/molecules/side-bar/side-bar-drawer.tsx +124 -0
- package/src/components/molecules/side-bar/side-bar.stories.tsx +110 -0
- package/src/components/molecules/side-bar/side-bar.tsx +31 -0
- package/src/components/molecules/side-bar/styles/classes.ts +28 -0
- package/src/components/molecules/side-bar/styles/index.ts +2 -0
- package/src/components/molecules/side-bar/styles/styles.ts +13 -0
- package/src/components/organisms/footer/footer.tsx +20 -0
- package/src/components/organisms/footer/styles/classes.ts +15 -0
- package/src/components/organisms/footer/styles/index.ts +2 -0
- package/src/components/organisms/footer/styles/styles.ts +9 -0
- package/src/components/organisms/header/header.tsx +94 -0
- package/src/components/organisms/header/segmented-header-content.tsx +37 -0
- package/src/components/organisms/header/stories/header.stories.tsx +143 -0
- package/src/components/organisms/header/styles/classes.ts +22 -0
- package/src/components/organisms/header/styles/index.ts +2 -0
- package/src/components/organisms/header/styles/styles.ts +39 -0
- package/src/components/organisms/index.ts +4 -0
- package/src/components/templates/index.ts +1 -0
- package/src/components/templates/landing-page/index.ts +1 -0
- package/src/components/templates/landing-page/landing-page.stories.tsx +21 -0
- package/src/components/templates/landing-page/landing-page.tsx +57 -0
- package/src/components/templates/landing-page/styles/classes.ts +11 -0
- package/src/components/templates/landing-page/styles/index.ts +1 -0
- package/src/constants/defaults.ts +42 -7
- package/src/constants/fake.ts +2 -0
- package/src/constants/index.ts +2 -0
- package/src/constants/uploader.ts +27 -0
- package/src/context/emperor-ui-context.ts +4 -4
- package/src/context/index.ts +2 -0
- package/src/context/navigation-context.ts +6 -0
- package/src/context/uploader-context.ts +6 -0
- package/src/enums/index.ts +2 -0
- package/src/enums/placeholders.ts +4 -0
- package/src/enums/preserved-keys.ts +3 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/use-navigation.ts +12 -0
- package/src/hooks/use-uploader-context.ts +14 -0
- package/src/hooks/use-uploader.tsx +215 -0
- package/src/index.ts +9 -5
- package/src/main.tsx +3 -0
- package/src/mocks/header.tsx +118 -0
- package/src/mocks/index.ts +1 -0
- package/src/providers/config-provider.tsx +54 -0
- package/src/providers/emperor-ui-provider.tsx +17 -24
- package/src/providers/index.ts +3 -0
- package/src/providers/navigation-provider.tsx +42 -0
- package/src/providers/uploader-provider.tsx +53 -0
- package/src/styles/globals.css +13 -0
- package/src/styles/hero.ts +2 -0
- package/src/types/components/atoms/brand.ts +13 -0
- package/src/types/components/atoms/column.ts +3 -0
- package/src/types/components/atoms/container.ts +3 -0
- package/src/types/components/atoms/index.ts +6 -0
- package/src/types/components/atoms/portal.ts +6 -0
- package/src/types/components/atoms/row.ts +3 -0
- package/src/types/components/atoms/uploader.ts +104 -0
- package/src/types/components/index.ts +3 -8
- package/src/types/components/molecules/header/header.ts +51 -0
- package/src/types/components/molecules/index.ts +9 -0
- package/src/types/components/molecules/nav-bar/nav-bar.ts +65 -0
- package/src/types/components/molecules/side-bar/index.ts +1 -0
- package/src/types/components/molecules/side-bar/side-bar.ts +40 -0
- package/src/types/components/templates/index.ts +1 -0
- package/src/types/components/templates/landing-page.ts +10 -0
- package/src/types/context/config.ts +54 -0
- package/src/types/context/index.ts +2 -1
- package/src/types/context/navigation.ts +17 -0
- package/src/types/shared/components.ts +4 -0
- package/src/utils/compress-images.ts +36 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/storybook.tsx +15 -0
- package/tsconfig.app.json +3 -2
- package/tsconfig.node.json +0 -1
- package/vite.config.ts +4 -0
- package/dist/emperor-ui.js +0 -3171
- package/dist/emperor-ui.umd.cjs +0 -6
- package/dist/index.d.ts +0 -200
- package/src/components/footer/footer.tsx +0 -6
- package/src/components/header/header.tsx +0 -49
- package/src/components/item-card/item-card.tsx +0 -6
- package/src/components/nav-bar/index.ts +0 -1
- package/src/components/nav-bar/nav-bar.tsx +0 -6
- package/src/components/scaffold/scaffold.tsx +0 -15
- package/src/index.css +0 -1
- package/src/types/components/header/header.ts +0 -21
- package/src/types/components/nav-bar/nav-bar.ts +0 -9
- package/src/types/context/emperor-ui.ts +0 -37
- package/tailwind.config.js +0 -6
- /package/src/components/{filter → molecules/filter}/filter.tsx +0 -0
- /package/src/components/{filter → molecules/filter}/index.ts +0 -0
- /package/src/components/{item-card → molecules/item-card}/index.ts +0 -0
- /package/src/components/{scaffold → molecules/scaffold}/index.ts +0 -0
- /package/src/components/{footer → organisms/footer}/index.ts +0 -0
- /package/src/components/{header → organisms/header}/index.ts +0 -0
- /package/src/components/{item-details → organisms/item-details}/index.ts +0 -0
- /package/src/components/{item-details → organisms/item-details}/item-details.tsx +0 -0
- /package/src/components/{listings → organisms/listings}/index.ts +0 -0
- /package/src/components/{listings → organisms/listings}/listings.tsx +0 -0
- /package/src/types/components/{filter → molecules/filter}/filter.ts +0 -0
- /package/src/types/components/{filter → molecules/filter}/index.ts +0 -0
- /package/src/types/components/{footer → molecules/footer}/footer.ts +0 -0
- /package/src/types/components/{footer → molecules/footer}/index.ts +0 -0
- /package/src/types/components/{header → molecules/header}/index.ts +0 -0
- /package/src/types/components/{item-card → molecules/item-card}/index.ts +0 -0
- /package/src/types/components/{item-card → molecules/item-card}/item-card.ts +0 -0
- /package/src/types/components/{item-details → molecules/item-details}/index.ts +0 -0
- /package/src/types/components/{item-details → molecules/item-details}/item-details.ts +0 -0
- /package/src/types/components/{listings → molecules/listings}/index.ts +0 -0
- /package/src/types/components/{listings → molecules/listings}/listings.ts +0 -0
- /package/src/types/components/{nav-bar → molecules/nav-bar}/index.ts +0 -0
- /package/src/types/components/{scaffold → molecules/scaffold}/index.ts +0 -0
- /package/src/types/components/{scaffold → molecules/scaffold}/scaffold.ts +0 -0
package/.storybook/main.ts
CHANGED
|
@@ -4,16 +4,7 @@ import tsconfigPaths from "vite-tsconfig-paths";
|
|
|
4
4
|
|
|
5
5
|
const config: StorybookConfig = {
|
|
6
6
|
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
|
7
|
-
addons: [
|
|
8
|
-
"@chromatic-com/storybook",
|
|
9
|
-
"@storybook/addon-vitest",
|
|
10
|
-
"@storybook/addon-a11y",
|
|
11
|
-
"@storybook/addon-docs",
|
|
12
|
-
"@storybook/addon-links",
|
|
13
|
-
"@storybook/addon-essentials",
|
|
14
|
-
"@storybook/addon-onboarding",
|
|
15
|
-
"@storybook/addon-interactions",
|
|
16
|
-
],
|
|
7
|
+
addons: [],
|
|
17
8
|
framework: {
|
|
18
9
|
name: "@storybook/react-vite",
|
|
19
10
|
options: {},
|
|
@@ -22,7 +13,7 @@ const config: StorybookConfig = {
|
|
|
22
13
|
config.plugins?.push(
|
|
23
14
|
/** @see https://github.com/aleclarson/vite-tsconfig-paths */
|
|
24
15
|
tsconfigPaths({
|
|
25
|
-
projects: [path.resolve(
|
|
16
|
+
projects: [path.resolve("..", "tsconfig.json")],
|
|
26
17
|
}),
|
|
27
18
|
);
|
|
28
19
|
|
package/.storybook/preview.ts
CHANGED
package/README.md
CHANGED
|
@@ -1 +1,68 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Emperor UI
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
## Intro
|
|
6
|
+
|
|
7
|
+
A modular UI library built for React and Nextjs. It depends on HeroUI to implement advanced organisms and pages.
|
|
8
|
+
|
|
9
|
+
Each one of them has props to control every aspect pf the component, with enabling/disabling the optional features.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Components
|
|
14
|
+
|
|
15
|
+
### Footer
|
|
16
|
+
|
|
17
|
+
- copy rights placeholder
|
|
18
|
+
- Quick links
|
|
19
|
+
- Quick form
|
|
20
|
+
- Social buttons with logos
|
|
21
|
+
|
|
22
|
+
### Item Card
|
|
23
|
+
|
|
24
|
+
- Image
|
|
25
|
+
- Title
|
|
26
|
+
- Subtitle (for description)
|
|
27
|
+
- Price
|
|
28
|
+
- Drop-down with actions and a dots-icon for opening it
|
|
29
|
+
|
|
30
|
+
### Listings
|
|
31
|
+
|
|
32
|
+
- Listing any type of components
|
|
33
|
+
- Pagination or infinite scrolling
|
|
34
|
+
- Specifying the page size
|
|
35
|
+
- View controller: list, grid, carousel (swiper)
|
|
36
|
+
|
|
37
|
+
### Details page
|
|
38
|
+
|
|
39
|
+
- Breadcrumbs
|
|
40
|
+
- Image or carousel
|
|
41
|
+
- Title
|
|
42
|
+
- Subtitle
|
|
43
|
+
- Description
|
|
44
|
+
- Price
|
|
45
|
+
|
|
46
|
+
### Nav-bar
|
|
47
|
+
|
|
48
|
+
- Navigation buttons using a provided custom router
|
|
49
|
+
- Auto-controlled position: at the top for desktop, or at the bottom for mobile view
|
|
50
|
+
|
|
51
|
+
### Filter
|
|
52
|
+
|
|
53
|
+
- Filter layouts: side box on desktop, drawer on mobile
|
|
54
|
+
- Custom filter items with different types:
|
|
55
|
+
- search term
|
|
56
|
+
- checkbox
|
|
57
|
+
- Multiple checkboxes under an accordion
|
|
58
|
+
- autocomplete or select box
|
|
59
|
+
- Action buttons: apply filters, reset filters
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Documentation Page
|
|
64
|
+
|
|
65
|
+
- Introducing the tool and its usage
|
|
66
|
+
- Installation guide
|
|
67
|
+
- Components with usage and code variants
|
|
68
|
+
- Components API
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@js-empire/emperor-ui",
|
|
3
3
|
"description": "They provide the atoms, we provide the empire.",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"author": "JS Empire - Mustafa Alhasanat",
|
|
6
6
|
"license": "ISC",
|
|
7
7
|
"type": "module",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"import": "./dist/emperor-ui.js",
|
|
16
16
|
"require": "./dist/emperor-ui-umd.cjs"
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"./globals.css": "./dist/globals.css"
|
|
18
19
|
},
|
|
19
20
|
"scripts": {
|
|
20
21
|
"dev": "vite",
|
|
@@ -24,7 +25,8 @@
|
|
|
24
25
|
"lint": "eslint .",
|
|
25
26
|
"preview": "vite preview",
|
|
26
27
|
"storybook": "storybook dev -p 6006",
|
|
27
|
-
"build-storybook": "storybook build"
|
|
28
|
+
"build-storybook": "storybook build",
|
|
29
|
+
"prepare": "husky"
|
|
28
30
|
},
|
|
29
31
|
"publishConfig": {
|
|
30
32
|
"access": "public"
|
|
@@ -43,15 +45,25 @@
|
|
|
43
45
|
]
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
48
|
+
"@heroui/react": "^2.8.5",
|
|
49
|
+
"@heroui/theme": "^2.4.25",
|
|
50
|
+
"@storybook/react": "^10.1.8",
|
|
46
51
|
"@tailwindcss/vite": "^4.1.17",
|
|
52
|
+
"browser-image-compression": "^2.0.2",
|
|
47
53
|
"class-variance-authority": "^0.7.1",
|
|
48
54
|
"clsx": "^2.1.1",
|
|
55
|
+
"framer-motion": "^12.23.26",
|
|
56
|
+
"husky": "^9.1.7",
|
|
57
|
+
"lucide-react": "^0.560.0",
|
|
58
|
+
"motion": "^12.26.2",
|
|
49
59
|
"prettier": "^3.7.4",
|
|
50
60
|
"react": "^19.2.0",
|
|
51
61
|
"react-dom": "^19.2.0",
|
|
52
62
|
"tailwind-merge": "^3.4.0",
|
|
63
|
+
"tailwind-scrollbar-hide": "^4.0.0",
|
|
53
64
|
"tailwindcss": "^4.1.17",
|
|
54
|
-
"vite-tsconfig-paths": "^5.1.4"
|
|
65
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
66
|
+
"xlsx": "^0.18.5"
|
|
55
67
|
},
|
|
56
68
|
"devDependencies": {
|
|
57
69
|
"@chromatic-com/storybook": "^4.1.3",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Brand } from "@components";
|
|
3
|
+
import { getStorybookDecorators } from "@utils";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Brand> = {
|
|
6
|
+
title: "Atoms/Brand",
|
|
7
|
+
component: Brand,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
decorators: getStorybookDecorators({
|
|
13
|
+
config: {
|
|
14
|
+
layout: {
|
|
15
|
+
withScaffold: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
args: {},
|
|
27
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { BrandProps } from "@types";
|
|
2
|
+
import { cn } from "@utils";
|
|
3
|
+
import { VariantProps } from "class-variance-authority";
|
|
4
|
+
import { ComponentProps, forwardRef } from "react";
|
|
5
|
+
import { Row } from "@components";
|
|
6
|
+
import { brandStyles } from "./styles";
|
|
7
|
+
import { Image } from "@heroui/react";
|
|
8
|
+
|
|
9
|
+
export const Brand = forwardRef<
|
|
10
|
+
HTMLElement,
|
|
11
|
+
ComponentProps<"div"> & VariantProps<typeof brandStyles> & BrandProps
|
|
12
|
+
>(
|
|
13
|
+
(
|
|
14
|
+
{
|
|
15
|
+
className,
|
|
16
|
+
variant,
|
|
17
|
+
src = "/images/emperor-ui-logo.png",
|
|
18
|
+
alt = "Emperor UI",
|
|
19
|
+
name = "Emperor UI",
|
|
20
|
+
isIconOnly = false,
|
|
21
|
+
classNames,
|
|
22
|
+
...props
|
|
23
|
+
},
|
|
24
|
+
ref,
|
|
25
|
+
) => {
|
|
26
|
+
return (
|
|
27
|
+
<Row
|
|
28
|
+
ref={ref}
|
|
29
|
+
data-slot="emperor-brand"
|
|
30
|
+
className={cn(
|
|
31
|
+
brandStyles({ variant, className: cn(className, classNames?.base) }),
|
|
32
|
+
)}
|
|
33
|
+
{...props}
|
|
34
|
+
>
|
|
35
|
+
{src && (
|
|
36
|
+
<Image
|
|
37
|
+
data-slot="emperor-brand-logo"
|
|
38
|
+
src={src}
|
|
39
|
+
alt={alt}
|
|
40
|
+
radius="md"
|
|
41
|
+
className={cn("min-w-7 min-h-7 size-7", classNames?.logo)}
|
|
42
|
+
/>
|
|
43
|
+
)}
|
|
44
|
+
|
|
45
|
+
{name && !isIconOnly && (
|
|
46
|
+
<p
|
|
47
|
+
data-slot="emperor-brand-name"
|
|
48
|
+
className={cn("font-semibold text-lg", classNames?.name)}
|
|
49
|
+
>
|
|
50
|
+
{name}
|
|
51
|
+
</p>
|
|
52
|
+
)}
|
|
53
|
+
</Row>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./brand";
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Column } from "@components";
|
|
3
|
+
import { getStorybookDecorators } from "@utils";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Column> = {
|
|
6
|
+
title: "Atoms/Column",
|
|
7
|
+
component: Column,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
decorators: getStorybookDecorators({
|
|
13
|
+
config: {
|
|
14
|
+
layout: {
|
|
15
|
+
withScaffold: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
args: {},
|
|
27
|
+
render: (args) => (
|
|
28
|
+
<Column {...args}>
|
|
29
|
+
{Array.from({ length: 5 }).map((_, index) => (
|
|
30
|
+
<div key={index} className="bg-blue-300 p-2 rounded-md">
|
|
31
|
+
Item {index + 1}
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
</Column>
|
|
35
|
+
),
|
|
36
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ColumnProps } from "@types";
|
|
2
|
+
import { cn } from "@utils";
|
|
3
|
+
import { cva, VariantProps } from "class-variance-authority";
|
|
4
|
+
import { forwardRef, ComponentProps } from "react";
|
|
5
|
+
|
|
6
|
+
const columnStyles = cva(["flex flex-col gap-3"], {
|
|
7
|
+
variants: {},
|
|
8
|
+
defaultVariants: {},
|
|
9
|
+
compoundVariants: [],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const Column = forwardRef<
|
|
13
|
+
HTMLElement,
|
|
14
|
+
ComponentProps<"section"> & VariantProps<typeof columnStyles> & ColumnProps
|
|
15
|
+
>(({ className, children, ...props }, ref) => {
|
|
16
|
+
return (
|
|
17
|
+
<section ref={ref} className={cn(columnStyles({ className }))} {...props}>
|
|
18
|
+
{children}
|
|
19
|
+
</section>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./column";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Container } from "@components";
|
|
3
|
+
import { getStorybookDecorators } from "@utils";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Container> = {
|
|
6
|
+
title: "Atoms/Container",
|
|
7
|
+
component: Container,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "fullscreen",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
decorators: getStorybookDecorators({
|
|
13
|
+
config: {
|
|
14
|
+
layout: {
|
|
15
|
+
withScaffold: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
args: {
|
|
27
|
+
className: "h-screen flex items-center justify-center",
|
|
28
|
+
},
|
|
29
|
+
render: (args) => (
|
|
30
|
+
<Container {...args}>
|
|
31
|
+
<div className="bg-blue-300 p-2 text-center rounded-md w-full h-fit">
|
|
32
|
+
Responsive contained content
|
|
33
|
+
</div>
|
|
34
|
+
</Container>
|
|
35
|
+
),
|
|
36
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ContainerProps } from "@types";
|
|
2
|
+
import { cn } from "@utils";
|
|
3
|
+
import { cva, VariantProps } from "class-variance-authority";
|
|
4
|
+
import { forwardRef, ComponentProps } from "react";
|
|
5
|
+
|
|
6
|
+
const containerStyles = cva(["flex w-full container p-4 mx-auto"], {
|
|
7
|
+
variants: {},
|
|
8
|
+
defaultVariants: {},
|
|
9
|
+
compoundVariants: [],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const Container = forwardRef<
|
|
13
|
+
HTMLElement,
|
|
14
|
+
ComponentProps<"section"> &
|
|
15
|
+
VariantProps<typeof containerStyles> &
|
|
16
|
+
ContainerProps
|
|
17
|
+
>(({ className, children, ...props }, ref) => {
|
|
18
|
+
return (
|
|
19
|
+
<section
|
|
20
|
+
ref={ref}
|
|
21
|
+
data-slot="container"
|
|
22
|
+
className={cn(containerStyles({ className }))}
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</section>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./container";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./portal";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Portal } from "@components";
|
|
3
|
+
import { getStorybookDecorators } from "@utils";
|
|
4
|
+
import { FAKE_PARAGRAPH } from "@constants";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Portal> = {
|
|
7
|
+
title: "Atoms/Portal",
|
|
8
|
+
component: Portal,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "fullscreen",
|
|
11
|
+
},
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
decorators: getStorybookDecorators({
|
|
14
|
+
config: {
|
|
15
|
+
layout: {
|
|
16
|
+
withScaffold: false,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
|
|
26
|
+
export const Default: Story = {
|
|
27
|
+
args: {},
|
|
28
|
+
render: () => (
|
|
29
|
+
<main className="h-screen w-full flex flex-col gap-10 p-5">
|
|
30
|
+
<div id="portal-container" />
|
|
31
|
+
|
|
32
|
+
<p>{FAKE_PARAGRAPH}</p>
|
|
33
|
+
<p>{FAKE_PARAGRAPH}</p>
|
|
34
|
+
<p>{FAKE_PARAGRAPH}</p>
|
|
35
|
+
|
|
36
|
+
<Portal containerId="portal-container">
|
|
37
|
+
<div className="bg-blue-300 p-2 rounded-md absolute top-5 left-1/2 -translate-x-1/2">
|
|
38
|
+
<h2>Portal Content</h2>
|
|
39
|
+
</div>
|
|
40
|
+
</Portal>
|
|
41
|
+
</main>
|
|
42
|
+
),
|
|
43
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PortalProps } from "@types";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
|
|
5
|
+
export function Portal({
|
|
6
|
+
children,
|
|
7
|
+
containerId,
|
|
8
|
+
isVisible = true,
|
|
9
|
+
}: PortalProps) {
|
|
10
|
+
const [container, setContainer] = useState<HTMLElement | null>(null);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const element = document.getElementById(containerId);
|
|
14
|
+
|
|
15
|
+
setContainer(element);
|
|
16
|
+
}, [containerId]);
|
|
17
|
+
|
|
18
|
+
if (!container || !isVisible) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return createPortal(children, container);
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./row";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Row } from "@components";
|
|
3
|
+
import { getStorybookDecorators } from "@utils";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Row> = {
|
|
6
|
+
title: "Atoms/Row",
|
|
7
|
+
component: Row,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
decorators: getStorybookDecorators({
|
|
13
|
+
config: {
|
|
14
|
+
layout: {
|
|
15
|
+
withScaffold: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
args: {},
|
|
27
|
+
render: (args) => (
|
|
28
|
+
<Row {...args}>
|
|
29
|
+
{Array.from({ length: 5 }).map((_, index) => (
|
|
30
|
+
<div key={index} className="bg-blue-300 p-2 rounded-md">
|
|
31
|
+
Item {index + 1}
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
</Row>
|
|
35
|
+
),
|
|
36
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RowProps } from "@types";
|
|
2
|
+
import { cn } from "@utils";
|
|
3
|
+
import { cva, VariantProps } from "class-variance-authority";
|
|
4
|
+
import { forwardRef, ComponentProps } from "react";
|
|
5
|
+
|
|
6
|
+
const rowStyles = cva(["flex items-center gap-3"], {
|
|
7
|
+
variants: {},
|
|
8
|
+
defaultVariants: {},
|
|
9
|
+
compoundVariants: [],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const Row = forwardRef<
|
|
13
|
+
HTMLElement,
|
|
14
|
+
ComponentProps<"section"> & VariantProps<typeof rowStyles> & RowProps
|
|
15
|
+
>(({ className, children, ...props }, ref) => {
|
|
16
|
+
return (
|
|
17
|
+
<section
|
|
18
|
+
ref={ref}
|
|
19
|
+
data-slot="row"
|
|
20
|
+
className={cn(rowStyles({ className }))}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</section>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Placeholders } from "@enums";
|
|
4
|
+
import { Avatar, Spinner, cn } from "@heroui/react";
|
|
5
|
+
import { useEmperorUI, useUploaderContext } from "@hooks";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
|
|
8
|
+
export function AvatarLabel() {
|
|
9
|
+
const { config } = useEmperorUI();
|
|
10
|
+
const [draggableMessage, setDraggableMessage] = useState<string | null>(null);
|
|
11
|
+
const {
|
|
12
|
+
labelId,
|
|
13
|
+
classNames,
|
|
14
|
+
labelContent,
|
|
15
|
+
isDraggable,
|
|
16
|
+
onInputChange,
|
|
17
|
+
avatarLabelContent,
|
|
18
|
+
placeholderImage,
|
|
19
|
+
files,
|
|
20
|
+
isLoading,
|
|
21
|
+
} = useUploaderContext();
|
|
22
|
+
|
|
23
|
+
const locales = config?.interLocalization?.locales;
|
|
24
|
+
const lang = config?.interLocalization?.lang;
|
|
25
|
+
|
|
26
|
+
const locale = locales?.[lang || "en"];
|
|
27
|
+
|
|
28
|
+
const handleDrop = (
|
|
29
|
+
event: React.ChangeEvent<HTMLInputElement> &
|
|
30
|
+
React.DragEvent<HTMLLabelElement>,
|
|
31
|
+
) => {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
if (onInputChange) onInputChange(event);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const handleDragOver = (
|
|
37
|
+
event: React.ChangeEvent<HTMLInputElement> &
|
|
38
|
+
React.DragEvent<HTMLLabelElement>,
|
|
39
|
+
) => {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
setDraggableMessage(locale?.dropHere || "");
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleDragLeave = () => {
|
|
45
|
+
setDraggableMessage("");
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
if (isLoading)
|
|
49
|
+
return (
|
|
50
|
+
<div className={cn("mx-auto", classNames?.label)}>
|
|
51
|
+
<Spinner className="mx-auto" size="lg" />;
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<label
|
|
57
|
+
className={cn(
|
|
58
|
+
"w-full cursor-pointer mx-auto transition-opacity flex flex-col gap-5",
|
|
59
|
+
draggableMessage && "opacity-60",
|
|
60
|
+
classNames?.label,
|
|
61
|
+
)}
|
|
62
|
+
htmlFor={labelId}
|
|
63
|
+
onDrop={isDraggable ? handleDrop : () => {}}
|
|
64
|
+
onDragOver={isDraggable ? handleDragOver : () => {}}
|
|
65
|
+
onDragLeave={isDraggable ? handleDragLeave : () => {}}
|
|
66
|
+
>
|
|
67
|
+
{avatarLabelContent}
|
|
68
|
+
|
|
69
|
+
{labelContent || (
|
|
70
|
+
<Avatar
|
|
71
|
+
src={
|
|
72
|
+
files?.[0]?.view ||
|
|
73
|
+
placeholderImage ||
|
|
74
|
+
Placeholders.PLACEHOLDER_MALE_AVATAR
|
|
75
|
+
}
|
|
76
|
+
alt="avatar"
|
|
77
|
+
size="lg"
|
|
78
|
+
className={cn("size-24", classNames?.avatar)}
|
|
79
|
+
/>
|
|
80
|
+
)}
|
|
81
|
+
</label>
|
|
82
|
+
);
|
|
83
|
+
}
|