From 7e44d2832582b161539e9899c4a760537638f7b8 Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Fri, 5 Sep 2025 17:55:11 +0200 Subject: [PATCH 1/4] chore(release): v0.76.3 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c86d5286..644b3aa4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # @cube-dev/ui-kit +## v0.76.3 + +[compare changes](https://github.com/cube-js/cube-ui-kit/compare/v0.76.2...v0.76.3) + ## 0.76.2 ### Patch Changes diff --git a/package.json b/package.json index 6f46dbbcb..60d854862 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cube-dev/ui-kit", - "version": "0.76.2", + "version": "0.76.3", "type": "module", "description": "UIKit for Cube Projects", "repository": { From e2c127e328665b0315c1fcaee4cea97f636273de Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Fri, 5 Sep 2025 18:01:21 +0200 Subject: [PATCH 2/4] feat(Modal): remove component --- .changeset/late-horses-play.md | 5 + .changeset/quick-cougars-hammer.md | 5 + src/components/actions/Menu/Menu.stories.tsx | 37 ++ src/components/actions/Menu/Menu.tsx | 5 - src/components/actions/Menu/styled.tsx | 2 + src/components/organisms/Modal/Modal.tsx | 448 ------------------- src/components/overlays/Dialog/Dialog.tsx | 2 +- src/index.ts | 2 - 8 files changed, 50 insertions(+), 456 deletions(-) create mode 100644 .changeset/late-horses-play.md create mode 100644 .changeset/quick-cougars-hammer.md delete mode 100644 src/components/organisms/Modal/Modal.tsx diff --git a/.changeset/late-horses-play.md b/.changeset/late-horses-play.md new file mode 100644 index 000000000..30f4f2ee9 --- /dev/null +++ b/.changeset/late-horses-play.md @@ -0,0 +1,5 @@ +--- +"@cube-dev/ui-kit": patch +--- + +Add side border radius to the header and the footer of the menus. diff --git a/.changeset/quick-cougars-hammer.md b/.changeset/quick-cougars-hammer.md new file mode 100644 index 000000000..310fd5a79 --- /dev/null +++ b/.changeset/quick-cougars-hammer.md @@ -0,0 +1,5 @@ +--- +"@cube-dev/ui-kit": minor +--- + +Remove legacy Modal component. diff --git a/src/components/actions/Menu/Menu.stories.tsx b/src/components/actions/Menu/Menu.stories.tsx index 47faac445..09a9188e5 100644 --- a/src/components/actions/Menu/Menu.stories.tsx +++ b/src/components/actions/Menu/Menu.stories.tsx @@ -1799,6 +1799,43 @@ export const SubMenuCustomization = () => { ); }; +export const WithHeaderAndFooter = (props) => { + return ( +
+ + }> + First Item + + }> + Second Item + + }> + Third Item + + }> + Fourth Item + + +
+ ); +}; + +WithHeaderAndFooter.parameters = { + docs: { + description: { + story: + 'Menu with both header and footer sections, both styled with light fill background.', + }, + }, +}; + export const ComprehensivePopoverSynchronization = () => { const MyMenuComponent = ({ onAction }) => ( diff --git a/src/components/actions/Menu/Menu.tsx b/src/components/actions/Menu/Menu.tsx index 0bce09711..3e803a8c8 100644 --- a/src/components/actions/Menu/Menu.tsx +++ b/src/components/actions/Menu/Menu.tsx @@ -14,12 +14,7 @@ import { Styles, } from '../../../tasty'; import { mergeProps } from '../../../utils/react'; -import { CubeBlockProps } from '../../Block'; import { Item } from '../../Item'; -import { - CubeTooltipProviderProps, - TooltipProvider, -} from '../../overlays/Tooltip/TooltipProvider'; import { useMenuContext } from './context'; import { MenuItem } from './MenuItem'; diff --git a/src/components/actions/Menu/styled.tsx b/src/components/actions/Menu/styled.tsx index aed2f8e26..6f0dbde26 100644 --- a/src/components/actions/Menu/styled.tsx +++ b/src/components/actions/Menu/styled.tsx @@ -79,6 +79,7 @@ export const StyledHeader = tasty(Space, { height: 'min $size', boxSizing: 'border-box', border: 'bottom', + radius: '1cr top', $size: { '': '$size-md', @@ -110,6 +111,7 @@ export const StyledFooter = tasty(Space, { }, boxSizing: 'border-box', border: 'top', + radius: '1cr bottom', }, }); diff --git a/src/components/organisms/Modal/Modal.tsx b/src/components/organisms/Modal/Modal.tsx deleted file mode 100644 index 405938abf..000000000 --- a/src/components/organisms/Modal/Modal.tsx +++ /dev/null @@ -1,448 +0,0 @@ -import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; -import { createRoot } from 'react-dom/client'; -import { CSSTransition } from 'react-transition-group'; - -import { CloseIcon } from '../../../icons'; -import { tasty } from '../../../tasty'; -import { Button } from '../../actions'; -import { Action } from '../../actions/Action/Action'; -import { Block } from '../../Block'; -import { Card, CubeCardProps } from '../../content/Card/Card'; -import { Title } from '../../content/Title'; -import { Flex } from '../../layout/Flex'; -import { Flow } from '../../layout/Flow'; -import { Space } from '../../layout/Space'; - -const Overlay = tasty({ - as: 'div', - styles: { - position: 'fixed', - top: 0, - right: 0, - bottom: 0, - left: 0, - '$enter-transition-time': '250ms', - '$leave-transition-time': '160ms', - fill: '#black.40', - place: 'center', - zIndex: 1000, - display: 'none', - whiteSpace: 'normal', - - '& > .cube-modal': { - '$base-translate': 'calc((50vh - 50%) / -3)', - transform: 'translate(0, calc(var(--base-translate)))', - }, - - '&.cube-modal-transition-enter': { - opacity: 0, - display: 'flex', - }, - - '&.cube-modal-transition-enter > .cube-modal': { - transform: 'translate(0, calc(-32px + var(--base-translate))) scale(0.5)', - }, - - '&.cube-modal-transition-enter-active': { - opacity: 1, - transition: 'all var(--enter-transition-time) cubic-bezier(0, 0.5, 0, 1)', - }, - - '&.cube-modal-transition-enter-active > .cube-modal': { - transform: 'translate(0, calc(var(--base-translate))) scale(1)', - transition: - 'all var(--enter-transition-time) cubic-bezier(0.5, 0.5, 0, 1)', - }, - - '&.cube-modal-transition-enter-done': { - display: 'flex', - }, - - '&.cube-modal-transition-exit': { - opacity: 1, - display: 'flex', - }, - - '&.cube-modal-transition-exit > .cube-modal': { - transform: 'translate(0, calc(var(--base-translate))) scale(1)', - }, - - '&.cube-modal-transition-exit-active': { - opacity: 0, - transition: 'all var(--leave-transition-time) ease-in', - }, - - '&.cube-modal-transition-exit-active > .cube-modal': { - transform: 'translate(0, calc(-32px + var(--base-translate))) scale(0.5)', - transition: 'all var(--leave-transition-time) ease-in', - }, - - '&.cube-modal-transition-exit-done': { - display: 'none', - }, - }, -}); - -export interface CubeModalProps extends CubeCardProps { - title?: string; - isVisible?: boolean; - type?: 'default' | 'primary' | 'info' | 'danger'; - isClosable?: boolean; - isLoading?: boolean; - okType?: 'default' | 'primary' | 'danger'; - okText?: string; - cancelText?: string; - onOk?: (any) => Promise | void | false; - onCancel?: () => Promise | void; - onClose?: () => Promise | void; - isDisabled?: boolean; -} - -/** - * @deprecated Prefer using Dialog instead - * - * DEPRECATED Modal component - * Designed after AntD Modal component and almost duplicate its API. - * Use Dialog component instead - */ -export function Modal(allProps: CubeModalProps) { - let { - title, - isVisible, - type, - okType, - isClosable, - isLoading, - children, - okText, - cancelText, - width, - onOk, - onCancel, - onClose, - qa, - isDisabled, - ...props - } = allProps; - - isClosable = !!isClosable; - - const nodeRef = useRef(null); - const [inProp, setInProp] = useState(false); - const [localLoading, setLocalLoading] = useState(false); - - useEffect(() => { - setInProp(isVisible || false); - }, [isVisible]); - - function cancel() { - if (onCancel) { - onCancel(); - } else if (onClose) { - onClose(); - } - } - - function close() { - if (!isVisible) return; - - if (onClose || onCancel) { - if (isClosable) { - // @ts-ignore - (onClose || onCancel)(); - } else if (onCancel) { - onCancel(); - } - } - } - - const onOverlayClick = (evt) => { - if (!evt || !evt.target) return; - - if (evt.target.classList.contains('cube-modal-overlay') && !isLoading) { - close(); - } - }; - - useEffect(() => { - function handleKeyDown(evt) { - if (evt.key === 'Escape' && !isLoading) { - close(); - } - } - - window.addEventListener('keydown', handleKeyDown); - - return () => { - window.removeEventListener('keydown', handleKeyDown); - }; - }, []); - - const handleOk = useCallback( - (arg) => { - setLocalLoading(true); - - (async () => { - if (onOk) { - try { - if ((await onOk(arg)) === false && (onClose || onCancel)) { - // @ts-ignore - (onClose || onCancel)(); - } - } catch (e) { - // do nothing - } finally { - setLocalLoading(false); - } - } - })(); - }, - [onOk], - ); - - return ( - - - - - {typeof title === 'object' ? ( - title - ) : ( - - {title} - - )} - {isClosable ? ( - - - - ) : null} - - - {typeof children === 'string' ? ( - {children} - ) : ( - children - )} - {type !== 'info' && (onOk || onCancel) ? ( - - - - - ) : null} - {type === 'info' ? ( - - - - ) : null} - - - - - ); -} - -let ID = 0; - -interface ModalService { - root: Element | null; - items: ModalItem[]; - init: () => void; - render: () => void; - _render: (items?: ModalItem[]) => void; - open: (item: ModalItem) => void; - close: (item: ModalItem) => void; - resolve: (item: ModalItem, arg?: any) => void; - reject: (item: ModalItem, arg?: any) => void; -} - -interface ModalItem extends Omit { - id?: number; - isVisible?: boolean; - resolve: (any) => void; - reject: (any) => void; - content: ReactNode; -} - -const modal: ModalService = { - root: null, - items: [], - init() { - if (this.root) return; - - this.root = document.createElement('div'); - - // @ts-ignore - this.root.classList.add('cube-modal-container'); - - document.body.appendChild(this.root); - - this._render([]); - }, - render() { - this.init(); - - this._render(); - }, - _render(items) { - if (!items) { - items = this.items; - } - - if (!this.root) return; - - const root = createRoot(this.root); - - root.render( - items.map((item) => { - const { id, onOk, onCancel, onClose, content, ...options } = item; - - const wrapOnOk = async (arg) => { - onOk && (await onOk(arg)); - - this.resolve(item, arg); - }; - const wrapOnCancel = () => { - onCancel && onCancel(); - - if (item.type === 'info') { - this.resolve(item); - } else { - this.reject(item); - } - }; - const wrapOnClose = () => { - onClose && onClose(); - - if (item.type === 'info') { - this.resolve(item); - } else { - this.reject(item); - } - }; - - return ( - - {content} - - ); - }), - ); - }, - open(item) { - item.isVisible = false; - item.id = ++ID; - - this.items.push(item); - - this.render(); - - setTimeout(() => { - item.isVisible = true; - - this.render(); - }); - - return new Promise((resolve, reject) => { - item.resolve = resolve; - item.reject = reject; - }); - }, - close(item) { - item.isVisible = false; - - this.render(); - - setTimeout(() => { - this.items = this.items.filter((modal) => item.id !== modal.id); - - this.render(); - }, 1000); - }, - resolve(item, arg) { - item.resolve(arg); - - this.close(item); - }, - reject(item, arg) { - item.reject(arg); - - this.close(item); - }, -}; - -Modal.confirm = (options) => { - return modal.open({ type: 'confirm', ...options }); -}; - -Modal.info = (options) => { - return modal.open({ type: 'info', ...options }); -}; diff --git a/src/components/overlays/Dialog/Dialog.tsx b/src/components/overlays/Dialog/Dialog.tsx index 6a76fe285..90c1ad0fa 100644 --- a/src/components/overlays/Dialog/Dialog.tsx +++ b/src/components/overlays/Dialog/Dialog.tsx @@ -190,7 +190,7 @@ const DialogContent = forwardRef(function DialogContent( let { qa, children, - size = 'S', + size = 'M', isDismissable = contextProps.isDismissable, onDismiss = contextProps.onClose, closeIcon, diff --git a/src/index.ts b/src/index.ts index b9a43b6c3..34d13ec1c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -123,8 +123,6 @@ export { LegacyTabs } from './components/navigation/LegacyTabs/LegacyTabs'; export type { CubeTabsProps } from './components/navigation/LegacyTabs/LegacyTabs'; export { FileTabs } from './components/organisms/FileTabs/FileTabs'; export type { CubeFileTabProps } from './components/organisms/FileTabs/FileTabs'; -export { Modal } from './components/organisms/Modal/Modal'; -export type { CubeModalProps } from './components/organisms/Modal/Modal'; export { StatsCard } from './components/organisms/StatsCard/StatsCard'; export type { CubeStatsCard } from './components/organisms/StatsCard/StatsCard'; export { From 51ad973dfb923a3af524f2347501931bcb06dc9b Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Fri, 5 Sep 2025 18:03:20 +0200 Subject: [PATCH 3/4] Revert "chore(release): v0.76.3" This reverts commit 7e44d2832582b161539e9899c4a760537638f7b8. --- CHANGELOG.md | 4 ---- package.json | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 644b3aa4f..2c86d5286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,5 @@ # @cube-dev/ui-kit -## v0.76.3 - -[compare changes](https://github.com/cube-js/cube-ui-kit/compare/v0.76.2...v0.76.3) - ## 0.76.2 ### Patch Changes diff --git a/package.json b/package.json index 60d854862..6f46dbbcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cube-dev/ui-kit", - "version": "0.76.3", + "version": "0.76.2", "type": "module", "description": "UIKit for Cube Projects", "repository": { From 8c08c6da869adfe3a2a0936f2ba09935ec1f1bb7 Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Fri, 5 Sep 2025 18:11:04 +0200 Subject: [PATCH 4/4] fix(FilterPicker): default popover width --- src/components/fields/FilterPicker/FilterPicker.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/fields/FilterPicker/FilterPicker.tsx b/src/components/fields/FilterPicker/FilterPicker.tsx index cf2475886..81a7edaac 100644 --- a/src/components/fields/FilterPicker/FilterPicker.tsx +++ b/src/components/fields/FilterPicker/FilterPicker.tsx @@ -1007,7 +1007,14 @@ export const FilterPicker = forwardRef(function FilterPicker( > {renderTrigger} {(close) => ( - +