datastake-daf 0.6.168 → 0.6.170

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.
Files changed (23) hide show
  1. package/dist/components/index.js +256 -130
  2. package/package.json +1 -1
  3. package/src/@daf/core/components/AvatarGroup/AvatarGroup.stories.jsx +1 -1
  4. package/src/@daf/core/components/Badge/Badge.stories.js +98 -94
  5. package/src/@daf/core/components/Dashboard/Widget/CarouselWidget/CarouselWidget.stories.js +42 -0
  6. package/src/@daf/core/components/Dashboard/Widget/CarouselWidget/index.jsx +72 -0
  7. package/src/@daf/core/components/Dashboard/Widget/ImageCarousel/ImageCarousel.stories.js +93 -0
  8. package/src/@daf/core/components/Dashboard/Widget/ImageCarousel/index.jsx +132 -0
  9. package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/ProjectWidget.stories.jsx +0 -3
  10. package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/components/SdgList.jsx +9 -77
  11. package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/index.jsx +78 -80
  12. package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/style.js +47 -74
  13. package/src/@daf/core/components/EditForm/_index.scss +3 -3
  14. package/src/@daf/core/components/Icon/CustomIcon.stories.js +177 -179
  15. package/src/@daf/core/components/ProgressBar/MultiBarProgress/MultibarProgress.stories.jsx +48 -41
  16. package/src/@daf/core/components/ProgressBar/Progress.stories.jsx +31 -31
  17. package/src/@daf/core/components/Segment/Segment.stories.js +70 -64
  18. package/src/@daf/core/components/UI/SDGIcon/SGDIcon.stories.jsx +55 -0
  19. package/src/@daf/core/components/UI/SDGIcon/index.jsx +100 -0
  20. package/src/@daf/core/components/UI/SDGIcon/styles.js +26 -0
  21. package/src/@daf/core/components/ViewForm/_index.scss +1 -1
  22. package/src/index.js +2 -0
  23. package/src/@daf/core/components/Icon/Icon.stories.js +0 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.168",
3
+ "version": "0.6.170",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -2,7 +2,7 @@ import AvatarGroup from "./index.jsx";
2
2
  import ThemeLayout from "../ThemeLayout/index.jsx";
3
3
 
4
4
  export default {
5
- title: "Core/AvatarGroup/AvatarGroup",
5
+ title: "Components/AvatarGroup",
6
6
  component: AvatarGroup,
7
7
  tags: ["autodocs"],
8
8
  args: {
@@ -1,87 +1,85 @@
1
1
  import Badge from "./index.jsx";
2
2
  import ThemeLayout from "../ThemeLayout/index.jsx";
3
3
 
4
-
5
4
  export default {
6
- title: "Core/Badge/Badge",
7
- component: Badge,
8
- tags: ["autodocs"],
9
- args: {
10
- children: "Badge Text",
11
- variant: 'success',
12
- },
13
- decorators: [
14
- (Story) => (
15
- <div style={{ margin: "3em" }}>
16
- <ThemeLayout>
17
- <Story />
18
- </ThemeLayout>
19
- </div>
20
- ),
21
- ],
5
+ title: "Components/Badge",
6
+ component: Badge,
7
+ tags: ["autodocs"],
8
+ args: {
9
+ children: "Badge Text",
10
+ variant: "success",
11
+ },
12
+ decorators: [
13
+ (Story) => (
14
+ <div style={{ margin: "3em" }}>
15
+ <ThemeLayout>
16
+ <Story />
17
+ </ThemeLayout>
18
+ </div>
19
+ ),
20
+ ],
22
21
  };
23
22
 
24
23
  export const Primary = {
25
- name: "Badge",
26
- render: (args) => <div style={{ display: "flex", gap: "1em" }}>
27
- <Badge {...args} />
28
- </div>
24
+ name: "Badge",
25
+ render: (args) => (
26
+ <div style={{ display: "flex", gap: "1em" }}>
27
+ <Badge {...args} />
28
+ </div>
29
+ ),
29
30
  };
30
31
 
31
32
  export const Variants = {
32
- render: (args) => (
33
- <div style={{ display: "flex", gap: "1em", flexDirection: "column" }}>
34
- <Badge {...args} variant="default" />
35
- <Badge {...args} variant="success" />
36
- <Badge {...args} variant="danger" />
37
- <Badge {...args} variant="warning" />
38
- </div>
39
- ),
33
+ render: (args) => (
34
+ <div style={{ display: "flex", gap: "1em", flexDirection: "column" }}>
35
+ <Badge {...args} variant="default" />
36
+ <Badge {...args} variant="success" />
37
+ <Badge {...args} variant="danger" />
38
+ <Badge {...args} variant="warning" />
39
+ </div>
40
+ ),
40
41
  };
41
42
 
42
43
  export const IconSize = {
43
- args: {
44
- size: "icon",
45
- },
46
- render: (args) => (
47
- <div style={{ display: "flex", gap: "1em" }}>
48
- <Badge {...args} variant="default" />
49
- <Badge {...args} />
50
- <Badge {...args} variant="danger" />
51
- <Badge {...args} variant="warning" />
52
- </div>
53
- ),
44
+ args: {
45
+ size: "icon",
46
+ },
47
+ render: (args) => (
48
+ <div style={{ display: "flex", gap: "1em" }}>
49
+ <Badge {...args} variant="default" />
50
+ <Badge {...args} />
51
+ <Badge {...args} variant="danger" />
52
+ <Badge {...args} variant="warning" />
53
+ </div>
54
+ ),
54
55
  };
55
56
 
56
57
  export const CustomWidth = {
57
- render: (args) => (
58
- <div style={{ display: "flex", gap: "1em", flexDirection: "column" }}>
59
- <Badge {...args} size={600} />
60
- <Badge {...args} size={50} />
61
- <Badge {...args} size={500} />
62
- <Badge {...args} size={300} />
63
- </div>
64
- ),
58
+ render: (args) => (
59
+ <div style={{ display: "flex", gap: "1em", flexDirection: "column" }}>
60
+ <Badge {...args} size={600} />
61
+ <Badge {...args} size={50} />
62
+ <Badge {...args} size={500} />
63
+ <Badge {...args} size={300} />
64
+ </div>
65
+ ),
65
66
  };
66
67
 
67
68
  export const BorderRadios = {
68
-
69
- render: (args) => (
70
- <div style={{ display: "flex", gap: "1em" }}>
71
- <Badge {...args} rounded="none" />
72
- <Badge {...args} rounded="half" />
73
- <Badge {...args} rounded="full" />
74
- </div>
75
- ),
69
+ render: (args) => (
70
+ <div style={{ display: "flex", gap: "1em" }}>
71
+ <Badge {...args} rounded="none" />
72
+ <Badge {...args} rounded="half" />
73
+ <Badge {...args} rounded="full" />
74
+ </div>
75
+ ),
76
76
  };
77
77
 
78
-
79
-
80
78
  export const CustomBadge = {
81
- render: (args) => (
82
- <>
83
- <style>
84
- {`
79
+ render: (args) => (
80
+ <>
81
+ <style>
82
+ {`
85
83
  .test {
86
84
  color: white !important;
87
85
  }
@@ -94,38 +92,44 @@ export const CustomBadge = {
94
92
  color: #ff169f;
95
93
  border: 1px dashed #ff169f;
96
94
  }`}
97
- </style>
98
- <div style={{ display: "flex", gap: "1em" }} className="test">
99
- <Badge {...args} rounded="half" customIcon={"Delete"} className="custom_badge_blue">
100
- CUSTOMIZED
101
- </Badge>
102
- <Badge
103
- {...args}
104
- rounded="none"
105
- size="icon"
106
- customIcon={"Search"}
107
- className="custom_badge_pink"
108
- >
109
- CUSTOMIZED
110
- </Badge>
111
- </div>
112
- </>
113
- ),
95
+ </style>
96
+ <div style={{ display: "flex", gap: "1em" }} className="test">
97
+ <Badge
98
+ {...args}
99
+ rounded="half"
100
+ customIcon={"Delete"}
101
+ className="custom_badge_blue"
102
+ >
103
+ CUSTOMIZED
104
+ </Badge>
105
+ <Badge
106
+ {...args}
107
+ rounded="none"
108
+ size="icon"
109
+ customIcon={"Search"}
110
+ className="custom_badge_pink"
111
+ >
112
+ CUSTOMIZED
113
+ </Badge>
114
+ </div>
115
+ </>
116
+ ),
114
117
  };
115
118
 
116
119
  export const WithTooltip = {
117
- render: (args) => (
118
- <div style={{ display: "flex", gap: "1em" }}>
119
- <Badge {...args} size={144} tooltip>
120
- lorem ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit amet
121
- consectetur adipiscing elit
122
- </Badge>
123
- <Badge {...args} tooltip="Yes this is a tooltip">
124
- Tooltip with your text
125
- </Badge>
126
- <Badge {...args} variant="danger" tooltip size="icon">
127
- Tooltip with danger
128
- </Badge>
129
- </div>
130
- ),
131
- };
120
+ render: (args) => (
121
+ <div style={{ display: "flex", gap: "1em" }}>
122
+ <Badge {...args} size={144} tooltip>
123
+ lorem ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor
124
+ sit amet consectetur adipiscing elit
125
+ </Badge>
126
+ <Badge {...args} tooltip="Yes this is a tooltip">
127
+ Tooltip with your text
128
+ </Badge>
129
+ <Badge {...args} variant="danger" tooltip size="icon">
130
+ Tooltip with danger
131
+ </Badge>
132
+ </div>
133
+ ),
134
+ };
135
+
@@ -0,0 +1,42 @@
1
+ import CarouselWidget from "./index";
2
+ import ThemeLayout from "../../../ThemeLayout";
3
+ import WidgetCard from "../WidgetCard";
4
+
5
+ export default {
6
+ title: "Dashboard/Widgets/CarouselWidget",
7
+ component: CarouselWidget,
8
+ tags: ["autodocs"],
9
+ decorators: [
10
+ (Story) => (
11
+ <ThemeLayout>
12
+ <Story />
13
+ </ThemeLayout>
14
+ ),
15
+ ],
16
+ };
17
+
18
+ const contentStyle = {
19
+ margin: 0,
20
+ height: '160px',
21
+ color: '#fff',
22
+ lineHeight: '160px',
23
+ textAlign: 'center',
24
+ background: '#364d79',
25
+ };
26
+
27
+ export const Primary = {
28
+ name: "CarouselWidget",
29
+ render: () => (
30
+ <CarouselWidget title="Carousel">
31
+ <div>
32
+ <h3 style={contentStyle}>1</h3>
33
+ </div>
34
+ <div>
35
+ <h3 style={contentStyle}>2</h3>
36
+ </div>
37
+ </CarouselWidget>
38
+ ),
39
+ args: {
40
+ title: "Carousel",
41
+ },
42
+ };
@@ -0,0 +1,72 @@
1
+ import React from 'react'
2
+ import Widget from '../index.jsx'
3
+ import { Carousel } from 'antd';
4
+
5
+ /**
6
+ * CarouselWidget Component - A reusable widget wrapper for Ant Design Carousel with consistent styling
7
+ *
8
+ * @component
9
+ * @example
10
+ * // Basic usage
11
+ * <CarouselWidget title="My Content">
12
+ * <div>Slide 1</div>
13
+ * <div>Slide 2</div>
14
+ * </CarouselWidget>
15
+ *
16
+ * @example
17
+ * // With additional carousel props
18
+ * <CarouselWidget
19
+ * title="Auto-play Carousel"
20
+ * autoplay
21
+ * dots={true}
22
+ * speed={500}
23
+ * >
24
+ * <div>Content 1</div>
25
+ * <div>Content 2</div>
26
+ * </CarouselWidget>
27
+ *
28
+ * @param {Object} props - Component props
29
+ * @param {string} props.title - The title displayed in the widget header
30
+ * @param {React.ReactNode} props.children - Child elements to be rendered as carousel slides
31
+ * @param {Object} [props.rest] - Additional props passed to the Ant Design Carousel component
32
+ * @param {boolean} [props.autoplay] - Whether to auto-play the carousel (passed via rest)
33
+ * @param {boolean} [props.dots=true] - Whether to show navigation dots (passed via rest)
34
+ * @param {number} [props.speed=500] - Animation speed in milliseconds (passed via rest)
35
+ * @param {boolean} [props.infinite=true] - Whether to enable infinite loop (passed via rest)
36
+ * @param {'horizontal'|'vertical'} [props.dotPosition='bottom'] - Position of navigation dots (passed via rest)
37
+ * @param {function} [props.beforeChange] - Callback before slide change (passed via rest)
38
+ * @param {function} [props.afterChange] - Callback after slide change (passed via rest)
39
+ *
40
+ * @features
41
+ * - ✅ Consistent widget styling with header and borders
42
+ * - ✅ Full Ant Design Carousel functionality support
43
+ * - ✅ Slide change event logging for debugging
44
+ * - ✅ Flexible content rendering via children
45
+ * - ✅ Responsive design integration
46
+ *
47
+ * @returns {JSX.Element} The rendered CarouselWidget component
48
+ */
49
+ function CarouselWidget({title, children, ...rest}) {
50
+
51
+ /**
52
+ * Handles carousel slide change events
53
+ * @param {number} currentSlide - The index of the current slide after change
54
+ * @private
55
+ */
56
+ const onChange = (currentSlide) => {
57
+ console.log(currentSlide);
58
+ };
59
+
60
+ return (
61
+ <Widget
62
+ title={title}
63
+ className="with-border-header h-w-btn-header"
64
+ >
65
+ <Carousel afterChange={onChange} {...rest}>
66
+ {children}
67
+ </Carousel>
68
+ </Widget>
69
+ )
70
+ }
71
+
72
+ export default CarouselWidget;
@@ -0,0 +1,93 @@
1
+ import { Image } from "antd";
2
+ import ImageCarousel from "./index";
3
+ import ThemeLayout from "../../../ThemeLayout";
4
+ import WidgetCard from "../WidgetCard";
5
+
6
+ export default {
7
+ title: "Dashboard/Widgets/ImageCarousel",
8
+ component: ImageCarousel,
9
+ tags: ["autodocs"],
10
+ decorators: [
11
+ (Story) => (
12
+ <ThemeLayout>
13
+ <Story />
14
+ </ThemeLayout>
15
+ ),
16
+ ],
17
+ argTypes: {
18
+ height: {
19
+ control: { type: 'range', min: 200, max: 600, step: 50 },
20
+ description: 'Height of the carousel images'
21
+ },
22
+ },
23
+ };
24
+
25
+ // High quality sample images with proper alt text
26
+ const sampleImages = [
27
+ {
28
+ src: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop",
29
+ alt: "Scenic mountain landscape with lake reflection"
30
+ },
31
+ {
32
+ src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800&h=600&fit=crop",
33
+ alt: "Dense forest path with sunlight filtering through trees"
34
+ },
35
+ {
36
+ src: "https://images.unsplash.com/photo-1448375240586-882707db888b?w=800&h=600&fit=crop",
37
+ alt: "Rolling green hills under a cloudy sky"
38
+ },
39
+ {
40
+ src: "https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=800&h=600&fit=crop",
41
+ alt: "Serene forest landscape with tall pine trees"
42
+ }
43
+ ];
44
+
45
+ const mixedQualityImages = [
46
+ {
47
+ src: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop",
48
+ alt: "High quality mountain landscape"
49
+ },
50
+ {
51
+ src: "https://invalid-url-to-show-fallback.jpg",
52
+ alt: "Broken image to demonstrate fallback functionality"
53
+ },
54
+ {
55
+ src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=400&h=300&fit=crop",
56
+ alt: "Lower resolution forest image"
57
+ },
58
+ {
59
+ src: "https://images.unsplash.com/photo-1448375240586-882707db888b?w=1200&h=800&fit=crop",
60
+ alt: "High resolution hills landscape"
61
+ }
62
+ ];
63
+
64
+ export const Primary = {
65
+ name: "Basic ImageCarousel",
66
+ render: (args) => (
67
+ <div>
68
+ <p style={{ marginBottom: '16px', color: '#666' }}>
69
+ <strong>💡 Tip:</strong> Click any image to open preview, then use ← → arrow keys to navigate between images!
70
+ </p>
71
+ <ImageCarousel
72
+ title="Nature Gallery"
73
+ images={sampleImages}
74
+ {...args}
75
+ />
76
+ </div>
77
+ ),
78
+ args: {
79
+ title: "Nature Gallery",
80
+ height: 400,
81
+ },
82
+ };
83
+
84
+ export const WithFallbacks = {
85
+ name: "With Error Handling",
86
+ render: () => (
87
+ <ImageCarousel
88
+ title="Mixed Quality Images"
89
+ images={mixedQualityImages}
90
+ height={350}
91
+ />
92
+ ),
93
+ };
@@ -0,0 +1,132 @@
1
+ import React, { useState, useRef } from "react";
2
+ import CarouselWidget from "../CarouselWidget/index.jsx";
3
+ import { Image, Carousel } from "antd";
4
+
5
+ /**
6
+ * @typedef {Object} ImageObject
7
+ * @property {string} src - The source URL of the image
8
+ * @property {string} alt - Alternative text for the image
9
+ */
10
+
11
+ /**
12
+ * ImageCarousel Component - A responsive image carousel with preview functionality and keyboard navigation
13
+ *
14
+ * @component
15
+ * @example
16
+ * // Basic usage with string URLs
17
+ * <ImageCarousel
18
+ * title="My Gallery"
19
+ * images={["image1.jpg", "image2.jpg"]}
20
+ * />
21
+ *
22
+ * @example
23
+ * // Advanced usage with image objects and custom height
24
+ * <ImageCarousel
25
+ * title="Nature Gallery"
26
+ * images={[
27
+ * { src: "landscape.jpg", alt: "Beautiful mountain landscape" },
28
+ * { src: "forest.jpg", alt: "Dense forest path" }
29
+ * ]}
30
+ * height={300}
31
+ * fallback="/custom-fallback.svg"
32
+ * />
33
+ *
34
+ * @param {Object} props - Component props
35
+ * @param {string} props.title - The title displayed in the widget header
36
+ * @param {(string|ImageObject)[]} props.images - Array of image URLs (strings) or image objects with src and alt properties
37
+ * @param {number} [props.height=400] - Height of the carousel images in pixels
38
+ * @param {string} [props.fallback="/assets/images/empty-box.svg"] - Fallback image URL when original image fails to load
39
+ * @param {Object} [props.rest] - Additional props passed to the underlying CarouselWidget component
40
+ *
41
+ * @features
42
+ * - ✅ Responsive image display with lazy loading
43
+ * - ✅ Click-to-preview with full-screen image viewer
44
+ * - ✅ Keyboard navigation in preview mode (← → arrow keys)
45
+ * - ✅ Automatic fallback for broken images
46
+ * - ✅ Support for both string URLs and image objects with alt text
47
+ * - ✅ Synchronized carousel and preview navigation
48
+ * - ✅ Infinite scrolling in both carousel and preview modes
49
+ *
50
+ * @accessibility
51
+ * - Proper alt text support for screen readers
52
+ * - Keyboard navigation support
53
+ * - Focus management in preview mode
54
+ *
55
+ */
56
+ function ImageCarousel({
57
+ title,
58
+ images,
59
+ height = 400,
60
+ fallback = "/assets/images/empty-box.svg",
61
+ ...rest
62
+ }) {
63
+ const [previewVisible, setPreviewVisible] = useState(false);
64
+ const [current, setCurrent] = useState(0);
65
+ const carouselRef = useRef(null);
66
+
67
+ const handleCarouselChange = (index) => {
68
+ setCurrent(index);
69
+ };
70
+
71
+ return (
72
+ <>
73
+ <CarouselWidget title={title} {...rest} dots={false}>
74
+ <Carousel ref={carouselRef} afterChange={handleCarouselChange} infinite>
75
+ {images.map((image, index) => {
76
+ const imageSrc = typeof image === "string" ? image : image.src;
77
+ const imageAlt =
78
+ typeof image === "string"
79
+ ? `${title} - Image ${index + 1}`
80
+ : image.alt;
81
+
82
+ return (
83
+ <div key={imageSrc}>
84
+ <Image
85
+ src={imageSrc}
86
+ alt={imageAlt}
87
+ height={height}
88
+ width="100%"
89
+ fallback={fallback}
90
+ loading="lazy"
91
+ preview={{
92
+ visible: false,
93
+ }}
94
+ onClick={() => {
95
+ setCurrent(index);
96
+ setPreviewVisible(true);
97
+ }}
98
+ />
99
+ </div>
100
+ );
101
+ })}
102
+ </Carousel>
103
+ </CarouselWidget>
104
+
105
+ <div style={{ display: "none" }}>
106
+ <Image.PreviewGroup
107
+ preview={{
108
+ visible: previewVisible,
109
+ current,
110
+ onVisibleChange: (vis) => setPreviewVisible(vis),
111
+ onChange: (idx) => {
112
+ setCurrent(idx);
113
+ carouselRef.current?.goTo(idx);
114
+ },
115
+ }}
116
+ >
117
+ {images.map((image, index) => {
118
+ const imageSrc = typeof image === "string" ? image : image.src;
119
+ const imageAlt =
120
+ typeof image === "string"
121
+ ? `${title} - Image ${index + 1}`
122
+ : image.alt;
123
+
124
+ return <Image key={imageSrc} src={imageSrc} alt={imageAlt} />;
125
+ })}
126
+ </Image.PreviewGroup>
127
+ </div>
128
+ </>
129
+ );
130
+ }
131
+
132
+ export default ImageCarousel;
@@ -1,7 +1,6 @@
1
1
  import ProjectWidget from "./index.jsx";
2
2
  import ThemeLayout from "../../../ThemeLayout/index.jsx";
3
3
  import Widget from "../index.jsx";
4
-
5
4
  import DashboardLayout from "../../DashboardLayout/index.jsx";
6
5
  export default {
7
6
  title: "Dashboard/Widgets/ProjectWidget",
@@ -21,8 +20,6 @@ export default {
21
20
  export const Primary = {
22
21
  name: "ProjectWidget",
23
22
  args: {
24
- image:
25
- "https://images.steamusercontent.com/ugc/2064377508522269100/6E178CC9C29DDA679B4941E43DF799E93163804A/?imw=637&imh=358&ima=fit&impolicy=Letterbox&imcolor=%23000000&letterbox=true",
26
23
  onLinkClick: () => {},
27
24
  linkIcon: "Link",
28
25
  sdgList: [