Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/palantir/blueprint into …
Browse files Browse the repository at this point in the history
…jj/2793-fix-exceed-time-bounds
  • Loading branch information
Jacek Jagiello committed Sep 7, 2018
2 parents d84f545 + 5abc450 commit 9c6d3be
Show file tree
Hide file tree
Showing 80 changed files with 1,690 additions and 1,571 deletions.
6 changes: 2 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ jobs:
- restore_cache: *restore_cache
- run: yarn dist:libs
- run: yarn dist:apps
# skip dist:docs because we do not publish GitHub Pages from CI
- persist_to_workspace: *persist_to_workspace

test-react-16: &test-react
Expand Down Expand Up @@ -134,8 +133,7 @@ jobs:
- checkout
- attach_workspace:
at: '.'
- store_artifacts:
path: docs
- restore_cache: *restore_cache
- store_artifacts:
path: packages/docs-app/dist
- store_artifacts:
Expand All @@ -144,7 +142,7 @@ jobs:
path: packages/table-dev-app/dist
- run:
name: Submit Github comment with links to built artifacts
command: ./scripts/submit-preview-comment
command: node ./scripts/preview.js

deploy-npm:
<<: *setup_env
Expand Down
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ Blueprint is a React-based UI toolkit for the web.
It is optimized for building complex, data-dense web interfaces for _desktop applications_.
If you rely heavily on mobile interactions and are looking for a mobile-first UI toolkit, this may not be for you.


[**Read the introductory blog post ▸**](https://medium.com/@palantir/scaling-product-design-with-blueprint-25492827bb4a)

[**View the full documentation ▸**](http://blueprintjs.com/docs)

[**Try it out on CodeSandbox ▸**](https://codesandbox.io/s/rypm429574)

[**Read our FAQ on the wiki ▸**](https://github.com/palantir/blueprint/wiki/Frequently-Asked-Questions)

## :tada: 3.0 is here! :tada:
Expand Down Expand Up @@ -97,12 +100,6 @@ Run `yarn dev` from the root directory to watch changes across all packages and
Alternately, each library has its own dev script to run the docs app and watch changes to just that package (and its dependencies): `yarn dev:core`, `yarn dev:datetime`, etc.
One exception is `table`: since it has its own dev application, the `dev:table` script runs `table-dev-app` instead of the docs.

### Updating dependencies

1. Edit the `package.json` where you wish to change dependencies.
1. Run `yarn` at the root to update lockfiles.
1. Commit the result.

### Updating documentation

Much of Blueprint's documentation lives inside source code as JSDoc comments in `.tsx` files and KSS markup in `.scss` files. This documentation is extracted and converted into static JSON data using [documentalist](https://github.com/palantir/documentalist/).
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@
"@types/react-transition-group": "^2.0.6",
"@types/sinon": "^4.1.2",
"@types/webpack": "^3.8.8",
"better-handlebars": "github:wmeldon/better-handlebars",
"chai": "^4.1.2",
"circle-github-bot": "^1.0.0",
"cross-env": "^5.1.3",
"gh-pages": "^1.1.0",
"http-server": "^0.11.1",
"language-less": "github:atom/language-less",
"language-typescript": "github:giladgray/language-typescript#10.1.15",
"lerna": "^2.7.1",
"npm-run-all": "^4.1.2",
"sinon": "^4.1.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@blueprintjs/core",
"version": "3.2.0",
"version": "3.5.1",
"description": "Core styles & components",
"main": "lib/cjs/index.js",
"module": "lib/esm/index.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/common/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
@import "mixins";

// Namespace appended to the beginning of each CSS class: `.#{$ns}-button`.
$ns: "bp3" !default;
// Do not quote this value, for Less consumers.
$ns: bp3 !default;

// easily the most important variable, so it comes up top
// (so other variables can use it to define themselves)
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/common/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export const DIALOG_FOOTER = `${DIALOG}-footer`;
export const DIALOG_FOOTER_ACTIONS = `${DIALOG}-footer-actions`;
export const DIALOG_HEADER = `${DIALOG}-header`;

export const DIVIDER = `${NS}-divider`;

export const EDITABLE_TEXT = `${NS}-editable-text`;
export const EDITABLE_TEXT_CONTENT = `${EDITABLE_TEXT}-content`;
export const EDITABLE_TEXT_EDITING = `${EDITABLE_TEXT}-editing`;
Expand Down Expand Up @@ -206,6 +208,7 @@ export const START = `${NS}-start`;
export const END = `${NS}-end`;

export const SPINNER = `${NS}-spinner`;
export const SPINNER_ANIMATION = `${SPINNER}-animation`;
export const SPINNER_HEAD = `${SPINNER}-head`;
export const SPINNER_NO_SPIN = `${NS}-no-spin`;
export const SPINNER_TRACK = `${SPINNER}-track`;
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ export function isFunction(value: any): value is Function {
return typeof value === "function";
}

/**
* Returns true if `node` is null/undefined, false, empty string, or an array
* composed of those. If `node` is an array, only one level of the array is
* checked, for performance reasons.
*/
export function isReactNodeEmpty(node?: React.ReactNode, skipArray = false): boolean {
return (
node == null ||
node === "" ||
node === false ||
(!skipArray &&
Array.isArray(node) &&
// only recurse one level through arrays, for performance
(node.length === 0 || node.every(n => isReactNodeEmpty(n, true))))
);
}

/**
* Converts a React child to an element: non-empty string or number or
* `React.Fragment` (React 16.3+) is wrapped in given tag name; empty strings
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/components/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@import "card/card";
@import "collapse/collapse";
@import "context-menu/context-menu";
@import "divider/divider";
@import "dialog/dialog";
@import "editable-text/editable-text";
@import "forms/index";
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/components/button/_button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,9 @@ Styleguide button
}

.#{$ns}-button-spinner {
// spinner appears centered within button
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
}

> :not(.#{$ns}-button-spinner) {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/button/abstractButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Alignment } from "../../common/alignment";
import * as Classes from "../../common/classes";
import * as Keys from "../../common/keys";
import { IActionProps } from "../../common/props";
import { safeInvoke } from "../../common/utils";
import { isReactNodeEmpty, safeInvoke } from "../../common/utils";
import { Icon, IconName } from "../icon/icon";
import { Spinner } from "../spinner/spinner";

Expand Down Expand Up @@ -149,7 +149,7 @@ export abstract class AbstractButton<H extends React.HTMLAttributes<any>> extend
return [
loading && <Spinner key="loading" className={Classes.BUTTON_SPINNER} size={Icon.SIZE_LARGE} />,
<Icon key="leftIcon" icon={icon} />,
((text != null && text !== "") || (children != null && children !== "")) && (
(!isReactNodeEmpty(text) || !isReactNodeEmpty(children)) && (
<span key="text" className={Classes.BUTTON_TEXT}>
{text}
{children}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/components/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@page card
@page collapse
@page collapsible-list
@page divider
@page editable-text
@page html
@page html-table
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/components/divider/_divider.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2018 Palantir Technologies, Inc. All rights reserved.
// Licensed under the terms of the LICENSE file distributed with this project.

@import "../../common/variables";

$divider-margin: $pt-grid-size / 2 !default;

.#{$ns}-divider {
margin: $divider-margin;
// since the element is empty, it will occupy minimal space and only show
// the appropriate border based on direction of container.
border-right: 1px solid $pt-divider-black;
border-bottom: 1px solid $pt-divider-black;


.#{$ns}-dark & {
border-color: $pt-dark-divider-black;
}
}
17 changes: 17 additions & 0 deletions packages/core/src/components/divider/divider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
tag: new
---

@# Divider

`Divider` visually separate contents with a thin line and margin on all sides.

Dividers work best in flex layouts where they will adapt to orientation without
additional styles. Otherwise, a divider will appear as a full-width 1px-high
block element.

@reactExample DividerExample

@## Props

@interface IDividerProps
31 changes: 31 additions & 0 deletions packages/core/src/components/divider/divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the terms of the LICENSE file distributed with this project.
*/

import classNames from "classnames";
import * as React from "react";

import { DIVIDER } from "../../common/classes";
import { DISPLAYNAME_PREFIX, IProps } from "../../common/props";

export interface IDividerProps extends IProps, React.HTMLAttributes<HTMLElement> {
/**
* HTML tag to use for element.
* @default "div"
*/
tagName?: keyof JSX.IntrinsicElements;
}

// this component is simple enough that tests would be purely tautological.
/* istanbul ignore next */
export class Divider extends React.PureComponent<IDividerProps> {
public static displayName = `${DISPLAYNAME_PREFIX}.Divider`;

public render() {
const { className, tagName: TagName = "div", ...htmlProps } = this.props;
const classes = classNames(DIVIDER, className);
return <TagName {...htmlProps} className={classes} />;
}
}
5 changes: 3 additions & 2 deletions packages/core/src/components/hotkeys/_hotkeys.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
@import "../../common/variables";
@import "../../common/mixins";

.#{$ns}-key-combo .#{$ns}-key:not(:last-child) {
margin-right: $pt-grid-size / 2;
.#{$ns}-key-combo {
@include pt-flex-container(row, $pt-grid-size / 2);
align-items: center;
}

.#{$ns}-hotkey-dialog {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/components/html-select/_html-select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Styleguide select

.#{$ns}-icon {
@extend %pt-select-arrow;
@include pt-icon-colors();
}

&.#{$ns}-minimal select {
Expand Down
19 changes: 16 additions & 3 deletions packages/core/src/components/html-select/htmlSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as React from "react";
import { DISABLED, FILL, HTML_SELECT, LARGE, MINIMAL } from "../../common/classes";
import { IOptionProps } from "../../common/props";
import { IElementRefProps } from "../html/html";
import { Icon } from "../icon/icon";
import { Icon, IIconProps } from "../icon/icon";

export interface IHTMLSelectProps
extends IElementRefProps<HTMLSelectElement>,
Expand All @@ -20,6 +20,9 @@ export interface IHTMLSelectProps
/** Whether this element should fill its container. */
fill?: boolean;

/** Props to spread to the `<Icon>` element. */
iconProps?: Partial<IIconProps>;

/** Whether to use large styles. */
large?: boolean;

Expand Down Expand Up @@ -47,7 +50,17 @@ export interface IHTMLSelectProps
/* istanbul ignore next */
export class HTMLSelect extends React.PureComponent<IHTMLSelectProps> {
public render() {
const { className, disabled, elementRef, fill, large, minimal, options = [], ...htmlProps } = this.props;
const {
className,
disabled,
elementRef,
fill,
iconProps,
large,
minimal,
options = [],
...htmlProps
} = this.props;
const classes = classNames(
HTML_SELECT,
{
Expand All @@ -70,7 +83,7 @@ export class HTMLSelect extends React.PureComponent<IHTMLSelectProps> {
{optionChildren}
{htmlProps.children}
</select>
<Icon icon="double-caret-vertical" />
<Icon icon="double-caret-vertical" {...iconProps} />
</div>
);
}
Expand Down
43 changes: 33 additions & 10 deletions packages/core/src/components/icon/_icon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,33 @@

@import "~@blueprintjs/icons/src/icons";

#{$icon-classes} {
// the icon class which will contain an SVG icon
.#{$ns}-icon {
// ensure icons sit inline with text & isolate svg from surrounding elements
// (vertical alignment in flow is usually off due to svg - not an issue with flex.)
display: inline-block;
// respect dimensions exactly
flex: 0 0 auto;

&:not(:empty)::before {
// clear font icon when there's an <svg> image
// stylelint-disable-next-line declaration-no-important
content: unset !important;
}

> svg {
// prevent extra vertical whitespace
display: block;

// inherit text color unless explicit fill is set
&:not([fill]) {
fill: currentColor;
}
}
}

// intent support for both SVG and legacy font icons
#{$icon-classes} {
@each $intent, $color in $pt-intent-text-colors {
&.#{$ns}-intent-#{$intent} {
color: $color;
Expand All @@ -17,15 +41,22 @@
}
}

//
// LEGACY icon font styles
//

span.#{$ns}-icon-standard {
@include pt-icon($pt-icon-size-standard);
display: inline-block;
}

span.#{$ns}-icon-large {
@include pt-icon($pt-icon-size-large);
display: inline-block;
}

span.#{$ns}-icon {
// only apply icon font styles when <svg> image is not present
span.#{$ns}-icon:empty {
line-height: 1;
font-family: $icons20-family;
font-size: inherit;
Expand All @@ -42,11 +73,3 @@ span.#{$ns}-icon {
content: $content;
}
}

svg.#{$ns}-icon {
// respect dimensions exactly
flex: 0 0 auto;
vertical-align: top;
// inherit text color by default
fill: currentColor;
}
7 changes: 5 additions & 2 deletions packages/core/src/components/icon/icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ Many Blueprint components provide an `icon` prop which accepts an icon name

Use the `<Icon>` component to easily render __SVG icons__ in React. The `icon`
prop is typed such that editors can offer autocomplete for known icon names. The
optional `iconSize` prop determines the expected width and height of the icon
element. The component also accepts all valid HTML props for an `<svg>` element.
optional `iconSize` prop determines the exact width and height of the icon
image; the icon element itself can be sized separately using CSS.

The HTML element rendered by `<Icon>` can be customized with the `tagName` prop
(defaults to `span`), and additional props are passed to this element.

Data files in the __@blueprintjs/icons__ package provide SVG path information
for Blueprint's 300+ icons for 16px and 20px grids. The `icon` prop dictates
Expand Down
Loading

0 comments on commit 9c6d3be

Please sign in to comment.