From 3748b402e5e6dcc28c7f93012300ebfbedbbd5a0 Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Wed, 13 Dec 2023 18:02:34 +0100 Subject: [PATCH] feat(Modal): add slug to Modal, ComposedModal (#15350) * feat(Modal): add slug to Modal, ComposedModal * test(snapshot): update snapshots * docs(Slug): add slug to controls table * fix(Modal): remove shadows, use callout gradient * test(snapshot): update snapshots * fix(Modal): adjust background, fix conditional class --- .../__snapshots__/PublicAPI-test.js.snap | 6 ++ .../ComposedModal/ComposedModal.tsx | 29 ++++++- packages/react/src/components/Modal/Modal.tsx | 23 ++++- .../components/Slug/Slug-examples.stories.js | 87 ++++++++++++++++++- .../react/src/components/Slug/Slug.stories.js | 2 +- .../react/src/components/Slug/slug-story.scss | 4 + .../styles/scss/components/modal/_modal.scss | 34 +++++++- .../styles/scss/utilities/_ai-gradient.scss | 22 +++-- 8 files changed, 192 insertions(+), 15 deletions(-) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 647770e0d9de..157ed84b7142 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -1486,6 +1486,9 @@ Map { ], "type": "oneOf", }, + "slug": Object { + "type": "node", + }, }, "render": [Function], }, @@ -4833,6 +4836,9 @@ Map { ], "type": "oneOf", }, + "slug": Object { + "type": "node", + }, }, "render": [Function], }, diff --git a/packages/react/src/components/ComposedModal/ComposedModal.tsx b/packages/react/src/components/ComposedModal/ComposedModal.tsx index 483bc8467273..8a44f827ef73 100644 --- a/packages/react/src/components/ComposedModal/ComposedModal.tsx +++ b/packages/react/src/components/ComposedModal/ComposedModal.tsx @@ -10,7 +10,7 @@ import React, { type RefObject, } from 'react'; import { isElement } from 'react-is'; -import PropTypes from 'prop-types'; +import PropTypes, { ReactNodeLike } from 'prop-types'; import { ModalHeader, type ModalHeaderProps } from './ModalHeader'; import { ModalFooter, type ModalFooterProps } from './ModalFooter'; @@ -180,6 +180,11 @@ export interface ComposedModalProps extends HTMLAttributes { selectorsFloatingMenus?: Array; size?: 'xs' | 'sm' | 'md' | 'lg'; + + /** + * **Experimental**: Provide a `Slug` component to be rendered inside the `ComposedModal` component + */ + slug?: ReactNodeLike; } const ComposedModal = React.forwardRef( @@ -200,6 +205,7 @@ const ComposedModal = React.forwardRef( selectorsFloatingMenus, size, launcherButtonRef, + slug, ...rest }, ref @@ -270,8 +276,11 @@ const ComposedModal = React.forwardRef( const modalClass = cx( `${prefix}--modal`, - isOpen && 'is-visible', - danger && `${prefix}--modal--danger`, + { + 'is-visible': isOpen, + [`${prefix}--modal--danger`]: danger, + [`${prefix}--modal--slug`]: slug, + }, customClassName ); @@ -344,6 +353,14 @@ const ComposedModal = React.forwardRef( } }, [open, selectorPrimaryFocus, isOpen]); + // Slug is always size `lg` + let normalizedSlug; + if (slug && slug['type']?.displayName === 'Slug') { + normalizedSlug = React.cloneElement(slug as React.ReactElement, { + size: 'lg', + }); + } + return (
( Focus sentinel
+ {normalizedSlug} {childrenWithProps}
{/* Non-translatable: Focus-wrap code makes this `
+

AI Explained

@@ -268,6 +275,47 @@ export const _Combobox = { ), }; +export const _ComposedModal = { + argTypes: { + slug: { + description: + '**Experimental**: Provide a `Slug` component to be rendered inside the component', + }, + }, + render: () => ( +
+ + + +

+ Custom domains direct requests for your apps in this Cloud Foundry + organization to a URL that you own. A custom domain can be a shared + domain, a shared subdomain, or a shared domain and host. +

+ + +
+ +
+
+ ), +}; + export const _DatePicker = { args: args, argTypes: argTypes, @@ -327,6 +375,43 @@ export const _FilterableMultiselect = { ), }; +export const _Modal = { + argTypes: { + slug: { + description: + '**Experimental**: Provide a `Slug` component to be rendered inside the component', + }, + }, + render: () => ( +
+ +

+ Custom domains direct requests for your apps in this Cloud Foundry + organization to a URL that you own. A custom domain can be a shared + domain, a shared subdomain, or a shared domain and host. +

+ + +