From 62b5df2cfcccb9efd0de0cd3eca5a4e43e2c921c Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 16:03:11 +0200 Subject: [PATCH 01/20] Initial commit --- packages/core/src/common/classes.ts | 10 ++ packages/core/src/components/_index.scss | 1 + packages/core/src/components/components.md | 1 + packages/core/src/components/index.ts | 2 + .../core/src/components/section/_section.scss | 59 ++++++++++ .../components/section/section-content.tsx | 44 ++++++++ .../core/src/components/section/section.md | 17 +++ .../core/src/components/section/section.tsx | 89 +++++++++++++++ .../src/examples/core-examples/index.ts | 1 + .../examples/core-examples/sectionExample.tsx | 106 ++++++++++++++++++ 10 files changed, 330 insertions(+) create mode 100644 packages/core/src/components/section/_section.scss create mode 100644 packages/core/src/components/section/section-content.tsx create mode 100644 packages/core/src/components/section/section.md create mode 100644 packages/core/src/components/section/section.tsx create mode 100644 packages/docs-app/src/examples/core-examples/sectionExample.tsx diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index 33b5af5dad..4eccb1d9f1 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -72,6 +72,8 @@ export const INTENT_DANGER = intentClass(Intent.DANGER)!; export const FOCUS_DISABLED = `${NS}-focus-disabled`; export const FOCUS_STYLE_MANAGER_IGNORE = `${NS}-focus-style-manager-ignore`; +export const PADDED = `${NS}-padded`; + // text utilities export const UI_TEXT = `${NS}-ui-text`; export const RUNNING_TEXT = `${NS}-running-text`; @@ -213,6 +215,14 @@ export const MULTISTEP_DIALOG_RIGHT_PANEL = `${MULTISTEP_DIALOG}-right-panel`; export const MULTISTEP_DIALOG_NAV_TOP = `${MULTISTEP_DIALOG}-nav-top`; export const MULTISTEP_DIALOG_NAV_RIGHT = `${MULTISTEP_DIALOG}-nav-right`; +export const SECTION = `${NS}-section`; +export const SECTION_HEADER = `${SECTION}-header`; +export const SECTION_HEADER_LEFT = `${SECTION_HEADER}-left`; +export const SECTION_HEADER_TITLE = `${SECTION_HEADER}-title`; +export const SECTION_HEADER_SUB_TITLE = `${SECTION_HEADER}-sub-title`; +export const SECTION_HEADER_RIGHT = `${SECTION_HEADER}-right`; +export const SECTION_CONTENT = `${SECTION}-content`; + export const NAVBAR = `${NS}-navbar`; export const NAVBAR_GROUP = `${NAVBAR}-group`; export const NAVBAR_HEADING = `${NAVBAR}-heading`; diff --git a/packages/core/src/components/_index.scss b/packages/core/src/components/_index.scss index 3c065d9702..b45a29ebf0 100644 --- a/packages/core/src/components/_index.scss +++ b/packages/core/src/components/_index.scss @@ -31,6 +31,7 @@ @import "popover/popover"; @import "portal/portal"; @import "progress-bar/progress-bar"; +@import "section/section"; @import "skeleton/skeleton"; @import "slider/slider"; @import "spinner/spinner"; diff --git a/packages/core/src/components/components.md b/packages/core/src/components/components.md index 8700a5195d..65371e41dd 100644 --- a/packages/core/src/components/components.md +++ b/packages/core/src/components/components.md @@ -22,6 +22,7 @@ @page panel-stack2 @page progress-bar @page resize-sensor +@page section @page skeleton @page spinner @page tabs diff --git a/packages/core/src/components/index.ts b/packages/core/src/components/index.ts index 53586422ac..68ad4bb853 100644 --- a/packages/core/src/components/index.ts +++ b/packages/core/src/components/index.ts @@ -97,6 +97,8 @@ export { ResizeEntry, ResizeSensor, ResizeSensorProps } from "./resize-sensor/re export { HandleHtmlProps, HandleInteractionKind, HandleProps, HandleType } from "./slider/handleProps"; export { MultiSlider, MultiSliderProps, SliderBaseProps } from "./slider/multiSlider"; export { NumberRange, RangeSlider, RangeSliderProps } from "./slider/rangeSlider"; +export { Section, SectionProps } from "./section/section"; +export { SectionContent, SectionContentProps } from "./section/section-content"; export { Slider, SliderProps } from "./slider/slider"; export { Spinner, SpinnerProps, SpinnerSize } from "./spinner/spinner"; export { Tab, TabId, TabProps } from "./tabs/tab"; diff --git a/packages/core/src/components/section/_section.scss b/packages/core/src/components/section/_section.scss new file mode 100644 index 0000000000..027202a92d --- /dev/null +++ b/packages/core/src/components/section/_section.scss @@ -0,0 +1,59 @@ +@use "sass:math"; +@import "../../common/variables"; + +.#{$ns}-section { + padding: 0; + width: 100%; + + &-header { + align-items: stretch; + display: flex; + justify-content: space-between; + position: relative; + width: 100%; + gap: $pt-grid-size; + min-height: 50px; + padding: $pt-grid-size $pt-grid-size $pt-grid-size $pt-grid-size * 2; + + border-bottom: 1px solid $pt-divider-black; + + &.#{$ns}-dark, + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + + &-left { + align-items: center; + display: flex; + gap: $pt-grid-size; + } + + &-title { + margin-bottom: 0; + } + + &-sub-title { + margin-top: 2px; + } + + &-right { + align-items: center; + display: flex; + } + } + + &-content { + &.#{$ns}-padded { + padding: $pt-grid-size * 2; + } + + &:not(:last-child) { + border-bottom: 1px solid $pt-divider-black; + + &.#{$ns}-dark, + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + } + } +} diff --git a/packages/core/src/components/section/section-content.tsx b/packages/core/src/components/section/section-content.tsx new file mode 100644 index 0000000000..04d6b8abce --- /dev/null +++ b/packages/core/src/components/section/section-content.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import * as React from "react"; + +import { Classes } from "../../common"; +import { DISPLAYNAME_PREFIX, HTMLDivProps, Props } from "../../common/props"; + +export interface SectionContentProps extends Props, HTMLDivProps, React.RefAttributes { + padded?: boolean; +} + +/** + * Section content component. + * + * @see https://blueprintjs.com/docs/#core/components/section-content + */ +export const SectionContent: React.FC = React.forwardRef((props, ref) => { + const { className, children, padded, ...htmlProps } = props; + const classes = classNames(Classes.SECTION_CONTENT, { [Classes.PADDED]: padded }, className); + return ( +
+ {children} +
+ ); +}); +SectionContent.defaultProps = { + padded: true, +}; +SectionContent.displayName = `${DISPLAYNAME_PREFIX}.SectionContent`; diff --git a/packages/core/src/components/section/section.md b/packages/core/src/components/section/section.md new file mode 100644 index 0000000000..d987c4c6bf --- /dev/null +++ b/packages/core/src/components/section/section.md @@ -0,0 +1,17 @@ +@# Section + +todo + +@reactExample SectionExample + +@## Props + +@interface SectionProps + +@# Section Content + +- Multiple section content can be added under one section, they will be stacked. + +@## Props + +@interface SectionContentProps diff --git a/packages/core/src/components/section/section.tsx b/packages/core/src/components/section/section.tsx new file mode 100644 index 0000000000..1817076c2b --- /dev/null +++ b/packages/core/src/components/section/section.tsx @@ -0,0 +1,89 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import * as React from "react"; + +import { IconName } from "@blueprintjs/icons"; + +import { Classes, Elevation } from "../../common"; +import { SECTION_HEADER } from "../../common/classes"; +import { DISPLAYNAME_PREFIX, MaybeElement, Props } from "../../common/props"; +import { Card, CardProps } from "../card/card"; +import { H6 } from "../html/html"; +import { Icon } from "../icon/icon"; + +export interface SectionProps + extends Props, + Omit, + React.RefAttributes { + /** + * Name of a Blueprint UI icon (or an icon element) to render in the + * section's header. Note that the header will only be rendered if `sectionTitle` is + * provided. + */ + icon?: IconName | MaybeElement; + + /** + * Title of the section. + */ + sectionTitle?: JSX.Element | string; + + /** + * Sub-title of the section. + * Note that the header will only be rendered if `sectionTitle` is provided. + */ + subtitle?: JSX.Element | string; + + /** + * Element to render on the right side of the section header + */ + rightItem?: JSX.Element; +} + +/** + * Section component. + * + * @see https://blueprintjs.com/docs/#core/components/section + */ +export const Section: React.FC = React.forwardRef((props, ref) => { + const { className, icon, sectionTitle, rightItem, subtitle, children, ...cardProps } = props; + const classes = classNames(Classes.SECTION, className); + return ( + +
+
+ {sectionTitle && icon && ( + + )} +
+ {sectionTitle &&
{sectionTitle}
} + {sectionTitle && subtitle && ( +
+ {subtitle} +
+ )} +
+
+ {rightItem &&
{rightItem}
} +
+ + {children} +
+ ); +}); +Section.defaultProps = {}; +Section.displayName = `${DISPLAYNAME_PREFIX}.Section`; diff --git a/packages/docs-app/src/examples/core-examples/index.ts b/packages/docs-app/src/examples/core-examples/index.ts index 9b82562c05..e550cab033 100644 --- a/packages/docs-app/src/examples/core-examples/index.ts +++ b/packages/docs-app/src/examples/core-examples/index.ts @@ -63,6 +63,7 @@ export * from "./popoverSizingExample"; export * from "./progressExample"; export * from "./rangeSliderExample"; export * from "./radioExample"; +export * from "./sectionExample"; export * from "./sliderExample"; export * from "./switchExample"; export * from "./tagInputExample"; diff --git a/packages/docs-app/src/examples/core-examples/sectionExample.tsx b/packages/docs-app/src/examples/core-examples/sectionExample.tsx new file mode 100644 index 0000000000..0666453f9d --- /dev/null +++ b/packages/docs-app/src/examples/core-examples/sectionExample.tsx @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; + +import { Button, Classes, H5, Intent, Section, SectionContent, Switch, Text } from "@blueprintjs/core"; +import { Example, ExampleProps } from "@blueprintjs/docs-theme"; +import { IconNames } from "@blueprintjs/icons"; + +export interface SectionExampleState { + hasIcon: boolean; + hasDescription: boolean; + hasRightItem: boolean; + hasMultipleSectionContent: boolean; +} + +export class SectionExample extends React.PureComponent { + public state: SectionExampleState = { + hasDescription: false, + hasIcon: false, + hasMultipleSectionContent: false, + hasRightItem: true, + }; + + public render() { + const { hasDescription, hasIcon, hasRightItem, hasMultipleSectionContent } = this.state; + + const options = ( + <> +
Props
+ + + + + + ); + + return ( + +
+ Edit + + ) : undefined + } + > + + + Basil; Ocimum basilicum, also called great basil, is a culinary herb of the family Lamiaceae + (mints). It is a tender plant, and is used in cuisines worldwide. In Western cuisine, the + generic term "basil" refers to the variety also known as sweet basil or Genovese basil. + Basil is native to tropical regions from Central Africa to Southeast Asia. + + + + {hasMultipleSectionContent && ( + +
+
+ KingdomPlantae +
+
+ CladeTracheophytes +
+
+ FamilyLamiaceae +
+
+
+ )} +
+
+ ); + } + + private handleIconChange = () => this.setState({ hasIcon: !this.state.hasIcon }); + + private handleDescriptionChange = () => this.setState({ hasDescription: !this.state.hasDescription }); + + private handleRightItemChange = () => this.setState({ hasRightItem: !this.state.hasRightItem }); + + private handleMultpleSectionContentChange = () => + this.setState({ hasMultipleSectionContent: !this.state.hasMultipleSectionContent }); +} From 28528bc6e64251dc0e5f095aea85972a5233ee48 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 16:56:06 +0200 Subject: [PATCH 02/20] initial commit --- packages/core/src/common/classes.ts | 4 ++ .../src/components/card-list/CardList.tsx | 53 +++++++++++++++++++ .../src/components/card-list/card-list.scss | 20 +++++++ 3 files changed, 77 insertions(+) create mode 100644 packages/core/src/components/card-list/CardList.tsx create mode 100644 packages/core/src/components/card-list/card-list.scss diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index 33b5af5dad..73ecf36636 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -72,6 +72,8 @@ export const INTENT_DANGER = intentClass(Intent.DANGER)!; export const FOCUS_DISABLED = `${NS}-focus-disabled`; export const FOCUS_STYLE_MANAGER_IGNORE = `${NS}-focus-style-manager-ignore`; +export const CONTAINED = `${NS}-contained`; + // text utilities export const UI_TEXT = `${NS}-ui-text`; export const RUNNING_TEXT = `${NS}-running-text`; @@ -115,6 +117,8 @@ export const CARD = `${NS}-card`; export const COLLAPSE = `${NS}-collapse`; export const COLLAPSE_BODY = `${COLLAPSE}-body`; +export const CARD_LIST = `${NS}-card-list`; + export const CONTEXT_MENU = `${NS}-context-menu`; export const CONTEXT_MENU_VIRTUAL_TARGET = `${CONTEXT_MENU}-virtual-target`; export const CONTEXT_MENU_POPOVER = `${CONTEXT_MENU}-popover`; diff --git a/packages/core/src/components/card-list/CardList.tsx b/packages/core/src/components/card-list/CardList.tsx new file mode 100644 index 0000000000..70139ec3ff --- /dev/null +++ b/packages/core/src/components/card-list/CardList.tsx @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import React from "react"; + +import { AbstractPureComponent2, Classes, DISPLAYNAME_PREFIX, Elevation, HTMLDivProps, Props } from "../../common"; + +// eslint-disable-next-line deprecation/deprecation +export type CardListProps = ICardListProps; +/** @deprecated use CardProps */ +export interface ICardListProps extends Props, HTMLDivProps { + // Set true if the list is in a container without padding + contained?: boolean; +} + +export class CardList extends AbstractPureComponent2 { + public static displayName = `${DISPLAYNAME_PREFIX}.CardList`; + + public render() { + const { className, contained, children, ...htmlProps } = this.props; + const renderableChildren = React.Children.toArray(children); // .filter(isRenderable); + const classes = classNames( + Classes.CARD_LIST, + { [Classes.CONTAINED]: contained }, + { [Classes.ELEVATION_0]: !contained }, + className, + ); + + return renderableChildren.length > 0 ? ( +
+ {renderableChildren.map((child, index) => ( +
{child}
+ ))} +
+ ) : null; + } +} + +// const isRenderable = (o: T | undefined | null | boolean) => isNonNullable(o) && isNotBoolean(o); diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss new file mode 100644 index 0000000000..73547d722f --- /dev/null +++ b/packages/core/src/components/card-list/card-list.scss @@ -0,0 +1,20 @@ +@import "../../common/variables"; + +.card-list { + &:not(.contained) { + border-radius: $pt-border-radius; + } + + & > .#{$ns}-card { + border-radius: 0; + box-shadow: none; + + &:not(:last-child) { + border-bottom: 1px solid $pt-divider-black; + + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + } + } +} From eb8e6fd34f47ca8918bf363494807cf1c236a86a Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 14:25:56 +0200 Subject: [PATCH 03/20] Dark mode --- packages/core/src/common/classes.ts | 5 +- packages/core/src/components/_index.scss | 1 + .../src/components/card-list/CardList.tsx | 53 ------------- .../src/components/card-list/card-list.md | 33 ++++++++ .../src/components/card-list/card-list.scss | 44 +++++++++-- .../src/components/card-list/card-list.tsx | 53 +++++++++++++ packages/core/src/components/components.md | 1 + packages/core/src/components/index.ts | 1 + .../core-examples/cardListExample.tsx | 76 +++++++++++++++++++ .../src/examples/core-examples/index.ts | 1 + 10 files changed, 206 insertions(+), 62 deletions(-) delete mode 100644 packages/core/src/components/card-list/CardList.tsx create mode 100644 packages/core/src/components/card-list/card-list.md create mode 100644 packages/core/src/components/card-list/card-list.tsx create mode 100644 packages/docs-app/src/examples/core-examples/cardListExample.tsx diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index 73ecf36636..a1f2f66ef7 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -114,11 +114,12 @@ export const CALLOUT_ICON = `${CALLOUT}-icon`; export const CARD = `${NS}-card`; +export const CARD_LIST = `${NS}-card-list`; +export const CARD_LIST_ITEM = `${CARD_LIST}-item`; + export const COLLAPSE = `${NS}-collapse`; export const COLLAPSE_BODY = `${COLLAPSE}-body`; -export const CARD_LIST = `${NS}-card-list`; - export const CONTEXT_MENU = `${NS}-context-menu`; export const CONTEXT_MENU_VIRTUAL_TARGET = `${CONTEXT_MENU}-virtual-target`; export const CONTEXT_MENU_POPOVER = `${CONTEXT_MENU}-popover`; diff --git a/packages/core/src/components/_index.scss b/packages/core/src/components/_index.scss index 3c065d9702..1c937565b5 100644 --- a/packages/core/src/components/_index.scss +++ b/packages/core/src/components/_index.scss @@ -7,6 +7,7 @@ @import "button/button-group"; @import "callout/callout"; @import "card/card"; +@import "card-list/card-list"; @import "collapse/collapse"; @import "context-menu/context-menu"; @import "divider/divider"; diff --git a/packages/core/src/components/card-list/CardList.tsx b/packages/core/src/components/card-list/CardList.tsx deleted file mode 100644 index 70139ec3ff..0000000000 --- a/packages/core/src/components/card-list/CardList.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2017 Palantir Technologies, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import classNames from "classnames"; -import React from "react"; - -import { AbstractPureComponent2, Classes, DISPLAYNAME_PREFIX, Elevation, HTMLDivProps, Props } from "../../common"; - -// eslint-disable-next-line deprecation/deprecation -export type CardListProps = ICardListProps; -/** @deprecated use CardProps */ -export interface ICardListProps extends Props, HTMLDivProps { - // Set true if the list is in a container without padding - contained?: boolean; -} - -export class CardList extends AbstractPureComponent2 { - public static displayName = `${DISPLAYNAME_PREFIX}.CardList`; - - public render() { - const { className, contained, children, ...htmlProps } = this.props; - const renderableChildren = React.Children.toArray(children); // .filter(isRenderable); - const classes = classNames( - Classes.CARD_LIST, - { [Classes.CONTAINED]: contained }, - { [Classes.ELEVATION_0]: !contained }, - className, - ); - - return renderableChildren.length > 0 ? ( -
- {renderableChildren.map((child, index) => ( -
{child}
- ))} -
- ) : null; - } -} - -// const isRenderable = (o: T | undefined | null | boolean) => isNonNullable(o) && isNotBoolean(o); diff --git a/packages/core/src/components/card-list/card-list.md b/packages/core/src/components/card-list/card-list.md new file mode 100644 index 0000000000..1dc5d6459d --- /dev/null +++ b/packages/core/src/components/card-list/card-list.md @@ -0,0 +1,33 @@ +@# Card List + +A card list is a wrapper around Cards. Compared to stand-alone cards, it can be used to reduce visual weight and allows inner scrolling. + +@reactExample CardListExample + + +@## Props + +```tsx +import { Button, Card, Elevation } from "@blueprintjs/core"; + + + + Chicken Basquaise + + + + + Tarte Flambée + + + + + Pain au Chocolat + + + +``` + +@interface CardListProps + +@css card-list diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index 73547d722f..fe85595cc1 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -1,20 +1,50 @@ @import "../../common/variables"; -.card-list { - &:not(.contained) { - border-radius: $pt-border-radius; +.#{$ns}-card-list { + width: 100%; + overflow: auto; + padding: 0; + + &.#{$ns}-contained { + box-shadow: none; + border-radius: 0; + } + + // HACK: The card dark mode border is inset, adding margin / padding to prevent items from going over it + .#{$ns}-dark & { + padding: 1px; + + &.#{$ns}-contained { + margin: 1px; + } } - & > .#{$ns}-card { + &-item { + > .#{$ns}-card { border-radius: 0; box-shadow: none; + min-height: 50px; + padding-top: 10px; + padding-bottom: 10px; + display: flex; + align-items: center; - &:not(:last-child) { - border-bottom: 1px solid $pt-divider-black; + &.#{$ns}-interactive:hover { + background-color: $light-gray5; + box-shadow: none; .#{$ns}-dark & { - border-color: $pt-dark-divider-white; + background-color: $dark-gray4; } } + } + + &:not(:last-child) > .#{$ns}-card { + border-bottom: 1px solid $pt-divider-black; + + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + } } } diff --git a/packages/core/src/components/card-list/card-list.tsx b/packages/core/src/components/card-list/card-list.tsx new file mode 100644 index 0000000000..27ba72dbcc --- /dev/null +++ b/packages/core/src/components/card-list/card-list.tsx @@ -0,0 +1,53 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import * as React from "react"; + +import { Classes, DISPLAYNAME_PREFIX, Elevation, HTMLDivProps, Props } from "../../common"; +import { Card } from "../card/card"; + +export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes { + /** + * Set true if the list is in a container without padding. + * Elevation and border radius will be removed. + */ + contained?: boolean; +} + +export const CardList: React.FC = React.forwardRef((props, ref) => { + const { className, contained, children, ...htmlProps } = props; + + const renderableChildren = React.Children.toArray(children); // .filter(isRenderable); + const classes = classNames(Classes.CARD_LIST, { [Classes.CONTAINED]: contained }, className); + + return renderableChildren.length > 0 ? ( + + {renderableChildren.map((child, index) => ( +
+ {child} +
+ ))} +
+ ) : null; +}); + +CardList.defaultProps = { + contained: false, +}; +CardList.displayName = `${DISPLAYNAME_PREFIX}.CardList`; + +// const isRenderable = (o: T | undefined | null | boolean) => isNonNullable(o) && isNotBoolean(o); diff --git a/packages/core/src/components/components.md b/packages/core/src/components/components.md index 8700a5195d..079f687d00 100644 --- a/packages/core/src/components/components.md +++ b/packages/core/src/components/components.md @@ -7,6 +7,7 @@ @page button-group @page callout @page card +@page card-list @page collapse @page divider @page editable-text diff --git a/packages/core/src/components/index.ts b/packages/core/src/components/index.ts index 53586422ac..73fbd1758d 100644 --- a/packages/core/src/components/index.ts +++ b/packages/core/src/components/index.ts @@ -27,6 +27,7 @@ export type { export { ButtonGroup, ButtonGroupProps } from "./button/buttonGroup"; export { Callout, CalloutProps } from "./callout/callout"; export { Card, CardProps } from "./card/card"; +export { CardList, CardListProps } from "./card-list/card-list"; export { Collapse, CollapseProps } from "./collapse/collapse"; export { ContextMenu, diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx new file mode 100644 index 0000000000..c2750de9fb --- /dev/null +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; + +import { Button, Card, CardList, Classes, H6, Icon, Intent, Tag } from "@blueprintjs/core"; +import { Example, ExampleProps } from "@blueprintjs/docs-theme"; +import { IconNames } from "@blueprintjs/icons"; + +export class CardListExample extends React.PureComponent { + public render() { + return ( + + +
+
My french reciepes
+
+ + + Chicken Basquaise + + + + Tarte Flambée + + + + Pain au Chocolat + + + +
+ + + + Olive oil + + + + Ground black pepper + + + + Carrots + + Added + + + + Onions + + + +
+ ); + } +} diff --git a/packages/docs-app/src/examples/core-examples/index.ts b/packages/docs-app/src/examples/core-examples/index.ts index 9b82562c05..b65437fd26 100644 --- a/packages/docs-app/src/examples/core-examples/index.ts +++ b/packages/docs-app/src/examples/core-examples/index.ts @@ -24,6 +24,7 @@ export * from "./calloutExample"; export * from "./checkboxExample"; export * from "./collapseExample"; export * from "./cardExample"; +export * from "./cardListExample"; export { ContextMenuExample } from "./contextMenuExample"; export { ContextMenuPopoverExample } from "./contextMenuPopoverExample"; export * from "./controlGroupExample"; From e84529f67793d0bbac25a62168a39ab9f2316e6a Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 16:03:11 +0200 Subject: [PATCH 04/20] Initial commit --- packages/core/src/common/classes.ts | 9 ++ packages/core/src/components/_index.scss | 1 + packages/core/src/components/components.md | 1 + packages/core/src/components/index.ts | 2 + .../core/src/components/section/_section.scss | 59 ++++++++++ .../components/section/section-content.tsx | 44 ++++++++ .../core/src/components/section/section.md | 17 +++ .../core/src/components/section/section.tsx | 89 +++++++++++++++ .../src/examples/core-examples/index.ts | 1 + .../examples/core-examples/sectionExample.tsx | 106 ++++++++++++++++++ 10 files changed, 329 insertions(+) create mode 100644 packages/core/src/components/section/_section.scss create mode 100644 packages/core/src/components/section/section-content.tsx create mode 100644 packages/core/src/components/section/section.md create mode 100644 packages/core/src/components/section/section.tsx create mode 100644 packages/docs-app/src/examples/core-examples/sectionExample.tsx diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index a1f2f66ef7..48c3c9ca11 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -73,6 +73,7 @@ export const FOCUS_DISABLED = `${NS}-focus-disabled`; export const FOCUS_STYLE_MANAGER_IGNORE = `${NS}-focus-style-manager-ignore`; export const CONTAINED = `${NS}-contained`; +export const PADDED = `${NS}-padded`; // text utilities export const UI_TEXT = `${NS}-ui-text`; @@ -218,6 +219,14 @@ export const MULTISTEP_DIALOG_RIGHT_PANEL = `${MULTISTEP_DIALOG}-right-panel`; export const MULTISTEP_DIALOG_NAV_TOP = `${MULTISTEP_DIALOG}-nav-top`; export const MULTISTEP_DIALOG_NAV_RIGHT = `${MULTISTEP_DIALOG}-nav-right`; +export const SECTION = `${NS}-section`; +export const SECTION_HEADER = `${SECTION}-header`; +export const SECTION_HEADER_LEFT = `${SECTION_HEADER}-left`; +export const SECTION_HEADER_TITLE = `${SECTION_HEADER}-title`; +export const SECTION_HEADER_SUB_TITLE = `${SECTION_HEADER}-sub-title`; +export const SECTION_HEADER_RIGHT = `${SECTION_HEADER}-right`; +export const SECTION_CONTENT = `${SECTION}-content`; + export const NAVBAR = `${NS}-navbar`; export const NAVBAR_GROUP = `${NAVBAR}-group`; export const NAVBAR_HEADING = `${NAVBAR}-heading`; diff --git a/packages/core/src/components/_index.scss b/packages/core/src/components/_index.scss index 1c937565b5..43483c3ba9 100644 --- a/packages/core/src/components/_index.scss +++ b/packages/core/src/components/_index.scss @@ -32,6 +32,7 @@ @import "popover/popover"; @import "portal/portal"; @import "progress-bar/progress-bar"; +@import "section/section"; @import "skeleton/skeleton"; @import "slider/slider"; @import "spinner/spinner"; diff --git a/packages/core/src/components/components.md b/packages/core/src/components/components.md index 079f687d00..348e10a96b 100644 --- a/packages/core/src/components/components.md +++ b/packages/core/src/components/components.md @@ -23,6 +23,7 @@ @page panel-stack2 @page progress-bar @page resize-sensor +@page section @page skeleton @page spinner @page tabs diff --git a/packages/core/src/components/index.ts b/packages/core/src/components/index.ts index 73fbd1758d..38f7ef9576 100644 --- a/packages/core/src/components/index.ts +++ b/packages/core/src/components/index.ts @@ -98,6 +98,8 @@ export { ResizeEntry, ResizeSensor, ResizeSensorProps } from "./resize-sensor/re export { HandleHtmlProps, HandleInteractionKind, HandleProps, HandleType } from "./slider/handleProps"; export { MultiSlider, MultiSliderProps, SliderBaseProps } from "./slider/multiSlider"; export { NumberRange, RangeSlider, RangeSliderProps } from "./slider/rangeSlider"; +export { Section, SectionProps } from "./section/section"; +export { SectionContent, SectionContentProps } from "./section/section-content"; export { Slider, SliderProps } from "./slider/slider"; export { Spinner, SpinnerProps, SpinnerSize } from "./spinner/spinner"; export { Tab, TabId, TabProps } from "./tabs/tab"; diff --git a/packages/core/src/components/section/_section.scss b/packages/core/src/components/section/_section.scss new file mode 100644 index 0000000000..027202a92d --- /dev/null +++ b/packages/core/src/components/section/_section.scss @@ -0,0 +1,59 @@ +@use "sass:math"; +@import "../../common/variables"; + +.#{$ns}-section { + padding: 0; + width: 100%; + + &-header { + align-items: stretch; + display: flex; + justify-content: space-between; + position: relative; + width: 100%; + gap: $pt-grid-size; + min-height: 50px; + padding: $pt-grid-size $pt-grid-size $pt-grid-size $pt-grid-size * 2; + + border-bottom: 1px solid $pt-divider-black; + + &.#{$ns}-dark, + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + + &-left { + align-items: center; + display: flex; + gap: $pt-grid-size; + } + + &-title { + margin-bottom: 0; + } + + &-sub-title { + margin-top: 2px; + } + + &-right { + align-items: center; + display: flex; + } + } + + &-content { + &.#{$ns}-padded { + padding: $pt-grid-size * 2; + } + + &:not(:last-child) { + border-bottom: 1px solid $pt-divider-black; + + &.#{$ns}-dark, + .#{$ns}-dark & { + border-color: $pt-dark-divider-white; + } + } + } +} diff --git a/packages/core/src/components/section/section-content.tsx b/packages/core/src/components/section/section-content.tsx new file mode 100644 index 0000000000..04d6b8abce --- /dev/null +++ b/packages/core/src/components/section/section-content.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import * as React from "react"; + +import { Classes } from "../../common"; +import { DISPLAYNAME_PREFIX, HTMLDivProps, Props } from "../../common/props"; + +export interface SectionContentProps extends Props, HTMLDivProps, React.RefAttributes { + padded?: boolean; +} + +/** + * Section content component. + * + * @see https://blueprintjs.com/docs/#core/components/section-content + */ +export const SectionContent: React.FC = React.forwardRef((props, ref) => { + const { className, children, padded, ...htmlProps } = props; + const classes = classNames(Classes.SECTION_CONTENT, { [Classes.PADDED]: padded }, className); + return ( +
+ {children} +
+ ); +}); +SectionContent.defaultProps = { + padded: true, +}; +SectionContent.displayName = `${DISPLAYNAME_PREFIX}.SectionContent`; diff --git a/packages/core/src/components/section/section.md b/packages/core/src/components/section/section.md new file mode 100644 index 0000000000..d987c4c6bf --- /dev/null +++ b/packages/core/src/components/section/section.md @@ -0,0 +1,17 @@ +@# Section + +todo + +@reactExample SectionExample + +@## Props + +@interface SectionProps + +@# Section Content + +- Multiple section content can be added under one section, they will be stacked. + +@## Props + +@interface SectionContentProps diff --git a/packages/core/src/components/section/section.tsx b/packages/core/src/components/section/section.tsx new file mode 100644 index 0000000000..1817076c2b --- /dev/null +++ b/packages/core/src/components/section/section.tsx @@ -0,0 +1,89 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import classNames from "classnames"; +import * as React from "react"; + +import { IconName } from "@blueprintjs/icons"; + +import { Classes, Elevation } from "../../common"; +import { SECTION_HEADER } from "../../common/classes"; +import { DISPLAYNAME_PREFIX, MaybeElement, Props } from "../../common/props"; +import { Card, CardProps } from "../card/card"; +import { H6 } from "../html/html"; +import { Icon } from "../icon/icon"; + +export interface SectionProps + extends Props, + Omit, + React.RefAttributes { + /** + * Name of a Blueprint UI icon (or an icon element) to render in the + * section's header. Note that the header will only be rendered if `sectionTitle` is + * provided. + */ + icon?: IconName | MaybeElement; + + /** + * Title of the section. + */ + sectionTitle?: JSX.Element | string; + + /** + * Sub-title of the section. + * Note that the header will only be rendered if `sectionTitle` is provided. + */ + subtitle?: JSX.Element | string; + + /** + * Element to render on the right side of the section header + */ + rightItem?: JSX.Element; +} + +/** + * Section component. + * + * @see https://blueprintjs.com/docs/#core/components/section + */ +export const Section: React.FC = React.forwardRef((props, ref) => { + const { className, icon, sectionTitle, rightItem, subtitle, children, ...cardProps } = props; + const classes = classNames(Classes.SECTION, className); + return ( + +
+
+ {sectionTitle && icon && ( + + )} +
+ {sectionTitle &&
{sectionTitle}
} + {sectionTitle && subtitle && ( +
+ {subtitle} +
+ )} +
+
+ {rightItem &&
{rightItem}
} +
+ + {children} +
+ ); +}); +Section.defaultProps = {}; +Section.displayName = `${DISPLAYNAME_PREFIX}.Section`; diff --git a/packages/docs-app/src/examples/core-examples/index.ts b/packages/docs-app/src/examples/core-examples/index.ts index b65437fd26..47fe9b2183 100644 --- a/packages/docs-app/src/examples/core-examples/index.ts +++ b/packages/docs-app/src/examples/core-examples/index.ts @@ -64,6 +64,7 @@ export * from "./popoverSizingExample"; export * from "./progressExample"; export * from "./rangeSliderExample"; export * from "./radioExample"; +export * from "./sectionExample"; export * from "./sliderExample"; export * from "./switchExample"; export * from "./tagInputExample"; diff --git a/packages/docs-app/src/examples/core-examples/sectionExample.tsx b/packages/docs-app/src/examples/core-examples/sectionExample.tsx new file mode 100644 index 0000000000..0666453f9d --- /dev/null +++ b/packages/docs-app/src/examples/core-examples/sectionExample.tsx @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; + +import { Button, Classes, H5, Intent, Section, SectionContent, Switch, Text } from "@blueprintjs/core"; +import { Example, ExampleProps } from "@blueprintjs/docs-theme"; +import { IconNames } from "@blueprintjs/icons"; + +export interface SectionExampleState { + hasIcon: boolean; + hasDescription: boolean; + hasRightItem: boolean; + hasMultipleSectionContent: boolean; +} + +export class SectionExample extends React.PureComponent { + public state: SectionExampleState = { + hasDescription: false, + hasIcon: false, + hasMultipleSectionContent: false, + hasRightItem: true, + }; + + public render() { + const { hasDescription, hasIcon, hasRightItem, hasMultipleSectionContent } = this.state; + + const options = ( + <> +
Props
+ + + + + + ); + + return ( + +
+ Edit + + ) : undefined + } + > + + + Basil; Ocimum basilicum, also called great basil, is a culinary herb of the family Lamiaceae + (mints). It is a tender plant, and is used in cuisines worldwide. In Western cuisine, the + generic term "basil" refers to the variety also known as sweet basil or Genovese basil. + Basil is native to tropical regions from Central Africa to Southeast Asia. + + + + {hasMultipleSectionContent && ( + +
+
+ KingdomPlantae +
+
+ CladeTracheophytes +
+
+ FamilyLamiaceae +
+
+
+ )} +
+
+ ); + } + + private handleIconChange = () => this.setState({ hasIcon: !this.state.hasIcon }); + + private handleDescriptionChange = () => this.setState({ hasDescription: !this.state.hasDescription }); + + private handleRightItemChange = () => this.setState({ hasRightItem: !this.state.hasRightItem }); + + private handleMultpleSectionContentChange = () => + this.setState({ hasMultipleSectionContent: !this.state.hasMultipleSectionContent }); +} From b6e165c0481bdcf9ed92f09d414c114b3eb098f6 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 16:21:25 +0200 Subject: [PATCH 05/20] Use section --- .../core-examples/cardListExample.tsx | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index c2750de9fb..0f3d0a9f98 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -16,7 +16,7 @@ import * as React from "react"; -import { Button, Card, CardList, Classes, H6, Icon, Intent, Tag } from "@blueprintjs/core"; +import { Button, Card, CardList, Classes, Icon, Intent, Section, SectionContent, Tag } from "@blueprintjs/core"; import { Example, ExampleProps } from "@blueprintjs/docs-theme"; import { IconNames } from "@blueprintjs/icons"; @@ -24,25 +24,24 @@ export class CardListExample extends React.PureComponent { public render() { return ( - -
-
My french reciepes
-
- - - Chicken Basquaise - - - - Tarte Flambée - - - - Pain au Chocolat - - - -
+
+ + + + Chicken Basquaise + + + + Tarte Flambée + + + + Pain au Chocolat + + + + +
From bd5a2f4eea0654ae156d714d3d32304646b3c308 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 18:20:20 +0200 Subject: [PATCH 06/20] Small --- packages/core/src/common/_color-aliases.scss | 3 + .../src/components/card-list/card-list.md | 24 +--- .../src/components/card-list/card-list.scss | 23 +++- .../src/components/card-list/card-list.tsx | 17 ++- .../core-examples/cardListExample.tsx | 115 +++++++++++------- 5 files changed, 106 insertions(+), 76 deletions(-) diff --git a/packages/core/src/common/_color-aliases.scss b/packages/core/src/common/_color-aliases.scss index c81def3560..7ea06d1a90 100644 --- a/packages/core/src/common/_color-aliases.scss +++ b/packages/core/src/common/_color-aliases.scss @@ -43,8 +43,11 @@ $pt-dark-icon-color-disabled: $pt-dark-text-color-disabled !default; $pt-dark-icon-color-selected: $pt-intent-primary !default; $pt-divider-black: rgba($black, 0.15) !default; +$pt-divider-black-muted: rgba($black, 0.1) !default; $pt-dark-divider-black: rgba($black, 0.4) !default; +$pt-dark-divider-black-muted: rgba($black, 0.2) !default; $pt-dark-divider-white: rgba($white, 0.2) !default; +$pt-dark-divider-white-muted: rgba($white, 0.1) !default; $pt-code-text-color: $pt-text-color-muted !default; $pt-dark-code-text-color: $pt-dark-text-color-muted !default; diff --git a/packages/core/src/components/card-list/card-list.md b/packages/core/src/components/card-list/card-list.md index 1dc5d6459d..b2cf0eb274 100644 --- a/packages/core/src/components/card-list/card-list.md +++ b/packages/core/src/components/card-list/card-list.md @@ -1,33 +1,19 @@ @# Card List -A card list is a wrapper around Cards. Compared to stand-alone cards, it can be used to reduce visual weight and allows inner scrolling. +Simple wrapper around Cards. Can be used to reduce visual weight and have inner scrolling. @reactExample CardListExample - @## Props ```tsx import { Button, Card, Elevation } from "@blueprintjs/core"; - - - Chicken Basquaise - - - - - Tarte Flambée - - - - - Pain au Chocolat - - + + Olive oil + Ground black pepper + Carrots ``` @interface CardListProps - -@css card-list diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index fe85595cc1..389f6920ab 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -1,5 +1,11 @@ @import "../../common/variables"; +$card-default-min-height: 50px; +$card-default-padding: 10px 20px; + +$card-small-min-height: 40px; +$card-small-padding: 7px 15px; + .#{$ns}-card-list { width: 100%; overflow: auto; @@ -23,13 +29,13 @@ > .#{$ns}-card { border-radius: 0; box-shadow: none; - min-height: 50px; - padding-top: 10px; - padding-bottom: 10px; + min-height: $card-default-min-height; + padding: $card-default-padding; display: flex; align-items: center; - &.#{$ns}-interactive:hover { + &.#{$ns}-interactive:hover, + &.#{$ns}-interactive:active { background-color: $light-gray5; box-shadow: none; @@ -40,11 +46,16 @@ } &:not(:last-child) > .#{$ns}-card { - border-bottom: 1px solid $pt-divider-black; + border-bottom: 1px solid $pt-divider-black-muted; .#{$ns}-dark & { - border-color: $pt-dark-divider-white; + border-color: $pt-dark-divider-white-muted; } } } + + &.#{$ns}-small .#{$ns}-card-list-item > .#{$ns}-card { + min-height: $card-small-min-height; + padding: $card-small-padding; + } } diff --git a/packages/core/src/components/card-list/card-list.tsx b/packages/core/src/components/card-list/card-list.tsx index 27ba72dbcc..6260204e44 100644 --- a/packages/core/src/components/card-list/card-list.tsx +++ b/packages/core/src/components/card-list/card-list.tsx @@ -26,13 +26,21 @@ export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes< * Elevation and border radius will be removed. */ contained?: boolean; + + /** Whether card list items should use small styles. */ + small?: boolean; } export const CardList: React.FC = React.forwardRef((props, ref) => { - const { className, contained, children, ...htmlProps } = props; + const { className, contained, children, small, ...htmlProps } = props; - const renderableChildren = React.Children.toArray(children); // .filter(isRenderable); - const classes = classNames(Classes.CARD_LIST, { [Classes.CONTAINED]: contained }, className); + const renderableChildren = React.Children.toArray(children); + const classes = classNames( + Classes.CARD_LIST, + { [Classes.CONTAINED]: contained }, + { [Classes.SMALL]: small }, + className, + ); return renderableChildren.length > 0 ? ( @@ -47,7 +55,6 @@ export const CardList: React.FC = React.forwardRef((props, ref) = CardList.defaultProps = { contained: false, + small: false, }; CardList.displayName = `${DISPLAYNAME_PREFIX}.CardList`; - -// const isRenderable = (o: T | undefined | null | boolean) => isNonNullable(o) && isNotBoolean(o); diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index 0f3d0a9f98..a7677570a4 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -16,60 +16,83 @@ import * as React from "react"; -import { Button, Card, CardList, Classes, Icon, Intent, Section, SectionContent, Tag } from "@blueprintjs/core"; +import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionContent, Switch } from "@blueprintjs/core"; import { Example, ExampleProps } from "@blueprintjs/docs-theme"; import { IconNames } from "@blueprintjs/icons"; +export interface CardListExampleState { + isContained: boolean; + hasInteractiveCards: boolean; + isSmall: boolean; +} + export class CardListExample extends React.PureComponent { + public state: CardListExampleState = { + hasInteractiveCards: true, + isContained: false, + isSmall: false, + }; + public render() { + const { isContained, hasInteractiveCards, isSmall } = this.state; + + const options = ( + <> +
Props
+ + +
Example
+ + + ); + return ( - -
- - - - Chicken Basquaise - - - - Tarte Flambée - - - - Pain au Chocolat - - - - -
+ + {isContained ? ( +
+ {this.renderList()} +
+ ) : ( + this.renderList() + )} +
+ ); + } - - - Olive oil - - - - Ground black pepper - - - - Carrots - - Added - - - - Onions - + private renderList() { + const { hasInteractiveCards, isContained, isSmall } = this.state; + const ingredients: string[] = ["Olive oil", "Ground black pepper", "Carrots", "Onions"]; + + return ( + + {ingredients.map(ingredient => ( + + {ingredient} + {hasInteractiveCards ? ( + + ) : ( + + )} - -
+ ))} +
); } + + private handleSmallChange = () => this.setState({ isSmall: !this.state.isSmall }); + + private handleContainedChange = () => this.setState({ isContained: !this.state.isContained }); + + private handleInteractiveCardsChange = () => + this.setState({ hasInteractiveCards: !this.state.hasInteractiveCards }); } From 4322ae2320ff7bc414d4a72c01422d31096a940f Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 18:30:44 +0200 Subject: [PATCH 07/20] small --- .../core/src/components/section/_section.scss | 23 ++++++++++++++++--- .../core/src/components/section/section.tsx | 7 ++++-- .../examples/core-examples/sectionExample.tsx | 8 ++++++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/core/src/components/section/_section.scss b/packages/core/src/components/section/_section.scss index 027202a92d..dc66910b99 100644 --- a/packages/core/src/components/section/_section.scss +++ b/packages/core/src/components/section/_section.scss @@ -1,6 +1,12 @@ @use "sass:math"; @import "../../common/variables"; +$section-default-min-height: 50px; +$section-default-padding: $pt-grid-size * 2; + +$section-small-min-height: 40px; +$section-small-padding: 15px; + .#{$ns}-section { padding: 0; width: 100%; @@ -12,8 +18,8 @@ position: relative; width: 100%; gap: $pt-grid-size; - min-height: 50px; - padding: $pt-grid-size $pt-grid-size $pt-grid-size $pt-grid-size * 2; + min-height: $section-default-min-height; + padding: $pt-grid-size $pt-grid-size $pt-grid-size $section-default-padding; border-bottom: 1px solid $pt-divider-black; @@ -44,7 +50,7 @@ &-content { &.#{$ns}-padded { - padding: $pt-grid-size * 2; + padding: $section-default-padding; } &:not(:last-child) { @@ -56,4 +62,15 @@ } } } + + &.#{$ns}-small { + .#{$ns}-section-header { + min-height: $section-small-min-height; + padding: 7px 7px 7px $section-small-padding; + } + + .#{$ns}-section-content { + padding: $section-small-padding; + } + } } diff --git a/packages/core/src/components/section/section.tsx b/packages/core/src/components/section/section.tsx index 1817076c2b..0ec89f252e 100644 --- a/packages/core/src/components/section/section.tsx +++ b/packages/core/src/components/section/section.tsx @@ -52,6 +52,9 @@ export interface SectionProps * Element to render on the right side of the section header */ rightItem?: JSX.Element; + + /** Whether this section should use small styles. */ + small?: boolean; } /** @@ -60,8 +63,8 @@ export interface SectionProps * @see https://blueprintjs.com/docs/#core/components/section */ export const Section: React.FC = React.forwardRef((props, ref) => { - const { className, icon, sectionTitle, rightItem, subtitle, children, ...cardProps } = props; - const classes = classNames(Classes.SECTION, className); + const { className, icon, sectionTitle, rightItem, subtitle, children, small, ...cardProps } = props; + const classes = classNames(Classes.SECTION, { [Classes.SMALL]: small }, className); return (
diff --git a/packages/docs-app/src/examples/core-examples/sectionExample.tsx b/packages/docs-app/src/examples/core-examples/sectionExample.tsx index 0666453f9d..83453fb6ce 100644 --- a/packages/docs-app/src/examples/core-examples/sectionExample.tsx +++ b/packages/docs-app/src/examples/core-examples/sectionExample.tsx @@ -25,6 +25,7 @@ export interface SectionExampleState { hasDescription: boolean; hasRightItem: boolean; hasMultipleSectionContent: boolean; + isSmall: boolean; } export class SectionExample extends React.PureComponent { @@ -33,14 +34,16 @@ export class SectionExample extends React.PureComponent
Props
+ @@ -55,6 +58,7 @@ export class SectionExample extends React.PureComponent
this.setState({ isSmall: !this.state.isSmall }); + private handleIconChange = () => this.setState({ hasIcon: !this.state.hasIcon }); private handleDescriptionChange = () => this.setState({ hasDescription: !this.state.hasDescription }); From ec6c339754b18aee7573f8f92ba085233a55a019 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 18:40:57 +0200 Subject: [PATCH 08/20] small section --- .../docs-app/src/examples/core-examples/cardListExample.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index a7677570a4..60c5e42de2 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -53,7 +53,7 @@ export class CardListExample extends React.PureComponent { return ( {isContained ? ( -
+
{this.renderList()}
) : ( From 06504ac63fd1581a482465493f10a685cfe1ba6d Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 26 Jun 2023 18:43:49 +0200 Subject: [PATCH 09/20] padded --- packages/core/src/components/section/_section.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/section/_section.scss b/packages/core/src/components/section/_section.scss index dc66910b99..d5eee6df5e 100644 --- a/packages/core/src/components/section/_section.scss +++ b/packages/core/src/components/section/_section.scss @@ -69,7 +69,7 @@ $section-small-padding: 15px; padding: 7px 7px 7px $section-small-padding; } - .#{$ns}-section-content { + .#{$ns}-section-content.#{$ns}-padded { padding: $section-small-padding; } } From 023e9f30e5eb7f8b050a2cb61191648f0230278e Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 12 Jul 2023 11:45:40 +0100 Subject: [PATCH 10/20] Change rendering --- packages/core/src/common/classes.ts | 4 +- .../src/components/card-list/card-list.scss | 46 +++++++++---------- .../src/components/card-list/card-list.tsx | 27 +++++------ .../core/src/components/section/_section.scss | 10 ---- .../components/section/section-content.tsx | 44 ------------------ .../core-examples/cardListExample.tsx | 22 ++++----- 6 files changed, 48 insertions(+), 105 deletions(-) delete mode 100644 packages/core/src/components/section/section-content.tsx diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index 0cbb6e45de..a9731ba30f 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -35,6 +35,7 @@ if (typeof BLUEPRINT_NAMESPACE !== "undefined") { export const ACTIVE = `${NS}-active`; export const ALIGN_LEFT = `${NS}-align-left`; export const ALIGN_RIGHT = `${NS}-align-right`; +export const CONTAINED = `${NS}-contained`; export const COMPACT = `${NS}-compact`; export const DARK = `${NS}-dark`; export const DISABLED = `${NS}-disabled`; @@ -73,9 +74,6 @@ export const INTENT_DANGER = intentClass(Intent.DANGER)!; export const FOCUS_DISABLED = `${NS}-focus-disabled`; export const FOCUS_STYLE_MANAGER_IGNORE = `${NS}-focus-style-manager-ignore`; -export const CONTAINED = `${NS}-contained`; -export const PADDED = `${NS}-padded`; - // text utilities export const UI_TEXT = `${NS}-ui-text`; export const RUNNING_TEXT = `${NS}-running-text`; diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index 389f6920ab..5b8090aaca 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -1,10 +1,10 @@ @import "../../common/variables"; -$card-default-min-height: 50px; -$card-default-padding: 10px 20px; +$card-list-item-default-min-height: 50px; +$card-list-item-default-padding: 10px 20px; -$card-small-min-height: 40px; -$card-small-padding: 7px 15px; +$card-list-item-small-min-height: 40px; +$card-list-item-small-padding: 7px 15px; .#{$ns}-card-list { width: 100%; @@ -25,27 +25,25 @@ $card-small-padding: 7px 15px; } } - &-item { - > .#{$ns}-card { - border-radius: 0; + & > .#{$ns}-card { + border-radius: 0; + box-shadow: none; + min-height: $card-list-item-default-min-height; + padding: $card-list-item-default-padding; + display: flex; + align-items: center; + + &.#{$ns}-interactive:hover, + &.#{$ns}-interactive:active { + background-color: $light-gray5; box-shadow: none; - min-height: $card-default-min-height; - padding: $card-default-padding; - display: flex; - align-items: center; - - &.#{$ns}-interactive:hover, - &.#{$ns}-interactive:active { - background-color: $light-gray5; - box-shadow: none; - - .#{$ns}-dark & { - background-color: $dark-gray4; - } + + .#{$ns}-dark & { + background-color: $dark-gray4; } } - &:not(:last-child) > .#{$ns}-card { + &:not(:last-child) { border-bottom: 1px solid $pt-divider-black-muted; .#{$ns}-dark & { @@ -54,8 +52,8 @@ $card-small-padding: 7px 15px; } } - &.#{$ns}-small .#{$ns}-card-list-item > .#{$ns}-card { - min-height: $card-small-min-height; - padding: $card-small-padding; + &.#{$ns}-compact > .#{$ns}-card { + min-height: $card-list-item-small-min-height; + padding: $card-list-item-small-padding; } } diff --git a/packages/core/src/components/card-list/card-list.tsx b/packages/core/src/components/card-list/card-list.tsx index 6260204e44..805838e69e 100644 --- a/packages/core/src/components/card-list/card-list.tsx +++ b/packages/core/src/components/card-list/card-list.tsx @@ -24,37 +24,38 @@ export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes< /** * Set true if the list is in a container without padding. * Elevation and border radius will be removed. + * + * @default false */ contained?: boolean; - /** Whether card list items should use small styles. */ - small?: boolean; + /** + * Whether this section should use compact styles. + * + * @default false + */ + compact?: boolean; } export const CardList: React.FC = React.forwardRef((props, ref) => { - const { className, contained, children, small, ...htmlProps } = props; + const { className, contained, children, compact, ...htmlProps } = props; - const renderableChildren = React.Children.toArray(children); const classes = classNames( Classes.CARD_LIST, { [Classes.CONTAINED]: contained }, - { [Classes.SMALL]: small }, + { [Classes.COMPACT]: compact }, className, ); - return renderableChildren.length > 0 ? ( + return ( - {renderableChildren.map((child, index) => ( -
- {child} -
- ))} + {children}
- ) : null; + ); }); CardList.defaultProps = { + compact: false, contained: false, - small: false, }; CardList.displayName = `${DISPLAYNAME_PREFIX}.CardList`; diff --git a/packages/core/src/components/section/_section.scss b/packages/core/src/components/section/_section.scss index f1b270802b..62be30b0f0 100644 --- a/packages/core/src/components/section/_section.scss +++ b/packages/core/src/components/section/_section.scss @@ -1,15 +1,6 @@ @use "sass:math"; @import "../../common/variables"; -<<<<<<< HEAD -$section-default-min-height: 50px; -$section-default-padding: $pt-grid-size * 2; - -$section-small-min-height: 40px; -$section-small-padding: 15px; - -.#{$ns}-section { -======= $section-min-height: $pt-grid-size * 5 !default; $section-vertical-padding: $pt-grid-size !default; $section-horizontal-padding: $pt-grid-size * 2 !default; @@ -22,7 +13,6 @@ $section-compact-panel-padding: $pt-grid-size * 1.5 !default; .#{$ns}-section { overflow: hidden; ->>>>>>> 253ad84de41afc11eb2e702a20c55b300ff3db44 padding: 0; width: 100%; diff --git a/packages/core/src/components/section/section-content.tsx b/packages/core/src/components/section/section-content.tsx deleted file mode 100644 index 04d6b8abce..0000000000 --- a/packages/core/src/components/section/section-content.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Palantir Technologies, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import classNames from "classnames"; -import * as React from "react"; - -import { Classes } from "../../common"; -import { DISPLAYNAME_PREFIX, HTMLDivProps, Props } from "../../common/props"; - -export interface SectionContentProps extends Props, HTMLDivProps, React.RefAttributes { - padded?: boolean; -} - -/** - * Section content component. - * - * @see https://blueprintjs.com/docs/#core/components/section-content - */ -export const SectionContent: React.FC = React.forwardRef((props, ref) => { - const { className, children, padded, ...htmlProps } = props; - const classes = classNames(Classes.SECTION_CONTENT, { [Classes.PADDED]: padded }, className); - return ( -
- {children} -
- ); -}); -SectionContent.defaultProps = { - padded: true, -}; -SectionContent.displayName = `${DISPLAYNAME_PREFIX}.SectionContent`; diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index 60c5e42de2..80fff3798a 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -16,31 +16,31 @@ import * as React from "react"; -import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionContent, Switch } from "@blueprintjs/core"; +import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionPanel, Switch } from "@blueprintjs/core"; import { Example, ExampleProps } from "@blueprintjs/docs-theme"; import { IconNames } from "@blueprintjs/icons"; export interface CardListExampleState { isContained: boolean; hasInteractiveCards: boolean; - isSmall: boolean; + isCompact: boolean; } export class CardListExample extends React.PureComponent { public state: CardListExampleState = { hasInteractiveCards: true, + isCompact: false, isContained: false, - isSmall: false, }; public render() { - const { isContained, hasInteractiveCards, isSmall } = this.state; + const { isContained, hasInteractiveCards, isCompact } = this.state; const options = ( <>
Props
- +
Example
{ return ( {isContained ? ( -
- {this.renderList()} +
+ {this.renderList()}
) : ( this.renderList() @@ -64,11 +64,11 @@ export class CardListExample extends React.PureComponent { } private renderList() { - const { hasInteractiveCards, isContained, isSmall } = this.state; + const { hasInteractiveCards, isContained, isCompact } = this.state; const ingredients: string[] = ["Olive oil", "Ground black pepper", "Carrots", "Onions"]; return ( - + {ingredients.map(ingredient => ( { {hasInteractiveCards ? ( ) : ( - )} @@ -89,7 +89,7 @@ export class CardListExample extends React.PureComponent { ); } - private handleSmallChange = () => this.setState({ isSmall: !this.state.isSmall }); + private handleSmallChange = () => this.setState({ isCompact: !this.state.isCompact }); private handleContainedChange = () => this.setState({ isContained: !this.state.isContained }); From ebdec0768bacaff22eb6d65ad925e13f21af61bc Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 12 Jul 2023 11:51:54 +0100 Subject: [PATCH 11/20] Remove card list item prop --- packages/core/src/common/classes.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/common/classes.ts b/packages/core/src/common/classes.ts index a9731ba30f..206aa5b102 100644 --- a/packages/core/src/common/classes.ts +++ b/packages/core/src/common/classes.ts @@ -115,7 +115,6 @@ export const CALLOUT_ICON = `${CALLOUT}-icon`; export const CARD = `${NS}-card`; export const CARD_LIST = `${NS}-card-list`; -export const CARD_LIST_ITEM = `${CARD_LIST}-item`; export const COLLAPSE = `${NS}-collapse`; export const COLLAPSE_BODY = `${COLLAPSE}-body`; From e7a0d91c5d23030793d87f784d78ab3a8073907b Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 24 Jul 2023 10:46:24 -0400 Subject: [PATCH 12/20] Fix lint --- .../core/src/components/card-list/card-list.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index 5b8090aaca..2821d660e7 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -7,16 +7,16 @@ $card-list-item-small-min-height: 40px; $card-list-item-small-padding: 7px 15px; .#{$ns}-card-list { - width: 100%; overflow: auto; padding: 0; + width: 100%; &.#{$ns}-contained { - box-shadow: none; border-radius: 0; + box-shadow: none; } - // HACK: The card dark mode border is inset, adding margin / padding to prevent items from going over it + // The card border is inset in dark theme, so we need to add margin / padding to prevent items from going over it .#{$ns}-dark & { padding: 1px; @@ -25,13 +25,13 @@ $card-list-item-small-padding: 7px 15px; } } - & > .#{$ns}-card { + > .#{$ns}-card { + align-items: center; border-radius: 0; box-shadow: none; + display: flex; min-height: $card-list-item-default-min-height; padding: $card-list-item-default-padding; - display: flex; - align-items: center; &.#{$ns}-interactive:hover, &.#{$ns}-interactive:active { From 4cb24150a3d59176e39c083ee1aacd2e7bb6097d Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 24 Jul 2023 10:47:02 -0400 Subject: [PATCH 13/20] Fix component file name --- .../src/components/card-list/{card-list.tsx => cardList.tsx} | 0 packages/core/src/components/index.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/core/src/components/card-list/{card-list.tsx => cardList.tsx} (100%) diff --git a/packages/core/src/components/card-list/card-list.tsx b/packages/core/src/components/card-list/cardList.tsx similarity index 100% rename from packages/core/src/components/card-list/card-list.tsx rename to packages/core/src/components/card-list/cardList.tsx diff --git a/packages/core/src/components/index.ts b/packages/core/src/components/index.ts index 1baa982f66..18d732ffc9 100644 --- a/packages/core/src/components/index.ts +++ b/packages/core/src/components/index.ts @@ -27,7 +27,7 @@ export type { export { ButtonGroup, ButtonGroupProps } from "./button/buttonGroup"; export { Callout, CalloutProps } from "./callout/callout"; export { Card, CardProps } from "./card/card"; -export { CardList, CardListProps } from "./card-list/card-list"; +export { CardList, CardListProps } from "./card-list/cardList"; export { Collapse, CollapseProps } from "./collapse/collapse"; export { ContextMenu, From bef474a228406dc9ff341fb3950bfca5c1fffded Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 24 Jul 2023 10:47:18 -0400 Subject: [PATCH 14/20] Tag component as 'new' in docs --- packages/core/src/components/card-list/card-list.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/components/card-list/card-list.md b/packages/core/src/components/card-list/card-list.md index b2cf0eb274..424f31907f 100644 --- a/packages/core/src/components/card-list/card-list.md +++ b/packages/core/src/components/card-list/card-list.md @@ -1,3 +1,7 @@ +--- +tag: new +--- + @# Card List Simple wrapper around Cards. Can be used to reduce visual weight and have inner scrolling. From bf447b60ab32aee4eea75d4e66deafd330ab951e Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 24 Jul 2023 11:05:47 -0400 Subject: [PATCH 15/20] Fix reference to SectionCard in docs --- .../docs-app/src/examples/core-examples/cardListExample.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index 80fff3798a..854e6377c8 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -16,7 +16,7 @@ import * as React from "react"; -import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionPanel, Switch } from "@blueprintjs/core"; +import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionCard, Switch } from "@blueprintjs/core"; import { Example, ExampleProps } from "@blueprintjs/docs-theme"; import { IconNames } from "@blueprintjs/icons"; @@ -54,7 +54,7 @@ export class CardListExample extends React.PureComponent { {isContained ? (
- {this.renderList()} + {this.renderList()}
) : ( this.renderList() From c040aae02a875d05bd1585775506f016b5c8515b Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 24 Jul 2023 11:27:58 -0400 Subject: [PATCH 16/20] Improve docs & code style --- .../src/components/card-list/card-list.md | 29 +++++++-- .../src/components/card-list/card-list.scss | 8 ++- .../src/components/card-list/cardList.tsx | 13 ++-- .../core-examples/cardListExample.tsx | 62 +++++++++---------- packages/docs-app/src/styles/_examples.scss | 6 ++ 5 files changed, 71 insertions(+), 47 deletions(-) diff --git a/packages/core/src/components/card-list/card-list.md b/packages/core/src/components/card-list/card-list.md index 424f31907f..4e1902db52 100644 --- a/packages/core/src/components/card-list/card-list.md +++ b/packages/core/src/components/card-list/card-list.md @@ -4,20 +4,41 @@ tag: new @# Card List -Simple wrapper around Cards. Can be used to reduce visual weight and have inner scrolling. +__CardList__ is a lightweight wrapper around the [__Card__](#core/components/card) component. It can be used to +visually group together cards in a list without any excess visual weight around or between them. Long lists may +be styled with CSS to scroll vertically. @reactExample CardListExample -@## Props +@## Usage ```tsx -import { Button, Card, Elevation } from "@blueprintjs/core"; +import { Card, CardList } from "@blueprintjs/core"; - + Olive oil Ground black pepper Carrots ``` +@## Combining with Section + +__CardList__ may be used as content for the [__Section__](#core/components/section) component. This allows support for +features like a title & description. + +```tsx +import { Card, CardList, Section } from "@blueprintjs/core"; + +
+ + Olive oil + Ground black pepper + Carrots + +
+``` + +@## Props interface + @interface CardListProps diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index 2821d660e7..cbbd8c049e 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -1,9 +1,11 @@ @import "../../common/variables"; -$card-list-item-default-min-height: 50px; -$card-list-item-default-padding: 10px 20px; +// N.B. min-height is calculated as height of a button + vertical padding. We need to add an extra pixel to account for +// the bottom border. +$card-list-item-default-min-height: ($pt-grid-size * 5) + 1px; +$card-list-item-default-padding: $pt-grid-size (2 * $pt-grid-size); -$card-list-item-small-min-height: 40px; +$card-list-item-small-min-height: ($pt-grid-size * 4) + 1px; $card-list-item-small-padding: 7px 15px; .#{$ns}-card-list { diff --git a/packages/core/src/components/card-list/cardList.tsx b/packages/core/src/components/card-list/cardList.tsx index 805838e69e..3e27db3e0b 100644 --- a/packages/core/src/components/card-list/cardList.tsx +++ b/packages/core/src/components/card-list/cardList.tsx @@ -30,7 +30,7 @@ export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes< contained?: boolean; /** - * Whether this section should use compact styles. + * Whether this component should use compact styles. * * @default false */ @@ -40,12 +40,10 @@ export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes< export const CardList: React.FC = React.forwardRef((props, ref) => { const { className, contained, children, compact, ...htmlProps } = props; - const classes = classNames( - Classes.CARD_LIST, - { [Classes.CONTAINED]: contained }, - { [Classes.COMPACT]: compact }, - className, - ); + const classes = classNames(Classes.CARD_LIST, className, { + [Classes.COMPACT]: compact, + [Classes.CONTAINED]: contained, + }); return ( @@ -53,7 +51,6 @@ export const CardList: React.FC = React.forwardRef((props, ref) = ); }); - CardList.defaultProps = { compact: false, contained: false, diff --git a/packages/docs-app/src/examples/core-examples/cardListExample.tsx b/packages/docs-app/src/examples/core-examples/cardListExample.tsx index 854e6377c8..8a16806fe7 100644 --- a/packages/docs-app/src/examples/core-examples/cardListExample.tsx +++ b/packages/docs-app/src/examples/core-examples/cardListExample.tsx @@ -16,43 +16,48 @@ import * as React from "react"; -import { Button, Card, CardList, Classes, H5, Icon, Intent, Section, SectionCard, Switch } from "@blueprintjs/core"; +import { Button, Card, CardList, Classes, Code, H5, Section, SectionCard, Switch } from "@blueprintjs/core"; import { Example, ExampleProps } from "@blueprintjs/docs-theme"; -import { IconNames } from "@blueprintjs/icons"; +import { ChevronRight } from "@blueprintjs/icons"; export interface CardListExampleState { - isContained: boolean; - hasInteractiveCards: boolean; isCompact: boolean; + useInteractiveCards: boolean; + useSectionContainer: boolean; } -export class CardListExample extends React.PureComponent { +export class CardListExample extends React.PureComponent { public state: CardListExampleState = { - hasInteractiveCards: true, isCompact: false, - isContained: false, + useInteractiveCards: true, + useSectionContainer: false, }; public render() { - const { isContained, hasInteractiveCards, isCompact } = this.state; + const { isCompact, useInteractiveCards, useSectionContainer } = this.state; const options = ( <> -
Props
- - -
Example
+
Layout
+ Use Section container + + } + onChange={this.toggleUseSectionContainer} /> +
CardList Props
+ +
Card Props
+ ); return ( - {isContained ? ( + {useSectionContainer ? (
{this.renderList()}
@@ -64,24 +69,18 @@ export class CardListExample extends React.PureComponent { } private renderList() { - const { hasInteractiveCards, isContained, isCompact } = this.state; + const { isCompact, useInteractiveCards, useSectionContainer } = this.state; const ingredients: string[] = ["Olive oil", "Ground black pepper", "Carrots", "Onions"]; return ( - + {ingredients.map(ingredient => ( - + {ingredient} - {hasInteractiveCards ? ( - + {useInteractiveCards ? ( + ) : ( - +