From 51fbb91888c8e64750ecf6aa3431709797839a5d Mon Sep 17 00:00:00 2001 From: Daria Larionova Date: Mon, 13 Jan 2025 14:30:06 +0300 Subject: [PATCH] feat(Title): add title font customization (#241) * feat(Title): add title font customization * feat(Title): mark fields as optional * feat(Title): add story for font-size only prop * feat(Title): add default story with data args * chore(Title): rename constant * feat(Title): custom font params with relative lineHeight * fix(Title): move constant and add check on fontSize presense --- src/plugins/Title/Title.tsx | 38 +++-- .../Title/__stories__/Title.stories.tsx | 130 +++++++++++++++++- src/plugins/Title/constants.ts | 26 ++++ src/plugins/Title/index.ts | 2 + src/plugins/Title/types.ts | 6 + src/plugins/Title/utils.ts | 5 + 6 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 src/plugins/Title/constants.ts create mode 100644 src/plugins/Title/types.ts create mode 100644 src/plugins/Title/utils.ts diff --git a/src/plugins/Title/Title.tsx b/src/plugins/Title/Title.tsx index f30fbef..a9c50fb 100644 --- a/src/plugins/Title/Title.tsx +++ b/src/plugins/Title/Title.tsx @@ -4,13 +4,15 @@ import {Plugin, PluginWidgetProps} from '../../typings'; import {cn} from '../../utils/cn'; import {PLUGIN_ROOT_ATTR_NAME} from '../constants'; -import './Title.scss'; +import {RECCOMMENDED_LINE_HEIGHT_MULTIPLIER} from './constants'; +import type {PluginTitleSize, TitleFontParams} from './types'; +import {isCustomSize} from './utils'; -export type PluginTitleSize = 'xl' | 'l' | 'm' | 's' | 'xs'; +import './Title.scss'; export interface PluginTitleProps extends PluginWidgetProps { data: { - size: PluginTitleSize; + size: PluginTitleSize | TitleFontParams; text: string; showInTOC: boolean; } & PluginWidgetProps['data']; @@ -18,19 +20,35 @@ export interface PluginTitleProps extends PluginWidgetProps { const b = cn('dashkit-plugin-title'); -export class PluginTitle extends React.Component { - render() { - const {data} = this.props; +export const PluginTitle = React.forwardRef( + function PluginTitleForwardRef(props, ref) { + const {data} = props; const text = data.text ? data.text : ''; - const size = data.size ? data.size : false; + + const size = isCustomSize(data.size) ? false : data.size; + const styles = + isCustomSize(data.size) && data.size?.fontSize + ? { + fontSize: data.size.fontSize, + lineHeight: data.size.lineHeight ?? RECCOMMENDED_LINE_HEIGHT_MULTIPLIER, + } + : undefined; + const id = data.showInTOC && text ? encodeURIComponent(text) : undefined; + return ( -
+
{text}
); - } -} + }, +); const plugin: Plugin = { type: 'title', diff --git a/src/plugins/Title/__stories__/Title.stories.tsx b/src/plugins/Title/__stories__/Title.stories.tsx index a95a720..df6ba44 100644 --- a/src/plugins/Title/__stories__/Title.stories.tsx +++ b/src/plugins/Title/__stories__/Title.stories.tsx @@ -1,9 +1,10 @@ import React from 'react'; -import {Flex} from '@gravity-ui/uikit'; +import {Card, Flex} from '@gravity-ui/uikit'; import {Meta, StoryObj} from '@storybook/react'; -import {PluginTitle, PluginTitleSize} from '../Title'; +import {PluginTitle} from '../Title'; +import {PluginTitleSize} from '../types'; export default { title: 'Components/Title', @@ -14,16 +15,131 @@ type Story = StoryObj; const sizes: PluginTitleSize[] = ['xs', 's', 'm', 'l', 'xl']; -export const Size: Story = { +const defaultDataParams = {showInTOC: true}; + +export const PresetSizes: Story = { render: ({data: _, ...args}) => ( - + {sizes.map((size) => ( + + + + ))} + + ), +}; + +export const CustomSize: Story = { + render: ({data: _, ...args}) => ( + + - ))} + + + + + + + + + + + + + + + + + + + + + + + + + ), }; + +export const Default: Story = { + render: ({data, ...args}) => ( + + + + ), + args: { + data: { + ...defaultDataParams, + size: 'm', + text: `Title`, + }, + }, +}; diff --git a/src/plugins/Title/constants.ts b/src/plugins/Title/constants.ts new file mode 100644 index 0000000..f205be3 --- /dev/null +++ b/src/plugins/Title/constants.ts @@ -0,0 +1,26 @@ +import {PluginTitleSize, TitleFontParams} from './types'; + +export const TITLE_DEFAULT_SIZES: Record = { + xl: { + fontSize: '32px', + lineHeight: '40px', + }, + l: { + fontSize: '24px', + lineHeight: '28px', + }, + m: { + fontSize: '20px', + lineHeight: '24px', + }, + s: { + fontSize: '17px', + lineHeight: '24px', + }, + xs: { + fontSize: '15px', + lineHeight: '20px', + }, +}; + +export const RECCOMMENDED_LINE_HEIGHT_MULTIPLIER = 1.25; diff --git a/src/plugins/Title/index.ts b/src/plugins/Title/index.ts index 4a0f03e..f89380c 100644 --- a/src/plugins/Title/index.ts +++ b/src/plugins/Title/index.ts @@ -1,2 +1,4 @@ export * from './Title'; export {default as pluginTitle} from './Title'; +export {PluginTitleSize, TitleFontParams} from './types'; +export {TITLE_DEFAULT_SIZES} from './constants'; diff --git a/src/plugins/Title/types.ts b/src/plugins/Title/types.ts new file mode 100644 index 0000000..a1c47dd --- /dev/null +++ b/src/plugins/Title/types.ts @@ -0,0 +1,6 @@ +export type PluginTitleSize = 'xl' | 'l' | 'm' | 's' | 'xs'; + +export interface TitleFontParams { + fontSize: string; + lineHeight?: string; +} diff --git a/src/plugins/Title/utils.ts b/src/plugins/Title/utils.ts new file mode 100644 index 0000000..1e146fe --- /dev/null +++ b/src/plugins/Title/utils.ts @@ -0,0 +1,5 @@ +import type {PluginTitleSize, TitleFontParams} from './types'; + +export function isCustomSize(size: PluginTitleSize | TitleFontParams): size is TitleFontParams { + return typeof size === 'object'; +}