From 804fb83230676534777427eb2a9ee20e904f5d28 Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Fri, 29 Mar 2024 11:55:11 -0700 Subject: [PATCH 1/3] style(DataTable): scope ai gradient styles to slug rows (#16090) --- packages/styles/scss/components/data-table/_data-table.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styles/scss/components/data-table/_data-table.scss b/packages/styles/scss/components/data-table/_data-table.scss index 123c5ed9157d..a111e567ede6 100644 --- a/packages/styles/scss/components/data-table/_data-table.scss +++ b/packages/styles/scss/components/data-table/_data-table.scss @@ -1003,7 +1003,7 @@ .#{$prefix}--data-table tbody tr.#{$prefix}--data-table--slug-row:hover, tr.#{$prefix}--data-table--slug-row:hover + .#{$prefix}--expandable-row[data-child-row], - tr.#{$prefix}--expandable-row--hover + tr.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row--hover + .#{$prefix}--expandable-row[data-child-row]:hover, tr.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--slug-row, tr.#{$prefix}--data-table--selected.#{$prefix}--parent-row.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--slug-row { From 599fbf0e82602943da7e48450ca8b0f9a9d59b51 Mon Sep 17 00:00:00 2001 From: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:58:38 +0530 Subject: [PATCH 2/3] fix(15510): Update Interface to Include href Prop in SwitcherItem Type (#16043) * fix(15510): update switcherItem interface * Update SwitcherItem.tsx * fix(15510): update propType and href passed to Link * chore(15510): fix typo * chore: update snaps --------- Co-authored-by: Andrea N. Cardona --- .../__tests__/__snapshots__/PublicAPI-test.js.snap | 3 +++ packages/react/src/components/UIShell/SwitcherItem.tsx | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 262754c98087..9eaeaf9a64fa 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -7482,6 +7482,9 @@ Map { "handleSwitcherItemFocus": Object { "type": "func", }, + "href": Object { + "type": "string", + }, "index": Object { "type": "number", }, diff --git a/packages/react/src/components/UIShell/SwitcherItem.tsx b/packages/react/src/components/UIShell/SwitcherItem.tsx index 90f303c73ade..06354fb7151e 100644 --- a/packages/react/src/components/UIShell/SwitcherItem.tsx +++ b/packages/react/src/components/UIShell/SwitcherItem.tsx @@ -46,6 +46,10 @@ interface BaseSwitcherItemProps { * Specify whether the panel is selected */ isSelected?: boolean; + /** + * Optionally provide an href for the underlying li` + */ + href?: string; } interface SwitcherItemWithAriaLabel extends BaseSwitcherItemProps { @@ -75,6 +79,7 @@ const SwitcherItem = forwardRef( index, handleSwitcherItemFocus, onKeyDown = () => {}, + href, ...rest } = props; @@ -116,6 +121,7 @@ const SwitcherItem = forwardRef( setTabFocus(evt); onKeyDown(evt); }} + href={href} ref={forwardRef} {...rest} className={linkClassName} @@ -143,6 +149,10 @@ SwitcherItem.propTypes = { * event handlers */ handleSwitcherItemFocus: PropTypes.func, + /** + * Optionally provide an href for the underlying li` + */ + href: PropTypes.string, /** * Specify the index of the SwitcherItem */ From daddb69aaa3ec33946257fcefac13c33c6ebe211 Mon Sep 17 00:00:00 2001 From: Joseph Schultz Date: Mon, 1 Apr 2024 12:35:16 -0500 Subject: [PATCH 3/3] feat: add types to `ComboButton` (#16038) Convert `ComboButton` to Typescript and export newly added interface `ComboButtonProps`. --- .../react/src/components/ComboButton/index.js | 216 -------------- .../src/components/ComboButton/index.tsx | 268 ++++++++++++++++++ 2 files changed, 268 insertions(+), 216 deletions(-) delete mode 100644 packages/react/src/components/ComboButton/index.js create mode 100644 packages/react/src/components/ComboButton/index.tsx diff --git a/packages/react/src/components/ComboButton/index.js b/packages/react/src/components/ComboButton/index.js deleted file mode 100644 index d6b2577bfcff..000000000000 --- a/packages/react/src/components/ComboButton/index.js +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright IBM Corp. 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React, { useRef, useState } from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -import { ChevronDown } from '@carbon/icons-react'; -import { IconButton } from '../IconButton'; -import Button from '../Button'; -import { Menu } from '../Menu'; - -import { useAttachedMenu } from '../../internal/useAttachedMenu'; -import { useId } from '../../internal/useId'; -import { useMergedRefs } from '../../internal/useMergedRefs'; -import { usePrefix } from '../../internal/usePrefix'; - -const spacing = 0; // top and bottom spacing between the button and the menu. in px -const defaultTranslations = { - 'carbon.combo-button.additional-actions': 'Additional actions', -}; - -function defaultTranslateWithId(messageId) { - return defaultTranslations[messageId]; -} - -const ComboButton = React.forwardRef(function ComboButton( - { - children, - className, - disabled, - label, - onClick, - size = 'lg', - menuAlignment = 'bottom', - tooltipAlignment, - translateWithId: t = defaultTranslateWithId, - ...rest - }, - forwardRef -) { - const id = useId('combobutton'); - const prefix = usePrefix(); - const containerRef = useRef(null); - const menuRef = useRef(null); - const ref = useMergedRefs([forwardRef, containerRef]); - const [width, setWidth] = useState(0); - const { - open, - x, - y, - handleClick: hookOnClick, - handleMousedown: handleTriggerMousedown, - handleClose, - } = useAttachedMenu(containerRef); - - function handleTriggerClick() { - if (containerRef.current) { - const { width: w } = containerRef.current.getBoundingClientRect(); - setWidth(w); - hookOnClick(); - } - } - - function handlePrimaryActionClick(e) { - if (onClick) { - onClick(e); - } - } - - function handleOpen() { - menuRef.current.style.inlineSize = `${width}px`; - menuRef.current.style.minInlineSize = `${width}px`; - - if (menuAlignment !== 'bottom' && menuAlignment !== 'top') { - menuRef.current.style.inlineSize = `fit-content`; - } - } - - const containerClasses = classNames( - `${prefix}--combo-button__container`, - `${prefix}--combo-button__container--${size}`, - { - [`${prefix}--combo-button__container--open`]: open, - }, - className - ); - - const menuClasses = classNames(`${prefix}--combo-button__${menuAlignment}`); - - const primaryActionClasses = classNames( - `${prefix}--combo-button__primary-action` - ); - const triggerClasses = classNames(`${prefix}--combo-button__trigger`); - - return ( -
-
- -
- - - - - {children} - -
- ); -}); - -ComboButton.propTypes = { - /** - * A collection of MenuItems to be rendered as additional actions for this ComboButton. - */ - children: PropTypes.node.isRequired, - - /** - * Additional CSS class names. - */ - className: PropTypes.string, - - /** - * Specify whether the ComboButton should be disabled, or not. - */ - disabled: PropTypes.bool, - - /** - * Provide the label to be renderd on the primary action button. - */ - label: PropTypes.string.isRequired, - - /** - * Experimental property. Specify how the menu should align with the button element - */ - menuAlignment: PropTypes.oneOf([ - 'top', - 'top-start', - 'top-end', - 'bottom', - 'bottom-start', - 'bottom-end', - ]), - - /** - * Provide an optional function to be called when the primary action element is clicked. - */ - onClick: PropTypes.func, - - /** - * Specify the size of the buttons and menu. - */ - size: PropTypes.oneOf(['sm', 'md', 'lg']), - - /** - * Specify how the trigger tooltip should be aligned. - */ - tooltipAlignment: PropTypes.oneOf([ - 'top', - 'top-left', - 'top-start', - 'top-right', - 'top-end', - 'bottom', - 'bottom-left', - 'bottom-start', - 'bottom-right', - 'bottom-end', - 'left', - 'right', - ]), - - /** - * Optional method that takes in a message id and returns an - * internationalized string. - */ - translateWithId: PropTypes.func, -}; - -export { ComboButton }; diff --git a/packages/react/src/components/ComboButton/index.tsx b/packages/react/src/components/ComboButton/index.tsx new file mode 100644 index 000000000000..a2123440fa9e --- /dev/null +++ b/packages/react/src/components/ComboButton/index.tsx @@ -0,0 +1,268 @@ +/** + * Copyright IBM Corp. 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { useRef, useState } from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +import { ChevronDown } from '@carbon/icons-react'; +import { IconButton } from '../IconButton'; +import Button from '../Button'; +import { Menu } from '../Menu'; + +import { useAttachedMenu } from '../../internal/useAttachedMenu'; +import { useId } from '../../internal/useId'; +import { useMergedRefs } from '../../internal/useMergedRefs'; +import { usePrefix } from '../../internal/usePrefix'; + +const spacing = 0; // top and bottom spacing between the button and the menu. in px +const defaultTranslations = { + 'carbon.combo-button.additional-actions': 'Additional actions', +}; + +function defaultTranslateWithId(messageId: string) { + return defaultTranslations[messageId]; +} + +interface ComboButtonProps { + /** + * A collection of `MenuItems` to be rendered as additional actions for this `ComboButton`. + */ + children: React.ComponentProps['children']; + + /** + * Additional CSS class names. + */ + className?: string; + + /** + * Specify whether the `ComboButton` should be disabled, or not. + */ + disabled?: boolean; + + /** + * Provide the label to be rendered on the primary action button. + */ + label: React.ComponentProps['title']; + + /** + * Experimental property. Specify how the menu should align with the button element + */ + menuAlignment?: React.ComponentProps['menuAlignment']; + + /** + * Provide an optional function to be called when the primary action element is clicked. + */ + onClick?: React.ComponentProps['onClick']; + + /** + * Specify the size of the buttons and menu. + */ + size?: 'sm' | 'md' | 'lg'; + + /** + * Specify how the trigger tooltip should be aligned. + */ + tooltipAlignment?: React.ComponentProps['align']; + + /** + * Optional method that takes in a message `id` and returns an + * internationalized string. + */ + translateWithId?: (id: string) => string; +} + +const ComboButton = React.forwardRef( + function ComboButton( + { + children, + className, + disabled, + label, + onClick, + size = 'lg', + menuAlignment = 'bottom', + tooltipAlignment, + translateWithId: t = defaultTranslateWithId, + ...rest + }, + forwardRef + ) { + const id = useId('combobutton'); + const prefix = usePrefix(); + const containerRef = useRef(null); + const menuRef = useRef>(null); + const ref = useMergedRefs([forwardRef, containerRef]); + const [width, setWidth] = useState(0); + const { + open, + x, + y, + handleClick: hookOnClick, + handleMousedown: handleTriggerMousedown, + handleClose, + } = useAttachedMenu(containerRef); + + function handleTriggerClick() { + if (containerRef.current) { + const { width: w } = containerRef.current.getBoundingClientRect(); + setWidth(w); + hookOnClick(); + } + } + + function handlePrimaryActionClick(e: React.MouseEvent) { + if (onClick) { + onClick(e); + } + } + + function handleOpen() { + if (menuRef.current) { + menuRef.current.style.inlineSize = `${width}px`; + menuRef.current.style.minInlineSize = `${width}px`; + + if (menuAlignment !== 'bottom' && menuAlignment !== 'top') { + menuRef.current.style.inlineSize = `fit-content`; + } + } + } + + const containerClasses = classNames( + `${prefix}--combo-button__container`, + `${prefix}--combo-button__container--${size}`, + { + [`${prefix}--combo-button__container--open`]: open, + }, + className + ); + + const menuClasses = classNames(`${prefix}--combo-button__${menuAlignment}`); + + const primaryActionClasses = classNames( + `${prefix}--combo-button__primary-action` + ); + const triggerClasses = classNames(`${prefix}--combo-button__trigger`); + + return ( +
+
+ +
+ + + + + {children} + +
+ ); + } +); + +ComboButton.propTypes = { + /** + * A collection of MenuItems to be rendered as additional actions for this ComboButton. + */ + children: PropTypes.node.isRequired, + + /** + * Additional CSS class names. + */ + className: PropTypes.string, + + /** + * Specify whether the ComboButton should be disabled, or not. + */ + disabled: PropTypes.bool, + + /** + * Provide the label to be rendered on the primary action button. + */ + label: PropTypes.string.isRequired, + + /** + * Experimental property. Specify how the menu should align with the button element + */ + menuAlignment: PropTypes.oneOf([ + 'top', + 'top-start', + 'top-end', + 'bottom', + 'bottom-start', + 'bottom-end', + ]), + + /** + * Provide an optional function to be called when the primary action element is clicked. + */ + onClick: PropTypes.func, + + /** + * Specify the size of the buttons and menu. + */ + size: PropTypes.oneOf(['sm', 'md', 'lg']), + + /** + * Specify how the trigger tooltip should be aligned. + */ + tooltipAlignment: PropTypes.oneOf([ + 'top', + 'top-left', + 'top-start', + 'top-right', + 'top-end', + 'bottom', + 'bottom-left', + 'bottom-start', + 'bottom-right', + 'bottom-end', + 'left', + 'right', + ]), + + /** + * Optional method that takes in a message id and returns an + * internationalized string. + */ + translateWithId: PropTypes.func, +}; + +export { ComboButton, type ComboButtonProps };