From 8176a0aa189c9cc873b2ec8dffced414e6d8f7a5 Mon Sep 17 00:00:00 2001 From: Mollpo <97024183+mollpo@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:57:12 +0200 Subject: [PATCH 1/4] WithPlaceholder component (#283) * make select item form field fix height * lint fix * write store in tsx * lint fix * add default option to placeholder * fix lint error * fix typo in props description * Update src/components/content/WithPlaceholder/WithPlaceholder.tsx Co-authored-by: Alex Lanz * Update src/components/content/WithPlaceholder/WithPlaceholder.tsx Co-authored-by: Alex Lanz * Update src/components/content/WithPlaceholder/WithPlacehoder.stories.tsx Co-authored-by: Alex Lanz * remove options from placeholder and cleanup * lint fix * lint fix * change props order --------- Co-authored-by: Alex Lanz --- .../WithPlacehoder.stories.tsx | 52 +++++++++++++++++++ .../WithPlaceholder/WithPlaceholder.tsx | 26 ++++++++++ src/components/content/index.ts | 1 + 3 files changed, 79 insertions(+) create mode 100644 src/components/content/WithPlaceholder/WithPlacehoder.stories.tsx create mode 100644 src/components/content/WithPlaceholder/WithPlaceholder.tsx diff --git a/src/components/content/WithPlaceholder/WithPlacehoder.stories.tsx b/src/components/content/WithPlaceholder/WithPlacehoder.stories.tsx new file mode 100644 index 00000000..eb1147c4 --- /dev/null +++ b/src/components/content/WithPlaceholder/WithPlacehoder.stories.tsx @@ -0,0 +1,52 @@ +import { + Controls, + Description, + Primary, + Stories, + Subheading, + Title, +} from '@storybook/blocks' +import { Meta, StoryObj } from '@storybook/react' +import { WithPlaceholder } from './WithPlaceholder' + +const children = { + options: ['Null', 'Undefined', 'Empty text', 'ReactNode'], + mapping: { + Null: null, + Undefined: undefined, + 'Empty text': '', + ReactNode: 'John Doe', + }, + control: { type: 'select' }, +} + +const meta = { + title: 'Components/Content/WithPlaceHolder', + component: WithPlaceholder, + args: { + placeholder: '-', + children: 'John Doe', + }, + argTypes: { + children, + }, + parameters: { + docs: { + page: () => ( + <> + + <Description /> + <Primary /> + <Subheading>Props</Subheading> + <Controls /> + <Stories /> + </> + ), + }, + }, +} satisfies Meta<typeof WithPlaceholder> +export default meta + +type Story = StoryObj<typeof meta> + +export const Default: Story = {} diff --git a/src/components/content/WithPlaceholder/WithPlaceholder.tsx b/src/components/content/WithPlaceholder/WithPlaceholder.tsx new file mode 100644 index 00000000..8dd068f3 --- /dev/null +++ b/src/components/content/WithPlaceholder/WithPlaceholder.tsx @@ -0,0 +1,26 @@ +import { PropsWithChildren, ReactNode } from 'react' + +export type WithPlaceholderProps = PropsWithChildren<{ + /** + * Defines the placeholder to be rendered if the children is not valid. + */ + placeholder?: ReactNode +}> + +/** + * This component validates the content and displays a placeholder if the content is empty, null or undefined. + */ +export function WithPlaceholder({ + placeholder = '-', + children, +}: WithPlaceholderProps) { + return ( + <> + {typeof children === 'number' + ? isNaN(children) + ? placeholder + : children + : children || placeholder} + </> + ) +} diff --git a/src/components/content/index.ts b/src/components/content/index.ts index 617ae4a0..959a5cb9 100644 --- a/src/components/content/index.ts +++ b/src/components/content/index.ts @@ -11,3 +11,4 @@ export * from './DescriptionItem/DescriptionItemTitle' export * from './DescriptionItem/DescriptionItemContent' export * from './DescriptionItem/LoadingDescriptionItem' export * from './DescriptionItem/types' +export * from './WithPlaceholder/WithPlaceholder' From 7d774010662833e1c46163420c696c11dbbb25cc Mon Sep 17 00:00:00 2001 From: Alex Lanz <alex.lanz@aboutbits.it> Date: Fri, 15 Sep 2023 16:59:09 +0200 Subject: [PATCH 2/4] 2.6.7 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9db5b061..18417843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@aboutbits/react-ui", - "version": "2.6.6", + "version": "2.6.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@aboutbits/react-ui", - "version": "2.6.6", + "version": "2.6.7", "dependencies": { "@aboutbits/pagination": "^2.0.0", "@aboutbits/react-material-icons": "^1.1.2", diff --git a/package.json b/package.json index a297f66f..aac3f708 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aboutbits/react-ui", - "version": "2.6.6", + "version": "2.6.7", "types": "./dist/types/index.d.ts", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", From 6f0b18435702bd4a39ed2ba8a119252c47c316f0 Mon Sep 17 00:00:00 2001 From: devgioele <gioele.devitti@aboutbits.it> Date: Tue, 19 Sep 2023 14:14:37 +0000 Subject: [PATCH 3/4] More flexible section list items (#288) * add possibility of not showing an icon inside a section list item * make implementation of SectionListItemButton and SectionListItemLink more similar * work with vertical padding rather than min height --- .../section/SectionItem/SectionListItem.tsx | 37 +++++++++++------- src/components/section/theme.ts | 7 +--- src/examples/List.stories.tsx | 39 ++++++++++++++----- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/components/section/SectionItem/SectionListItem.tsx b/src/components/section/SectionItem/SectionListItem.tsx index 50bd72c1..96d7dcde 100644 --- a/src/components/section/SectionItem/SectionListItem.tsx +++ b/src/components/section/SectionItem/SectionListItem.tsx @@ -22,19 +22,32 @@ export function SectionListItem({ className, children }: SectionListItemProps) { ) } +function SectionListItemIcon() { + const { section } = useTheme() + + return ( + <IconKeyboardArrowRight + width="24" + height="24" + className={section.listItemButtonLink.icon} + /> + ) +} + export type SectionListItemButtonProps = ClassNameProps & { /** * On click handler for the button. */ onClick: () => void children?: ReactNode + withIcon?: boolean } export const SectionListItemButton = forwardRef< HTMLButtonElement, SectionListItemButtonProps >(function SectionListItemButton( - { children, onClick, className, ...props }, + { children, onClick, className, withIcon = true, ...props }, ref, ) { const { section } = useTheme() @@ -43,30 +56,28 @@ export const SectionListItemButton = forwardRef< <button onClick={onClick} className={classNames( - section.listItemButton.base, section.listItem.base, + section.listItemButtonLink.base, className, )} ref={ref} {...props} > {children} - <IconKeyboardArrowRight - width="24" - height="24" - className={section.listItemButton.icon} - /> + {withIcon && <SectionListItemIcon />} </button> ) }) -export type SectionListItemLinkProps = LinkComponentProps +export type SectionListItemLinkProps = LinkComponentProps & { + withIcon?: boolean +} export const SectionListItemLink = forwardRef< HTMLAnchorElement, SectionListItemLinkProps >(function SectionListItemLink( - { children, className, internal = true, ...props }, + { children, className, internal = true, withIcon = true, ...props }, ref, ) { const LinkComponent = useLinkComponent() @@ -75,8 +86,8 @@ export const SectionListItemLink = forwardRef< return ( <LinkComponent className={classNames( - section.listItemLink.base, section.listItem.base, + section.listItemButtonLink.base, className, )} internal={internal} @@ -84,11 +95,7 @@ export const SectionListItemLink = forwardRef< {...props} > {children} - <IconKeyboardArrowRight - width="24" - height="24" - className={section.listItemButton.icon} - /> + {withIcon && <SectionListItemIcon />} </LinkComponent> ) }) diff --git a/src/components/section/theme.ts b/src/components/section/theme.ts index 464e1325..4c8c187a 100644 --- a/src/components/section/theme.ts +++ b/src/components/section/theme.ts @@ -30,7 +30,7 @@ export default { base: 'grid xl:grid-cols-2 xl:gap-x-11 gap-y-6 px-4 md:px-6 pt-4 md:pt-6 pb-8 md:pb-9', }, listItem: { - base: 'flex border-b border-neutral-200 last:border-0 items-center min-h-[3.5rem] bg-white px-4 md:px-6', + base: 'flex border-b border-neutral-200 last:border-0 items-center py-4 bg-white px-4 md:px-6', }, listItemWithAction: { base: 'justify-between space-x-4', @@ -38,13 +38,10 @@ export default { base: 'flex flex-shrink-0', }, }, - listItemButton: { + listItemButtonLink: { base: 'block w-full focus:outline-neutral-800 justify-between space-x-4 hover:bg-neutral-100 active:bg-neutral-100', icon: 'fill-current', }, - listItemLink: { - base: 'block focus:outline-neutral-800 justify-between space-x-4 hover:bg-neutral-100 active:bg-neutral-100', - }, subsectionTitle: { base: 'bg-neutral-100 px-4 md:px-6 py-1 border-b border-t first:border-t-none border-neutral-200 text-sm text-neutral-600', }, diff --git a/src/examples/List.stories.tsx b/src/examples/List.stories.tsx index bd7b129d..b341fa62 100644 --- a/src/examples/List.stories.tsx +++ b/src/examples/List.stories.tsx @@ -27,6 +27,8 @@ import { SelectField, Tone, Option, + SectionListItemButtonProps, + SectionListItemLink, } from '../components' import { SearchField } from '../components/form/SearchField' import { useFilter } from '../components/util/useFilter' @@ -66,7 +68,13 @@ function useMockedList(numberOfTotalItems: number) { ) } -const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => { +const List = ({ + numberOfTotalItems = 5, + withIcon, +}: { numberOfTotalItems?: number } & Pick< + SectionListItemButtonProps, + 'withIcon' +>) => { const content = useMockedList(numberOfTotalItems) return ( <Section> @@ -79,14 +87,25 @@ const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => { /> ) : ( <SectionContentList> - {content.map((item) => ( - <SectionListItemButton - key={item.name} - onClick={action('onItemClick')} - > - {`${item.name} (${item.role} - ${item.department})`} - </SectionListItemButton> - ))} + {content.map((item, index) => + index % 2 === 0 ? ( + <SectionListItemButton + key={item.name} + onClick={action('onItemClick')} + withIcon={withIcon} + > + {`Button ${item.name} (${item.role} - ${item.department})`} + </SectionListItemButton> + ) : ( + <SectionListItemLink + key={item.name} + href="#" + withIcon={withIcon} + > + {`Link ${item.name} (${item.role} - ${item.department})`} + </SectionListItemLink> + ), + )} </SectionContentList> )} </SectionContainer> @@ -98,6 +117,8 @@ export const SimpleList: Story = () => <List /> export const EmptySimpleList: Story = () => <List numberOfTotalItems={0} /> +export const ListWithoutIcon: Story = () => <List withIcon={false} /> + /** * The following example shows how multiple section components and the in memory pagination are used to create an overview list with filters. */ From 1871c1716a70026a662431ed51e44e21284bd29f Mon Sep 17 00:00:00 2001 From: devgioele <gioele.devitti@aboutbits.it> Date: Tue, 19 Sep 2023 16:14:58 +0200 Subject: [PATCH 4/4] 2.6.8 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18417843..a36690c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@aboutbits/react-ui", - "version": "2.6.7", + "version": "2.6.8", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@aboutbits/react-ui", - "version": "2.6.7", + "version": "2.6.8", "dependencies": { "@aboutbits/pagination": "^2.0.0", "@aboutbits/react-material-icons": "^1.1.2", diff --git a/package.json b/package.json index aac3f708..2d2cf6bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aboutbits/react-ui", - "version": "2.6.7", + "version": "2.6.8", "types": "./dist/types/index.d.ts", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js",