Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(Dialog): Add ability to set custom footer #2005

Merged
merged 18 commits into from
Oct 18, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Button, Dialog, Box } from '@stardust-ui/react'
import * as React from 'react'

kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
const customStylesWithComponent = compStyles => {
const customStyles = {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'baseline',
}
return { ...customStyles, ...compStyles }
}

const CustomFooter = ({ styles, actions }) => {
return (
<Box styles={customStylesWithComponent(styles())}>
<span>any custom text in footer</span>
{actions}
</Box>
)
}

const DialogExampleContent: React.FC = () => (
<Dialog
cancelButton="Cancel"
confirmButton="Confirm"
content="Are you sure you want to confirm this action?"
header="Action confirmation"
trigger={<Button content="Open a dialog" />}
footer={render => render({}, (C, p) => <CustomFooter {...p} />)}
/>
)

export default DialogExampleContent
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions docs/src/examples/components/Dialog/Content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const DialogContentExamples = () => (
description="A dialog can contain an action in the header."
examplePath="components/Dialog/Content/DialogExampleHeaderAction"
/>
<ComponentExample
title="Footer"
description="A dialog can contain a custom footer."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description="A dialog can contain a custom footer."
description="A dialog can contain a footer."

I want to keep this thing aligned with other examples.

examplePath="components/Dialog/Content/DialogExampleFooter"
/>
</ExampleSection>
)

Expand Down
40 changes: 38 additions & 2 deletions packages/react/src/components/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Box, { BoxProps } from '../Box/Box'
import Header, { HeaderProps } from '../Header/Header'
import Portal, { TriggerAccessibility } from '../Portal/Portal'
import Flex from '../Flex/Flex'
import DialogFooter from './DialogFooter'

export interface DialogSlotClassNames {
header: string
Expand Down Expand Up @@ -63,6 +64,9 @@ export interface DialogProps
/** A dialog can contain a button next to the header. */
headerAction?: ShorthandValue<ButtonProps>

/** A dialog can contain a footer. */
footer?: ShorthandValue<any>
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Called after a user clicks the cancel button.
* @param {SyntheticEvent} event - React's original SyntheticEvent.
Expand Down Expand Up @@ -137,6 +141,7 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
backdrop: true,
closeOnOutsideClick: true,
overlay: {},
footer: {},
trapFocus: true,
}

Expand Down Expand Up @@ -246,9 +251,31 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
overlay,
trapFocus,
trigger,
footer,
} = this.props
const { open } = this.state

const dialogActions = ButtonGroup.create(actions, {
defaultProps: {
styles: styles.actions,
},
overrideProps: {
content: (
<Flex gap="gap.smaller">
{Button.create(cancelButton, {
overrideProps: this.handleCancelButtonOverrides,
})}
{Button.create(confirmButton, {
defaultProps: {
primary: true,
},
overrideProps: this.handleConfirmButtonOverrides,
})}
</Flex>
),
},
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This thing looks really weird, but we agreed to tackle it separately.


const dialogContent = (
<Ref innerRef={this.contentRef}>
<ElementType
Expand Down Expand Up @@ -285,7 +312,16 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
},
})}

{ButtonGroup.create(actions, {
{/* <div style={styles.footer}> */}
{DialogFooter.create(footer, {
overrideProps: {
actions: dialogActions,
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
styles: styles.footer,
},
})}
{/* </div> */}

{/* {ButtonGroup.create(actions, {
defaultProps: {
styles: styles.actions,
},
Expand All @@ -304,7 +340,7 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
</Flex>
),
},
})}
})} */}
</ElementType>
</Ref>
)
Expand Down
53 changes: 53 additions & 0 deletions packages/react/src/components/Dialog/DialogFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from 'react'
import * as customPropTypes from '@stardust-ui/react-proptypes'

import {
createShorthandFactory,
UIComponent,
UIComponentProps,
ChildrenComponentProps,
ContentComponentProps,
commonPropTypes,
ShorthandFactory,
childrenExist,
} from '../../lib'

import { ShorthandValue, WithAsProp, withSafeTypeForAs } from '../../types'
import { BoxProps } from '../Box/Box'

export interface DialogFooterProps
extends UIComponentProps,
ChildrenComponentProps,
ContentComponentProps {
/** Dialog actions */
actions: ShorthandValue<BoxProps>
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
}

class DialogFooter extends UIComponent<WithAsProp<DialogFooterProps>> {
static create: ShorthandFactory<DialogFooterProps>

static displayName = 'DialogFooter'
static className = 'ui-dialog__footer'

static propTypes = {
...commonPropTypes.createCommon(),
actions: customPropTypes.itemShorthand,
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
}

renderComponent({ ElementType, classes, unhandledProps }): React.ReactNode {
const { children, actions, styles } = this.props

return (
<ElementType style={{ styles }} className={classes.root} {...unhandledProps}>
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
{childrenExist(children) ? children : actions}
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved
</ElementType>
)
}
}

DialogFooter.create = createShorthandFactory({ Component: DialogFooter })
kolaps33 marked this conversation as resolved.
Show resolved Hide resolved

/**
* A TooltipContent contains the content of a Tooltip component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, incorrect description...

*/
export default withSafeTypeForAs<typeof DialogFooter, DialogFooterProps>(DialogFooter)
1 change: 1 addition & 0 deletions packages/react/src/themes/teams/componentStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export { default as ChatMessage } from './components/Chat/chatMessageStyles'
export { default as Checkbox } from './components/Checkbox/checkboxStyles'

export { default as Dialog } from './components/Dialog/dialogStyles'
export { default as DialogFooter } from './components/Dialog/dialogFooterStyles'

export { default as Divider } from './components/Divider/dividerStyles'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ICSSInJSStyle } from '../../../types'

export default {
root: (): ICSSInJSStyle => ({
textAlign: 'right',
}),
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ export default {
color: v.foregroundColor,
}),

actions: (): ICSSInJSStyle => ({
footer: (): ICSSInJSStyle => ({
gridColumn: '1 / -1',
gridRow: 3,
gridColumn: '1 / span 2',
'-ms-grid-column-align': 'end',
justifySelf: 'right',
}),

actions: (): ICSSInJSStyle => ({
display: 'inline-block',
}),

content: ({ variables: v }: DialogStyleParams): ICSSInJSStyle => ({
Expand Down