profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/abutterworth/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Adam Butterworth abutterworth edX Cambridge, MA

abutterworth/abutterworth.github.io 0

Adam Butterworth's Homepage

abutterworth/awakko-website 0

Website for San Francisco Awakko-ren

abutterworth/carbon-themes 0

A collection of themes for use with Carbon Components

abutterworth/crawler 0

A fun web crawler experiment

abutterworth/edx-frontend-site-header-2 0

Alternative Site Header

abutterworth/electron 0

Build cross platform desktop apps with JavaScript, HTML, and CSS

startedncase/crowds

started time in 20 days

Pull request review commentedx/paragon

feat: menu and menu item components

+import { useRef, useEffect } from 'react';++/**+ * A react hook to enable arrow key navigation on a component.+ */++function handleEnter({ event, currentIndex, activeElement }) {+  if (currentIndex === -1) { return; }++  activeElement.click();+  event.preventDefault();

is clicking the active element not the default behavior? (do we need this?)

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+import React from 'react';+import PropTypes from 'prop-types';+import classNames from 'classnames';+import useArrowKeyNavigationHook from '../hooks/useArrowKeyNavigation';++const Menu = ({+  as,+  arrowKeyNavigationSelector,+  children,+  ...props+}) => {+  const parentRef = useArrowKeyNavigationHook({ selectors: arrowKeyNavigationSelector });+  const className = classNames(props.className, 'pgn__menu');++  return React.createElement(+    as,+    {+      ...props,+      ref: parentRef,+      className,+    },+    (+      <>+        <div className={className}>+          {children}+        </div>+      </>+    ),
    children,

className is currently used twice in this component. See the snapshot: the html output of component is currently

<div className="pgn__menu">
  <div className="pgn__menu">
    ...
  </div>
</div>
connorhaugh

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+---+title: 'Menu'+type: 'component'+components:+- MenuItem+- Menu+categories:+- Navigation+- Buttonlike+status: 'New'+designStatus: 'Done'+devStatus: 'Done'+notes: ''+---++### MenuItem++A menu item is a link, button, or checkbox for use by any kind of menu overlay, dropdown menu, or nav menu. A menu item can be text-only or combined with an icon. Passing a component to the `as` prop, MenuItems will also be an instance of that component.++```jsx live+() => {+  return (+      <div className="bg-white p-3 rounded shadow" style={{width: 400}}>

I might skip the standalone MenuItem example. It's the first thing an engineer will see and we don't want anyone copying this example.

connorhaugh

comment created time in a month

Pull request review commentedx/paragon

feat: menu and menu item components

+import React from 'react';+import { mount } from 'enzyme';+import renderer from 'react-test-renderer';+import { MenuItem } from '..';+import Menu from '.';+import { Add, Check } from '../../icons';+import Hyperlink from '../Hyperlink';+import Button from '../Button';+import Form from '../Form';++// Mock the whole navigation modulue++describe('Menu Item renders correctly', () => {+  it('renders as just a div With empty usage', () => {+    const wrapper = mount(<Menu />);+    expect(wrapper.find('div').exists()).toEqual(true);+  });+  it('renders as expected with menu items', () => {+    const tree = renderer.create((+      <Menu>+        <MenuItem> A Menu Item</MenuItem>+        <MenuItem iconBefore={Add} stoven>A Menu Item With an Icon Before</MenuItem>+        <MenuItem iconAfter={Check}>A Menu Item With an Icon After </MenuItem>+        <MenuItem disabled>A Disabled Menu Item</MenuItem>+        <MenuItem as={Hyperlink} href="https://en.wikipedia.org/wiki/Hyperlink">A Link Menu Item</MenuItem>+        <MenuItem as={Button} variant="primary" size="inline">A Button Menu Item</MenuItem>+        <MenuItem as={Form.Checkbox}>A Checkbox Menu Item</MenuItem>+      </Menu>+    )).toJSON();+    expect(tree).toMatchSnapshot();+  });+  it('Renders disabled menutitems, but you cant click them', () => {+    const clickFn = jest.fn();+    const wrapper = mount((+      <Menu>+        <MenuItem as={Button} iconBefore={Add} onClick={clickFn} disabled>Cant Touch This</MenuItem>+      </Menu>+    ));+    expect(clickFn).toHaveBeenCalledTimes(0);+    wrapper+      .find('button')+      .simulate('click');+    expect(clickFn).toHaveBeenCalledTimes(0);+  });+});++describe('Keyoard Interactions', () => {+  const wrapper = mount(+    <Menu>+      <MenuItem>Default</MenuItem>+      <MenuItem as={Button} iconBefore={Add}>Cant Touch This</MenuItem>+      <MenuItem iconBefore={Add}>Icon Before</MenuItem>+    </Menu>,+  );++  const menuContainer = wrapper.find(Menu);+  const menuItems = wrapper.find(MenuItem);++  it('should focus on the first item after click', () => {+    menuItems.at(0).simulate('click');+    expect(menuItems.at(0) === document.activeElement);

Yes I believe this is correct

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+.pgn__menu-item {+    .pgn__menu-item-content-spacer {+      flex-grow: 1;+    }+    display: flex;+    align-items: center;+    justify-content: flex-start;+    width: 100%;+    font-family: $btn-font-family;+    font-weight: $btn-font-weight;+    color: $body-color;+    text-align: center;+    vertical-align: middle;+    user-select: none;+    background-color: transparent;+    border: $btn-border-width solid transparent;+    padding: $btn-padding-y $btn-padding-x;+    font-size: $btn-font-size;+    line-height: $btn-line-height;+    border-radius: 0;++    @include hover {+      color: $body-color;+      text-decoration: none;+    }++    // Disabled comes first so active can properly restyle+    &.disabled,+    &:disabled {+      opacity: $btn-disabled-opacity;+    }++    $background: $btn-tertiary-bg;+    $border: transparent;+    $hover-background: $btn-tertiary-hover-bg;+    $hover-border: transparent;+    $active-background: $btn-tertiary-active-bg;+    $active-border: transparent;++    color: $btn-tertiary-color;+    border-color: $border;++    @include hover {+      color: $btn-tertiary-color;+      border-color: $hover-border;+      background: $hover-background;+    }

This selector also exists above on like 22. Redundant?

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+.pgn__menu-item {+    .pgn__menu-item-content-spacer {+      flex-grow: 1;+    }+    display: flex;+    align-items: center;+    justify-content: flex-start;+    width: 100%;+    font-family: $btn-font-family;+    font-weight: $btn-font-weight;+    color: $body-color;+    text-align: center;+    vertical-align: middle;+    user-select: none;+    background-color: transparent;+    border: $btn-border-width solid transparent;+    padding: $btn-padding-y $btn-padding-x;+    font-size: $btn-font-size;+    line-height: $btn-line-height;+    border-radius: 0;++    @include hover {+      color: $body-color;+      text-decoration: none;+    }++    // Disabled comes first so active can properly restyle+    &.disabled,+    &:disabled {+      opacity: $btn-disabled-opacity;+    }++    $background: $btn-tertiary-bg;+    $border: transparent;+    $hover-background: $btn-tertiary-hover-bg;+    $hover-border: transparent;+    $active-background: $btn-tertiary-active-bg;+    $active-border: transparent;++    color: $btn-tertiary-color;+    border-color: $border;

color and border are defined above on lines 11 and 16 above. Is this redundant?

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+import React from 'react';+import { mount } from 'enzyme';+import renderer from 'react-test-renderer';+import { MenuItem } from '..';+import Menu from '.';+import { Add, Check } from '../../icons';+import Hyperlink from '../Hyperlink';+import Button from '../Button';+import Form from '../Form';++// Mock the whole navigation modulue+

imo this is an unneeded comment

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+.pgn__menu-item {+    .pgn__menu-item-content-spacer {+      flex-grow: 1;+    }+    display: flex;+    align-items: center;+    justify-content: flex-start;+    width: 100%;+    font-family: $btn-font-family;+    font-weight: $btn-font-weight;+    color: $body-color;+    text-align: center;+    vertical-align: middle;+    user-select: none;+    background-color: transparent;+    border: $btn-border-width solid transparent;+    padding: $btn-padding-y $btn-padding-x;+    font-size: $btn-font-size;+    line-height: $btn-line-height;+    border-radius: 0;++    @include hover {+      color: $body-color;+      text-decoration: none;+    }++    // Disabled comes first so active can properly restyle+    &.disabled,+    &:disabled {+      opacity: $btn-disabled-opacity;+    }++    $background: $btn-tertiary-bg;+    $border: transparent;+    $hover-background: $btn-tertiary-hover-bg;+    $hover-border: transparent;+    $active-background: $btn-tertiary-active-bg;+    $active-border: transparent;++    color: $btn-tertiary-color;+    border-color: $border;++    @include hover {+      color: $btn-tertiary-color;+      border-color: $hover-border;+      background: $hover-background;+    }++    &:not(:disabled):not(.disabled):active,+    &:not(:disabled):not(.disabled).active,+    .show > &.dropdown-toggle {+      color: $btn-tertiary-color;+      background-color: $active-background;+      border-color: $active-border;+    }++    &.focus,+    &:focus{+        font-weight: $font-weight-bolder;+        color: $btn-tertiary-color;+        background-color: $active-background;+        border-color: $active-border;+    }++    .btn-icon-before {+      margin-inline-end: 0.5rem;+      margin-left: -0.25em;+    }++    .btn-icon-after {+      margin-inline-start: 0.5rem;+      margin-right: -0.25em;+    }+  }+.pgn__menu-item:nth-last-child(1) {+    @include hover {+      border-bottom-right-radius: 0.25em;+      border-bottom-left-radius: 0.25em;+    }+}+.pgn__menu-item:nth-child(1) {+  @include hover {+    border-top-right-radius: 0.25em;+    border-top-left-radius: 0.25em;+  }+}+.pgn__menu{+  border-radius: 0.25em;+  box-shadow: $box-shadow;+  background-color: $btn-tertiary-bg;+  border-color: transparent;+}

Need empty line at end of file

connorhaugh

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+.pgn__menu-item {+    .pgn__menu-item-content-spacer {+      flex-grow: 1;+    }+    display: flex;+    align-items: center;+    justify-content: flex-start;+    width: 100%;+    font-family: $btn-font-family;+    font-weight: $btn-font-weight;+    color: $body-color;+    text-align: center;+    vertical-align: middle;+    user-select: none;+    background-color: transparent;+    border: $btn-border-width solid transparent;+    padding: $btn-padding-y $btn-padding-x;+    font-size: $btn-font-size;+    line-height: $btn-line-height;+    border-radius: 0;++    @include hover {+      color: $body-color;+      text-decoration: none;+    }++    // Disabled comes first so active can properly restyle+    &.disabled,+    &:disabled {+      opacity: $btn-disabled-opacity;+    }++    $background: $btn-tertiary-bg;+    $border: transparent;+    $hover-background: $btn-tertiary-hover-bg;+    $hover-border: transparent;+    $active-background: $btn-tertiary-active-bg;+    $active-border: transparent;++    color: $btn-tertiary-color;+    border-color: $border;++    @include hover {+      color: $btn-tertiary-color;+      border-color: $hover-border;+      background: $hover-background;+    }++    &:not(:disabled):not(.disabled):active,+    &:not(:disabled):not(.disabled).active,+    .show > &.dropdown-toggle {+      color: $btn-tertiary-color;+      background-color: $active-background;+      border-color: $active-border;+    }++    &.focus,+    &:focus{+        font-weight: $font-weight-bolder;+        color: $btn-tertiary-color;+        background-color: $active-background;+        border-color: $active-border;+    }++    .btn-icon-before {+      margin-inline-end: 0.5rem;+      margin-left: -0.25em;+    }++    .btn-icon-after {+      margin-inline-start: 0.5rem;+      margin-right: -0.25em;+    }+  }+.pgn__menu-item:nth-last-child(1) {+    @include hover {+      border-bottom-right-radius: 0.25em;+      border-bottom-left-radius: 0.25em;+    }+}+.pgn__menu-item:nth-child(1) {+  @include hover {+    border-top-right-radius: 0.25em;+    border-top-left-radius: 0.25em;+  }+}

Could simplify to :first-child and :last-child?

But you could avoid these selectors entirely if you add a background and border-radius to the menu and use overflow:hidden which I think would be appropriate here.

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+---+title: 'Menu'+type: 'component'+components:+- MenuItem+- Menu+categories:+- Navigation+- Buttonlike+status: 'New'+designStatus: 'Done'+devStatus: 'Done'+notes: ''+---++### MenuItem++A menu item is a link, button, or checkbox for use by any kind of menu overlay, dropdown menu, or nav menu. A menu item can be text-only or combined with an icon.++```jsx live+() => {+  return (+      <div className="bg-white p-3 rounded shadow" style={{width: 400}}>+        <MenuItem> A Menu Item</MenuItem>+        <MenuItem as={Button} iconBefore={Add}>A Menu Item With an Icon Before</MenuItem>+        <MenuItem iconAfter={Check}>A Menu Item With an Icon After </MenuItem>+        <MenuItem disabled>A Disabled Menu Item</MenuItem>+        <MenuItem as= {Hyperlink} href = "https://en.wikipedia.org/wiki/Hyperlink">A Link Menu Item</MenuItem>+        <MenuItem as= {Button} variant="primary" size="inline">A Button Menu Item</MenuItem>+        <MenuItem as= {Form.Checkbox} >A Checkbox Menu Item</MenuItem>+      </div>+  );+}+```++### Menu

@connorhaugh your point makes sense to me. I think just adding the modal popup example works.

connorhaugh

comment created time in a month

PullRequestReviewEvent

Pull request review commentedx/paragon

feat: menu and menu item components

+---+title: 'Menu'+type: 'component'+components:+- MenuItem+- Menu+categories:+- Navigation+- Buttonlike+status: 'New'+designStatus: 'Done'+devStatus: 'Done'+notes: ''+---++### MenuItem++A menu item is a link, button, or checkbox for use by any kind of menu overlay, dropdown menu, or nav menu. A menu item can be text-only or combined with an icon.++```jsx live+() => {+  return (+      <div className="bg-white p-3 rounded shadow" style={{width: 400}}>+        <MenuItem> A Menu Item</MenuItem>+        <MenuItem as={Button} iconBefore={Add}>A Menu Item With an Icon Before</MenuItem>+        <MenuItem iconAfter={Check}>A Menu Item With an Icon After </MenuItem>+        <MenuItem disabled>A Disabled Menu Item</MenuItem>+        <MenuItem as= {Hyperlink} href = "https://en.wikipedia.org/wiki/Hyperlink">A Link Menu Item</MenuItem>+        <MenuItem as= {Button} variant="primary" size="inline">A Button Menu Item</MenuItem>+        <MenuItem as= {Form.Checkbox} >A Checkbox Menu Item</MenuItem>+      </div>+  );+}+```++### Menu

It's probably worth adding an example of how to make a menu that has a trigger to open and close. And for menus, hitting escape should close the menu – so it may be worth adding an onEscapeKey handler prop to the component

connorhaugh

comment created time in a month

Pull request review commentedx/paragon

feat: menu and menu item components

+import React from 'react';+import PropTypes from 'prop-types';+import classNames from 'classnames';+import useArrowKeyNavigationHook from '../hooks/useArrowKeyNavigation';++const Menu = ({+  as,+  arrowKeyNavigationSelector,+  children,+  ...props+}) => {+  const parentRef = useArrowKeyNavigationHook({ selectors: arrowKeyNavigationSelector });+  const className = classNames(props.className, 'pgn__menu');++  return React.createElement(+    as,+    {+      ...props,+      ref: parentRef,+      className,+    },+    (+      <>+        <div className="bg-white">

We should avoid using css utility classes in paragon components: https://github.com/edx/paragon/blob/master/docs/decisions/0012-css-styling-conventions#L21

connorhaugh

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentedx/paragon

feat: New Scrollable component PAR-472

+@import "variables";++.pgn__scrollable-body {+    overflow-x: hidden;

The horizontal scrollbar should be fixed in a different way. It's possible some combo of width setting + padding makes the child element wider than the parent.

binodpant

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentedx/paragon

feat: New Scrollable component PAR-472

+---++title: 'Scrollable'+type: 'component'+components:+- Scrollable+categories:+- Content+status: 'New'+designStatus: 'In Progress'+devStatus: 'In Progress'+notes: |+  Adds overflow:auto scrolling to wrapped elements. And adds dropshadows when content wrapped within is scrolled up or down++---++### Scrollable area adorned with top and bottom drop shadows on scroll detection++<span>+Shadow is shown on top if you scroll upwards+Shadow is shown on bottom if you scroll downwards++If you don't specify height you will get a default height per the Scrollable component (subject to change)+</span>++#### Demo with flex container around Scrollable+```jsx live+<div style={{'height': '80vh','display': 'flex','flex-direction': 'column'}}>

This example needs to change right?

binodpant

comment created time in a month