Skip to content

Commit

Permalink
Merge branch 'main' into renovate/downshift-9.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Gururajj77 authored Nov 11, 2024
2 parents 09fe3cb + 1a48fe3 commit c32f1c2
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 43 deletions.
Binary file not shown.
Binary file not shown.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@
"cross-spawn": "^7.0.0",
"doctoc": "^2.0.0",
"eslint": "^9.0.0",
"eslint-plugin-playwright": "^1.0.0",
"eslint-plugin-playwright": "^2.0.0",
"fs-extra": "^11.0.0",
"glob": "^10.0.0",
"glob": "^11.0.0",
"husky": "^9.0.0",
"jest": "^28.1.0",
"jest-junit": "^16.0.0",
Expand Down
7 changes: 4 additions & 3 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2940,6 +2940,9 @@ Map {
"className": Object {
"type": "string",
},
"decorator": Object {
"type": "node",
},
"direction": Object {
"args": Array [
Array [
Expand Down Expand Up @@ -3037,9 +3040,7 @@ Map {
],
"type": "oneOf",
},
"slug": Object {
"type": "node",
},
"slug": [Function],
"titleText": Object {
"isRequired": true,
"type": "node",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ const TableToolbarSearch = ({
const onChange = (e) => {
setValue(e.target.value);
if (onChangeProp) {
onChangeProp(e);
onChangeProp(e, e.target.value);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ export const Playground = (args) => {
<TableToolbarContent>
{/* pass in `onInputChange` change here to make filtering work */}
<TableToolbarSearch
onChange={(evt) => {
action('TableToolbarSearch - onChange')(evt);
onChange={(evt, value) => {
action(`TableToolbarSearch - onChange ${value}`)(evt);
onInputChange(evt);
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ interface TableToolbarFilterProps {
/**
* Provide an optional hook that is called each time the input is updated
*/
onChange?: (
event: '' | ChangeEvent<HTMLInputElement>,
value?: string
) => void;
onChange?: (event: '' | ChangeEvent<HTMLInputElement>) => void;

/**
* Provide an function that is called when the apply button is clicked
Expand Down
7 changes: 6 additions & 1 deletion packages/react/src/components/Dropdown/Dropdown.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export default {
disable: true,
},
},
slug: {
table: {
disable: true,
},
},
},
parameters: {
docs: {
Expand Down Expand Up @@ -294,7 +299,7 @@ export const withAILabel = () => (
label="Option 1"
items={items}
itemToString={(item) => (item ? item.text : '')}
slug={aiLabel}
decorator={aiLabel}
/>
</div>
);
42 changes: 34 additions & 8 deletions packages/react/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ export interface DropdownProps<ItemType>
*/
autoAlign?: boolean;

/**
* **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
*/
decorator?: ReactNode;

/**
* Specify the direction of the dropdown. Can be either top or bottom.
*/
Expand Down Expand Up @@ -214,6 +219,7 @@ export interface DropdownProps<ItemType>
size?: ListBoxSize;

/**
* @deprecated please use `decorator` instead.
* **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
*/
slug?: ReactNode;
Expand Down Expand Up @@ -282,6 +288,7 @@ const Dropdown = React.forwardRef(
{
autoAlign = false,
className: containerClassName,
decorator,
disabled = false,
direction = 'bottom',
items: itemsProp,
Expand Down Expand Up @@ -484,6 +491,7 @@ const Dropdown = React.forwardRef(
[`${prefix}--list-box__wrapper--fluid--focus`]:
isFluid && isFocused && !isOpen,
[`${prefix}--list-box__wrapper--slug`]: slug,
[`${prefix}--list-box__wrapper--decorator`]: decorator,
}
);

Expand Down Expand Up @@ -578,15 +586,16 @@ const Dropdown = React.forwardRef(
[autoAlign, getMenuProps, refs.setFloating, enableFloatingStyles]
);

// Slug is always size `mini`
const normalizedSlug = useMemo(() => {
if (slug && slug['type']?.displayName === 'AILabel') {
return React.cloneElement(slug as React.ReactElement<any>, {
// AILabel is always size `mini`
const normalizedDecorator = useMemo(() => {
const element = slug ?? decorator;
if (element && element['type']?.displayName === 'AILabel') {
return React.cloneElement(element as React.ReactElement<any>, {
size: 'mini',
});
}
return slug;
}, [slug]);
return element;
}, [slug, decorator]);

return (
<div className={wrapperClasses} {...other}>
Expand Down Expand Up @@ -645,7 +654,15 @@ const Dropdown = React.forwardRef(
translateWithId={translateWithId}
/>
</button>
{normalizedSlug}
{slug ? (
normalizedDecorator
) : decorator ? (
<div className={`${prefix}--list-box__inner-wrapper--decorator`}>
{normalizedDecorator}
</div>
) : (
''
)}
<ListBox.Menu {...menuProps}>
{isOpen &&
items.map((item, index) => {
Expand Down Expand Up @@ -734,6 +751,11 @@ Dropdown.propTypes = {
*/
className: PropTypes.string,

/**
* **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
*/
decorator: PropTypes.node,

/**
* Specify the direction of the dropdown. Can be either top or bottom.
*/
Expand Down Expand Up @@ -858,7 +880,11 @@ Dropdown.propTypes = {
/**
* **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
*/
slug: PropTypes.node,
slug: deprecate(
PropTypes.node,
'The `slug` prop for `Dropdown` has ' +
'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'
),

/**
* Provide the title text that will be read by a screen reader when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,26 @@ describe('Dropdown', () => {
expect(ref.current).toHaveAttribute('aria-haspopup', 'listbox');
});

it('should respect slug prop', async () => {
it('should respect decorator prop', async () => {
const { container } = render(
<Dropdown {...mockProps} decorator={<AILabel />} />
);
await waitForPosition();
expect(container.firstChild).toHaveClass(
`${prefix}--list-box__wrapper--decorator`
);
});

it('should respect deprecated slug prop', async () => {
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
const { container } = render(
<Dropdown {...mockProps} slug={<AILabel />} />
);
await waitForPosition();
expect(container.firstChild).toHaveClass(
`${prefix}--list-box__wrapper--slug`
);
spy.mockRestore();
});
});
});
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/components/FeatureFlags/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ function useChangedValue<T>(
*/
function useFeatureFlag(flag) {
const scope = useContext(FeatureFlagContext);
//updated to return false for undefined flags
return scope.enabled(flag) ?? false;
return scope.enabled(flag);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/components/Form/Form.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ export const withAILabel = (args) => {
label="Option 1"
items={items}
itemToString={(item) => (item ? item.text : '')}
slug={aiLabel}
decorator={aiLabel}
{...rest}
/>
<MultiSelect
Expand Down Expand Up @@ -429,7 +429,7 @@ export const withAILabel = (args) => {
label="Choose an option"
items={items}
itemToString={(item) => (item ? item.text : '')}
slug={aiLabel}
decorator={aiLabel}
{...rest}
/>
</div>
Expand Down
12 changes: 12 additions & 0 deletions packages/react/src/components/PaginationNav/PaginationNav-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ import PaginationNav from './PaginationNav';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

describe('PaginationNav', () => {
describe('renders as expected - Component API', () => {
it('should spread extra props onto outermost element', () => {
Expand Down
21 changes: 15 additions & 6 deletions packages/react/src/components/PaginationNav/PaginationNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
import { IconButton } from '../IconButton';
import { usePrefix } from '../../internal/usePrefix';
import { TranslateWithId } from '../../types/common';
import { breakpoints } from '@carbon/layout';
import { useMatchMedia } from '../../internal/useMatchMedia';

const translationIds = {
'carbon.pagination-nav.next': 'Next',
Expand Down Expand Up @@ -292,7 +294,7 @@ interface PaginationNavProps
disableOverflow?: boolean;

/**
* The number of items to be shown.
* The number of items to be shown (minimum of 4 unless props.items < 4).
*/
itemsShown?: number;

Expand Down Expand Up @@ -338,10 +340,14 @@ const PaginationNav = React.forwardRef<HTMLElement, PaginationNavProps>(
},
ref
) {
const smMediaQuery = `(max-width: ${breakpoints.sm.width})`;
const isSm = useMatchMedia(smMediaQuery);

const [currentPage, setCurrentPage] = useState(page);
const [itemsDisplayedOnPage, setItemsDisplayedOnPage] = useState(
itemsShown >= 4 ? itemsShown : 4
itemsShown >= 4 && !isSm ? itemsShown : 4
);

const [cuts, setCuts] = useState(
calculateCuts(currentPage, totalItems, itemsDisplayedOnPage)
);
Expand Down Expand Up @@ -398,9 +404,12 @@ const PaginationNav = React.forwardRef<HTMLElement, PaginationNavProps>(

// re-calculate cuts if props.totalItems or props.itemsShown change
useEffect(() => {
setItemsDisplayedOnPage(itemsShown >= 4 ? itemsShown : 4);
setCuts(calculateCuts(currentPage, totalItems, itemsShown));
}, [totalItems, itemsShown]); // eslint-disable-line react-hooks/exhaustive-deps
const itemsToBeShown = itemsShown >= 4 && !isSm ? itemsShown : 4;
setItemsDisplayedOnPage(Math.max(itemsToBeShown, 4));
setCuts(
calculateCuts(currentPage, totalItems, Math.max(itemsToBeShown, 4))
);
}, [totalItems, itemsShown, isSm]); // eslint-disable-line react-hooks/exhaustive-deps

// update cuts if necessary whenever currentPage changes
useEffect(() => {
Expand Down Expand Up @@ -622,7 +631,7 @@ PaginationNav.propTypes = {
disableOverflow: PropTypes.bool, // eslint-disable-line react/prop-types

/**
* The number of items to be shown.
* The number of items to be shown (minimum of 4 unless props.items < 4).
*/
itemsShown: PropTypes.number,

Expand Down
Loading

0 comments on commit c32f1c2

Please sign in to comment.