Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7378ac4
refactor: add gap between icon and text message
bishalshrestha013 Jul 15, 2025
cbf26d9
feat: add close message functionality
bishalshrestha013 Jul 15, 2025
e27a55a
feat: add codeblock for message demo
bishalshrestha013 Jul 15, 2025
ff7a733
feat: add serverity for message
bishalshrestha013 Jul 15, 2025
ef1f136
feat: add showIcon to show default icon
bishalshrestha013 Jul 15, 2025
bd0f0d7
feat: add example message using showIcon prop
bishalshrestha013 Jul 15, 2025
c53df3c
refactor: update message prop to support type react node
bishalshrestha013 Jul 15, 2025
2732f14
refactor: update translations
bishalshrestha013 Jul 15, 2025
8c73f82
refactor: update message to sentence case
bishalshrestha013 Jul 15, 2025
f147a9e
feat: add usage section and default column in properties table
bishalshrestha013 Jul 15, 2025
24938f9
refactor: update style to align close message to the right
bishalshrestha013 Jul 16, 2025
4bba829
refactor: udpate style to align close icon to the right
bishalshrestha013 Jul 16, 2025
7f2ff6c
refactor: update the color of message
bishalshrestha013 Jul 16, 2025
df6d8c2
refactor: update the color contrast
bishalshrestha013 Jul 16, 2025
73dc665
refactor: update color
bishalshrestha013 Jul 16, 2025
30b3c47
refactor: add translations
bishalshrestha013 Jul 16, 2025
206acbb
refactor: change the background color to make ligher
bishalshrestha013 Jul 16, 2025
7ad343d
refactor: add translations for description of props
bishalshrestha013 Jul 16, 2025
44257f6
feat: add support for passing array of messages
bishalshrestha013 Jul 16, 2025
1bded61
refactor: remove width of close message icon
bishalshrestha013 Jul 16, 2025
67de5d3
refactor: update translations
bishalshrestha013 Jul 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 162 additions & 5 deletions apps/demo/src/Views/Ui/components/Message.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
import { useTranslation } from "@dzangolab/react-i18n";
import { Button, Message, Page } from "@dzangolab/react-ui";
import { Button, Message, Page, TDataTable } from "@dzangolab/react-ui";
import { useNavigate } from "react-router-dom";

import { Section } from "../../../components/Demo";
import { CodeBlock, Section } from "../../../components/Demo";

export const MessageDemo = () => {
const [t] = useTranslation("ui");
const navigate = useNavigate();

const propertiesData = [
{
default: "false",
description: t("message.propertiesDescription.enableClose"),
prop: "enableClose",
type: "boolean",
},
{
default: "-",
description: t("message.propertiesDescription.icon"),
prop: "icon",
type: "string | ReactNode",
},
{
default: "-",
description: t("message.propertiesDescription.message"),
prop: "message",
type: "string | string[] | ReactNode",
},
{
default: "-",
description: t("message.propertiesDescription.onClose"),
prop: "onClose",
type: "() => void",
},
{
default: "info",
description: t("message.propertiesDescription.severity"),
prop: "severity",
type: `"info" | "success" | "warning" | "danger"`,
},
{
default: "true",
description: t("message.propertiesDescription.showIcon"),
prop: "showIcon",
type: "boolean",
},
];

return (
<Page
title={t("message.title")}
subtitle={t("message.subtitle")}
toolbar={
<Button
label={t("buttons.back")}
Expand All @@ -20,10 +60,127 @@ export const MessageDemo = () => {
/>
}
>
<Section>
<Section title={t("headers.usage")}>
<p>{t("common.usage", { component: "Message" })}</p>
<CodeBlock exampleCode='import { Message } from "@dzangolab/react-ui"' />
</Section>

<Section title={t("message.usage.basic")}>
<Message message={t("message.contents.content1")} />
<CodeBlock exampleCode='<Message message="Season sale: Up to 50% off selected items!" />' />
</Section>

<Section title={t("message.usage.customMessage")}>
<Message message={<b>{t("message.contents.content1")}</b>} />
<CodeBlock exampleCode="<Message message={<b>Season sale: Up to 50% off selected items!</b>} />" />
</Section>

<Section title={t("message.usage.arrayMessage")}>
<Message
message={[
t("message.contents.content1"),
t("message.contents.content2"),
t("message.contents.content3"),
]}
enableClose={true}
/>
<CodeBlock
exampleCode="<Message
message={
[
'Season Sale: Enjoy massive discounts with up to 50% off on a wide range of selected items — from fashion to electronics, don’t miss out on these limited-time offers!',
'New features just launched! Check them out!',
'New Year, New You: Start fresh with our services!'
]}
enableClose={true}
/>"
/>
</Section>

<Section title={t("message.usage.icons.icon")}>
<Message
message={t("message.contents.content2")}
icon="pi pi-android"
/>
<CodeBlock
exampleCode='<Message
message="New features just launched! Check them out!"
icon="pi pi-android"
/>'
/>
</Section>

<Section title={t("message.usage.icons.customIcon")}>
<Message
message={t("message.contents.content3")}
icon={<i className="pi pi-bell" />}
/>
<CodeBlock
exampleCode='<Message
message="New Year, New You: Start fresh with our services!"
icon={<i className="pi pi-bell" />}
/>'
/>
</Section>

<Section title={t("message.usage.enableClose")}>
<Message
message="This is a very important message."
icon={<i className="pi pi-info-circle" />}
enableClose={true}
icon={<i className="pi pi-bell" />}
message={t("message.contents.content4")}
/>
<CodeBlock
exampleCode='<Message
message="We value your feedback: take our quick survey!"
icon={<i className="pi pi-bell" />}
enableClose={true}
/>'
/>
</Section>

<Section title={t("message.usage.severity")}>
<Message message={t("message.contents.info")} severity="info" />
<Message message={t("message.contents.success")} severity="success" />
<Message message={t("message.contents.warning")} severity="warning" />
<Message message={t("message.contents.danger")} severity="danger" />

<CodeBlock
exampleCode='<Message message="Info message" severity="info" />
<Message message="Success message" severity="success" />
<Message message="Warning message" severity="warning" />
<Message message="Danger message" severity="danger" />'
/>
</Section>
<Section title={t("message.usage.hideIcon")}>
<Message message={t("message.contents.content1")} showIcon={false} />
<CodeBlock exampleCode='<Message message="Season sale: Up to 50% off selected items!" showIcon={false} />' />
</Section>
<Section
title={t("headers.propertiesValue", {
value: "MessageProperties",
})}
>
<TDataTable
columns={[
{
accessorKey: "prop",
header: t("propertiesTable.header.properties"),
},
{
accessorKey: "type",
header: t("propertiesTable.header.type"),
},
{
accessorKey: "default",
header: t("propertiesTable.header.default"),
},
{
accessorKey: "description",
header: t("propertiesTable.header.description"),
},
]}
data={propertiesData}
paginated={false}
/>
</Section>
</Page>
Expand Down
42 changes: 41 additions & 1 deletion apps/demo/src/locales/en/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
"common": {
"usage": "To use the {{component}} component, simply import it into your React file:"
},
"propertiesTable": {
"header": {
"default": "Default",
"description": "Description",
"properties": "Properties",
"type": "Type"
}
},
"headers": {
"buttons": "Buttons",
"data": "Data",
Expand Down Expand Up @@ -215,7 +223,39 @@
}
},
"message": {
"title": "Message"
"contents": {
"content1": "Season Sale: Enjoy massive discounts with up to 50% off on a wide range of selected items — from fashion to electronics, don’t miss out on these limited-time offers!",
"content2": "New features just launched! Check them out!",
"content3": "New Year, New You: Start fresh with our services!",
"content4": "We value your feedback: take our quick survey!",
"content5": "Warning: Limited time only! Sale ends soon!",
"danger": "Danger message",
"info": "Info message",
"success": "Success message",
"warning": "Warning message"
},
"subtitle": "The Message component displays contextual messages with optional icons and a closable action. It supports custom slots, making it flexible for various use cases.",
"propertiesDescription": {
"enableClose": "Displays a close icon if true, allowing the message to be dismissed.",
"icon": "Icon to display alongside the message.",
"message": "The message text to display in the component.",
"onClose": "Function to be called when the message is closed.",
"severity": "Defines the styling severity of the message. Defaults to 'info'.",
"showIcon": "Show default icon based on severity or custom icon if provided."
},
"title": "Message",
"usage": {
"arrayMessage": "Array of message",
"basic": "Basic",
"customMessage": "Custom message",
"enableClose": "Enable close",
"hideIcon": "Hide default icon",
"icons": {
"customIcon": "Custom icon",
"icon": "Icon"
},
"severity": "Severity"
}
},
"modal": {
"title": "Modal",
Expand Down
42 changes: 41 additions & 1 deletion apps/demo/src/locales/fr/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
"common": {
"usage": "To use the {{component}} component, simply import it into your React file (fr):"
},
"propertiesTable": {
"header": {
"default": "Default (fr)",
"description": "Description (fr)",
"properties": "Properties (fr)",
"type": "Type (fr)"
}
},
"headers": {
"buttons": "Buttons (fr)",
"data": "Data (fr)",
Expand Down Expand Up @@ -215,7 +223,39 @@
}
},
"message": {
"title": "Message (fr)"
"contents": {
"content1": "Season Sale: Enjoy massive discounts with up to 50% off on a wide range of selected items — from fashion to electronics, don’t miss out on these limited-time offers! (fr)",
"content2": "New features just launched! Check them out! (fr)",
"content3": "New Year, New You: Start fresh with our services! (fr)",
"content4": "We value your feedback: take our quick survey! (fr)",
"content5": "Warning: Limited time only! Sale ends soon! (fr)",
"danger": "Danger message (fr)",
"info": "Info message (fr)",
"success": "Success message (fr)",
"warning": "Warning message (fr)"
},
"subtitle": "The Message component displays contextual messages with optional icons and a closable action. It supports custom slots, making it flexible for various use cases. (fr)",
"propertiesDescription": {
"enableClose": "Displays a close icon if true, allowing the message to be dismissed. (fr)",
"icon": "Icon to display alongside the message. (fr)",
"message": "The message text to display in the component. (fr)",
"onClose": "Function to be called when the message is closed. (fr)",
"severity": "Defines the styling severity of the message. Defaults to 'info'. (fr)",
"showIcon": "Show default icon based on severity or custom icon if provided. (fr)"
},
"title": "Message (fr)",
"usage": {
"arrayMessage": "Array of message (fr)",
"basic": "Basic (fr)",
"customMessage": "Custom message (fr)",
"enableClose": "Enable close (fr)",
"hideIcon": "Hide default icon (fr)",
"icons": {
"customIcon": "Custom icon (fr)",
"icon": "Icon (fr)"
},
"severity": "Severity (fr)"
}
},
"modal": {
"title": "Modal (fr)",
Expand Down
77 changes: 69 additions & 8 deletions packages/ui/src/Message/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,84 @@
import { ReactNode } from "react";
import { ReactNode, useState } from "react";

type MessageProperties = {
message: string;
icon?: string | ReactNode;
enableClose?: boolean;
icon?: ReactNode;
message: string[] | ReactNode;
onClose?: () => void;
severity?: "info" | "success" | "warning" | "danger";
showIcon?: boolean;
};

const Message = ({ message, icon }: MessageProperties) => {
const Message = ({
onClose,
enableClose = false,
message,
icon,
severity = "info",
showIcon = true,
}: MessageProperties) => {
const [showMessage, setShowMessage] = useState(true);

const defaultSeverityIcons = {
info: "pi pi-info-circle",
success: "pi pi-check-circle",
warning: "pi pi-exclamation-triangle",
danger: "pi pi-times-circle",
};

const handleClose = () => {
setShowMessage(false);

if (onClose) {
onClose();
}
};

if (!showMessage) {
return null;
}

const renderIcon = () => {
return (
<span className="icon" data-testid="icon">
{typeof icon === "string" ? <i className={icon} /> : icon}
{!icon ? (
<i className={defaultSeverityIcons[severity]} />
) : typeof icon === "string" ? (
<i className={icon} />
) : (
icon
)}
</span>
);
};

const renderMessageContent = () => {
if (typeof message === "string") {
return <span>{message}</span>;
}

if (Array.isArray(message)) {
return (
<ul>
{message.map((message_, index) => (
<li key={index}>{message_}</li>
))}
</ul>
);
}

return message;
};

return (
<div className="message">
{renderIcon()}
<span className="message-content">{message}</span>
<div className={`message ${severity}`}>
{showIcon && renderIcon()}
<div className="message-content">{renderMessageContent()}</div>
{enableClose && (
<span className="close-message" onClick={handleClose}>
<i className="pi pi-times"></i>
</span>
)}
</div>
);
};
Expand Down
Loading