Skip to content

Commit

Permalink
Merge branch 'develop' into fix/bugs-ee
Browse files Browse the repository at this point in the history
  • Loading branch information
amovar18 committed Dec 2, 2024
2 parents 28fc87d + e24b9ec commit e898e31
Show file tree
Hide file tree
Showing 40 changed files with 1,700 additions and 863 deletions.
2 changes: 0 additions & 2 deletions packages/common/src/protectedAudience.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,3 @@ export type ReceivedBids = singleAuctionEvent & {
adUnitCode?: string;
mediaContainerSize?: number[];
};

export type AuctionEventsType = SingleSellerAuction | MultiSellerAuction | null;
1 change: 1 addition & 0 deletions packages/design-system/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export { default as useFiltersMapping } from './cookiesLanding/useFiltersMapping
export { default as useGlobalFiltering } from './cookiesLanding/useGlobalFiltering';
export { default as Tabs } from './tabs';
export * from './tabs';
export * from './tabs/useTabs';
export { default as QuickLinksList } from './landingPage/quickLinksList';
export { default as Pill } from './pill';
export { default as PillToggle } from './pillToggle';
Expand Down
40 changes: 17 additions & 23 deletions packages/design-system/src/components/tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,30 @@
import classNames from 'classnames';
import React, { useCallback } from 'react';

export type TabItems = Array<{
title: string;
content: {
Element: (props: any) => React.JSX.Element;
props?: Record<string, any>;
className?: string;
};
}>;
/**
* Internal dependencies
*/
import { useTabs } from './useTabs';

interface TabsProps {
items: TabItems;
activeTab: number;
setActiveTab: React.Dispatch<React.SetStateAction<number>>;
showBottomBorder?: boolean;
fontSizeClass?: string;
}

const Tabs = ({
items,
activeTab,
setActiveTab,
showBottomBorder = true,
fontSizeClass,
}: TabsProps) => {
const Tabs = ({ showBottomBorder = true, fontSizeClass }: TabsProps) => {
const { activeTab, setActiveTab, titles } = useTabs(({ state, actions }) => ({
activeTab: state.activeTab,
setActiveTab: actions.setActiveTab,
titles: state.titles,
}));

const handleKeyDown = useCallback(
(event: React.KeyboardEvent<HTMLButtonElement>) => {
event.preventDefault();

if (event.key === 'Tab') {
const nextIndex = activeTab + 1;
if (nextIndex < items.length) {
if (nextIndex < titles.length) {
setActiveTab(nextIndex);
} else {
setActiveTab(0);
Expand All @@ -61,11 +55,11 @@ const Tabs = ({
if (previousIndex >= 0) {
setActiveTab(previousIndex);
} else {
setActiveTab(items.length - 1);
setActiveTab(titles.length - 1);
}
}
},
[activeTab, items.length, setActiveTab]
[activeTab, titles.length, setActiveTab]
);

return (
Expand All @@ -81,7 +75,7 @@ const Tabs = ({
fontSizeClass ? fontSizeClass : 'text-sm'
)}
>
{items.map((item, index) => (
{titles.map((title, index) => (
<button
key={index}
onClick={() => setActiveTab(index)}
Expand All @@ -98,7 +92,7 @@ const Tabs = ({
}
)}
>
{item.title}
{title}
</button>
))}
</div>
Expand Down
31 changes: 13 additions & 18 deletions packages/design-system/src/components/tabs/tests/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,24 @@ import '@testing-library/jest-dom';
* Internal dependencies
*/
import Tabs from '..';
import { useTabs } from '../useTabs';

describe('Tabs', () => {
const props = {
items: [
{
title: 'title1',
content: {
Element: () => <div>content1</div>,
},
},
{
title: 'title2',
content: {
Element: () => <div>content2</div>,
},
},
],
};
jest.mock('../useTabs', () => ({
useTabs: jest.fn(),
}));
const mockUseTabs = useTabs as jest.Mock;

describe('Tabs', () => {
it('should render', () => {
const setActiveTab = jest.fn();

render(<Tabs setActiveTab={setActiveTab} {...props} />);
mockUseTabs.mockReturnValue({
activeTab: 0,
titles: ['title1', 'title2'],
setActiveTab,
});

render(<Tabs />);

expect(screen.getByText('title1')).toBeInTheDocument();
expect(screen.getByText('title1')).toHaveClass('border-b-2');
Expand Down
59 changes: 59 additions & 0 deletions packages/design-system/src/components/tabs/useTabs/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* External dependencies.
*/
import { createContext } from '@google-psat/common';

/**
* Internal dependencies.
*/
import { noop } from '../../../utils';

export interface TabsStoreContext {
state: {
activeTab: number;
titles: string[];
panel: {
Element: ((props: any) => React.JSX.Element) | null;
props?: Record<string, any>;
className?: string;
};
storage: string[];
};
actions: {
setStorage: (data: string, index?: number) => void;
setActiveTab: (tab: number) => void;
};
}

const initialState: TabsStoreContext = {
state: {
activeTab: 0,
titles: [],
panel: {
Element: null,
props: {},
},
storage: [],
},
actions: {
setStorage: noop,
setActiveTab: noop,
},
};

export const TabsContext = createContext<TabsStoreContext>(initialState);
18 changes: 18 additions & 0 deletions packages/design-system/src/components/tabs/useTabs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './provider';
export * from './types';
export * from './useTabs';
84 changes: 84 additions & 0 deletions packages/design-system/src/components/tabs/useTabs/provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* External dependencies.
*/
import React, {
PropsWithChildren,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';

/**
* Internal dependencies.
*/
import { TabsProviderProps } from './types';
import { TabsContext } from './context';

export const TabsProvider = ({
children,
items,
}: PropsWithChildren<TabsProviderProps>) => {
const [tabItems, setTabItems] = useState(items);
const [activeTab, setActiveTab] = useState(0);
const [storage, _setStorage] = useState(Array(items.length).fill(''));

useEffect(() => {
setTabItems(items);
_setStorage(Array(items.length).fill(''));
}, [items]);

const titles = useMemo(() => tabItems.map((item) => item.title), [tabItems]);
const panel = tabItems[activeTab].content;

const setStorage = useCallback(
(data: string, index?: number) => {
_setStorage((prev) => {
const next = [...prev];

if (!index) {
next[activeTab] = data;
} else {
next[index] = data;
}

return next;
});
},
[activeTab]
);

return (
<TabsContext.Provider
value={{
state: {
activeTab,
titles,
panel,
storage,
},
actions: {
setStorage,
setActiveTab,
},
}}
>
{children}
</TabsContext.Provider>
);
};
28 changes: 28 additions & 0 deletions packages/design-system/src/components/tabs/useTabs/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type TabsProviderProps = {
children: React.ReactNode;
items: TabItems;
};

export type TabItems = Array<{
title: string;
content: {
Element: (props: any) => React.JSX.Element;
props?: Record<string, any>;
className?: string;
};
}>;
38 changes: 38 additions & 0 deletions packages/design-system/src/components/tabs/useTabs/useTabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* External dependencies.
*/
import { useContextSelector } from '@google-psat/common';

/**
* Internal dependencies.
*/
import { TabsContext, TabsStoreContext } from './context';

export function useTabs(): TabsStoreContext;
export function useTabs<T>(selector: (state: TabsStoreContext) => T): T;

/**
* Tabs store hook.
* @param selector Selector function to partially select state.
* @returns selected part of the state
*/
export function useTabs<T>(
selector: (state: TabsStoreContext) => T | TabsStoreContext = (state) => state
) {
return useContextSelector(TabsContext, selector);
}
1 change: 1 addition & 0 deletions packages/design-system/src/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export { default as PlayIcon } from './play.svg';
export { default as RestartIcon } from './restart.svg';
export { default as PauseIcon } from './pause.svg';
export { default as SupportIcon } from './support.svg';
export { default as MoneyIcon } from './money.svg';
export { default as NextIcon } from './next.svg';
export { default as PreviousIcon } from './previous.svg';
export { default as WebStoriesIcon } from './web-stories.svg';
Expand Down
2 changes: 2 additions & 0 deletions packages/design-system/src/icons/money.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e898e31

Please sign in to comment.