Skip to content

Commit

Permalink
feat(Title): add title font customization (#241)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
DaryaLari authored Jan 13, 2025
1 parent 11dbeb0 commit 51fbb91
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 17 deletions.
38 changes: 28 additions & 10 deletions src/plugins/Title/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,51 @@ 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'];
}

const b = cn('dashkit-plugin-title');

export class PluginTitle extends React.Component<PluginTitleProps> {
render() {
const {data} = this.props;
export const PluginTitle = React.forwardRef<HTMLDivElement, PluginTitleProps>(
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 (
<div id={id} className={b({size})} {...{[PLUGIN_ROOT_ATTR_NAME]: 'title'}}>
<div
ref={ref}
id={id}
style={styles}
className={b({size})}
{...{[PLUGIN_ROOT_ATTR_NAME]: 'title'}}
>
{text}
</div>
);
}
}
},
);

const plugin: Plugin<PluginTitleProps> = {
type: 'title',
Expand Down
130 changes: 123 additions & 7 deletions src/plugins/Title/__stories__/Title.stories.tsx
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -14,16 +15,131 @@ type Story = StoryObj<typeof PluginTitle>;

const sizes: PluginTitleSize[] = ['xs', 's', 'm', 'l', 'xl'];

export const Size: Story = {
const defaultDataParams = {showInTOC: true};

export const PresetSizes: Story = {
render: ({data: _, ...args}) => (
<Flex direction="column" gap={2}>
<Flex direction="column" gap={6}>
{sizes.map((size) => (
<Card key={size}>
<PluginTitle
data={{size, text: `Title size=${size}`, showInTOC: true}}
{...args}
/>
</Card>
))}
</Flex>
),
};

export const CustomSize: Story = {
render: ({data: _, ...args}) => (
<Flex direction="column" gap={6}>
<Card>
<PluginTitle
key={size}
data={{size, text: `Title size=${size}`, showInTOC: true}}
data={{
...defaultDataParams,
size: {fontSize: '40px', lineHeight: '100px'},
text: `Title fontSize=40px, lineHeight=100px`,
}}
{...args}
/>
))}
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '40px', lineHeight: '20px'},
text: `Title fontSize=40px, lineHeight=20px 🤷`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '3em', lineHeight: '2'},
text: `Title fontSize=2em, lineHeight=2`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '3em', lineHeight: '.7em'},
text: `Title fontSize=3em, lineHeight=.7em`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '40px'},
text: `Title fontSize=40px`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '300%'},
text: `Title fontSize=300%`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '2.5rem'},
text: `Title fontSize=2.5rem`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '3em'},
text: `Title fontSize=3em`,
}}
{...args}
/>
</Card>
<Card>
<PluginTitle
data={{
...defaultDataParams,
size: {fontSize: '30pt'},
text: `Title fontSize=30pt`,
}}
{...args}
/>
</Card>
</Flex>
),
};

export const Default: Story = {
render: ({data, ...args}) => (
<Card>
<PluginTitle data={data} {...args} />
</Card>
),
args: {
data: {
...defaultDataParams,
size: 'm',
text: `Title`,
},
},
};
26 changes: 26 additions & 0 deletions src/plugins/Title/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {PluginTitleSize, TitleFontParams} from './types';

export const TITLE_DEFAULT_SIZES: Record<PluginTitleSize, TitleFontParams> = {
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;
2 changes: 2 additions & 0 deletions src/plugins/Title/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './Title';
export {default as pluginTitle} from './Title';
export {PluginTitleSize, TitleFontParams} from './types';
export {TITLE_DEFAULT_SIZES} from './constants';
6 changes: 6 additions & 0 deletions src/plugins/Title/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type PluginTitleSize = 'xl' | 'l' | 'm' | 's' | 'xs';

export interface TitleFontParams {
fontSize: string;
lineHeight?: string;
}
5 changes: 5 additions & 0 deletions src/plugins/Title/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type {PluginTitleSize, TitleFontParams} from './types';

export function isCustomSize(size: PluginTitleSize | TitleFontParams): size is TitleFontParams {
return typeof size === 'object';
}

0 comments on commit 51fbb91

Please sign in to comment.