GithubHelp home page GithubHelp logo

openedx / paragon Goto Github PK

View Code? Open in Web Editor NEW
118.0 78.0 66.0 322.6 MB

πŸ’Ž An accessible, theme-ready design system built for learning applications and Open edX.

Home Page: https://paragon-openedx.netlify.app

License: Apache License 2.0

JavaScript 87.84% Makefile 0.04% SCSS 3.94% Shell 0.05% HTML 0.01% TypeScript 6.24% MDX 1.89%
component-library react-components accessibility design-system react

paragon's Introduction

Paragon

Build Status npm_version status license codecov NPM downloads

Purpose

Paragon is a pattern library containing accessible React components and a SCSS foundation built on Twitter Bootstrap. Paragon is developed for the Open edX platform.

Documentation lives at https://paragon-openedx.netlify.app/.

Getting Started

Getting Help

Please reach out to the Paragon Working Group (PWG):

React Components

Paragon components require React 16 or higher. To install Paragon into your project:

In terminal:

npm i --save @openedx/paragon

In your React project:

import { ComponentName } from '@openedx/paragon';

SCSS Foundation

Usage for Open edX and others:

index.scss

// ... Any custom SCSS variables should be defined here
@import '~@openedx/paragon/scss/core/core.scss';

Usage on with @edx/brand:

index.scss

@import '~@edx/brand/paragon/fonts.scss';
@import '~@edx/brand/paragon/variables.scss';
@import '~@openedx/paragon/scss/core/core.scss';
@import '~@edx/brand/paragon/overrides.scss';

Note that including fonts will affect performance. In some applications may choose not to load the custom font to keep it highly performant.

Paragon CLI

The Paragon CLI (Command Line Interface) is a tool that provides various utility commands to automate actions within the Open edX environment.

Available Commands

  • paragon install-theme [theme]: Installs the specific @edx/brand package.

Use paragon help to see more information.

Internationalization

Paragon supports internationalization for its components out of the box with the support of react-intl. You may view translated strings for each component on the documentation website by switching languages in the settings.

Due to Paragon's dependence on react-intl, that means that your whole app needs to be wrapped in its provider, e.g.:

  import { IntlProvider } from 'react-intl';
  import { messages as paragonMessages } from '@openedx/paragon';

  ReactDOM.render(
    <IntlProvider locale={usersLocale} messages={paragonMessages[usersLocale]}>
      <App />
    </IntlProvider>,
    document.getElementById('root')
  )

Note that if you are using @edx/frontend-platform's AppProvider component, you don't need a separate context as IntlProvider is already included; you would only need to add Paragon's i18n messages like this:

  import { APP_READY, subscribe, initialize } from '@edx/frontend-platform';
  import { AppProvider } from '@edx/frontend-platform/react';
  import { messages as paragonMessages } from '@openedx/paragon';
  import App from './App';
  // this is your app's i18n messages
  import appMessages from './i18n';

  subscribe(APP_READY, () => {
    ReactDOM.render(
      <AppProvider>
        <App />
      </AppProvider>,
      document.getElementById('root')
    )
  })

  initialize({
    // this will add your app's messages as well as Paragon's messages to your app
    messages: [
      appMessages,
      paragonMessages,
    ],
    // here you will typically provide other configurations for you app
    ...
  });

Contributing

Please refer to the "How to Contribute" documentation and Code of Conduct from Open edX.

The Paragon Working Group accepts bug fixes, new features, documentation, and security patches. You may find open issues here or by visiting the Paragon Working Group project board.

If you'd like to contribute a new component or update an existing component, please consider reaching out to the Paragon Working Group via the channels described above to propose your changes.

The Paragon Working Group looks forward to your contributions! πŸ’Ž

Development

Developing locally against a micro-frontend (MFE)

If you want to test the changes with local MFE setup, you need to create a "module.config.js" file in your MFE's directory containing local module overrides. After that the webpack build for your application will automatically pick your local version of Paragon and use it. The example of module.config.js file looks like this (for more details about module.config.js, refer to the frontend-build documentation.):

module.exports = {
  /*
  Modules you want to use from local source code. Adding a module here means that when 
  your MFE runs its build, it'll resolve the source from peer directories of the app.

  moduleName: the name you use to import code from the module.
  dir: The relative path to the module's source code.
  dist: The sub-directory of the source code where it puts its build artifact. Often "dist".
  */
  localModules: [
    { moduleName: '@openedx/paragon/scss/core', dir: '../src/paragon', dist: 'scss/core' },
    { moduleName: '@openedx/paragon/icons', dir: '../src/paragon', dist: 'icons' },
    // Note that using dist: 'dist' will require you to run 'npm build' in Paragon
    // to add local changes to the 'dist' directory, so that they can be picked up by the MFE.
    // To avoid doing that you can use dist: 'src' to get any local changes hot reloaded on save in the MFE.
    { moduleName: '@openedx/paragon', dir: '../src/paragon', dist: 'dist' },
  ],
};

Then, when importing Paragon's core SCSS in your MFE the import needs to begin with a tilde ~ so that path to your local Paragon repository gets resolved correctly: @import "~@openedx/paragon/scss/core";

Internationalization

When developing a new component you should generally follow three rules:

  1. The component should not have any hardcoded strings as it would be impossible for consumers to translate it

  2. Internationalize all default values of props that expect strings, i.e.

    • For places where you need to display a string, and it's okay if it is a React element use FormattedMessage, e.g. (see Alert component for a full example)

      import { FormattedMessage } from 'react-intl';
      
      <FormattedMessage 
        id="pgn.Alert.closeLabel"
        defaultMessage="Dismiss"
        description="Label of a close button on Alert component"
      />
    • For places where the display string has to be a plain JavaScript string use formatMessage, this would require access to intl object from react-intl, e.g.

      • For class components use injectIntl HOC

        import { injectIntl } from 'react-intl';
        
        class MyClassComponent extends React.Component {
          render() {
            const { altText, intl } = this.props;
            const intlAltText = altText || intl.formatMessage({
              id: 'pgn.MyComponent.altText',
              defaultMessage: 'Close',
              description: 'Close label for Toast component',
            });
            
            return (
              <IconButton
                alt={intlCloseLabel}
                onClick={() => {}}
                variant="primary"
              />
            )
          }
        }
        
        export default injectIntl(MyClassComponent);
      • For functional components use useIntl hook

        import { useIntl } from 'react-intl';
        
        const MyFunctionComponent = ({ altText }) => {
          const intls = useIntl();
          const intlAltText = altText || intl.formatMessage({
            id: 'pgn.MyComponent.altText',
            defaultMessage: 'Close',
            description: 'Close label for Toast component',
          });
        
          return (
            <IconButton
              alt={intlCloseLabel}
              onClick={() => {}}
              variant="primary"
            />
          )
        }
        
        export default MyFunctionComponent;

    Notes on the format above:

    • id is required and must be a dot-separated string of the format pgn.<componentName>.<subcomponentName>.<propName>
    • The defaultMessage is required, and should be the English display string.
    • The description is optional, but highly recommended, this text gives context to translators about the string.
  3. If your component expects a string as a prop, allow the prop to also be an element since consumers may want to also pass instance of their own translated string, for example you might define a string prop like this:

    MyComponent.PropTypes = {
      myProp: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
    };

Adding a new component

1. Start the documentation site development server

The Paragon documentation site serves both as documentation and as a workbench to create your component within. To see your component in action, you need to run the documentation site locally.

npm install
npm start
2. Create new component

To create new component run

npm run generate-component MyComponent

where MyComponent is your new component's name.

This will create a directory in /src/ that will contain templates for all necessary files to start developing the component:

MyComponent
β”œβ”€β”€ index.jsx
β”œβ”€β”€ README.md
β”œβ”€β”€ MyComponent.scss
β”œβ”€β”€ _variables.scss
└── MyComponent.test.jsx

The script will also automatically export your component from Paragon.

3. Start developing

/src/MyComponent/index.jsx is where your component lives, the file is created with the following template, edit it to implement your own component.

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

const MyComponent = React.forwardRef(({ className, children }, ref) => (
  <div ref={ref} className={classNames('png__MyComponent', className)}>
    {children}
  </div>
));

MyComponent.defaultProps = {
  className: undefined,
};

MyComponent.propTypes = {
  /** A class name to append to the base element. */
  className: PropTypes.string,
  /** Specifies contents of the component. */
  children: PropTypes.node.isRequired,
};

export default MyComponent;
4. (Optional) Add styles to your component.

If your component requires additional styling (which most likely is the case), edit created SCSS style sheet in your component's directory /src/MyComponent/MyComponent.scss which by default contains an empty class for your component.

If you wish to use SASS variables (which is the preferred way of styling the components since values can be easily overridden and customized by the consumers of Paragon), add them in /src/MyComponent/_variables.scss (this file should contain all variables specific to your component). This way the variables will also get automatically picked up by documentation site and displayed on your component's page.

Please note that you need to follow Paragon's CSS styling conventions.

5. Document your component

The documentation for your component lives in src/MyComponent/README.md. The documentation site scans this directory for markdown or mdx files to create pages. By default, the file is created with following content:

---
title: 'MyComponent'
type: 'component'
components:
- MyComponent
status: 'New'
designStatus: 'Done'
devStatus: 'Done'
notes: |
  Something special about this component
---

Describe your component here and give usage examples.

### Basic Usage

```jsx live
<MyComponent>
  Hello!
</MyComponent>
```

Some notes on the format above:

The top part of the markdown file is known as frontmatter. This metadata with consumed by the documentation site to control the title of the page and the doc site navigation.

  • title controls the page title of the generated page
  • components is a list of react components by displayName. This usually matches the name you define the component as in code. (In our example so far it is MyComponent). Components added to this list will be scanned by react-docgen for code comments and a props api table will be rendered at the bottom of the page.
  • categories is a list of categories where this page will appear the documentation site menu.
  • status, designStatus, devStatus, and notes appear in the http://localhost:8000/status page.

JSX code blocks in the markdown file can be made interactive with the live attribute. All paragon components and icons are in scope. (Note: the scope of this code block is controlled by www/components/CodeBlock.jsx).

6. Navigate to your component on the doc site and start building

Visit the documentation at http://localhost:8000 and navigate to see your README.md powered page and workbench. Changes to the README.md file will auto refresh the page.

ESLint

Paragon runs ESLint as a pre-commit hook. If your code fails linting, you will not be able to commit. To avoid hitting a giant-wall-of-linter-failures when you try to commit, we recommend configuring your editor to run ESLint. To run ESLint in the console at any time, run the following:

$ npm run lint

Paragon's ESLint config is based off eslint-config-edx, which itself is based off eslint-config-airbnb. Paragon uses ESLint 3 (and will upgrade to v4 as soon as eslint-config-airbnb releases a supported version), which itself comes with a number of built-in rules. This configuration is highly opinionated and may contain some rules with which you aren't yet familiar, like comma-dangle, but rest assured, you're writing modern, best-practice JS πŸ’…

One of the most powerful features of this ESLint config is its inclusion of eslint-plugin-jsx-a11y. This plugin actually enforces accessibility best practices at the linter level. It will catch things reviewers might not notice, like event handlers bound to noninteractive elements. Of course, it won't catch all accessibility violations, but it's a pretty good low-pass filter.

Testing

Paragon uses Jest with Enzyme for tests and coverage. Both libraries are full-featured and very well supported.

Unit Testing

Jest is an all-in-one test runner and assertion library created for use with React components. Jest's API is similar to Jasmine's and comes with functionality for mocking and spying as well. Check out the docs for more details -- they are very comprehensive.

Paragon also uses Airbnb's Enzyme library to help render our components within unit tests. Enzyme comes with a number of utilities for shallow rendering, mounting components, querying the DOM, simulating DOM events, and querying React components themselves. Read the docs for more details.

To run the unit tests, run:

npm run test

To add unit tests for a component, create a file in your component's directory named <ComponentName>.test.js. Jest will automatically pick up this file and run the tests as part of the suite. Take a look at Dropdown.test.jsx or CheckBox.test.jsx for examples of good component unit tests.

Run Unit Tests in Chrome DevTools Inspector

To run the unit tests in the Chrome DevTools inspector, run:

npm run debug-test

Then, open chrome://inspect in your Chrome browser and select the "node_modules/.bin/jest" target to open the Chrome DevTools. You can set breakpoints in Chrome DevTools or insert a debugger; statement into the code to pause execution at that point.

Screenshot of Chrome on the chrome://inspect page

Snapshot Testing

Jest has built-in snapshot testing functionality which serves as a good means of smoketesting components to ensure they render in a predictable way.

When you modify components or stories (or add new components or stories), make sure to update the snapshots or else the snapshot tests will fail. It's easy to do -- just run:

$ npm run snapshot

If the snapshot tests fail, it's generally pretty easy to tell whether it's happening because of a bug or because the snapshots need to be updated. Don't be afraid to inspect the test output for clues!

Coverage

Paragon measures code coverage using Jest's built-in --coverage flag and report it via Codecov. Shoot for 100% test coverage on your PRs, but use your best judgment if you're really struggling to cover those last few lines. At the very least, don't reduce total coverage. Codecov will fail your build if your PR reduces coverage.

Example app

Paragon components can have different behavior in the MFE environment. example app in the project root allows you to test new changes inside the MFE environment.

Steps to install the example app.

  1. npm install to install dependencies.
  2. Launch any devstack. It is required for MFE to login into the system and set up configs.
  3. npm run start-example-mfe to start the app.
  4. Go to the example/src/MyComponent.jsx and use Paragon components inside the MFE environment.

Semantic Release

Paragon uses the semantic-release package to automate its release process (creating Git tags, creating GitHub releases, and publishing to NPM).

Preview next release version from Pull Requests


As a convenience, the "Node.js CI / build (push)" check on Pull Requests includes a step to analyze the commit(s) and outputs a preview of what version semantic-release will publish if a PR gets merged. This is done using the "--dry-run" option for the semantic-release CLI, which will skip the publish/release steps. Look for a message in this CI step along the lines of "The next release version is <NEXT_RELEASE_VERSION>".

Commit Messages

semantic-release analyzes commit messages to determine whether to create a major, minor, or patch release (or to skip a release). Paragon currently uses the default conventional Angular changelog rules which means that there are 3 commit types that will trigger a release:

  1. feat (minor release)
  2. fix (patch release)
  3. perf (patch release)

There are other commit types that will not trigger a release that you can use at your own discretion. Suggested prefixes are docs, chore, style, refactor, and test for non-changelog related tasks.

Breaking Changes

Any of the previous 3 commit types combined with BREAKING CHANGE in the commit message body will trigger a major version release.

Example Breaking Change commit message
perf(pencil): remove graphiteWidth option

BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason.

Treeshaking

Paragon is distributed on npm as ES6 modules. This means that webpack can use treeshaking on any Paragon components that a consuming app is not using, resulting in greatly reduced bundle sizes.

To get treeshaking to work, your app may require some updates - most notably, Babel 7. See this PR for an example of the changes necessary to update an app to take advantage of treeshaking with Paragon: openedx/frontend-app-payment#48

People

The assigned maintainers for this component and other project details may be found in Backstage. Backstage pulls this data from the catalog-info.yml file in this repository.

Reporting Security Issues

Please do not report security issues in public. Please email [email protected].

We tend to prioritize security issues which impact the published @openedx/paragon NPM library more so than the documentation website or example React application.

paragon's People

Contributors

abutterworth avatar adamstankiewicz avatar alasdairswan avatar arizzitano avatar auraalba avatar bbaker6225 avatar brian-smith-tcril avatar davidjoy avatar dependabot[bot] avatar dsjen avatar edx-requirements-bot avatar edx-semantic-release avatar feanil avatar github-actions[bot] avatar greenkeeper[bot] avatar greenkeeperio-bot avatar inferato avatar jaebradley avatar khudym avatar mehaknasir avatar michaelroytman avatar monteri avatar pkulkoraccoongang avatar renovate[bot] avatar sarahkf avatar semantic-release-bot avatar thallada avatar viktorrusakov avatar vlasovmichael avatar zainab-amir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paragon's Issues

Bootstrap 4 checkbox and radio buttons

In the Bootstrap 4 theme, the active/checked state for checkbox and radio buttons has the same highlight that is used to indicate focus state. See the documentation example here:
https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons

The problem is that when tabbing through a page if a checkbox/radio is already selected there is no visual indicator that the element has been focused upon. As a keyboard navigating user, I can't tell that I am interacting with the checkbox or radio group if it is already selected.

In order to fix this, I would recommend removing the focus highlight from the active state and adding it back only when focused.

Example:

/* Labels receive .focus and .active classes via the Bootstrap JS */

.btn:not([disabled]):not(.disabled).active,
.btn:not([disabled]):not(.disabled):active {
    box-shadow: none;
}
.btn.focus,
.btn:focus,
.btn.focus:not([disabled]):not(.disabled).active,
.btn.focus:not([disabled]):not(.disabled):active,
.btn:not([disabled]):not(.disabled).active:focus,
.btn:not([disabled]):not(.disabled):active:focus {
  /* Bootstrap uses different focus color for each button style. This example doesn't for simplicity */
  box-shadow: 0 0 0 0.2rem rgba(0,123,255,.5)
}

An in-range update of @storybook/addon-actions is breaking the build 🚨

Version 3.4.5 of @storybook/addon-actions was just published.

Branch Build failing 🚨
Dependency @storybook/addon-actions
Current Version 3.4.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@storybook/addon-actions is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details
  • βœ… coverage/coveralls First build on greenkeeper/@storybook/addon-actions-3.4.5 at 99.342% Details

Release Notes v3.4.5

2018-May-17

Features

  • Addon-info: improve prop options #3428

Bug Fixes

  • Addon-storysource: Remove nested braces in code block #3568
  • Addon-info: Fix double quotes in prop table, add additional examples #3401
  • Ignore any unstructured output from the package managers #3563
  • Use the --use-npm flag also for version checking #3535
FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @storybook/addon-storyshots is breaking the build 🚨

Version 3.4.5 of @storybook/addon-storyshots was just published.

Branch Build failing 🚨
Dependency @storybook/addon-storyshots
Current Version 3.4.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@storybook/addon-storyshots is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details
  • βœ… coverage/coveralls First build on greenkeeper/@storybook/addon-storyshots-3.4.5 at 99.342% Details

Release Notes v3.4.5

2018-May-17

Features

  • Addon-info: improve prop options #3428

Bug Fixes

  • Addon-storysource: Remove nested braces in code block #3568
  • Addon-info: Fix double quotes in prop table, add additional examples #3401
  • Ignore any unstructured output from the package managers #3563
  • Use the --use-npm flag also for version checking #3535
FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Link component

Suggested functionality:

  • a required href prop
  • an external prop. This will add a target="_blank" to the output <a>, plus an icon and screen reader text indicating it's an external link

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected πŸ€–


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

conditional isRequired propTypes

We currently use isRequiredIf from react-proptype-conditional-require for conditional propType requirement. It's useful for when we want to require specific props based on other props -- for example, StatusAlert only requiring an onClose callback function if it actually has a close button.

However, this function has a few drawbacks. As noted on #51, it only works within the object scope where it's invoked, meaning props nested within shapes or arrays don't have access to top-level props. For example, if a table is sortable, we might want to require specific props on its headings array, but can't do this because the headings array doesn't have access to the top-level isSortable prop.

To fix this, we could go one of three ways:

  • Patch react-proptype-conditional-require upstream. The maintainer seems open to PRs. Once changes are merged, bump its version in Paragon.
  • Use a different package, like react-required-if
  • Implement our own custom validator function as documented in prop-types

New component generator

Idea: an npm script to generate a directory, starter files, and a webpack entry point for a new component, given its name. This script would be targeted towards Paragon newcomers who may not be familiar with code conventions (or React!!) and just need an easy way to get started. But, it'd make things quicker for longtime contributors as well. So you'd run something like

$ npm run create-component Breadcrumb

And then you'd end up with a new directory within /src:

└─┬ Breadcrumb
  β”œβ”€β”€ Breadcrumb.scss
  β”œβ”€β”€ Breadcrumb.test.jsx
  β”œβ”€β”€ Breadcrumb.stories.jsx
  β”œβ”€β”€ index.jsx
  └── README.md

Each file would contain a minimal amount of boilerplate (imports, storiesOf, a starter README, etc.). I'm leaning towards not including boilerplate for the actual component itself within index.jsx, since it could differ significantly between stateless/stateful. I dunno though what do you guys think??

There's probably a package out there that does this. It used to be Yeoman's jam but I think that's fallen out of style/is unmaintained. Maybe we could use something like https://www.npmjs.com/package/create-component-app?? That might be too heavyweight for our purposes though.

An in-range update of @storybook/addon-info is breaking the build 🚨

☝️ Greenkeeper’s updated Terms of Service will come into effect on April 6th, 2018.

Version 3.4.0 of @storybook/addon-info was just published.

Branch Build failing 🚨
Dependency @storybook/addon-info
Current Version 3.3.15
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@storybook/addon-info is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build failed Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of webpack-build-notifier is breaking the build 🚨

Version 0.1.22 of webpack-build-notifier was just published.

Branch Build failing 🚨
Dependency webpack-build-notifier
Current Version 0.1.21
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

webpack-build-notifier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 3 commits.

  • 87bae27 Updated version number after merging PR.
  • 5445af6 Merge pull request #22 from blvz/patch-1
  • 1c7c496 Added terminal app detection.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Add a Listbox component

Adding a listbox would be useful for selecting items out of a list.

Studio-frontend is currently working on its own implementation of an accessible listbox. Once it is verified to be actually accessible, it could be pulled out into a generic Paragon component.

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


The push permission to the Git repository is required.

semantic-release cannot push the version tag to the branch master on remote Git repository.

Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

An in-range update of @storybook/channels is breaking the build 🚨

Version 3.4.5 of @storybook/channels was just published.

Branch Build failing 🚨
Dependency @storybook/channels
Current Version 3.4.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@storybook/channels is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details
  • βœ… coverage/coveralls First build on greenkeeper/@storybook/channels-3.4.5 at 99.342% Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of webpack-build-notifier is breaking the build 🚨

Version 0.1.26 of webpack-build-notifier was just published.

Branch Build failing 🚨
Dependency webpack-build-notifier
Current Version 0.1.25
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

webpack-build-notifier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 1 commits.

  • 3453624 Added new node-notifier config options for #26.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Bootstrap 4 responsive dropdowns

Dropdown menus in Bootstrap 4 have white-space: nowrap set for each dropdown list item. On smaller screens, this causes longer list items to overflow the window, forcing horizontal scrollbars to appear.

Before:
01_bs4-dropdown-before

In order to fix this, we can use the following CSS:

.dropdown-menu {
    /* Set dropdown menu container to 100% of the viewport width minus 0.625rem  (β‰ˆ5px). */
    max-width: calc(100vw - 0.625rem);
}
.dropdown-item {
    /* Truncate long menu items with an ellipsis. */
    text-overflow: ellipsis;
    overflow: hidden;
}

This snippet adds truncates long menu items and adds an ellipsis (…).

After:
02_bs4-dropdown-after

Viewport Units are supported in all current browsers except Opera Mini. However, "Chrome does not support viewport units…in calc() until version 34." More info from caniuse.com

Calc is supported in all current browsers except Opera Mini. However, "Safari & iOS Safari (both 6 and 7) does not support viewport units (vw, vh, etc) in calc()." More info from caniuse.com

Change Modal to Fragment when enzyme can handle it

Enzyme currently does not support Fragments, which forces the modal to wrap the modal-backdrop and modal divs in a parent div, creating some DOM clutter.

The Modal could be updated to a Fragment once this fix to enzyme is released (since currently our testing cannot handle having Fragments).

An in-range update of uglifyjs-webpack-plugin is breaking the build 🚨

Version 1.1.7 of uglifyjs-webpack-plugin was just published.

Branch Build failing 🚨
Dependency uglifyjs-webpack-plugin
Current Version 1.1.6
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

uglifyjs-webpack-plugin is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 4 commits.

  • 75943e1 chore(release): 1.1.7
  • 2343274 fix(index): reduce memory consumption (cacheKey.hash) (#215)
  • 7d1b487 test: update snapshots (#214)
  • f66f6f0 docs(README): mangle.props instead of mangle.properties (#207)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Remove usage of deprecated lifecycle methods

This will involve changing our components to use new component lifecycle methods since the ones we use now are deprecated and "UNSAFE".

componentWillUpdate:

  • Dropdown

componentWillReceiveProps:

  • StatusAlert
  • asInput
  • Fieldset
  • Modal
  • CheckBox

All consuming IDAs will need to upgrade to 16.3 as well before they can pull in Paragon v4.

Refactor asInput

Over time, asInput has grown a lot to support many features. It could be split up more to compose itself out of smaller sub-components. Part of this work was done by extracting the validation message out into a ValidationMessage component. We could also make Label and InputDescription components, for example. Exporting these components to Paragon users would also allow them to compose their own custom input components if asInput does give them the flexibility that they need.

See reactstrap for examples of how granular the sub-components could get (basically one component per HTML div). Internally, Paragon could build asInput out of these more granular components so that users of Paragon could use asInput to create basic inputs quickly, but also use the granular sub-components if they need more customization than asInput provides.

There are some special-cases for checkboxes, but not for radio buttons. That part could be a bit more abstracted.

move off yarn

npm5 gives us everything yarn does and is part of the standard node ecosystem. We should switch back to npm.

I'm also wondering if we should drop the lockfile entirely in line with the "lockfiles: good for apps, bad for libs" line of thinking. After all, consumers won't necessarily respect the lockfile unless they're also using a deterministic package manager.

Reasons to stay deterministic:

  • Avoid surprise failures/loss of functionality from new package releases within our dependency range (this could be solved with hourly/nightly master builds)
  • Avoid "works on my machine"
  • We currently don't have many consumers, so library flexibility isn't particularly crucial

Reasons to drop the lockfile:

  • Consumers don't benefit from it
  • Seems like it's better practice in the node world
  • Stay closer to the metal
  • PRs containing dep changes introduce hundreds of lines worth of semantically meaningless changes

Having written all that out I think I'm leaning towards dropping it and setting up scheduled builds against master, but am open to suggestions.

Figure out what to do with theme/variant props

Currently we have a Variant utility that is built to specify many different variant types, but right now only lists status variants. These are passed to components like StatusAlert, Modal, asInput, and Fieldset as either the prop themes or variant. Are we ever going to have different variant types other than status? Does it make more sense to change the theme/variant props to accept a single string: one of Variant.status? Should we have this utility at all? We could make every component have a status prop that can be one of the 4 different status strings.

More discussion about this: #215 (comment)

Tooltip component

It's time to solve one of the Hard Problems of frontend: let's add a tooltip component! @MichaelRoytman started working on this in #64, but we ran into some tricky gotchas and I wanted to capture all of it here for future iterations.

#thestruggle

At their core, tooltips are only a little bit difficult. You have to make sure they:

  • appear at an appropriate z-index
  • have a cute little triangular arrow centered relative to both the target and the tooltip text (depending which direction the tooltip is pointing), pointing towards the target, and pointing away from the tooltip text
  • are positioned appropriately relative to their target element
    • if positioned to the top or bottom it should be horizontally centered; if to the left or right it should be vertically centered
    • all positioning must take the size of the tooltip itself into account. We cannot count on a tooltip always being the same size -- it may have varying heights or widths based on what's inside it
  • have an appropriate max-width so they text-wrap when it makes sense
  • allow consumers to insert complex HTML (tbh I'd rather not, so let's avoid this as long as we can)

But CSS though

The tooltip problem gets WAY harder when we take reusability and positioning into account. Tooltips' position must be set explicitly -- although it's possible to do via CSS alone, it's not practical as it relies on :before and :after pseudoelements. If the target element already has pseudoelements, it won't work.

Anyway, for an explicit (that is, left: 343px; top: 123px;) position to work, the tooltip element itself must have position: absolute. The position defined on a position: absolute element is relative to its closest ancestor that also has position explicitly defined (either relative or absolute). To ensure predictable behavior when positioning the tooltip element itself, the tooltip component should be responsible for rendering its container as well (likely just a container element with position: relative. I'd like to avoid inserting this container element into the DOM inline with the target element, though -- if the target element itself is absolutely positioned, or if it sits within a group of statically positioned elements, it could cause some display weirdness.

We'll probably want to use something like getBoundingClientRect to retrieve the position of the target element, then do some fancy math based on the tooltip's size (we'll have to render it outside the viewport to get its size, then cache the size) to center it.

Also what about event handling

The tooltip's target element needs onMouseOver and onMouseOut handlers to show and hide the tooltip at the appropriate times. It's preferable for the consumer not to need to explicitly define these handlers on the target element, and have the tooltip itself handle everything.

We can get around this in one of two ways:

  • tooltip wraps the target element and passes in the handlers
  • tooltip is implemented as a HOC to augment existing handlers, removing the need for excess, unnecessary DOM elements (note: React 16 can render arrays of elements with no need for a top level wrapper, so maybe this isn't as much of a problem?)

Suggested Implementation(s)

  • VERY STRONG RECOMMENDATION: tooltip uses Bootstrap's classes, but NOT Bootstrap's javascript
  • RECOMMENDATION: implement a withTooltip HOC that wraps the target element, does NOT modify its DOM in any way, but simply augments its onMouseOver and onMouseOut methods.
  • RECOMMENDATION: Use a portal to render the tooltip elsewhere in the document, so we don't have to worry about absolute/relative positioning. This may require an upgrade to React 16 (#45) but is the lowest-CSS solution.
  • Tooltip renders alongside its target and is positioned using transform3d (this is how popper works)
  • Tooltip is implemented as a wrapper component around the target element
    • we can't get a ref to the target element if it's stateless, so we need to render it within an inline-block positioned div
    • setting an explicit position on this target wrapper could mess with other CSS adjacent to it
    • this is just kind of a janky solution in general -- it results in a lot of extra, meaningless DOM elements

Suggested Starter API

position: string enum; 'top', 'bottom', 'left', 'right'; default 'top'
label: string or element
target: element (or a ref to an element?)

I want to say this component is dependent on #45. Upgrading React in Paragon means we ought to update it across all our projects that use it. I don't think we have any warnings in any of our React code, so the upgrade should go smoothly.

cc @MichaelRoytman and @jaebradley -- maybe we can put our heads together and hack on this at an office hours sometime πŸ˜›

erroneous eslint errors in stories

Per #150, eslint is throwing some bizarre errors wrt stories. Specifically, it claims Storybook addon functions are imported but not used. Eslint has thrown erroneously in the past and may be related to out-of-sync deps in eslint-config-edx, so this is worth investigating.

Remove CssJail component

This is only used in Paragon's storybook and could be safely removed. Consumers of paragon are likely already importing and applying a Bootstrap reboot so it is unneeded.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.