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

Add Scoped Notification Component #1785

Merged
merged 17 commits into from May 3, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,82 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`DOM snapshots SLDSScopedNotification Dark 1`] = `
<div
className="slds-p-around_medium"
>
<div
className="slds-scoped-notification slds-media slds-media_center slds-scoped-notification_dark"
role="status"
>
<div
className="slds-media__figure"
>
<span>
<svg
aria-hidden="true"
className="slds-icon slds-icon_small"
>
<use
xlinkHref="/assets/icons/utility-sprite/svg/symbols.svg#info"
/>
</svg>

</span>
</div>
<div
className="slds-media__body"
>
<p>
It looks as if duplicates exist for this lead.

<a
href="javascript:void(0);"
>
View Duplicates.
</a>
</p>
</div>
</div>
</div>
`;

exports[`DOM snapshots SLDSScopedNotification Light 1`] = `
<div
className="slds-p-around_medium"
>
<div
className="slds-scoped-notification slds-media slds-media_center slds-scoped-notification_light"
role="status"
>
<div
className="slds-media__figure"
>
<span>
<svg
aria-hidden="true"
className="slds-icon slds-icon_small slds-icon-text-default"
>
<use
xlinkHref="/assets/icons/utility-sprite/svg/symbols.svg#info"
/>
</svg>

</span>
</div>
<div
className="slds-media__body"
>
<p>
It looks as if duplicates exist for this lead.

<a
href="javascript:void(0);"
>
View Duplicates.
</a>

</p>
</div>
</div>
</div>
`;
11 changes: 11 additions & 0 deletions components/scoped-notification/__docs__/site-stories.js
@@ -0,0 +1,11 @@
// This object is imported into the documentation site. An example for the documentation site should be part of the pull request for the component. The object key is the kabob case of the "URL folder". In the case of `http://localhost:8080/components/app-launcher/`, `app-launcher` is the `key`. The folder name is created by `components.component` value in `package.json`. The following uses webpack's raw-loader plugin to get "text files" that will be eval()'d by CodeMirror within the documentation site on page load.

/* eslint-env node */
/* eslint-disable global-require */

const siteStories = [
require('raw-loader!@salesforce/design-system-react/components/scoped-notification/__examples__/light.jsx'),
require('raw-loader!@salesforce/design-system-react/components/scoped-notification/__examples__/dark.jsx'),
];

module.exports = siteStories;
12 changes: 12 additions & 0 deletions components/scoped-notification/__docs__/storybook-stories.jsx
@@ -0,0 +1,12 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { SCOPED_NOTIFICATION } from '../../../utilities/constants';
import Light from '../__examples__/light';
import Dark from '../__examples__/dark';

storiesOf(SCOPED_NOTIFICATION, module)
.addDecorator((getStory) => (
<div className="slds-p-around_medium">{getStory()}</div>
))
.add('Light', () => <Light />)
.add('Dark', () => <Dark />);
21 changes: 21 additions & 0 deletions components/scoped-notification/__examples__/dark.jsx
@@ -0,0 +1,21 @@
import React from 'react';
import IconSettings from '~/components/icon-settings';
import ScopedNotification from '~/components/scoped-notification';

class Example extends React.Component {
render() {
return (
<IconSettings iconPath="/assets/icons">
<ScopedNotification theme="dark">
<p>
It looks as if duplicates exist for this lead.{' '}
<a href="javascript:void(0);">View Duplicates.</a>
</p>
</ScopedNotification>
</IconSettings>
);
}
}
Example.displayName = 'ScopedNotificationLight';

export default Example; // export is replaced with `ReactDOM.render(<Example />, mountNode);` at runtime
21 changes: 21 additions & 0 deletions components/scoped-notification/__examples__/light.jsx
@@ -0,0 +1,21 @@
import React from 'react';
import IconSettings from '~/components/icon-settings';
import ScopedNotification from '~/components/scoped-notification';

class Example extends React.Component {
render() {
return (
<IconSettings iconPath="/assets/icons">
<ScopedNotification theme="light">
<p>
It looks as if duplicates exist for this lead.{' '}
<a href="javascript:void(0);">View Duplicates.</a>{' '}
</p>
</ScopedNotification>
</IconSettings>
);
}
}
Example.displayName = 'ScopedNotificationLight';

export default Example; // export is replaced with `ReactDOM.render(<Example />, mountNode);` at runtime
7 changes: 7 additions & 0 deletions components/scoped-notification/docs.json
@@ -0,0 +1,7 @@
{
"component": "scoped-notification",
"status": "prod",
"display-name": "Scoped Notifications",
"SLDS-component-path": "/components/scoped-notification",
"url-slug": "scoped-notifications"
}
75 changes: 75 additions & 0 deletions components/scoped-notification/index.jsx
@@ -0,0 +1,75 @@
/* Copyright (c) 2015-present, salesforce.com, inc. All rights reserved */
/* Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license */

// Implements the [Scoped Notification design pattern](https://lightningdesignsystem.com/components/scoped-notifications/) in React.
// Based on SLDS v2.4.5
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Icon from '../icon';

import { SCOPED_NOTIFICATION } from '../../utilities/constants';

const propTypes = {
/**
* CSS classes to be added to tag with `.slds-scoped-notification`. Uses `classNames` [API](https://github.com/JedWatson/classnames).
*/
className: PropTypes.oneOfType([
PropTypes.array,
PropTypes.object,
PropTypes.string,
]),
/**
* Theme for the scoped notification
*/
theme: PropTypes.oneOf(['dark', 'light']),
/**
* Icon for the scoped notification. This is currently limited to the utility set of icons.
*/
iconName: PropTypes.string,
};

const defaultProps = {
theme: 'light',
iconName: 'info',
};

/**
* A Scoped Notification Component serve advisory information for the user that is not important enough to justify an alert.
*/
class ScopedNotification extends React.Component {
render() {
return (
<div
className={classNames(
`slds-scoped-notification`,
`slds-media`,
`slds-media_center`,
this.props.theme === 'light'
? 'slds-scoped-notification_light'
: 'slds-scoped-notification_dark',
this.props.className
)}
role="status"
>
<div className="slds-media__figure">
<Icon
assistiveText={this.props.assistiveText}
category="utility"
name={this.props.iconName}
colorVariant={this.props.theme === 'light' ? undefined : 'base'}
size="small"
/>
</div>
<div className="slds-media__body">{this.props.children}</div>
</div>
);
}
}

ScopedNotification.displayName = SCOPED_NOTIFICATION;
ScopedNotification.propTypes = propTypes;
ScopedNotification.defaultProps = defaultProps;

export default ScopedNotification;
1 change: 1 addition & 0 deletions components/story-based-tests.js
Expand Up @@ -48,6 +48,7 @@ export Spinner from '../components/spinner/__docs__/storybook-stories';
// export ProgressRing from '../components/progress-ring/__docs__/storybook-stories';
// export RadioGroup from '../components/radio-group/__docs__/storybook-stories';
// export RadioButtonGroup from '../components/radio-button-group/__docs__/storybook-stories';
export ScopedNotification from '../components/scoped-notification/__docs__/storybook-stories';
// export Search from '../components/input/__docs__/search/storybook-stories';
// export Slider from '../components/slider/__docs__/storybook-stories';
// export SplitView from '../components/split-view/__docs__/storybook-stories';
Expand Down
1 change: 1 addition & 0 deletions components/storybook-stories.js
Expand Up @@ -54,6 +54,7 @@ export Picklist from '../components/menu-picklist/__docs__/storybook-stories';
export RadioGroup from '../components/radio-group/__docs__/storybook-stories';
export Radio from '../components/radio/__docs__/storybook-stories';
export RadioButtonGroup from '../components/radio-button-group/__docs__/storybook-stories';
export ScopedNotification from '../components/scoped-notification/__docs__/storybook-stories';
export Slider from '../components/slider/__docs__/storybook-stories';
export SplitView from '../components/split-view/__docs__/storybook-stories';
export Spinner from '../components/spinner/__docs__/storybook-stories';
Expand Down
7 changes: 7 additions & 0 deletions package.json
Expand Up @@ -674,6 +674,13 @@
"SLDS-component-path": "/components/radio-button-group",
"url-slug": "radio-button-groups"
},
{
"component": "scoped-notification",
"status": "prod",
"display-name": "Scoped Notifications",
"SLDS-component-path": "/components/scoped-notification",
"url-slug": "scoped-notifications"
},
{
"component": "slider",
"status": "prod",
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions utilities/constants.js
Expand Up @@ -101,6 +101,7 @@ export const PROGRESS_INDICATOR_STEP_VERTICAL =
'SLDSProgressIndicatorStepVertical';
export const PROGRESS_RING = 'SLDSProgressRing';
export const PROGRESS_BAR = 'SLDSProgressBar';
export const SCOPED_NOTIFICATION = 'SLDSScopedNotification';
export const SLIDER = 'SLDSSlider';
export const SPINNER = 'SLDSSpinner';
export const SPLIT_VIEW = 'SLDSSplitView';
Expand Down