Improve responsive hook

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2024-12-16 16:48:00 +00:00
parent bf0446b004
commit 980446f395
8 changed files with 60 additions and 50 deletions
+7
View File
@@ -32,6 +32,13 @@ const preview: Preview = {
},
viewport: {
viewports: {
xs: {
name: 'XSmall',
styles: {
width: '320px',
height: '100%',
},
},
small: {
name: 'Small',
styles: {
@@ -16,21 +16,7 @@
import React, { forwardRef } from 'react';
import { Icon } from '../Icon';
import type { IconNames } from '../Icon/types';
/**
* Properties for {@link Button}
*
* @public
*/
export interface ButtonProps {
size?: 'small' | 'medium';
variant?: 'primary' | 'secondary' | 'tertiary';
children: React.ReactNode;
disabled?: boolean;
iconStart?: IconNames;
iconEnd?: IconNames;
}
import { ButtonProps } from './types';
/** @public */
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { Button } from './Button';
export type { ButtonProps } from './Button';
export type { ButtonProps } from './types';
@@ -13,29 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Breakpoints } from '../types';
import { IconNames } from '../Icon';
export const getResponsiveValue = (
value: any,
breakpoint: keyof Breakpoints,
) => {
if (typeof value === 'object') {
const breakpointsOrder: (keyof Breakpoints)[] = [
'xs',
'sm',
'md',
'lg',
'xl',
'2xl',
];
const index = breakpointsOrder.indexOf(breakpoint);
for (let i = index; i >= 0; i--) {
if (value[breakpointsOrder[i]]) {
return value[breakpointsOrder[i]];
}
}
return value['xs'];
}
return value;
};
/**
* Properties for {@link Button}
*
* @public
*/
export interface ButtonProps {
size?: 'small' | 'medium';
variant?: 'primary' | 'secondary' | 'tertiary';
children: React.ReactNode;
disabled?: boolean;
iconStart?: IconNames;
iconEnd?: IconNames;
}
@@ -60,7 +60,7 @@ export const Responsive: Story = {
...Default.args,
variant: {
xs: 'title4',
sm: 'display',
md: 'display',
},
},
};
@@ -17,14 +17,16 @@
import React, { forwardRef } from 'react';
import { HeadingProps } from './types';
import { useTheme } from '../../theme/context';
import { getResponsiveValue } from '../../utils/getResponsiveValue';
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
(props, ref) => {
const { children, variant = 'title1', as = 'h1', ...restProps } = props;
const { breakpoint } = useTheme();
const responsiveVariant = getResponsiveValue(variant, breakpoint);
const { getResponsiveValue } = useTheme();
// Get the responsive value for the variant
const responsiveVariant = getResponsiveValue(variant);
// Determine the component to render based on the variant
let Component = as;
if (variant === 'title2') Component = 'h2';
if (variant === 'title3') Component = 'h3';
+4 -4
View File
@@ -17,7 +17,6 @@
import React, { forwardRef } from 'react';
import { TextProps } from './types';
import { useTheme } from '../../theme/context';
import { getResponsiveValue } from '../../utils/getResponsiveValue';
export const Text = forwardRef<HTMLParagraphElement, TextProps>(
(props, ref) => {
@@ -28,10 +27,11 @@ export const Text = forwardRef<HTMLParagraphElement, TextProps>(
...restProps
} = props;
const { breakpoint } = useTheme();
const { getResponsiveValue } = useTheme();
const responsiveVariant = getResponsiveValue(variant, breakpoint);
const responsiveWeight = getResponsiveValue(weight, breakpoint);
// Get the responsive values for the variant and weight
const responsiveVariant = getResponsiveValue(variant);
const responsiveWeight = getResponsiveValue(weight);
return (
<p
+27 -1
View File
@@ -32,11 +32,13 @@ const defaultBreakpoints: Breakpoints = {
interface ThemeContextProps {
icons: IconMap;
breakpoint: keyof Breakpoints;
getResponsiveValue: (value: string | Partial<Breakpoints>) => string;
}
const ThemeContext = createContext<ThemeContextProps>({
icons: defaultIcons,
breakpoint: 'md',
getResponsiveValue: () => '',
});
interface ThemeProviderProps {
@@ -68,8 +70,32 @@ export const ThemeProvider = (props: ThemeProviderProps) => {
return 'xs';
})();
const getResponsiveValue = (value: string | Partial<Breakpoints>) => {
if (typeof value === 'object') {
const breakpointsOrder: (keyof Breakpoints)[] = [
'xs',
'sm',
'md',
'lg',
'xl',
'2xl',
];
const index = breakpointsOrder.indexOf(breakpoint);
for (let i = index; i >= 0; i--) {
if (value[breakpointsOrder[i]]) {
return value[breakpointsOrder[i]] as string;
}
}
return value['xs'] as string;
}
return value;
};
return (
<ThemeContext.Provider value={{ icons: combinedIcons, breakpoint }}>
<ThemeContext.Provider
value={{ icons: combinedIcons, breakpoint, getResponsiveValue }}
>
{children}
</ThemeContext.Provider>
);