Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #3196: Message: Override Icon using icon attribute #3214

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
150 changes: 96 additions & 54 deletions components/doc/messages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { Messages } from 'primereact/messages';
import { Message } from 'primereact/message';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import getConfig from 'next/config';
import * as CustomImage from './custom-icon-active.png';
import Image from 'next/image';

export class MessagesDemo extends Component {

Expand Down Expand Up @@ -82,7 +85,7 @@ export class MessagesDemo extends Component {
<Message severity="success" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="warn" text="Message Content" />
<Message severity="warn" icon={<Image src={CustomImage} width="20px" height="20px"/>} text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="error" text="Message Content" />
Expand Down Expand Up @@ -118,49 +121,71 @@ export class MessagesDemo extends Component {
tabName: 'Hooks Source',
content: `
import React, { useEffect, useRef } from 'react';
import { Messages } from 'primereact/messages';
import { Message } from 'primereact/message';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';

import { Messages } from '../../components/lib/messages/Messages';
import { Message } from '../../components/lib/message/Message';
import { InputText } from '../../components/lib/inputtext/InputText';
import { Button } from '../../components/lib/button/Button';
import MessagesDoc from '../../components/doc/messages';
import { DocActions } from '../../components/doc/common/docactions';
import Head from 'next/head';
import getConfig from 'next/config';
import * as CustomImage from './custom-icon-active.png';
import Image from 'next/image';

const MessagesDemo = () => {
const msgs1 = useRef(null);
const msgs2 = useRef(null);
const msgs3 = useRef(null);

useEffect(() => {
msgs1.current.show([
{ severity: 'success', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'info', summary: 'Info', detail: 'Message Content', sticky: true },
{ severity: 'warn', summary: 'Warning', detail: 'Message Content', sticky: true },
{ severity: 'error', summary: 'Error', detail: 'Message Content', sticky: true }
]);

msgs3.current.show({
severity: 'info', sticky: true, content: (
<React.Fragment>
<img alt="logo" src="showcase/images/logo.png" onError={(e) => e.target.src='https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'} width="32" />
<div className="ml-2">Always bet on Prime.</div>
</React.Fragment>
)
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const addMessages = () => {
msgs2.current.show([
{ severity: 'success', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'info', summary: 'Info', detail: 'Message Content', sticky: true },
{ severity: 'warn', summary: 'Warning', detail: 'Message Content', sticky: true },
{ severity: 'error', summary: 'Error', detail: 'Message Content', sticky: true }
]);
}

const clearMessages = () => {
msgs2.current.clear();
}
const msgs1 = useRef(null);
const msgs2 = useRef(null);
const msgs3 = useRef(null);
const contextPath = getConfig().publicRuntimeConfig.contextPath;

useEffect(() => {
msgs1.current.show([
{ severity: 'success', icon: 'pi pi-apple', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'info', summary: 'Info', detail: 'Message Content', sticky: true },
{ severity: 'warn', summary: 'Warning', detail: 'Message Content', sticky: true },
{ severity: 'error', summary: 'Error', detail: 'Message Content', sticky: true }
]);

msgs3.current.show({
severity: 'info',
sticky: true,
content: (
<React.Fragment>
<img alt="logo" src={"$'{contextPath}/images/logo.png"} onError={(e) => (e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png')} width="32" />
<div className="ml-2">Always bet on Prime.</div>
</React.Fragment>
)
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const addMessages = () => {
msgs2.current.show([
{ severity: 'success', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'info', summary: 'Info', detail: 'Message Content', sticky: true },
{ severity: 'warn', summary: 'Warning', detail: 'Message Content', sticky: true },
{ severity: 'error', summary: 'Error', detail: 'Message Content', sticky: true }
]);
};

const clearMessages = () => {
msgs2.current.clear();
};

return (
<div>
<Head>
<title>React Messages Component</title>
<meta name="description" content="Messages is used to display inline messages with various severities." />
</Head>
<div className="content-section introduction">
<div>
<h1>Messages</h1>
<p>Messages is used to display inline messages with various severities.</p>
</div>
<DocActions github="messages/index.js" />
</div>

return (
<div>
<div className="content-section implementation">
<div className="card">
<h5>Severities</h5>
<Messages ref={msgs1} />
Expand All @@ -181,24 +206,28 @@ const MessagesDemo = () => {
<Message severity="info" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="success" text="Message Content" />
<Message severity="success" icon={<Image src={CustomImage} width="20px" height="20px"/>} text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="warn" text="Message Content" />
<Message severity="warn" icon="pi pi-exclamation-triangle" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="error" text="Message Content" />
<Message severity="error" icon="pi pi-times-circle" text="Message Content" />
</div>
</div>

<h5>Validation Message</h5>
<div className="formgroup-inline mb-2">
<label htmlFor="username1" className="p-sr-only">Username</label>
<label htmlFor="username1" className="p-sr-only">
Username
</label>
<InputText id="username1" placeholder="Username" className="p-invalid mr-2" />
<Message severity="error" text="Username is required" />
</div>
<div className="formgroup-inline">
<label htmlFor="email" className="p-sr-only">email</label>
<label htmlFor="email" className="p-sr-only">
email
</label>
<InputText id="email" placeholder="Email" className="p-invalid mr-2" />
<Message severity="error" />
</div>
Expand All @@ -207,13 +236,17 @@ const MessagesDemo = () => {
<div className="field p-fluid">
<label htmlFor="username2">Username</label>
<InputText id="username2" aria-describedby="username-help" className="p-invalid mr-2" />
<small id="username-help" className="p-error">Username is not available.</small>
<small id="username-help" className="p-error">
Username is not available.
</small>
</div>
</div>
</div>
)
}
`
</div>
);
};

`
},
ts: {
tabName: 'TS Source',
Expand All @@ -223,6 +256,9 @@ import { Messages } from 'primereact/messages';
import { Message } from 'primereact/message';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import getConfig from 'next/config';
import * as CustomImage from './custom-icon-active.png';
import Image from 'next/image';

const MessagesDemo = () => {
const msgs1 = useRef(null);
Expand Down Expand Up @@ -285,7 +321,7 @@ const MessagesDemo = () => {
<Message severity="success" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="warn" text="Message Content" />
<Message severity="warn" icon={<Image src={CustomImage} width="20px" height="20px"/>} text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="error" text="Message Content" />
Expand Down Expand Up @@ -387,10 +423,10 @@ const MessagesDemo = () => {
<Message severity="info" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="success" text="Message Content" />
<Message severity="success" icon={<Image src={CustomImage} width="20px" height="20px"/>} width="20px" height="20px" />
</div>
<div className="col-12 md:col-3">
<Message severity="warn" text="Message Content" />
<Message severity="warn" icon="pi pi-exclamation-triangle" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="error" text="Message Content" />
Expand Down Expand Up @@ -662,6 +698,12 @@ messages.current.show({ life: 5000, severity: 'error', summary: 'Error Message',
<td>null</td>
<td>Style class of the element.</td>
</tr>
<tr>
<td>icon</td>
<td>string</td>
<td>null</td>
<td>Customize icon class of icon attributes</td>
</tr>
<tr>
<td>style</td>
<td>string</td>
Expand Down
26 changes: 17 additions & 9 deletions components/lib/message/Message.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import * as React from 'react';
import { classNames, ObjectUtils } from '../utils/Utils';
import { classNames, IconUtils, ObjectUtils } from '../utils/Utils';

export const Message = React.memo(
React.forwardRef((props, ref) => {
const elementRef = React.useRef(null);

React.useImperativeHandle(ref, () => ({
props,
getElement: () => elementRef.current
}));

const createIcon = () => {
return IconUtils.getJSXIcon(props.icon, { ...props.iconProps });
};

const createContent = () => {
const customIcon = createIcon();
if (props.content) {
return ObjectUtils.getJSXElement(props.content, props);
}
Expand All @@ -20,17 +30,12 @@ export const Message = React.memo(

return (
<>
<span className={icon}></span>
{props.icon ? <span className="p-inline-message-icon">{customIcon}</span> : <span className={icon}></span>}
<span className="p-inline-message-text">{text}</span>
</>
);
};

React.useImperativeHandle(ref, () => ({
props,
getElement: () => elementRef.current
}));

const otherProps = ObjectUtils.findDiffKeys(props, Message.defaultProps);
const className = classNames(
'p-inline-message p-component',
Expand Down Expand Up @@ -60,6 +65,9 @@ Message.defaultProps = {
className: null,
style: null,
text: null,
severity: 'info',
content: null
severity: null,
content: null,
icon: null,
iconProps: null,
iconPos: 'left'
};
3 changes: 3 additions & 0 deletions components/lib/message/message.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { IconType } from '../utils';

type MessageSeverityType = 'success' | 'info' | 'warn' | 'error';

Expand All @@ -11,6 +12,8 @@ export interface MessageProps extends Omit<React.DetailedHTMLProps<React.HTMLAtt
severity?: MessageSeverityType;
content?: MessageContentType;
children?: React.ReactNode;
icon?: IconType<MessageProps>;
iconProps?: React.HTMLAttributes<HTMLSpanElement>;
}

export declare class Message extends React.Component<MessageProps, any> {
Expand Down
Binary file added pages/messages/custom-icon-active.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions pages/messages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import MessagesDoc from '../../components/doc/messages';
import { DocActions } from '../../components/doc/common/docactions';
import Head from 'next/head';
import getConfig from 'next/config';
import * as CustomImage from './custom-icon-active.png';
import Image from 'next/image';

const MessagesDemo = () => {
const msgs1 = useRef(null);
Expand All @@ -16,7 +18,7 @@ const MessagesDemo = () => {

useEffect(() => {
msgs1.current.show([
{ severity: 'success', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'success', icon: 'pi pi-apple', summary: 'Success', detail: 'Message Content', sticky: true },
{ severity: 'info', summary: 'Info', detail: 'Message Content', sticky: true },
{ severity: 'warn', summary: 'Warning', detail: 'Message Content', sticky: true },
{ severity: 'error', summary: 'Error', detail: 'Message Content', sticky: true }
Expand Down Expand Up @@ -82,13 +84,13 @@ const MessagesDemo = () => {
<Message severity="info" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="success" text="Message Content" />
<Message severity="success" icon={<Image src={CustomImage} alt="custom-image" width="20px" height="20px" />} text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="warn" text="Message Content" />
<Message severity="warn" icon="pi pi-exclamation-triangle" text="Message Content" />
</div>
<div className="col-12 md:col-3">
<Message severity="error" text="Message Content" />
<Message severity="error" icon="pi pi-times-circle" text="Message Content" />
</div>
</div>

Expand Down