From f277e4816bbcdadad14f908fdf138ee7be97bedc Mon Sep 17 00:00:00 2001 From: Antoine Llorca Date: Thu, 15 Mar 2018 15:04:12 -0700 Subject: [PATCH 1/6] Add pt-interactive support for tags --- packages/core/src/components/tag/_common.scss | 49 ++++++++++++++++++- packages/core/src/components/tag/tag.tsx | 21 +++++++- .../src/examples/core-examples/tagExample.tsx | 21 ++++++-- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/tag/_common.scss b/packages/core/src/components/tag/_common.scss index b506095e85..da9b1dc69c 100644 --- a/packages/core/src/components/tag/_common.scss +++ b/packages/core/src/components/tag/_common.scss @@ -1,6 +1,9 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the terms of the LICENSE file distributed with this project. +$tag-default-color: $gray1; +$dark-tag-default-color: $gray5; + $tag-icon-spacing: 3px !default; $tag-height: $pt-grid-size * 2 !default; $tag-padding: ($tag-height - $pt-icon-size-standard) / 2 !default; @@ -10,12 +13,14 @@ $tag-height-large: $pt-grid-size * 3 !default; $tag-padding-large: ($tag-height-large - $pt-icon-size-large) / 2 !default; @mixin pt-tag() { + @include pt-tag-interactive($tag-default-color, 1); + display: inline-block; position: relative; border: none; border-radius: $pt-border-radius; box-shadow: none; - background-color: $gray1; + background-color: $tag-default-color; min-width: $tag-height; padding: $tag-padding ($tag-padding * 3); line-height: $pt-icon-size-standard; @@ -27,7 +32,9 @@ $tag-padding-large: ($tag-height-large - $pt-icon-size-large) / 2 !default; } .pt-dark & { - background-color: $gray5; + @include pt-tag-interactive($dark-tag-default-color, 1); + + background-color: $dark-tag-default-color; color: $pt-text-color; } @@ -56,31 +63,69 @@ $tag-padding-large: ($tag-height-large - $pt-icon-size-large) / 2 !default; } @mixin pt-tag-intent($background-color, $text-color: $white) { + @include pt-tag-interactive($background-color, 1); + background: $background-color; color: $text-color; } @mixin pt-tag-minimal() { &:not([class*="pt-intent-"]) { + @include pt-tag-minimal-interactive($tag-default-color, 0.2); + background-color: rgba($gray3, 0.2); color: $pt-text-color; .pt-dark & { + @include pt-tag-minimal-interactive($dark-tag-default-color, 0.2); + color: $pt-dark-text-color; } } } @mixin pt-tag-minimal-intent($background-color, $text-color, $dark-text-color) { + @include pt-tag-minimal-interactive($background-color, 0.15); + background-color: rgba($background-color, 0.15); color: $text-color; .pt-dark & { + @include pt-tag-minimal-interactive($background-color, 0.25); + background-color: rgba($background-color, 0.25); color: $dark-text-color; } } +@mixin pt-tag-interactive($background-color, $opacity) { + &.pt-interactive { + cursor: pointer; + + &:hover { + background-color: rgba($background-color, $opacity - 0.1); + } + + &:active { + background-color: rgba($background-color, $opacity - 0.2); + } + } +} + +@mixin pt-tag-minimal-interactive($background-color, $opacity) { + &.pt-interactive { + cursor: pointer; + + &:hover { + background-color: rgba($background-color, $opacity + 0.1); + } + + &:active { + background-color: rgba($background-color, $opacity + 0.2); + } + } +} + @mixin pt-tag-remove() { position: absolute; top: 0; diff --git a/packages/core/src/components/tag/tag.tsx b/packages/core/src/components/tag/tag.tsx index ddd8ef3960..58de0b9636 100644 --- a/packages/core/src/components/tag/tag.tsx +++ b/packages/core/src/components/tag/tag.tsx @@ -18,6 +18,22 @@ export interface ITagProps extends IProps, IIntentProps, React.HTMLAttributes) => void; + /** * Click handler for remove button. * Button will only be rendered if this prop is defined. @@ -29,7 +45,7 @@ export class Tag extends React.PureComponent { public static displayName = "Blueprint2.Tag"; public render() { - const { active, children, className, intent, onRemove, ...htmlProps } = this.props; + const { active, children, className, intent, interactive, onClick, onRemove, ...htmlProps } = this.props; const isRemovable = Utils.isFunction(onRemove); const tagClasses = classNames( Classes.TAG, @@ -37,6 +53,7 @@ export class Tag extends React.PureComponent { { [Classes.TAG_REMOVABLE]: isRemovable, [Classes.ACTIVE]: active, + [Classes.INTERACTIVE]: interactive, }, className, ); @@ -48,7 +65,7 @@ export class Tag extends React.PureComponent { ) : null; return ( - + {children} {removeButton} diff --git a/packages/docs-app/src/examples/core-examples/tagExample.tsx b/packages/docs-app/src/examples/core-examples/tagExample.tsx index fb11fbba84..7fdb994faa 100644 --- a/packages/docs-app/src/examples/core-examples/tagExample.tsx +++ b/packages/docs-app/src/examples/core-examples/tagExample.tsx @@ -13,6 +13,7 @@ import { IntentSelect } from "./common/intentSelect"; export interface ITagExampleState { intent: Intent; + interactive: boolean; large: boolean; minimal: boolean; removable: boolean; @@ -22,6 +23,7 @@ export interface ITagExampleState { export class TagExample extends BaseExample { public state: ITagExampleState = { intent: Intent.NONE, + interactive: false, large: false, minimal: false, removable: false, @@ -34,14 +36,21 @@ export class TagExample extends BaseExample { private handleLargeChange = handleBooleanChange(large => this.setState({ large })); private handleMinimalChange = handleBooleanChange(minimal => this.setState({ minimal })); private handleRemovableChange = handleBooleanChange(removable => this.setState({ removable })); + private handleInteractiveChange = handleBooleanChange(interactive => this.setState({ interactive })); protected renderExample() { - const { intent, large, minimal, removable } = this.state; + const { intent, interactive, large, minimal, removable } = this.state; const tagClasses = classNames({ [Classes.LARGE]: large, [Classes.MINIMAL]: minimal }); const tags = this.state.tags.map(tag => { const onRemove = () => this.setState({ tags: this.state.tags.filter(t => t !== tag) }); return ( - + {tag} ); @@ -50,12 +59,18 @@ export class TagExample extends BaseExample { } protected renderOptions() { - const { intent, large, minimal, removable } = this.state; + const { intent, interactive, large, minimal, removable } = this.state; return [ [ , , , + , ], [], [