Skip to content

Commit

Permalink
Merge pull request #104 from openinfradev/feature-form-section-row-align
Browse files Browse the repository at this point in the history
feature. Modify TFormSectionRow props
  • Loading branch information
Siyeop authored May 13, 2024
2 parents 71b12d5 + 8d74553 commit 7bf1565
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 66 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tksui-components",
"version": "0.6.21",
"version": "0.6.22",
"private": false,
"type": "module",
"module": "lib/esm/index.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {ReactElement, ReactNode, CSSProperties} from 'react';
import {TBaseProps} from '@/common/base/TBase.interface';

export type RowVerticalAlign = 'top' | 'middle';
export type LabelItemAlign = 'horizontal' | 'vertical';

export interface TFormSectionProps extends TBaseProps {
children: ReactNode,
Expand All @@ -17,11 +19,14 @@ export interface TFormSectionProps extends TBaseProps {
leftAction?: ReactElement,
rightAction?: ReactElement,

formLabelItemAlign?: 'horizontal' | 'vertical';
formLabelItemAlign?: LabelItemAlign;
formRowVerticalAlign?: RowVerticalAlign,
}


export interface TFormSectionRowProps extends TBaseProps {
children: ReactNode,
formRowVerticalAlign?: RowVerticalAlign,
}

export interface TFormSectionItemProps extends TBaseProps {
Expand All @@ -32,6 +37,5 @@ export interface TFormSectionItemProps extends TBaseProps {
required?: boolean,
label?: string,

labelMarginBottom?: string,
contentStyle?: CSSProperties,
}
11 changes: 8 additions & 3 deletions src/components/data-container/form-section/TFormSection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {CSSProperties, useMemo} from 'react';
import TIcon from '~/icon/TIcon';
import {TFormSectionProps} from '@/components';
import FormContext from './TFormSectionContext';
import TFormSectionContext from './TFormSectionContext';
import TSection from '~/data-container/section/TSection';


Expand Down Expand Up @@ -53,9 +53,13 @@ const TFormSection = (props: TFormSectionProps) => {
</div>
)
}
<FormContext.Provider value={{column: props.column, labelWidth: props.labelWidth}}>
<TFormSectionContext.Provider value={{
column: props.column,
labelWidth: props.labelWidth,
rowVerticalAlign: props.formRowVerticalAlign,
}}>
{props.children}
</FormContext.Provider>
</TFormSectionContext.Provider>
</TSection>
);

Expand All @@ -65,5 +69,6 @@ TFormSection.defaultProps = {
column: 2,
labelWidth: '104px',
formLabelItemAlign: 'horizontal',
formRowVerticalAlign: 'middle',
};
export default TFormSection;
15 changes: 12 additions & 3 deletions src/components/data-container/form-section/TFormSectionContext.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import {createContext} from 'react';
import {RowVerticalAlign} from '@/components';


interface FormContext {
export interface TFormSectionContext {
column: number,
labelWidth: string,

rowVerticalAlign: RowVerticalAlign
}

export const TFormSectionContext = createContext<TFormSectionContext>({
column: 2,
labelWidth: '104px',

rowVerticalAlign: 'middle',

});

export const formSectionContext = createContext<FormContext>(null);
export default formSectionContext;
export default TFormSectionContext;

38 changes: 12 additions & 26 deletions src/components/data-container/form-section/TFormSectionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {CSSProperties, useContext, useEffect, useId, useMemo, useRef, memo, useCallback} from 'react';
import {CSSProperties, memo, useContext, useId, useMemo, useRef} from 'react';
import TIcon from '~/icon/TIcon';
import TTooltip from '~/guide/tooltip/TTooltip';
import {TFormSectionItemProps} from '@/components';
import FormContext from './TFormSectionContext';
import TFormSectionContext from './TFormSectionContext';
import themeToken from '~style/designToken/ThemeToken.module.scss';


Expand All @@ -14,7 +14,7 @@ const TFormSectionItem = (props: TFormSectionItemProps) => {
// region [Hooks]

const rootRef = useRef<HTMLSpanElement>(null);
const {column, labelWidth} = useContext(FormContext);
const {column, labelWidth, rowVerticalAlign} = useContext(TFormSectionContext);

const tooltipId = useId();

Expand Down Expand Up @@ -62,13 +62,20 @@ const TFormSectionItem = (props: TFormSectionItemProps) => {

const labelStyle = useMemo((): CSSProperties => {

const style: CSSProperties = {marginBottom: props.labelMarginBottom};
const style: CSSProperties = {};

style.minWidth = labelWidth;
style.maxWidth = labelWidth;

if (rowVerticalAlign === 'middle') {
style.alignItems = 'center';
}
if (rowVerticalAlign === 'top') {
style.alignItems = 'flex-start';
}

return style;
}, [labelWidth, props.labelMarginBottom]);
}, [labelWidth, rowVerticalAlign]);


const contentStyle = useMemo((): CSSProperties => {
Expand All @@ -79,27 +86,6 @@ const TFormSectionItem = (props: TFormSectionItemProps) => {
// endregion


// region [Privates]

const adjustLabelAlignment = useCallback(() => {
if (rootRef.current?.clientHeight > 44) {
rootRef.current.style.alignItems = 'flex-start';
}
}, []);

// endregion


// region [Effects]

useEffect(() => {

adjustLabelAlignment();
}, [adjustLabelAlignment]);

// endregion


return (
<span ref={rootRef} className={`t-form-section-item ${rootClass}`}
style={rootStyle} role={'group'}>
Expand Down
20 changes: 18 additions & 2 deletions src/components/data-container/form-section/TFormSectionRow.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import {CSSProperties, useMemo} from 'react';
import {CSSProperties, useContext, useMemo} from 'react';
import {TFormSectionRowProps} from '@/components';
import TFormSectionContext from '~/data-container/form-section/TFormSectionContext';


const TFormSectionRow = (props: TFormSectionRowProps) => {

// region [Hooks]

const formContext = useContext(TFormSectionContext);

// endregion

// region [Styles]

Expand All @@ -21,11 +28,20 @@ const TFormSectionRow = (props: TFormSectionRowProps) => {

// endregion


return (
<div className={`t-form-section-row ${rootClass}`} style={rootStyle}>
{props.children}
<TFormSectionContext.Provider value={{
...formContext,
rowVerticalAlign: props.formRowVerticalAlign,
}}>
{props.children}
</TFormSectionContext.Provider>
</div>
);

};

TFormSectionRow.displayName = 'TFormSectionRow';

export default TFormSectionRow;
2 changes: 1 addition & 1 deletion src/components/data-container/tab-box/TTabBoxContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createContext, CSSProperties, MouseEvent} from 'react';
import {createContext} from 'react';
import {TTabBoxValue} from './TTabBox.interface';

type tabBoxContext = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const Template = (args: TFormSectionProps) => {
const verticalRightAction = useMemo(() => (<>
<TButton onClick={() => notify.info('취소 이벤트 발생')}>취소</TButton>
<TButton main onClick={verticalValidate}>저장</TButton>
</>), []);
</>), [verticalValidate]);

const noRowRightAction = useMemo(() => (<>
<TButton onClick={() => notify.info('취소 이벤트 발생')}>취소</TButton>
Expand All @@ -90,8 +90,10 @@ const Template = (args: TFormSectionProps) => {
<>
<TToast/>
<div style={{display: 'flex', flexDirection: 'column', gap: '24px'}}>
<TFormSection label={'Basic Properties'} column={2} {...args} customInformation={<>앱 생성 양식 예제입니다.</>}
>
<TFormSection label={'Basic Properties'}
column={2}
{...args}
customInformation={<>앱 생성 양식 예제입니다.</>} formRowVerticalAlign={'top'}>
<TFormSectionRow>
<TFormSectionItem label={'Name'} required>
<TTextField counter={30} {...name} />
Expand Down Expand Up @@ -149,9 +151,12 @@ const Template = (args: TFormSectionProps) => {
</TFormSectionItem>
</TFormSectionRow>

<TFormSectionRow>
<TFormSectionItem label={'Description'} span={2}>
<TTextField multiline counter={100} rows={5} {...profile} />
<TFormSectionRow formRowVerticalAlign={'top'}>
<TFormSectionItem label={'Description'} span={1}>
<TTextField multiline counter={100} rows={5} {...description} />
</TFormSectionItem>
<TFormSectionItem label={'Description'} span={1}>
<TTextField multiline counter={100} rows={5} {...description} />
</TFormSectionItem>
</TFormSectionRow>
</TFormSection>
Expand All @@ -176,10 +181,10 @@ const Template = (args: TFormSectionProps) => {
</TFormSectionItem>
</TFormSectionRow>

<TFormSectionRow>
<TFormSectionRow formRowVerticalAlign={'top'}>
<TFormSectionItem label={'Description'} span={2}>
<TTextField ref={noRowDescriptionRef} rules={[TValidatorRule.required()]} multiline
counter={100} rows={5} {...profile} />
counter={100} rows={5} {...description} />
</TFormSectionItem>
</TFormSectionRow>
</TFormSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,6 @@ describe('TFormSectionItem', () => {

});

it('When labelMarginBottom prop is applied, it should be displayed on label area', () => {

// Arrange
const labelMarginBottom = '10px';
render(
<TFormSection>
<TFormSectionRow>
<TFormSectionItem label={'레이블'} labelMarginBottom={labelMarginBottom}>content</TFormSectionItem>
</TFormSectionRow>
</TFormSection>,
);

// eslint-disable-next-line testing-library/no-node-access
const root = screen.getByText('레이블').parentElement;

// Assert
expect(root)
.toHaveStyle({marginBottom: labelMarginBottom});
});

it('When contentStyle prop is applied, it should be displayed on label content area', () => {

// Arrange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {render, screen} from '@testing-library/react';
import {TFormSection} from '@/components';
import TFormSectionRow from '~/data-container/form-section/TFormSectionRow';
import TFormSectionItem from '~/data-container/form-section/TFormSectionItem';


describe('TFormSectionRow', () => {

Expand Down Expand Up @@ -28,5 +31,26 @@ describe('TFormSectionRow', () => {
expect(root)
.toHaveStyle({width: '100%'});
});

it('VerticalAlign prop applies to root', () => {

// Arrange
const labelText = 'Test Label';

render(
<TFormSection>
<TFormSectionRow formRowVerticalAlign={'top'}>
<TFormSectionItem label={labelText}>Content</TFormSectionItem>
</TFormSectionRow>
</TFormSection>,
);
const itemRoot = screen.getByText(labelText);

// Assert
// eslint-disable-next-line testing-library/no-node-access
expect(itemRoot.parentElement)
.toHaveStyle({alignItems: 'flex-start'});
});

});
});

0 comments on commit 7bf1565

Please sign in to comment.