diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/dialog/Examples.js b/packages/dnb-design-system-portal/src/docs/uilib/components/dialog/Examples.js deleted file mode 100644 index 9a9fd938f5d..00000000000 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/dialog/Examples.js +++ /dev/null @@ -1,381 +0,0 @@ -/** - * UI lib Component Example - * - */ - -import React from 'react' -import ComponentBox from 'dnb-design-system-portal/src/shared/tags/ComponentBox' -import { - trash_medium, - log_out_medium, - cookie_medium, - bell_medium, - edit, -} from '@dnb/eufemia/src/icons' - -export const DialogExampleDefault = () => ( - - { - /* jsx */ ` - -

The Dialog component is a Modal variation that appears at the center of the screen. The Dialog has similar functionality to a traditional popup window and is mostly used for informational purposes (for example explaining a word on the page). Similar to Modal, it has to be triggered by the user to appear. Typical usage would be to read an explanation, then closing it.

- -
- ` - } -
-) - -export const DialogExampleHelpButton = () => ( - - { - /* jsx */ ` - -

Some additional information for the input field.

- - } -/> - ` - } -
-) - -export const DialogExampleFullscreen = () => ( - - { - /* jsx */ ` -"Hidden" Dialog title} - fullscreen - triggerAttributes={{ - variant: "tertiary", - text: "Open a fullscreen dialog", - icon: "bell" - }} - modalContent="The Dialog component is a Modal variation that appears at the center of the screen. The Dialog has similar functionality to a traditional popup window and is mostly used for informational purposes." -/> - ` - } - -) - -export const DialogExampleDelayClose = () => ( - - { - /* jsx */ ` - console.log('on_open', e)} - onClose={(e) => console.log('on_close', e)} - onClosePrevent={({ close, triggeredBy }) => { - console.log('triggeredBy', triggeredBy) - const timeout = setTimeout(close, 500) - return () => clearTimeout(timeout) // clear timeout on unmount - }} -> -

This is a Dialog with no close button.

-

Click outside me, and I will be closed within 1 second.

- Focus me with Tab key -
- ` - } -
-) - -export const DialogExampleCustomTrigger = () => ( - - { - /* jsx */ ` - ( - - )} -> -

This Modal was opened by a custom trigger component.

-
- ` - } -
-) - -export const FullDialogExample = () => ( - {} }} - > - { - /* jsx */ ` - - - - - -

This is in the Dialog header

-
- - - This is a formstatus in a Dialog -
-` - } -
-) - -export const DialogExampleProgressIndicator = () => ( - - { - /* jsx */ ` - - - - ` - } - -) - -export const DialogConfirmDefault = () => ( - - { - /* jsx */ ` - close()} - triggerAttributes={{ - text: 'Trigger button', - }} -/>` - } - -) - -export const DialogConfirmDelete = () => ( - - { - /* jsx */ ` - close()} - triggerAttributes={{ - text: 'Delete record', - icon: trash_medium, - }} -/>` - } - -) - -const loginHandler = () => {} - -export const DialogConfirmLoggedOut = () => ( - - { - /* jsx */ ` -const Component = () => { - const [open, setOpen] = React.useState(false) - return ( - <> - + + +) + +export const DialogExampleHelpButton = () => ( + + +

Some additional information for the input field.

+ + } + /> +
+) + +export const DialogExampleFullscreen = () => ( + + "Hidden" Dialog title} + fullscreen + triggerAttributes={{ + variant: 'tertiary', + text: 'Open a fullscreen dialog', + icon: 'bell', + }} + modalContent="The Dialog component is a Modal variation that appears at the center of the screen. The Dialog has similar functionality to a traditional popup window and is mostly used for informational purposes." + /> + +) + +export const DialogExampleDelayClose = () => ( + + console.log('on_open', e)} + onClose={(e) => console.log('on_close', e)} + onClosePrevent={({ close, triggeredBy }) => { + console.log('triggeredBy', triggeredBy) + const timeout = setTimeout(close, 500) + return () => clearTimeout(timeout) // clear timeout on unmount + }} + > +

This is a Dialog with no close button.

+

Click outside me, and I will be closed within 1 second.

+ + Focus me with Tab key + +
+
+) + +export const DialogExampleCustomTrigger = () => ( + + ( + + )} + > +

This Modal was opened by a custom trigger component.

+
+
+) + +export const FullDialogExample = () => ( + + {() => { + const handleBack = () => null + return ( + <> + + + + + +

This is in the Dialog header

+
+ + + + This is a formstatus in a Dialog + +
+ + ) + }} +
+) + +export const DialogExampleProgressIndicator = () => ( + + + + + +) + +export const DialogConfirmDefault = () => ( + + close()} + triggerAttributes={{ + text: 'Trigger button', + }} + /> + +) + +export const DialogConfirmDelete = () => ( + + close()} + triggerAttributes={{ + text: 'Delete record', + icon: trash_medium, + }} + /> + +) + +export const DialogConfirmLoggedOut = () => { + return ( + + {() => { + const DemoComponent = () => { + const [open, setOpen] = React.useState(false) + const loginHandler = () => null + return ( + <> + + + + ) + } + + render() + + expect(document.querySelector('.dnb-dialog__actions')).toBeTruthy() + }) + + it('supports spacing', () => { + const MockComponent = () => { + return ( + + + + + + ) + } + + render() + + const element = document.querySelector('.dnb-dialog__actions') + + expect(Array.from(element.classList)).toEqual([ + 'dnb-space', + 'dnb-space__top--large', + 'dnb-dialog__actions', + ]) + }) + + it('should contain children content', () => { + render( + + + + + + ) + + const element = document.querySelector('.dnb-dialog__actions') + + expect(element.textContent).toBe('‌Button') + }) + + it('should be seciton element', () => { + const MockComponent = () => { + return ( + + + + + + ) + } + + render() + + const element = document.querySelector('.dnb-dialog__actions') + + expect(element.nodeName).toBe('SECTION') + }) + + it('should include custom attributes', () => { + const MockComponent = () => { + return ( + + + + + + ) + } + + render() + + const element = document.querySelector('.dnb-dialog__actions') + + expect(element.getAttribute('aria-label')).toBe('Custom section label') + }) +}) diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap index 48087839451..01ba768c311 100644 --- a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap @@ -2337,8 +2337,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; height: 100%; } .dnb-dialog--information { - min-width: var(--dialog-min-width); width: var(--dialog-avg-width); + min-width: var(--dialog-min-width); max-width: var(--dialog-max-width); } .dnb-dialog--confirmation { max-width: var(--dialog-confirm-max-width); @@ -2398,6 +2398,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; } .dnb-dialog__actions > :not(:last-child) { margin-right: 1rem; } + .dnb-dialog--information .dnb-dialog__actions { + justify-content: left; } .dnb-dialog__align--center .dnb-dialog__content { align-items: center; text-align: center; } @@ -2422,22 +2424,6 @@ button.dnb-button::-moz-focus-inner { display: flex; flex-direction: row; justify-content: space-between; } - .dnb-dialog__icon__primary.dnb-icon--border::after { - left: -50%; - right: -50%; - top: -50%; - bottom: -50%; - border: none; - background-color: currentColor; - opacity: 0.1; } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning { - color: var(--color-fire-red); } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning ::after { - background-color: var(--color-fire-red-8); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info { - color: var(--color-emerald-green); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info ::after { - background-color: var(--color-pistachio); } html:not([data-visual-test]) .dnb-dialog { animation: show-modal var(--modal-animation-duration) ease-out; } html:not([data-visual-test]) .dnb-dialog--hide { @@ -2465,6 +2451,8 @@ button.dnb-button::-moz-focus-inner { margin-bottom: 0; } .dnb-dialog--spacing .dnb-dialog__header .dnb-tabs { margin-top: 3.5rem; } + .dnb-dialog__icon { + display: flex; } .dnb-dialog__icon ~ .dnb-dialog__header { margin-top: 1.5rem; } @supports (-webkit-touch-callout: none) { diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-cookie-concent-confirmation-1-d7887.snap.png b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-cookie-concent-confirmation-1-d7887.snap.png index 0711bee34da..0688174cc56 100644 Binary files a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-cookie-concent-confirmation-1-d7887.snap.png and b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-cookie-concent-confirmation-1-d7887.snap.png differ diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-default-confirmation-1-9cac8.snap.png b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-default-confirmation-1-9cac8.snap.png index d2c94c8d5ab..51a5a0f6b63 100644 Binary files a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-default-confirmation-1-9cac8.snap.png and b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-default-confirmation-1-9cac8.snap.png differ diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-delete-confirmation-1-43bd3.snap.png b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-delete-confirmation-1-43bd3.snap.png index b1404fca22e..c5829167515 100644 Binary files a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-delete-confirmation-1-43bd3.snap.png and b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-delete-confirmation-1-43bd3.snap.png differ diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-logged-out-confirmation-1-0c48e.snap.png b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-logged-out-confirmation-1-0c48e.snap.png index f2f2a409965..52cb5deed89 100644 Binary files a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-logged-out-confirmation-1-0c48e.snap.png and b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/dialog-screenshot-test-js-dialog-confirmation-screenshot-have-to-match-the-logged-out-confirmation-1-0c48e.snap.png differ diff --git a/packages/dnb-eufemia/src/components/dialog/parts/DialogAction.tsx b/packages/dnb-eufemia/src/components/dialog/parts/DialogAction.tsx index be45da71372..76fbc231285 100644 --- a/packages/dnb-eufemia/src/components/dialog/parts/DialogAction.tsx +++ b/packages/dnb-eufemia/src/components/dialog/parts/DialogAction.tsx @@ -1,14 +1,19 @@ import React, { useContext } from 'react' +import classNames from 'classnames' import Button from '../../button/Button' +import Space from '../../space/Space' import { Context } from '../../../shared' import ModalContext from '../../modal/ModalContext' import { dispatchCustomElementEvent } from '../../../shared/component-helper' +import type { SpacingProps } from '../../space/types' + type extendedMouseEvent = { event: React.MouseEvent close: () => void } -interface DialogActionProps { + +export type DialogActionProps = { /** * For dialog actions, give a custom text for the decline button. */ @@ -40,6 +45,10 @@ interface DialogActionProps { children?: React.ReactElement | Array } +export type DialogActionAllProps = DialogActionProps & + SpacingProps & + Omit, 'children'> + const fallbackCloseAction = ({ close }: extendedMouseEvent) => close() const DialogAction = ({ @@ -48,8 +57,10 @@ const DialogAction = ({ hideDecline = false, onConfirm = fallbackCloseAction, onDecline = fallbackCloseAction, + className, children, -}: DialogActionProps) => { + ...props +}: DialogActionAllProps) => { const { translation, Button: ButtonContext } = useContext(Context) const { close } = useContext(ModalContext) let childrenWithCloseFunc: Array @@ -77,7 +88,11 @@ const DialogAction = ({ } return ( -
+ {childrenWithCloseFunc} {!children && !hideDecline && ( @@ -106,9 +121,8 @@ const DialogAction = ({ size={ButtonContext?.size || 'large'} /> )} -
+ ) } export default DialogAction -export type { DialogActionProps } diff --git a/packages/dnb-eufemia/src/components/dialog/style/_dialog.scss b/packages/dnb-eufemia/src/components/dialog/style/_dialog.scss index 32c3758bd8e..57a0217b827 100644 --- a/packages/dnb-eufemia/src/components/dialog/style/_dialog.scss +++ b/packages/dnb-eufemia/src/components/dialog/style/_dialog.scss @@ -41,8 +41,8 @@ } &--information { - min-width: var(--dialog-min-width); width: var(--dialog-avg-width); + min-width: var(--dialog-min-width); max-width: var(--dialog-max-width); } @@ -119,6 +119,9 @@ margin-right: 1rem; } } + &--information &__actions { + justify-content: left; + } &__align--center &__content { align-items: center; @@ -159,35 +162,6 @@ justify-content: space-between; } - &__icon { - // Modify the border prop from the icon component - &__primary.dnb-icon--border::after { - left: -50%; - right: -50%; - top: -50%; - bottom: -50%; - - border: none; - background-color: currentColor; - opacity: 0.1; - } - - &__primary#{&}--warning { - color: var(--color-fire-red); - - ::after { - background-color: var(--color-fire-red-8); - } - } - &__primary#{&}--info { - color: var(--color-emerald-green); - - ::after { - background-color: var(--color-pistachio); - } - } - } - // Animation in html:not([data-visual-test]) & { animation: show-modal var(--modal-animation-duration) ease-out; @@ -236,6 +210,9 @@ } } + &__icon { + display: flex; + } &__icon ~ &__header { margin-top: 1.5rem; } diff --git a/packages/dnb-eufemia/src/components/dialog/style/themes/dnb-dialog-theme-ui.scss b/packages/dnb-eufemia/src/components/dialog/style/themes/dnb-dialog-theme-ui.scss index 944247444c8..eb9db20eba0 100644 --- a/packages/dnb-eufemia/src/components/dialog/style/themes/dnb-dialog-theme-ui.scss +++ b/packages/dnb-eufemia/src/components/dialog/style/themes/dnb-dialog-theme-ui.scss @@ -7,4 +7,33 @@ .dnb-dialog { background: var(--color-white); + + &__icon { + // Modify the border prop from the icon component + &__primary.dnb-icon--border::after { + left: -50%; + right: -50%; + top: -50%; + bottom: -50%; + + border: none; + background-color: currentColor; + opacity: 0.1; + } + + &__primary#{&}--warning { + color: var(--color-fire-red); + + ::after { + background-color: var(--color-fire-red-8); + } + } + &__primary#{&}--info { + color: var(--color-emerald-green); + + ::after { + background-color: var(--color-pistachio); + } + } + } } diff --git a/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap b/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap index 7d312667892..965d8d285f2 100644 --- a/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap @@ -2353,8 +2353,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; height: 100%; } .dnb-dialog--information { - min-width: var(--dialog-min-width); width: var(--dialog-avg-width); + min-width: var(--dialog-min-width); max-width: var(--dialog-max-width); } .dnb-dialog--confirmation { max-width: var(--dialog-confirm-max-width); @@ -2414,6 +2414,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; } .dnb-dialog__actions > :not(:last-child) { margin-right: 1rem; } + .dnb-dialog--information .dnb-dialog__actions { + justify-content: left; } .dnb-dialog__align--center .dnb-dialog__content { align-items: center; text-align: center; } @@ -2438,22 +2440,6 @@ button.dnb-button::-moz-focus-inner { display: flex; flex-direction: row; justify-content: space-between; } - .dnb-dialog__icon__primary.dnb-icon--border::after { - left: -50%; - right: -50%; - top: -50%; - bottom: -50%; - border: none; - background-color: currentColor; - opacity: 0.1; } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning { - color: var(--color-fire-red); } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning ::after { - background-color: var(--color-fire-red-8); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info { - color: var(--color-emerald-green); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info ::after { - background-color: var(--color-pistachio); } html:not([data-visual-test]) .dnb-dialog { animation: show-modal var(--modal-animation-duration) ease-out; } html:not([data-visual-test]) .dnb-dialog--hide { @@ -2481,6 +2467,8 @@ button.dnb-button::-moz-focus-inner { margin-bottom: 0; } .dnb-dialog--spacing .dnb-dialog__header .dnb-tabs { margin-top: 3.5rem; } + .dnb-dialog__icon { + display: flex; } .dnb-dialog__icon ~ .dnb-dialog__header { margin-top: 1.5rem; } @supports (-webkit-touch-callout: none) { diff --git a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap index c4fb9e2afed..0898dffd45d 100644 --- a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap @@ -2324,8 +2324,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; height: 100%; } .dnb-dialog--information { - min-width: var(--dialog-min-width); width: var(--dialog-avg-width); + min-width: var(--dialog-min-width); max-width: var(--dialog-max-width); } .dnb-dialog--confirmation { max-width: var(--dialog-confirm-max-width); @@ -2385,6 +2385,8 @@ button.dnb-button::-moz-focus-inner { width: 100%; } .dnb-dialog__actions > :not(:last-child) { margin-right: 1rem; } + .dnb-dialog--information .dnb-dialog__actions { + justify-content: left; } .dnb-dialog__align--center .dnb-dialog__content { align-items: center; text-align: center; } @@ -2409,22 +2411,6 @@ button.dnb-button::-moz-focus-inner { display: flex; flex-direction: row; justify-content: space-between; } - .dnb-dialog__icon__primary.dnb-icon--border::after { - left: -50%; - right: -50%; - top: -50%; - bottom: -50%; - border: none; - background-color: currentColor; - opacity: 0.1; } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning { - color: var(--color-fire-red); } - .dnb-dialog__icon__primary.dnb-dialog__icon--warning ::after { - background-color: var(--color-fire-red-8); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info { - color: var(--color-emerald-green); } - .dnb-dialog__icon__primary.dnb-dialog__icon--info ::after { - background-color: var(--color-pistachio); } html:not([data-visual-test]) .dnb-dialog { animation: show-modal var(--modal-animation-duration) ease-out; } html:not([data-visual-test]) .dnb-dialog--hide { @@ -2452,6 +2438,8 @@ button.dnb-button::-moz-focus-inner { margin-bottom: 0; } .dnb-dialog--spacing .dnb-dialog__header .dnb-tabs { margin-top: 3.5rem; } + .dnb-dialog__icon { + display: flex; } .dnb-dialog__icon ~ .dnb-dialog__header { margin-top: 1.5rem; } @supports (-webkit-touch-callout: none) {