profile
viewpoint
Brent Traut btraut California btraut.com Web Dev / Manager @ Pinterest, tinkerer, (proud) founder of failed startups

btraut/EXIFy-Safari-Extension 7

Safari Extension that allows users to view EXIF data on any image

btraut/sudo 3

Sudo – simple, elegant Sudoku: an iOS app

btraut/eol-loader 2

Webpack loader to replace EOL characters with the platform's default character.

btraut/gestalt 1

Gestalt is a set of React UI that enforces Pinterest’s design language.

btraut/ClassCreate 0

ClassCreate is an extremely barebones function that aids classical inheritance programming patterns in Javascript.

btraut/commonjs-assert 0

simple assertion library for javascript

btraut/DefinitelyTyped 0

The repository for high quality TypeScript type definitions.

btraut/express-validator 0

An express.js middleware for node-validator.

btraut/HLSpriteKit 0

SpriteKit scene and node subclasses, plus various utilities.

btraut/OCISL 0

Open Community Indie Software License

pull request commentpinterest/gestalt

Remove prop-types

Probably worth updating the description on this. I love the changes, but there's historical context worth capturing here.

chrislloyd

comment created time in 6 days

Pull request review commentpinterest/gestalt

Fix Box types

 const SizeDisplayPropType = PropTypes.oneOf([   'inlineBlock', ]); -// $FlowFixMe[prop-missing]-Box.propTypes = {+// $FlowFixMe

What's the reason for this $FlowFixMe? I'm surprised it doesn't make you label the suppression type.

chrislloyd

comment created time in 6 days

Pull request review commentpinterest/gestalt

Internal: Flow: Enable types-first

 type Props = {|   text: string, |}; -export default function Badge(props: Props) {+export default function Badge(props: Props): React.Element<'span'> {

Does it make sense to be this specific? I typically type all component returns as React.Node since it shouldn't matter externally what it is.

christianvuerings

comment created time in 22 days

issue commentpinterest/gestalt

Box ref: No overload matches this call.

Sorry @v4iv, we don't use TypeScript at Pinterest (yet). The type definitions in DT were created by a random contributor and they're pretty out of date at this point. If you'd like to submit an update, you're more than welcome. You may even find some luck in porting over the flow types from the Gestalt source.

v4iv

comment created time in 22 days

pull request commentpinterest/gestalt

Masonry/defaultLayout: Add a layout `basicCentered` to center justify grid content

Adding more context here: this PR is an extension of the former https://github.com/pinterest/gestalt/pull/905. It fixes a bug that existed in that PR, but it's essentially the same approach as far as the API is concerned. Again, I'm looking to @bishwei and @chrislloyd for any additional feedback/concerns.

The addition of rawItemCount to the layout function is not my favorite, but the layout really needs that information to do its job properly. FWIW: Masonry9 always passes the full list of items to layout functions even if we don't have layout info yet. This prevents the need to pass that additional information separately.

As far as I'm concerned, this change is fine and I'm going to approve. Would just love to see more eyes from others.

mminute

comment created time in a month

Pull request review commentpinterest/gestalt

Touchable: Add inline prop

 card(         defaultValue: true,         href: 'fullHeightWidthExample',       },+      {+        name: 'inline',+        type: 'boolean',

boolean props :(

Perhaps this could have display: 'block' | 'boolean' with default block?

dangerismycat

comment created time in a month

Pull request review commentpinterest/gestalt

[DatePicker] New DatePicker component in new gestalt-datepicker package

+**/__*__/**

I read it as files that are in the form of __FOO__. Looks like __snapshots__ fit that description.

AlbertCarreras

comment created time in a month

Pull request review commentpinterest/gestalt

Tooltip: fix state update on unmounted component warning

+// @flow strict+import { useEffect, useRef } from 'react';

It took me reading this file a few times before I fully understood it. Since you added this file as a peer to all other source/components as opposed to inline to Tooltip.js, can you add a comments describing what it does?

christianvuerings

comment created time in a month

Pull request review commentpinterest/gestalt

Touchable: forward ref, inline prop, touch feedback, and more (BREAKING CHANGE)

 card(         name: 'onTouch',         type:           '({ event: SyntheticMouseEvent<HTMLDivElement> | SyntheticKeyboardEvent<HTMLDivElement> }) => void',-        required: true,         href: 'basicExample',       },+      {+        name: 'pressBackgroundEnabled',

we might be inviting more unnecessary re-render of Touchable because the array reference is new each time parent renders

As long as we don't have side-effects based on these re-renders, I highly doubt this will be a problem. It's technically okay to set a contract with the parent component to maintain memoization of params if we really want stability. I'm not saying we should or shouldn't go with an array, but just adding my 2 cents that re-rendering probably shouldn't be a big concern.

jackhsu978

comment created time in a month

pull request commentpinterest/gestalt

WIP[Masonry]- Add option to center justify grid content

fwiw, with Masonry9, I actually carved out a generic property bag of "layout specific settings" that Masonry passes to the layouts. justifyContent would be a perfect example of these given that it may not apply to all custom layout types. I had originally suggested to Mason that he just creates a separate layout type for the time being given that it's a happy medium between amount of new code and as little disruption as possible to pinboard.

mminute

comment created time in a month

pull request commentpinterest/gestalt

WIP[Masonry]- Add option to center justify grid content

@chrislloyd @bishwei I wanted your thoughts on this as well. I talked with Mason and he's aware that we'll need to change our gridCentered styles as well, but this was the starting point. We discussed two options:

  1. Creating a basicCentered layout, or
  2. Adding an option into the existing basic layout that chooses to either center or left-align.

There's tradeoffs to both, and it's possible I'm missing other options, so I'd love your feedback.

mminute

comment created time in a month

pull request commentpinterest/gestalt

Docs: Add search

Duuuuuude! This is so cool!!!

christianvuerings

comment created time in a month

push eventpinterest/gestalt

Tiago Romero Garcia

commit sha 5587e335512fdf3411afe3359bd9204521a57eab

Button, IconButton, Touchable: Update docs and examples (#894) Co-authored-by: Tiago Romero Garcia <tromerogarcia@pinterest.com>

view details

push time in a month

PR merged pinterest/gestalt

Button, IconButton, Touchable: Update docs and examples patch release

TODO

  • [X] Accessibility checkup
  • [X] Update documentation
  • [X] Add/update Tests
  • [X] Format PR title: ComponentName: Description.

Adopting suggestions by @christianvuerings on https://github.com/pinterest/gestalt/pull/889

+18 -18

1 comment

3 changed files

themindfuldev

pr closed time in a month

issue commentpinterest/gestalt

Masonry stacking items and only rendering a single row

I would love a PR, @Narutuffy!

To be honest, we could use a lot of love on the Masonry documentation. There's a lot of gotchyas and best practices that are left up to developers to discover on their own today.

oyeanuj

comment created time in 2 months

issue closedpinterest/gestalt

Pass additional props to the component in Masonry

Right now only three fixed props are being passed to the component in masonry (those are data: T, itemIdx: number, and isMeasuring: boolean). There should be an optional additional props which could be sent to the component used by Masonry.

closed time in 2 months

Narutuffy

issue commentpinterest/gestalt

Pass additional props to the component in Masonry

What are you passing currently into data? Can you just pass the ref along with its corresponding data?

Narutuffy

comment created time in 2 months

issue commentpinterest/gestalt

Pass additional props to the component in Masonry

Can you tell me more about what you're trying to accomplish? There's two ways you could accomplish the same thing today:

  1. data is already your property bag. As far as Masonry is concerned, there's no conceptual difference between data and other additional props, so you could just combine those into data. Just know that if you do this by creating objects, you should memoize those objects to prevent unstable data items on re-render.

  2. While the comp function is expected to be pure and idempotent, you can break that expectation if you're careful. You could just have the comp function close over variables in the outer scope (either other local variables in a function component or even class properties such as state/props in a class component). The risk here is that updating those variables won't necessarily cause Masonry to re-render or to re-measure the affected items, so it's up to you to take more manual control.

Narutuffy

comment created time in 2 months

Pull request review commentpinterest/gestalt

Modal: Fix shadows on scroll

 export default function Modal({     }   }; +  const updateShadows = () => {+    const target = content.current;+    if (!target) {+      return;+    }+    const hasVerticalScrollbar = target.clientHeight < target.scrollHeight;+    setShowTopShadow(hasVerticalScrollbar && target.scrollTop > 0);+    setShowBottomShadow(+      hasVerticalScrollbar &&+        target.offsetHeight + target.scrollTop < target.scrollHeight+    );+  };++  React.useEffect(() => {+    window.addEventListener('resize', updateShadows);+    return () => {+      window.removeEventListener('resize', updateShadows);+    };+  }, []);++  React.useEffect(() => {+    updateShadows();+  }, []);+

This code makes me realize we don't have the hooks exhaustive deps linter plugged in properly. In this case, the useEffect calls should have updateShadows set as deps, and updateShadows should be memoized. I'm fairly certain there's no bugs in the way you've written it, but it'd be better to make it future-proof.

christianvuerings

comment created time in 2 months

push eventJPArriola/gestalt

Brent Traut

commit sha 01a984b015aaa82a1a17da485db26b47f8d6feac

One more update to changelog

view details

push time in 2 months

push eventJPArriola/gestalt

Brent Traut

commit sha 481fc46b81743339438067cd0ff2dd0c5b991634

Removed next version from the log since it's not released yet

view details

push time in 2 months

Pull request review commentpinterest/gestalt

VideoControls: overwriting overflow default behavior on timestamp text

  </details> +## 1.47.1 (May 7, 2020)+

Oh, no need to add the date here since we haven't released it yet. This should go under the "unreleased" part.

JPArriola

comment created time in 2 months

pull request commentpinterest/gestalt

VideoControls: overwriting overflow default behavior on timestamp text

@JPArriola: Can you please add an entry in the CHANGELOG?

JPArriola

comment created time in 2 months

Pull request review commentpinterest/gestalt

Table: add basic table components

+// @flow+import * as React from 'react';+import { Table } from 'gestalt';+import Card from './components/Card.js';+import Example from './components/Example.js';+import PageHeader from './components/PageHeader.js';+import PropTable from './components/PropTable.js';++const cards = [];+const card = c => cards.push(c);++card(+  <PageHeader+    name="Table"+    description="The Table contains the following composable elements: Table, Table.Body, Table.Cell, Table.Header, Table.HeaderCell, Table.Row."+  />+);++card(+  <PropTable+    Component={Table}+    props={[+      {+        name: 'children',+        type: 'React.Node',+      },+    ]}+  />+);++card(+  <Example+    name="Example: Basic Table"+    defaultCode={`+<Table>+  <Table.Header>+    <Table.Row>+      <Table.HeaderCell>+        <Text weight="bold">Name</Text>+      </Table.HeaderCell>+      <Table.HeaderCell>+        <Text weight="bold">House</Text>+      </Table.HeaderCell>+      <Table.HeaderCell>+        <Text weight="bold">Birthday</Text>+      </Table.HeaderCell>+    </Table.Row>+  </Table.Header>+  <Table.Body>+    <Table.Row>+      <Table.Cell>+        <Text>Luna Lovegood</Text>+      </Table.Cell>+      <Table.Cell>+        <Text>Ravenclaw</Text>+      </Table.Cell>+      <Table.Cell>+        <Text>June 25, 1993</Text>+      </Table.Cell>+    </Table.Row>+    <Table.Row>+      <Table.Cell>+        <Text>Draco Malfoy</Text>+      </Table.Cell>+      <Table.Cell>+        <Text>Slytherin</Text>+      </Table.Cell>+      <Table.Cell>+        <Text>December 3, 1992</Text>+      </Table.Cell>+    </Table.Row>+  </Table.Body>+</Table>+`}+  />+);++card(<Card name="Table.Body" />);++card(+  <PropTable+    Component={Table.Body}+    props={[+      {+        name: 'children',+        type: 'React.Node',+      },+    ]}+  />+);++card(<Card name="Table.Cell" />);++card(+  <PropTable+    Component={Table.Cell}+    props={[+      {+        name: 'children',+        type: 'React.Node',+      },+      {+        name: 'colSpan',+        type: 'number',+        defaultValue: 1,+      },+      {+        name: 'rowSpan',+        type: 'number',+        defaultValue: 1,+      },+    ]}+  />+);++card(<Card name="Table.Header" />);++card(+  <PropTable+    Component={Table.Header}+    props={[+      {+        name: 'children',+        type: 'React.Node',

Is it allowed for Table.Header to have components other than Table.HeaderCell as children? If not, I would type this as Table.HeaderCell | Array<Table.HeaderCell> and add a corresponding check in the code.

Same goes for regular cells (outside header).

PayalModi

comment created time in 2 months

Pull request review commentmicrosoft/ReSub

2.3.0: Added an auto-subscribe wrapper for functional components to u…

 export function warnIfAutoSubscribeEnabled<T extends Function>(target: InstanceT      return descriptor; }++const autoSubscribeHookHandler = {+    masterVal: 0,+    handle(self: any, store: StoreBase, key: string) {+        const [ _, setter ] = useState(this.masterVal);+        useEffect(() => {+            const token = store.subscribe(() => {+                const val = ++this.masterVal;+                if (this.masterVal > 1000000000) {+                    this.masterVal = 0;+                }

No need to do all this fancy stuff. Just pass {} into the setter and it'll fail reference checks every time thus triggering a re-render.

deregtd

comment created time in 3 months

Pull request review commentmicrosoft/ReSub

2.3.0: Added an auto-subscribe wrapper for functional components to u…

 describe('AutoSubscribe', function() {      runTests(makeComponent); });++it('Test hook system', function() {+    SimpleStoreInstance = new SimpleStore();++    function FuncComp(): JSX.Element {+        const val = SimpleStoreInstance.getDataSingleKeyed();+        return <>{ val.toString() }</>;

I hate that TS makes you do this. Function components should be allowed to return strings directly. :(

deregtd

comment created time in 3 months

Pull request review commentpinterest/gestalt

Masonry: Add RTL support for Masonry Grid to have 1st element at top …

 type Props<T> = {|           from: number,         }       ) => void | boolean | {}),+  rtlLayout?: boolean,

nit: I'm always suspicious of whether booleans communicate their impact properly. How do you feel about naming this something along the lines of layoutDirection: 'rtl' | 'ltr' and then setting a defaultProps to ltr?

vincenttian

comment created time in 3 months

pull request commentpinterest/gestalt

Masonry: Add RTL support for Masonry Grid to have 1st element at top …

Everything here looks good to me. It's possible at some point that we'll want to carve out a separate "layoutOptions" that contains things like "rtlLayout", but that's a matter for another day. @bishwei, @chrislloyd, or @christianvuerings -- can you all take a look as well? I'd love a second set of eyes on this. As for corresponding pinboard changes, I've reached out to @vincenttian in our #gestalt channel.

vincenttian

comment created time in 3 months

more