diff --git a/react/css/package.json b/react/css/package.json index cb6787c31e..47fd0f5312 100644 --- a/react/css/package.json +++ b/react/css/package.json @@ -1,6 +1,6 @@ { "name": "@egovernments/digit-ui-components-css", - "version": "0.0.2-beta.25", + "version": "0.0.2-beta.26", "license": "MIT", "main": "dist/index.css", "author": "Jagankumar ", diff --git a/react/css/src/digitv2/components/accordionV2.scss b/react/css/src/digitv2/components/accordionV2.scss index ca825c6863..1e5f847764 100644 --- a/react/css/src/digitv2/components/accordionV2.scss +++ b/react/css/src/digitv2/components/accordionV2.scss @@ -102,4 +102,71 @@ &.cardBg{ background-color: theme(digitv2.lightTheme.paper-secondary); } + } + + @keyframes rotateOpen { + from { + transform: rotate(-180deg); + } + to { + transform: rotate(-90deg); + } + } + + @keyframes rotateClose { + from { + transform: rotate(-90deg); + } + to { + transform: rotate(-180deg); + } + } + + .digit-accordion-toggle.animate-open svg { + animation: rotateOpen 0.5s ease forwards; + } + + .digit-accordion-toggle.animate-close svg { + animation: rotateClose 0.5s ease forwards; + } + + +/* .digit-accordion-content { + transform: scaleY(0); + transform-origin: top; + opacity: 0; + height: 0; + overflow: hidden; + transition: transform 0.3s ease, opacity 0.3s ease; + } + + .digit-accordion-content.open { + transform: scaleY(1); + opacity: 1; + height: auto; + overflow: visible; + }*/ + + .digit-accordion-wrapper{ + display: flex; + flex-direction: column; + + @media (max-aspect-ratio: 9/16) { + /* Media query for mobile */ + gap: theme(digitv2.spacers.spacer4); + } + + @media (min-aspect-ratio: 9/16) and (max-aspect-ratio: 3/4) { + /* Media query for tablets */ + gap: theme(digitv2.spacers.spacer5); + } + + @media (min-aspect-ratio: 3/4) { + /* Media query for desktop */ + gap: theme(digitv2.spacers.spacer6); + } + } + + .digit-accordion-divider{ + width: 100%; } \ No newline at end of file diff --git a/react/css/src/digitv2/components/mobilesidebarV2.scss b/react/css/src/digitv2/components/mobilesidebarV2.scss index af20a5ee82..2dbb95a42d 100644 --- a/react/css/src/digitv2/components/mobilesidebarV2.scss +++ b/react/css/src/digitv2/components/mobilesidebarV2.scss @@ -1,4 +1,4 @@ -.msb-sidebar { +.digit-msb-sidebar { background-color: theme(digitv2.lightTheme.paper-primary); color: theme(digitv2.lightTheme.primary-2); display: flex; @@ -10,6 +10,7 @@ left: 0; top: 0; min-width: 17.5rem; + z-index: 1000; flex-direction: column; &.dark { @@ -18,7 +19,7 @@ } } -.msb-profile { +.digit-msb-profile { display: flex; align-items: center; padding: theme(digitv2.spacers.spacer6); @@ -26,21 +27,20 @@ gap: theme(digitv2.spacers.spacer3); } -.msb-profile-icon { +.digit-msb-profile-icon { width: 3.875rem; height: 4rem; margin-right: theme(digitv2.spacers.spacer4); } -.msb-profile-details { +.digit-msb-profile-details { display: flex; flex-direction: column; gap: theme(digitv2.spacers.spacer1); - ; text-align: center; } -.msb-profile-name { +.digit-msb-profile-name { font-family: theme(digitv2.fontFamily.sans); font-style: theme(digitv2.fontStyle.normal); font-weight: theme(digitv2.fontWeight.bold); @@ -68,7 +68,7 @@ } } -.msb-profile-phone { +.digit-msb-profile-phone { font-family: theme(digitv2.fontFamily.sans); font-style: theme(digitv2.fontStyle.normal); font-weight: theme(digitv2.fontWeight.regular); @@ -96,45 +96,49 @@ } } -.msb-sidebar-items { +.digit-msb-sidebar-items { flex: 1; overflow-y: auto; overflow-x: hidden; } -.msb-item-child-wrapper { +.digit-msb-item-child-wrapper { display: flex; flex-direction: column; height: theme(digitv2.spacers.spacer12); padding: theme(digitv2.spacers.spacer3) theme(digitv2.spacers.spacer6); - ; justify-content: space-between; border-top: 0.063rem solid theme(digitv2.lightTheme.generic-divider); + + &.usermanuals{ + padding: theme(digitv2.spacers.spacer4) theme(digitv2.spacers.spacer6); + height: 3.5rem; + } } -.msb-item-child-wrapper:last-child, -.msb-item-child-wrapper.expanded { +.digit-msb-item-child-wrapper:last-child, +.digit-msb-item-child-wrapper.expanded { border-bottom: 0.063rem solid theme(digitv2.lightTheme.generic-divider); } -.msb-item-child-wrapper:not(.dark):nth-child(2n+1) { +.digit-msb-item-child-wrapper:not(.dark):nth-child(2n+1) { background-color: theme(digitv2.lightTheme.paper-secondary); } -.msb-item-child-wrapper.expanded { +.digit-msb-item-child-wrapper.expanded { height: auto; } -.msb-sidebar-item { +.digit-msb-sidebar-item { display: flex; align-items: center; cursor: pointer; } -.msb-sidebar-item.msb-parentLevel { +.digit-msb-sidebar-item.digit-msb-parentLevel { height: theme(digitv2.spacers.spacer6); - .msb-item-label { + .digit-msb-item-label { font-family: theme(digitv2.fontFamily.sans); font-style: theme(digitv2.fontStyle.normal); font-weight: theme(digitv2.fontWeight.bold); @@ -157,19 +161,52 @@ } } -.msb-sidebar-item .msb-icon { +.digit-msb-item-label{ + &.usermanuals{ + @extend .typography.body-xs; + font-family: theme(digitv2.fontFamily.sans); + font-style: theme(digitv2.fontStyle.normal); + font-weight: theme(digitv2.fontWeight.regular); + line-height: theme(digitv2.lineHeight.lineheight2); + + @media (max-aspect-ratio: 9/16) { + /* Media query for mobile */ + font-size: theme(digitv2.fontSize.body-xs.mobile); + } + + @media (min-aspect-ratio: 9/16) and (max-aspect-ratio: 3/4) { + /* Media query for tablets */ + font-size: theme(digitv2.fontSize.body-xs.tablet); + } + + @media (min-aspect-ratio: 3/4) { + /* Media query for desktop */ + font-size: theme(digitv2.fontSize.body-xs.desktop); + } + } +} +.digit-msb-sidebar-item .digit-msb-icon { margin-right: theme(digitv2.spacers.spacer4); + + &.usermanuals{ + display: flex; + width: theme(digitv2.spacers.spacer6); + height: theme(digitv2.spacers.spacer6); + justify-content: center; + align-items: center; + margin-right: theme(digitv2.spacers.spacer2); + } } -.msb-expand-icon { +.digit-msb-expand-icon { margin-left: auto; } -.msb-sidebar-children { +.digit-msb-sidebar-children { width: "100%"; transition: height 0.3s ease; - .inner-level-child { + .digit-inner-level-child { margin-left: 3.5rem; border-left: 0.063rem solid theme(digitv2.lightTheme.generic-divider); @@ -179,19 +216,49 @@ } } +.digit-msb-no-results{ + @extend .typography.body-s; + display: flex; + flex-direction: column; + height: theme(digitv2.spacers.spacer12); + padding: theme(digitv2.spacers.spacer3) theme(digitv2.spacers.spacer6); + justify-content: space-between; + border-top: 0.063rem solid theme(digitv2.lightTheme.generic-divider); + color:theme(digitv2.lightTheme.text-disabled); + font-family: theme(digitv2.fontFamily.sans); + font-style: theme(digitv2.fontStyle.normal); + font-weight: theme(digitv2.fontWeight.regular); + line-height: theme(digitv2.lineHeight.lineheight2); + + @media (max-aspect-ratio: 9/16) { + /* Media query for mobile */ + font-size: theme(digitv2.fontSize.body-s.mobile); + } + + @media (min-aspect-ratio: 9/16) and (max-aspect-ratio: 3/4) { + /* Media query for tablets */ + font-size: theme(digitv2.fontSize.body-s.tablet); + } -.msb-sidebar-children.expanded { + @media (min-aspect-ratio: 3/4) { + /* Media query for desktop */ + font-size: theme(digitv2.fontSize.body-s.desktop); + } +} + + +.digit-msb-sidebar-children.expanded { height: auto; } -.mb-search-container { +.digit-mb-search-container { height: 4.5rem; min-width: 15rem; width: auto; padding: theme(digitv2.spacers.spacer4) !important; - .mb-search { + .digit-mb-search { height: theme(digitv2.spacers.spacer10) !important; min-width: 13rem; @@ -251,13 +318,13 @@ } } -.mb-search-container.dark { +.digit-mb-search-container.dark { height: 4.5rem; min-width: 15rem; width: auto; padding: theme(digitv2.spacers.spacer4) !important; - .mb-search { + .digit-mb-search { height: theme(digitv2.spacers.spacer10) !important; min-width: 13rem; @@ -316,7 +383,7 @@ } } -.msb-sidebar-bottom { +.digit-msb-sidebar-bottom { background-color: theme(digitv2.lightTheme.paper-secondary); z-index: 5; padding: theme(digitv2.spacers.spacer4); @@ -342,14 +409,14 @@ } } -.icon-msb { +.digit-icon-msb { margin-right: theme(digitv2.spacers.spacer3); width: theme(digitv2.spacers.spacer6); height: theme(digitv2.spacers.spacer6); margin-left: theme(digitv2.spacers.spacer7); } -.item-label-msb { +.digit-item-label-msb { font-family: theme(digitv2.fontFamily.sans); font-style: theme(digitv2.fontStyle.normal); @@ -370,9 +437,13 @@ /* Media query for desktop */ font-size: theme(digitv2.fontSize.body-s.desktop); } + + &.withoutIcon{ + margin-left: theme(digitv2.spacers.spacer7); + } } -.expand-icon-msb { +.digit-expand-icon-msb { width: theme(digitv2.spacers.spacer6); height: theme(digitv2.spacers.spacer6); margin-left: auto !important; @@ -382,7 +453,7 @@ } } -.sidebar-item-msb { +.digit-sidebar-item-msb { display: flex; align-items: center; text-decoration: none; @@ -395,33 +466,33 @@ } -.item-child-wrapper-msb { +.digit-item-child-wrapper-msb { width: 100%; height: theme(digitv2.spacers.spacer12); display: flex; align-items: center; justify-content: center; - .sidebar-item-msb:hover { + .digit-sidebar-item-msb:hover { background-color: #FFFFFF4D; } - .sidebar-item-msb:active, - .sidebar-item-msb.selected, - .sidebar-item-msb.selectedAsParent { + .digit-sidebar-item-msb:active, + .digit-sidebar-item-msb.selected, + .digit-sidebar-item-msb.selectedAsParent { background: #c84c0e1a; - .item-label-msb { + .digit-item-label-msb { color: theme(digitv2.lightTheme.primary-2); } } - .sidebar-item-msb.selected::before, - .sidebar-item-msb:active::before, - .sidebar-item-msb:active:hover::before, - .sidebar-item-msb.selected:hover::before, - .sidebar-item-msb.selectedAsParent::before, - .sidebar-item-msb.selectedAsParent:hover::before { + .digit-sidebar-item-msb.selected::before, + .digit-sidebar-item-msb:active::before, + .digit-sidebar-item-msb:active:hover::before, + .digit-sidebar-item-msb.selected:hover::before, + .digit-sidebar-item-msb.selectedAsParent::before, + .digit-sidebar-item-msb.selectedAsParent:hover::before { content: ''; position: absolute; top: 0.062rem; @@ -433,21 +504,21 @@ border-bottom-right-radius: theme(digitv2.spacers.spacer1); } - .sidebar-item-msb.dark:active, - .sidebar-item-msb.dark.selected, - .sidebar-item-msb.dark.selectedAsParent { + .digit-sidebar-item-msb.dark:active, + .digit-sidebar-item-msb.dark.selected, + .digit-sidebar-item-msb.dark.selectedAsParent { background: theme(digitv2.lightTheme.primary-1); - .item-label-msb { + .digit-item-label-msb { color: theme(digitv2.lightTheme.paper-primary); } } - .sidebar-item-msb.dark.selected::before, - .sidebar-item-msb.dark:active::before, - .sidebar-item-msb.dark.selectedAsParent::before, - .sidebar-item-msb.dark:active:hover::before, - .sidebar-item-msb.dark.selected:hover::before, - .sidebar-item-msb.dark.selectedAsParent:hover::before { + .digit-sidebar-item-msb.dark.selected::before, + .digit-sidebar-item-msb.dark:active::before, + .digit-sidebar-item-msb.dark.selectedAsParent::before, + .digit-sidebar-item-msb.dark:active:hover::before, + .digit-sidebar-item-msb.dark.selected:hover::before, + .digit-sidebar-item-msb.dark.selectedAsParent:hover::before { content: ''; position: absolute; top: 0.062rem; @@ -461,17 +532,23 @@ } -.msb-sidebar-items::-webkit-scrollbar { +.digit-msb-sidebar-items::-webkit-scrollbar { width: 0.375rem; background-color: theme(digitv2.lightTheme.generic-background); } -.msb-sidebar-items::-webkit-scrollbar-track { +.digit-msb-sidebar-items::-webkit-scrollbar-track { background-color: theme(digitv2.lightTheme.generic-background); border-radius: 0.563rem; } -.msb-sidebar-items::-webkit-scrollbar-thumb { +.digit-msb-sidebar-items::-webkit-scrollbar-thumb { background-color: theme(digitv2.lightTheme.generic-divider); border-radius: 0.563rem; +} + +.digit-hamburger-profile{ + width: 3.875rem; + height: 4rem; + object-fit: cover; } \ No newline at end of file diff --git a/react/example/package.json b/react/example/package.json index 9e2d440121..25baa06a85 100644 --- a/react/example/package.json +++ b/react/example/package.json @@ -10,14 +10,14 @@ "build": "webpack --mode production" }, "dependencies": { - "@egovernments/digit-ui-components": "0.0.2-beta.26", + "@egovernments/digit-ui-components": "0.0.2-beta.28", "@egovernments/digit-ui-libraries": "1.8.2-beta.1", "@egovernments/digit-ui-module-common": "1.7.10", "@egovernments/digit-ui-module-core": "1.8.1-beta.6", "@egovernments/digit-ui-module-project": "0.3.4", "@egovernments/digit-ui-module-sample": "0.0.1", "@egovernments/digit-ui-react-components": "1.7.10", - "@egovernments/digit-ui-svg-components": "1.0.4", + "@egovernments/digit-ui-svg-components": "1.0.11", "http-proxy-middleware": "^1.0.5", "react": "17.0.2", "react-dom": "17.0.2", diff --git a/react/example/public/index.html b/react/example/public/index.html index f6983db876..b9edbe26ab 100644 --- a/react/example/public/index.html +++ b/react/example/public/index.html @@ -9,7 +9,7 @@ rel='stylesheet' type='text/css'> diff --git a/react/modules/core/package.json b/react/modules/core/package.json index 5da7622e73..8c34191c90 100644 --- a/react/modules/core/package.json +++ b/react/modules/core/package.json @@ -14,7 +14,7 @@ "prepublish": "yarn build" }, "dependencies": { - "@egovernments/digit-ui-components": "0.0.2-beta.27", + "@egovernments/digit-ui-components": "0.0.2-beta.28", "@egovernments/digit-ui-react-components": "1.8.1-beta.4", "react": "17.0.2", "react-dom": "17.0.2", diff --git a/react/modules/sample/package.json b/react/modules/sample/package.json index e1e21f18d6..9eb7806e0d 100644 --- a/react/modules/sample/package.json +++ b/react/modules/sample/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@egovernments/digit-ui-react-components": "1.8.1-beta.4", - "@egovernments/digit-ui-components": "0.0.2-beta.27", + "@egovernments/digit-ui-components": "0.0.2-beta.28", "react": "17.0.2", "react-date-range": "^1.4.0", "react-dom": "17.0.2", diff --git a/react/package.json b/react/package.json index 9bcf196347..b80fe46425 100644 --- a/react/package.json +++ b/react/package.json @@ -79,13 +79,13 @@ "@babel/plugin-syntax-jsx": "^7.24.1", "@babel/preset-react": "^7.24.1", "@egovernments/digit-ui-libraries": "1.8.2-beta.1", - "@egovernments/digit-ui-components-css":"0.0.2-beta.25", + "@egovernments/digit-ui-components-css":"0.0.2-beta.26", "@egovernments/digit-ui-module-core": "1.8.1-beta.6", "@egovernments/digit-ui-module-project": "0.3.4", "@egovernments/digit-ui-module-sample": "0.0.1", "@egovernments/digit-ui-react-components": "1.7.10", - "@egovernments/digit-ui-svg-components": "1.0.4", - "@egovernments/digit-ui-components": "0.0.2-beta.27", + "@egovernments/digit-ui-svg-components": "1.0.11", + "@egovernments/digit-ui-components": "0.0.2-beta.28", "babel-loader": "8.1.0", "clean-webpack-plugin": "4.0.0", "css-loader": "5.2.6", diff --git a/react/ui-components/CHANGELOG.md b/react/ui-components/CHANGELOG.md index 173f6d2a0a..dab7afba99 100644 --- a/react/ui-components/CHANGELOG.md +++ b/react/ui-components/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.0.2-beta.28] - 2024-08-29 +### New Changes +- Updated Sidebar and added AccordionWrapper + ## [0.0.2-beta.27] - 2024-08-27 ### New Changes - Fixed MobileSidebar issue diff --git a/react/ui-components/package.json b/react/ui-components/package.json index 1ba079c50d..32f9e43ed1 100644 --- a/react/ui-components/package.json +++ b/react/ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@egovernments/digit-ui-components", - "version": "0.0.2-beta.27", + "version": "0.0.2-beta.28", "license": "MIT", "main": "dist/index.js", "module": "dist/index.modern.js", @@ -51,9 +51,9 @@ "dist" ], "dependencies": { - "@egovernments/digit-ui-components-css": "0.0.2-beta.25", + "@egovernments/digit-ui-components-css": "0.0.2-beta.26", "@egovernments/digit-ui-libraries": "1.8.1-beta.1", - "@egovernments/digit-ui-svg-components": "1.0.4", + "@egovernments/digit-ui-svg-components": "1.0.11", "@googlemaps/js-api-loader": "1.13.10", "autoprefixer": "^10.4.15", "postcss-flexbugs-fixes": "^5.0.2", diff --git a/react/ui-components/src/atoms/Accordion.js b/react/ui-components/src/atoms/Accordion.js index d1788f5de7..4dbc3f40dd 100644 --- a/react/ui-components/src/atoms/Accordion.js +++ b/react/ui-components/src/atoms/Accordion.js @@ -1,9 +1,10 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import PropTypes from "prop-types"; import { SVG } from "./SVG"; import { Colors } from "../constants/colors/colorconstants"; import { iconRender } from "../utils/iconRender"; import { Spacers } from "../constants/spacers/spacers"; +import Divider from "./Divider"; const Accordion = ({ title, @@ -20,18 +21,27 @@ const Accordion = ({ hideCardBorder, hideDivider, hideCardBg, - hideBorderRadius + hideBorderRadius, + isClosed }) => { const [isOpen, setIsOpen] = useState(isOpenInitially); const iconColor = Colors.lightTheme.text.primary; const toggleiconSize = Spacers.spacer8; const iconSize = Spacers.spacer6; + const handleToggle = () => { setIsOpen(!isOpen); onToggle && onToggle(!isOpen); }; + useEffect(() => { + if (isClosed !== undefined && isClosed) { + setIsOpen(false); + } + }, [isClosed]); + + return (
)}
{title}
-
- {isOpen ? ( - - ) : ( +
- )}
- {isOpen &&
{content}
} + {isOpen && !isClosed &&
{content}
}
); }; @@ -101,6 +101,7 @@ Accordion.propTypes = { onToggle: PropTypes.func, customClassName: PropTypes.string, customStyles: PropTypes.object, + isClosed: PropTypes.bool, }; Accordion.defaultProps = { @@ -113,6 +114,65 @@ Accordion.defaultProps = { hideDivider: false, hideCardBg: false, hideBorderRadius: false, + isClosed:false +}; + +const AccordionWrapper = ({ + children, + allowMultipleOpen, + addDivider, + className, + styles +}) => { + const [openIndex, setOpenIndex] = useState( + allowMultipleOpen ? [] : -1 + ); + + const handleToggle = (index) => { + if (allowMultipleOpen) { + setOpenIndex((prevState) => + prevState.includes(index) + ? prevState.filter((i) => i !== index) + : [...prevState, index] + ); + } else { + setOpenIndex(index === openIndex ? -1 : index); + } + }; + + useEffect(() => { + },[openIndex]); + + return ( +
+ {React.Children.map(children, (child, index) => ( + + {React.cloneElement(child, { + isClosed: allowMultipleOpen + ? openIndex.length >0 && !openIndex.includes(index) + : openIndex !== index, + onToggle: () => handleToggle(index) + })} + {addDivider && index < React.Children.count(children) - 1 && } + + ))} +
+ ); +}; + +AccordionWrapper.propTypes = { + children: PropTypes.node.isRequired, + allowMultipleOpen: PropTypes.bool, + addDivider: PropTypes.bool, + customClassName: PropTypes.string, + customStyles: PropTypes.object, +}; + +AccordionWrapper.defaultProps = { + allowMultipleOpen: false, + addDivider: true, + customClassName: "", + customStyles: {}, }; -export default Accordion; +export {AccordionWrapper,Accordion}; diff --git a/react/ui-components/src/atoms/MobileSidebar.js b/react/ui-components/src/atoms/MobileSidebar.js index 465e004d35..5783829841 100644 --- a/react/ui-components/src/atoms/MobileSidebar.js +++ b/react/ui-components/src/atoms/MobileSidebar.js @@ -1,10 +1,13 @@ -import React, { useState,Fragment} from "react"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; import PropTypes from "prop-types"; import { SVG } from "./SVG"; import { CustomSVG } from "./CustomSVG"; import Button from "./Button"; import TextInput from "./TextInput"; import { Colors } from "../constants/colors/colorconstants"; +import { iconRender } from "../utils/iconRender"; +import { Spacers } from "../constants/spacers/spacers"; const MobileSidebar = ({ items, @@ -13,14 +16,24 @@ const MobileSidebar = ({ theme, className, styles, + isSearchable, + hideUserManuals, + userManualLabel, + profile, + usermanuals, + onSelect, ref }) => { + const { t } = useTranslation(); const [searchTerms, setSearchTerms] = useState({}); const [selectedItem, setSelectedItem] = useState({}); const [expandedItems, setExpandedItems] = useState({}); + const [openUserManuals, setOpenUserManuals] = useState(false); + const iconSize = Spacers.spacer6; const handleItemClick = (item, index, parentIndex) => { setSelectedItem({ item: item, index: index, parentIndex: parentIndex }); + onSelect && onSelect({ item: item, index: index, parentIndex: parentIndex }); }; const handleSearchChange = (index, value) => { @@ -47,10 +60,10 @@ const MobileSidebar = ({ const lightThemeIconColor = Colors.lightTheme.primary[2]; const renderSearch = (index) => ( -
+
handleSearchChange(index, e.target.value)} placeholder="Search" @@ -69,35 +82,50 @@ const MobileSidebar = ({ } }; - const renderItems = (items, parentIndex = -1) => - items.map((item, index) => { + const userManualsToShow = + usermanuals && usermanuals.length > 0 + ? usermanuals + : [ + { + label: "Help", + icon: "Home", + }, + { + label: "Settings", + icon: "Settings", + }, + ]; + + const renderItems = (items, parentIndex = -1) => items?.map((item, index) => { const currentIndex = parentIndex >= 0 ? `${parentIndex}-${index}` : index; const isExpanded = expandedItems[currentIndex]; const isTopLevel = parentIndex === -1; - return ( <>
handleArrowClick(item, currentIndex, parentIndex)} tabIndex={0} > - {(item.selectedIcon || item.icon) && ( - - {item.selectedIcon ? item.selectedIcon : item.icon} - - )} - {{item.label}} + {item.icon && + iconRender( + item.icon, + theme === "light" ? lightThemeIconColor : darkThemeIconColor, + "1.5rem", + "1.5rem", + `digit-msb-icon` + )} + {{item.label}} {item.children && ( - + {isExpanded ? (
{item.children && isExpanded && ( -
- {renderSearch(currentIndex)} - {renderChildItems( - filterItems(item.children, searchTerms[currentIndex] || ""), - currentIndex +
+ {isSearchable && renderSearch(currentIndex)} + {filterItems(item.children, searchTerms[currentIndex] || "") + .length > 0 ? ( + renderChildItems( + filterItems(item.children, searchTerms[currentIndex] || ""), + currentIndex, + false + ) + ) : ( +
{t("No Results Found")}
)}
)} @@ -133,30 +167,32 @@ const MobileSidebar = ({ ); }); - const renderChildItems = (items, parentIndex = -1) => - items.map((item, index) => { + const renderChildItems = (items, parentIndex = -1, isUserManual) => + items?.map((item, index) => { const currentIndex = parentIndex >= 0 ? `${parentIndex}-${index}` : index; const isExpanded = expandedItems[currentIndex]; - return ( <> -
+
handleItemClick(item, currentIndex, parentIndex)} tabIndex={0} > - { - - {item.selectedIcon ? item.selectedIcon : item.icon} - - } - {{item.label}} + {item.icon && + iconRender( + item.icon, + theme === "light" ? lightThemeIconColor : darkThemeIconColor, + iconSize, + iconSize, + `digit-icon-msb` + )} + {{item.label}} {item.children && ( { e.stopPropagation(); handleArrowClick(item, currentIndex, parentIndex); @@ -184,9 +220,12 @@ const MobileSidebar = ({ )}
-
+
{item.children && isExpanded && ( -
+
{renderChildItems(item.children, currentIndex)}
)} @@ -199,22 +238,59 @@ const MobileSidebar = ({ return (
-
- -
-
{profileName}
-
+
+ {!profile && } + {profile && ( + Profile + )} +
+
{profileName}
+
{profileNumber}
-
{renderItems(filteredItems)}
-
-
); @@ -230,6 +306,8 @@ MobileSidebar.propTypes = { ).isRequired, profileName: PropTypes.string, profileNumber: PropTypes.string, + isSearchable:PropTypes.bool, + userManualLabel:PropTypes.string }; -export default MobileSidebar; +export default MobileSidebar; \ No newline at end of file diff --git a/react/ui-components/src/atoms/Sidebar.js b/react/ui-components/src/atoms/Sidebar.js index bc8b250d99..a703c4cca5 100644 --- a/react/ui-components/src/atoms/Sidebar.js +++ b/react/ui-components/src/atoms/Sidebar.js @@ -1,5 +1,6 @@ import React, { useState, useEffect } from "react"; import PropTypes from "prop-types"; +import { useTranslation } from "react-i18next"; import { SVG, TextInput } from "../atoms"; import { IMAGES } from "../constants/images/images"; import { Colors } from "../constants/colors/colorconstants"; @@ -15,7 +16,10 @@ const Sidebar = ({ hideAccessbilityTools, expandedWidth, collapsedWidth, + onSelect, + onBottomItemClick }) => { + const { t } = useTranslation(); const [hovered, setHovered] = useState(false); const [search, setSearch] = useState(""); const [selectedItem, setSelectedItem] = useState({}); @@ -37,6 +41,7 @@ const Sidebar = ({ const handleItemClick = (item, index, parentIndex) => { setSelectedItem({ item: item, index: index, parentIndex: parentIndex }); + onSelect && onSelect({ item: item, index: index, parentIndex: parentIndex }); }; const isParentOfSelectedItem = (index) => { @@ -129,8 +134,8 @@ const Sidebar = ({ ); }; - const renderItems = (items, parentIndex = -1) => - items.map((item, index) => { + const renderItems = (items, parentIndex = -1) => + items?.map((item, index) => { const currentIndex = parentIndex >= 0 ? `${parentIndex}-${index}` : index; const isExpanded = expandedItems[currentIndex]; const isSelected = selectedItem.item === item; @@ -249,26 +254,30 @@ const Sidebar = ({ variant || "" }`} > - {renderItems(filteredItems)} + {filteredItems.length > 0 ? ( + renderItems(filteredItems) + ) : ( +
{t("No Results Found")}
+ )}
{hovered && !hideAccessbilityTools && (
-
+
onBottomItemClick && onBottomItemClick("Help")}> - Help + {t("Help")}
-
+
onBottomItemClick && onBottomItemClick("Settings")}> - Settings + {t("Settings")}
-
+
onBottomItemClick && onBottomItemClick("Logout")}> - Logout + {t("Logout")}

diff --git a/react/ui-components/src/atoms/index.js b/react/ui-components/src/atoms/index.js index f34bac2240..1a2a933957 100644 --- a/react/ui-components/src/atoms/index.js +++ b/react/ui-components/src/atoms/index.js @@ -1,4 +1,5 @@ -import Accordion from "./Accordion"; +import { Accordion } from "./Accordion"; +import {AccordionWrapper} from "./Accordion"; import ActionBar from "./ActionBar"; import ActionLinks from "./ActionLinks"; import Amount from "./Amount"; @@ -104,6 +105,7 @@ export { BottomSheet, Switch, Accordion, + AccordionWrapper, Tooltip, Banner, BodyContainer, diff --git a/react/ui-components/src/atoms/stories/Accordion.stories.js b/react/ui-components/src/atoms/stories/Accordion.stories.js index 8d6886e5f7..55c49cb1c9 100644 --- a/react/ui-components/src/atoms/stories/Accordion.stories.js +++ b/react/ui-components/src/atoms/stories/Accordion.stories.js @@ -1,5 +1,5 @@ import React from "react"; -import Accordion from "../Accordion"; +import {Accordion} from "../Accordion"; import { IMAGES } from "../../constants/images/images"; export default { @@ -198,3 +198,15 @@ Content.args = { ), content: Powered by DIGIT, }; + + +export const NestedAccordion = Template.bind({}); +NestedAccordion.args = { + isOpenInitially: false, + hideCardBorder: false, + hideDivider: false, + hideCardBg: false, + hideBorderRadius: false, + title: "NestedAccordion", + content: +}; \ No newline at end of file diff --git a/react/ui-components/src/atoms/stories/AccordionWrapper.stories.js b/react/ui-components/src/atoms/stories/AccordionWrapper.stories.js new file mode 100644 index 0000000000..16402fd11d --- /dev/null +++ b/react/ui-components/src/atoms/stories/AccordionWrapper.stories.js @@ -0,0 +1,90 @@ +import React from "react"; +import { AccordionWrapper } from "../Accordion"; +import { Accordion } from "../Accordion"; + +export default { + title: "Atoms/AccordionWrapper", + component: AccordionWrapper, + argTypes: { + className: { control: "text" }, + styles: { control: "object" }, + allowMultipleOpen: { control: "boolean" }, + addDivider: { control: "boolean" }, + }, +}; + +const Template = (args) => ; + +const children = [ + , + , + , + , +]; + +const commonArgs = { + className: "", + style: {}, + allowMultipleOpen: false, + addDivider: true, +}; + +export const Default = Template.bind({}); +Default.args = { + ...commonArgs, + children: children, +}; + +export const WithoutDivider = Template.bind({}); +WithoutDivider.args = { + ...commonArgs, + children: children, + addDivider: false, +}; + +export const WithMultipleOpen = Template.bind({}); +WithMultipleOpen.args = { + ...commonArgs, + children: children, + allowMultipleOpen:true +}; + +export const CustomStyles = Template.bind({}); +CustomStyles.args = { + ...commonArgs, + children: children, + styles: { + backgroundColor: "#FFFFFF", + border: "1px solid #d6d5d4", + borderRadius: "4px", + padding: "24px", + }, +}; diff --git a/react/ui-components/src/atoms/stories/Hamburger.stories.js b/react/ui-components/src/atoms/stories/Hamburger.stories.js index 927f05fd47..dd8ba7964f 100644 --- a/react/ui-components/src/atoms/stories/Hamburger.stories.js +++ b/react/ui-components/src/atoms/stories/Hamburger.stories.js @@ -1,16 +1,23 @@ import React from "react"; import { BrowserRouter as Router } from "react-router-dom"; -import MobileSidebar from "../MobileSidebar"; // Adjust the import path as needed -import { SVG } from "../SVG"; // Adjust the import path for SVG components +import MobileSidebar from "../MobileSidebar"; +import { SVG } from "../SVG"; + export default { title: "Atoms/Hamburger", component: MobileSidebar, argTypes: { items: { control: "object" }, + usermanuals: { control: "object" }, theme: { control: "select", options: ["dark", "light"] }, variant: { control: "select", options: ["primary", "secondary"] }, transitionDuration: { control: "number" }, + isSearchable:{control:"boolean"}, + hideUserManuals:{control:"boolean"}, + userManualLabel:{control:"text"}, + profile:{control:"text"}, + onSelect:{ action: "onChange" } }, }; @@ -23,16 +30,17 @@ const Template = (args) => ( const darkThemeItems = [ { label: "City", + icon:"Home", children: [ { path: "/", label: "City 1", - icon: , + icon: "Lightbulb", }, { path: "/", label: "City 2", - icon: , + icon: "Label", }, ], }, @@ -42,12 +50,12 @@ const darkThemeItems = [ { path: "/", label: "Language 1", - icon: , + icon: "DriveFileMove", }, { path: "/", label: "Language 2", - icon: , + icon: "Delete", }, ], }, @@ -57,24 +65,24 @@ const darkThemeItems = [ { path: "/", label: "SubModule 1", - icon: , + icon: "Accessibility", children: [ { path: "/", label: "InnerModule 1", - icon: , + icon: "Lock", }, { path: "/", label: "InnerModule 2", - icon: , + icon: "LabelImportant", }, ], }, { path: "/", label: "SubModule 2", - icon: , + icon: "CheckCircle", }, ], }, @@ -83,16 +91,17 @@ const darkThemeItems = [ const lightThemeItems = [ { label: "City", + icon:"Home", children: [ { path: "/", label: "City 1", - icon: , + icon: "Lightbulb", }, { path: "/", label: "City 2", - icon: , + icon: "Label", }, ], }, @@ -102,12 +111,12 @@ const lightThemeItems = [ { path: "/", label: "Language 1", - icon: , + icon: "DriveFileMove", }, { path: "/", label: "Language 2", - icon: , + icon: "Delete", }, ], }, @@ -117,35 +126,56 @@ const lightThemeItems = [ { path: "/", label: "SubModule 1", - icon: , - // children: [ - // { - // path: "/", - // label: "InnerModule 1", - // icon: , - // }, - // { - // path: "/", - // label: "InnerModule 2", - // icon: , - // }, - // ], + icon: "Accessibility", + children: [ + { + path: "/", + label: "InnerModule 1", + icon: "Lock", + }, + { + path: "/", + label: "InnerModule 2", + icon: "LabelImportant", + }, + ], }, { path: "/", label: "SubModule 2", - icon: , + icon: "CheckCircle", }, ], }, ]; +const exampleusermanuals = [ + { + label:"Example1", + icon:"Help" + }, + { + label:"Example2", + icon:"Settings" + } +] + +const onSelect = (e) => { + console.log(e,"event") +} + const commonArgs = { items: darkThemeItems, transitionDuration: 0.3, theme: "dark", profileName:"ProfileName", - profileNumber:'+258 6387387' + profileNumber:'+258 6387387', + isSearchable:true, + hideUserManuals:false, + userManualLabel:"UserManual", + profile:"", + usermanuals:[], + onSelect:onSelect }; export const LightTheme = Template.bind({}); @@ -155,9 +185,73 @@ LightTheme.args = { items: lightThemeItems, }; +export const LightThemeWithProfile = Template.bind({}); +LightThemeWithProfile.args = { + ...commonArgs, + theme: "light", + items: lightThemeItems, + profile:"https://cdn1.iconfinder.com/data/icons/website-internet/48/website_-_male_user-512.png" +}; + +export const LightThemeWithoutSearch = Template.bind({}); +LightThemeWithoutSearch.args = { + ...commonArgs, + theme: "light", + items: lightThemeItems, + isSearchable:false +}; + +export const LightThemeWithoutUserManuals = Template.bind({}); +LightThemeWithoutUserManuals.args = { + ...commonArgs, + theme: "light", + items: lightThemeItems, + hideUserManuals:true +}; + +export const LightThemeWithCustomUserManuals = Template.bind({}); +LightThemeWithCustomUserManuals.args = { + ...commonArgs, + theme: "light", + items: lightThemeItems, + usermanuals:exampleusermanuals +}; + export const DarkTheme = Template.bind({}); DarkTheme.args = { ...commonArgs, theme: "dark", items: darkThemeItems, }; + +export const DarkThemeWithProfile = Template.bind({}); +DarkThemeWithProfile.args = { + ...commonArgs, + theme: "dark", + items: darkThemeItems, + profile:"https://cdn1.iconfinder.com/data/icons/website-internet/48/website_-_male_user-512.png" +}; + +export const DarkThemeWithoutSearch = Template.bind({}); +DarkThemeWithoutSearch.args = { + ...commonArgs, + theme: "dark", + items: darkThemeItems, + isSearchable:false +}; + +export const DarkThemeWithoutUsermanuals = Template.bind({}); +DarkThemeWithoutUsermanuals.args = { + ...commonArgs, + theme: "dark", + items: darkThemeItems, + hideUserManuals:true +}; + +export const DarkThemeWithCustomUsermanuals = Template.bind({}); +DarkThemeWithCustomUsermanuals.args = { + ...commonArgs, + theme: "dark", + items: darkThemeItems, + usermanuals:exampleusermanuals +}; \ No newline at end of file diff --git a/react/ui-components/src/atoms/stories/SideBar.stories.js b/react/ui-components/src/atoms/stories/SideBar.stories.js index 9671e4ba29..4ea00295bb 100644 --- a/react/ui-components/src/atoms/stories/SideBar.stories.js +++ b/react/ui-components/src/atoms/stories/SideBar.stories.js @@ -14,6 +14,8 @@ export default { theme: { control: "select", options: ["dark", "light"] }, variant: { control: "select", options: ["primary", "secondary"] }, hideAccessbilityTools: { control: "boolean" }, + onSelect:{ action: "onChange" }, + onBottomItemClick:{action:"onChange"} }, }; @@ -302,10 +304,19 @@ const lightThemesecondaryitems = [ }, ]; +const onSelect = (e) =>{ + console.log(e,"selected") +} +const onBottomItemClick =(e) => { + console.log(e,"onAccessibilityClick") +} + const commonArgs = { items: darkThemeitems, transitionDuration: 0.3, theme: "dark", + onSelect:onSelect, + onBottomItemClick:onBottomItemClick }; export const DarkThemePrimarySideBar = Template.bind({}); diff --git a/react/ui-components/src/index.js b/react/ui-components/src/index.js index fb41e28cfd..b5b8fde666 100644 --- a/react/ui-components/src/index.js +++ b/react/ui-components/src/index.js @@ -1,5 +1,6 @@ import { Accordion, + AccordionWrapper, ActionBar, ActionLinks, Amount, @@ -129,6 +130,7 @@ export { MobileSidebar, BottomSheet, Accordion, + AccordionWrapper, Switch, Tooltip, Banner,