Socket
Socket
Sign inDemoInstall

@hig/banner

Package Overview
Dependencies
Maintainers
5
Versions
284
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hig/banner - npm Package Compare versions

Comparing version 0.2.0-alpha.a6b0e91c to 0.2.0-alpha.a8872f53

.babelrc

26

package.json
{
"name": "@hig/banner",
"version": "0.2.0-alpha.a6b0e91c",
"version": "0.2.0-alpha.a8872f53",
"description": "HIG Banner",

@@ -11,4 +11,5 @@ "author": "Autodesk Inc.",

"devDependencies": {
"@hig/scripts": "0.2.0-alpha.a6b0e91c",
"@hig/styles": "0.1.0-alpha.a6b0e91c"
"@hig/eslint-config": "0.2.0-alpha.a8872f53",
"@hig/scripts": "0.2.0-alpha.a8872f53",
"@hig/styles": "0.1.0-alpha.a8872f53"
},

@@ -20,7 +21,20 @@ "peerDependencies": {

"scripts": {
"build": "hig-scripts-build"
"build": "hig-scripts-build",
"lint": "eslint ./src/**/*"
},
"dependencies": {
"hig-react": "0.29.0-alpha.a6b0e91c"
}
"@hig/icon": "0.1.0-alpha.a8872f53",
"@hig/icon-button": "0.1.0-alpha.a8872f53",
"@hig/icons": "0.1.0-alpha.a8872f53",
"@hig/themes": "0.1.0-alpha.a8872f53",
"@hig/typography": "0.1.0-alpha.a8872f53"
},
"eslintConfig": {
"extends": "@hig"
},
"eslintIgnore": [
"*.scss",
"*.json",
"*.js.snap"
]
}

@@ -5,7 +5,33 @@ import React from "react";

import { action } from "@storybook/addon-actions";
import { text, select } from "@storybook/addon-knobs/react";
import { text, select, boolean } from "@storybook/addon-knobs/react";
import { withInfo } from "@storybook/addon-info";
import { makeSelectOptions, translate as t } from "@hig/storybook/utils";
import { Button, RichText } from "hig-react";
import readme from "../../README.md";
import { Button } from "hig-react";
import Banner from "../Banner";
import * as languages from "./i18n";
const typeOptions = makeSelectOptions(Banner.types);
const placementOptions = makeSelectOptions(Banner.placements);
const knobGroupIds = {
basic: "Basic",
animation: "Animation",
a11y: "Accessibility",
actions: "Actions",
i18n: "i18n"
};
const knobLabels = {
type: "Style",
children: "Message",
placement: "Placement",
isVisible: "Visible",
label: "Label",
dismissButtonTitle: "Dismiss title",
onDismiss: "Banner dismissed",
language: "Language"
};
function getBannerKnobs(props) {

@@ -15,4 +41,5 @@ const {

placement,
children,
isVisible = true,
label,
message,
dismissButtonTitle,

@@ -24,43 +51,52 @@ onDismiss,

return {
type: select("Type", Banner.AVAILABLE_TYPES, type),
placement: select("Placement", Banner.AVAILABLE_PLACEMENTS, placement),
label: text("Label", label),
message: text("Message", message),
dismissButtonTitle: text("Dismiss title", dismissButtonTitle),
onDismiss: action("Banner dismissed", onDismiss),
labelId: "unique-id",
isVisible: true,
...otherProps
...otherProps,
type: select(knobLabels.type, typeOptions, type, knobGroupIds.basic),
children: text(knobLabels.children, children, knobGroupIds.basic),
placement: select(
knobLabels.placement,
placementOptions,
placement,
knobGroupIds.animation
),
isVisible: boolean(knobLabels.isVisible, isVisible, knobGroupIds.animation),
label: text(knobLabels.label, label, knobLabels.a11y),
dismissButtonTitle: text(
knobLabels.dismissButtonTitle,
dismissButtonTitle,
knobGroupIds.a11y
),
onDismiss: action(knobLabels.onDismiss, onDismiss, knobGroupIds.actions)
};
}
function BannerDemo({ children, ...props }) {
return (
<div style={{ marginBottom: "15px" }}>
<Banner {...getBannerKnobs(props)}>{children}</Banner>
</div>
);
}
const bannerStories = storiesOf("Banner", module);
function BannerStory({ props }) {
return <BannerDemo {...props} />;
}
bannerStories.add(
"default",
withInfo({
propTables: [Banner],
text: <RichText dangerouslySetInnerHTML={{ __html: readme }} />
})(() => {
const { children, ...otherProps } = getBannerKnobs({});
return <Banner {...otherProps}>{children}</Banner>;
})
);
const bannerStories = storiesOf("Banner", module);
const stories = [
{
description: "default",
props: {}
},
{
description: "verbose, with interactions",
props: {
bannerStories.add(
"verbose, with interactions",
withInfo({
propTables: [Banner],
text: <RichText dangerouslySetInnerHTML={{ __html: readme }} />
})(() => {
const chosenLanguage = select(
knobLabels.language,
languages.languageOptions,
"en",
knobGroupIds.i18n
);
const props = {
type: Banner.types.WARNING,
label: "PROCESS COMPLETE",
// eslint-disable-next-line max-len
message:
"Changes have been made to you document. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.",
children: t(languages, chosenLanguage, "BANNER_MESSAGE"),
/** @todo Cleanup/refactor */
children: ({ isWrappingActions }) => (
actions: ({ isWrappingActions }) => (
<Banner.Interactions isWrappingActions={isWrappingActions}>

@@ -72,3 +108,6 @@ <Banner.Action>

width={isWrappingActions ? "grow" : "shrink"}
title={text("Resolve text", "Accept Changes")}
title={text(
"Resolve text",
t(languages, chosenLanguage, "BANNER_RESOLVE_BUTTON_TEXT")
)}
/>

@@ -81,3 +120,6 @@ </Banner.Action>

width={isWrappingActions ? "grow" : "shrink"}
title={text("Reject text", "Reject Changes")}
title={text(
"Reject text",
t(languages, chosenLanguage, "BANNER_REJECT_BUTTON_TEXT")
)}
/>

@@ -87,8 +129,6 @@ </Banner.Action>

)
}
}
];
stories.forEach(({ description, props }) => {
bannerStories.add(description, () => <BannerStory props={props} />);
});
};
const { children, ...otherProps } = getBannerKnobs(props);
return <Banner {...otherProps}>{children}</Banner>;
})
);

@@ -17,6 +17,6 @@ import React, { Component } from "react";

* @property {string} [label]
* @property {string} [message]
* @property {string} [labelledBy]
* @property {any} [actions]
* @property {string} [dismissButtonTitle]
* @property {Function} [onDismiss]
* @property {string} [labelId]
* @property {boolean} [isVisible]

@@ -44,4 +44,6 @@ * @property {any} [children]

label: PropTypes.string,
/** The displayed message */
message: PropTypes.string,
/** The ID used for ARIA labeling */
labelledBy: PropTypes.string,
/** Banner actions; Any JSX, or a render prop function */
actions: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
/** Accessibility text for the dismiss button */

@@ -51,8 +53,6 @@ dismissButtonTitle: PropTypes.string,

onDismiss: PropTypes.func,
/** The ID used for ARIA labeling */
labelId: PropTypes.string,
/** Animation; Determines the visibility of the banner */
isVisible: PropTypes.bool,
/** Banner actions; Any JSX, or a render prop function */
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
/** The displayed message */
children: PropTypes.string
};

@@ -74,3 +74,3 @@

render() {
const { isVisible, children: actions } = this.props;
const { isVisible, actions } = this.props;
const { renderPresenter } = this;

@@ -77,0 +77,0 @@

@@ -7,21 +7,22 @@ import { mount } from "enzyme";

describe("banner/Banner", () => {
describe("Action", () => {
it("exposes the `Action` component", () => {
expect(Banner).toHaveProperty("Action", expect.any(Function));
});
});
const exposedComponents = ["Action", "Interactions", "Presenter"];
const componentMatcher = expect.any(Function);
describe("Interactions", () => {
it("exposes the `Interactions` component", () => {
expect(Banner).toHaveProperty("Interactions", expect.any(Function));
exposedComponents.forEach(componentName => {
describe(componentName, () => {
it(`exposes the \`${componentName}\` component`, () => {
expect(Banner).toHaveProperty(componentName, componentMatcher);
});
});
});
describe("Presenter", () => {
it("exposes the `Presenter` component", () => {
expect(Banner).toHaveProperty("Presenter", expect.any(Function));
});
});
describe("rendering", () => {
const renderedComponents = [
"BannerAnimator",
"BannerContainer",
"BannerPresenter"
];
describe("rendering", () => {
let wrapper;
beforeAll(() => {

@@ -31,2 +32,6 @@ window.requestAnimationFrame = jest.fn();

beforeEach(() => {
wrapper = mount(<Banner />);
});
afterAll(() => {

@@ -36,20 +41,10 @@ delete window.requestAnimationFrame;

it("renders the `BannerAnimator`", () => {
const wrapper = mount(<Banner />);
expect(wrapper.find("BannerAnimator")).toBePresent();
renderedComponents.forEach(componentName => {
describe(componentName, () => {
it(`renders a \`${componentName}\` component`, () => {
expect(wrapper.find(componentName)).toBePresent();
});
});
});
it("renders the `BannerContainer`", () => {
const wrapper = mount(<Banner />);
expect(wrapper.find("BannerContainer")).toBePresent();
});
it("renders the `BannerPresenter`", () => {
const wrapper = mount(<Banner />);
expect(wrapper.find("BannerPresenter")).toBePresent();
});
});
});

@@ -193,3 +193,3 @@ import { Component } from "react";

refInteractionsWrapper,
children: this.renderActions()
actions: this.renderActions()
};

@@ -196,0 +196,0 @@ }

@@ -28,3 +28,3 @@ import { shallow } from "enzyme";

expect(presenterBag).toMatchObject({
children: "foobar",
actions: "foobar",
isWrappingContent: false,

@@ -31,0 +31,0 @@ refContent: expect.any(Function),

@@ -5,3 +5,2 @@ import React from "react";

import { types, AVAILABLE_TYPES } from "../types";
import { placements, AVAILABLE_PLACEMENTS } from "../placements";

@@ -11,5 +10,3 @@ import {

DismissButton,
Icon,
InteractionsWrapper,
Label,
Message,

@@ -19,2 +16,3 @@ Notification,

} from "./presenters";
import IconBackground from "../presenters/IconBackground";

@@ -24,8 +22,7 @@ /**

* @property {string} [type]
* @property {string} [placement]
* @property {string} [label]
* @property {string} [message]
* @property {string} [labelledBy]
* @property {any} [actions]
* @property {string} [dismissButtonTitle]
* @property {Function} [onDismiss]
* @property {string} [labelId]
* @property {boolean} [isWrappingContent]

@@ -46,8 +43,7 @@ * @property {function(HTMLDivElement): any} [refContent]

type,
placement,
label,
message,
labelledBy,
actions,
dismissButtonTitle,
onDismiss,
labelId,
isWrappingContent,

@@ -57,8 +53,6 @@ refContent,

refInteractionsWrapper,
children
children: message
} = props;
const hasLabel = !!label;
const hasActions = React.Children.count(children) > 0;
const wrapperLabelledBy = hasLabel ? labelId : undefined;
const hasActions = React.Children.count(actions) > 0;

@@ -68,11 +62,10 @@ return (

type={type}
placement={placement}
hasActions={hasActions}
isWrappingContent={isWrappingContent}
labelledBy={wrapperLabelledBy}
label={label}
labelledBy={labelledBy}
>
<Icon type={type} />
<IconBackground type={type} />
<Content innerRef={refContent}>
<Notification innerRef={refNotification}>
{hasLabel ? <Label id={labelId}>{label}</Label> : null}
<Message>{message}</Message>

@@ -82,3 +75,3 @@ </Notification>

<InteractionsWrapper innerRef={refInteractionsWrapper}>
{children}
{actions}
</InteractionsWrapper>

@@ -95,6 +88,5 @@ ) : null}

type: types.PRIMARY,
placement: placements.STANDARD,
message: "Message",
dismissButtonTitle: "Dismiss",
isWrappingContent: false
isWrappingContent: false,
children: "Message"
};

@@ -105,8 +97,8 @@

type: PropTypes.oneOf(AVAILABLE_TYPES),
/** Determines the intended placement of banner */
placement: PropTypes.oneOf(AVAILABLE_PLACEMENTS),
/** The label of the message displayed */
label: PropTypes.string,
/** The displayed message */
message: PropTypes.string,
/** The ID used for ARIA labeling */
labelledBy: PropTypes.string,
/** Banner actions */
actions: PropTypes.node,
/** Accessibility text for the dismiss button */

@@ -116,4 +108,2 @@ dismissButtonTitle: PropTypes.string,

onDismiss: PropTypes.func,
/** The ID used for ARIA labeling */
labelId: PropTypes.string,
/** Determines whether the banner content wraps */

@@ -127,4 +117,4 @@ isWrappingContent: PropTypes.bool,

refInteractionsWrapper: PropTypes.func,
/** Banner actions */
/** The displayed message */
children: PropTypes.node
};
import React from "react";
import renderer from "react-test-renderer";
import { placements } from "../placements";
import { types } from "../types";

@@ -19,23 +18,22 @@ import BannerPresenter from "./BannerPresenter";

label: "HELLO",
message: "World"
children: "World"
}
},
{
description: "renders with a string as children",
description: "renders with a string as actions",
props: {
placement: placements.TOP,
children: "foobar"
actions: "foobar"
}
},
{
description: "renders with a node as children",
description: "renders with a node as actions",
props: {
dismissButtonTitle: "boom",
children: <span>foo</span>
actions: <span>foo</span>
}
},
{
description: "renders with a fragment as children",
description: "renders with a fragment as actions",
props: {
children: [<span key="0">bar</span>, <div key="1">baz</div>]
actions: [<span key="0">bar</span>, <div key="1">baz</div>]
}

@@ -42,0 +40,0 @@ }

@@ -6,7 +6,10 @@ /* eslint-disable react/prop-types */

import { Icon as BasicIcon, IconButton, Text } from "hig-react";
import { names as iconNames } from "@hig/icon";
import IconButton, { types as iconButtonTypes } from "@hig/icon-button";
import { Text } from "@hig/typography";
import { ThemeContext } from "@hig/themes";
import "./banner-presenter.scss";
import { placements } from "../placements";
import { types } from "../types";
import classNames from "../presenters/classNames";

@@ -16,32 +19,3 @@ /** @todo Reference from constant on `Text` component */

const { types: iconButtonTypes } = IconButton;
const { names: iconNames, sizes: iconSizes } = BasicIcon;
/** @type {Object.<string, string>} */
const classNames = Object.freeze({
action: "hig__banner__action",
actionsWrapper: "hig__banner__action-wrapper",
content: "hig__banner__content",
dismissButton: "hig__banner__dismiss-button",
iconBackground: "hig__banner__icon-background",
interactionsWrapper: "hig__banner__interactions-wrapper",
notification: "hig__banner__notification",
wrapper: "hig__banner",
wrapperBottom: "hig__banner--bottom",
wrapperUrgent: "hig__banner--urgent",
wrapperInteractive: "hig__banner--interactive",
wrapperPrimary: "hig__banner--primary",
wrapperComplete: "hig__banner--complete",
wrapperTop: "hig__banner--top",
wrapperWarning: "hig__banner--warning",
wrapperWrapContent: "hig__banner--wrap-content"
});
/** @type {Object.<string, string>} */
const wrapperModifiersByPlacement = {
[placements.BOTTOM]: classNames.wrapperBottom,
[placements.TOP]: classNames.wrapperTop
};
/** @type {Object.<string, string>} */
const wrapperModifiersByType = {

@@ -54,10 +28,2 @@ [types.PRIMARY]: classNames.wrapperPrimary,

/** @type {Object.<string, string>} */
const iconNamesByType = {
[types.PRIMARY]: iconNames.INFO,
[types.COMPLETE]: iconNames.COMPLETE,
[types.WARNING]: iconNames.ISSUE,
[types.URGENT]: iconNames.ERROR
};
/**

@@ -72,3 +38,2 @@ * @typedef {Object} StyledProps

* @property {string} type
* @property {string} placement
* @property {boolean} hasActions

@@ -87,4 +52,4 @@ * @property {string | undefined} [labelledBy]

type,
placement,
hasActions,
label,
labelledBy,

@@ -95,14 +60,25 @@ isWrappingContent,

const classes = cx(
classNames.wrapper,
wrapperModifiersByType[type],
wrapperModifiersByPlacement[placement],
hasActions ? classNames.wrapperInteractive : undefined,
isWrappingContent ? classNames.wrapperWrapContent : undefined
);
function classes(themeClass) {
return cx(
classNames.wrapper,
wrapperModifiersByType[type],
hasActions ? classNames.wrapperInteractive : undefined,
isWrappingContent ? classNames.wrapperWrapContent : undefined,
themeClass
);
}
return (
<div role="alert" aria-labelledby={labelledBy} className={classes}>
{children}
</div>
<ThemeContext.Consumer>
{({ themeClass }) => (
<div
role="alert"
aria-label={label}
aria-labelledby={labelledBy}
className={classes(themeClass)}
>
{children}
</div>
)}
</ThemeContext.Consumer>
);

@@ -148,19 +124,2 @@ }

/**
* @typedef {Object} IconProps
* @property {string} type
*/
/**
* @param {IconProps} props
* @returns {JSX.Element}
*/
export function Icon({ type }) {
return (
<figure className={classNames.iconBackground}>
<BasicIcon name={iconNamesByType[type]} size={iconSizes.MEDIUM} />
</figure>
);
}
/**
* @param {StyledProps} props

@@ -178,16 +137,2 @@ * @returns {JSX.Element}

/**
* @typedef {Object} LabelProps
* @property {string} [id]
* @property {any} [children]
*/
/**
* @param {LabelProps} props
* @returns {JSX.Element}
*/
export function Label({ id, children }) {
return <Text color={TEXT_COLOR} id={id}>{`${children}: `}</Text>;
}
/**
* @param {StyledProps} props

@@ -201,6 +146,2 @@ * @returns {JSX.Element}

if (typeof children === "function") {
return children();
}
return children;

@@ -207,0 +148,0 @@ }

import "./external.scss";
export { default } from "./Banner";

@@ -3,0 +4,0 @@ export { default as BannerAction } from "./BannerAction";

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc