Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(design): add Textarea component #1778

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/design/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"rc-picker": "^4.3.0",
"rc-segmented": "^2.3.0",
"rc-select": "^14.13.0",
"rc-textarea": "^1.6.3",
"rc-tooltip": "^6.2.0",
"rc-util": "^5.39.1",
"react-draggable": "^4.4.6",
Expand Down
1 change: 0 additions & 1 deletion packages/design/src/components/input/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export const InputSize = {
render() {
return (
<>
<Input size="mini" />
<Input size="small" />
<Input />
<Input size="large" />
Expand Down
3 changes: 1 addition & 2 deletions packages/design/src/components/input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export interface IInputProps extends Pick<InputProps, 'onFocus' | 'onBlur'> {
* The input size
* @default middle
*/
size?: 'mini' | 'small' | 'middle' | 'large';
size?: 'small' | 'middle' | 'large';

/**
* Whether the input is clearable
Expand Down Expand Up @@ -116,7 +116,6 @@ export function Input(props: IInputProps) {
}

const _className = clsx(className, {
[styles.inputAffixWrapperMini]: size === 'mini',
[styles.inputAffixWrapperSmall]: size === 'small',
[styles.inputAffixWrapperMiddle]: size === 'middle',
[styles.inputAffixWrapperLarge]: size === 'large',
Expand Down
4 changes: 1 addition & 3 deletions packages/design/src/components/input/InputWithSlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ export interface IInputWithSlotProps extends IInputProps {
slot: React.ReactNode;
}

function getPaddingRightBySize(size?: 'mini' | 'small' | 'middle' | 'large'): number {
function getPaddingRightBySize(size?: 'small' | 'middle' | 'large'): number {
switch (size) {
case 'mini':
return 2;
case 'small':
return 6;
case 'middle':
Expand Down
17 changes: 7 additions & 10 deletions packages/design/src/components/input/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,24 @@

transition: all 0.15s;

&-mini {
display: inline-block;
padding: 2px var(--padding-lg);
font-size: var(--font-size-xs);
}

&-small {
display: inline-block;
padding: 6px var(--padding-lg);
font-size: var(--font-size-xs);
width: 136px;
padding: 4px var(--padding-sm);
font-size: var(--font-size-sm);
}

&-middle {
display: inline-block;
padding: 6px var(--padding-lg);
width: 200px;
padding: 5px var(--padding-sm);
font-size: var(--font-size-sm);
}

&-large {
display: inline-block;
padding: 8px var(--padding-lg);
width: 280px;
padding: 6px var(--padding-sm);
font-size: var(--font-size-sm);
}

Expand Down
47 changes: 47 additions & 0 deletions packages/design/src/components/textarea/Textarea.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* 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
*
* http://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.
*/

import type { Meta } from '@storybook/react';
import React from 'react';

import { Textarea } from './Textarea';

const meta: Meta<typeof Textarea> = {
title: 'Components / Textarea',
component: Textarea,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
};

export default meta;

export const TextareaBasic = {
render() {
return (
<>
<Textarea autoSize={{ minRows: 4 }} />
</>
);
},
};

export const TextareaDisabled = {
render() {
return <Textarea disabled />;
},
};
111 changes: 111 additions & 0 deletions packages/design/src/components/textarea/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* 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
*
* http://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.
*/

import clsx from 'clsx';
import type { TextAreaProps } from 'rc-textarea';
import RcTextarea from 'rc-textarea';
import React from 'react';

import styles from './index.module.less';

export interface ITextareaProps extends Pick<TextAreaProps, 'onFocus' | 'onBlur'> {
/**
* Whether the input is autoFocus
* @default false
*/
autoFocus?: boolean;

/**
* The input class name
*/
className?: string;

/**
* The input affix wrapper style
*/
style?: React.CSSProperties;

/**
* The input affix wrapper style
*/
autoSize?: boolean | { minRows?: number; maxRows?: number };

/**
* The input placeholder
*/
placeholder?: string;

/**
* The input content value
*/
value?: string;

/**
* Whether the input is disabled
* @default false
*/
disabled?: boolean;

/**
* Callback when user press a key
* @param e
*/
onKeyDown?: React.KeyboardEventHandler;

/**
* Callback when user input
* @param value
*/
onChange?: (value: string) => void;

}

export function Textarea(props: ITextareaProps) {
const {
autoFocus = false,
autoSize = false,
className,
placeholder,
value,
disabled = false,
onKeyDown,
onChange,
...rest
} = props;

function handleChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
const { value } = e.target;
onChange?.(value);
}

const _className = clsx(className, {
}, className);

return (
<RcTextarea
prefixCls={styles.textarea}
classNames={{ affixWrapper: _className }}
autoFocus={autoFocus}
autoSize={autoSize}
placeholder={placeholder}
value={value}
disabled={disabled}
onKeyDown={onKeyDown}
onChange={handleChange}
{...rest}
/>
);
}
24 changes: 24 additions & 0 deletions packages/design/src/components/textarea/index.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@textarea-prefix-cls: textarea;

.@{textarea-prefix-cls} {
position: relative;

width: 280px;

padding: var(--padding-sm);

box-sizing: border-box;

border: 1px solid rgb(var(--border-color));
border-radius: var(--border-radius-base);

overflow: hidden;

transition: all 0.15s;

&:hover,
&:focus {
border-color: rgb(var(--primary-color));
outline: none;
}
}
17 changes: 17 additions & 0 deletions packages/design/src/components/textarea/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* 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
*
* http://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 ITextareaProps, Textarea } from './Textarea';
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ import { CFNumberOperator,
CFSubRuleType,
CFTextOperator,
CFTimePeriodOperator,
createDefaultValue } from '@univerjs/sheets-conditional-formatting';
createDefaultValue,
} from '@univerjs/sheets-conditional-formatting';
import type {
IConditionalFormattingRuleConfig,
IHighlightCell,
INumberHighlightCell,
ITextHighlightCell,
ITimePeriodHighlightCell } from '@univerjs/sheets-conditional-formatting';
ITimePeriodHighlightCell,
} from '@univerjs/sheets-conditional-formatting';
import { ConditionalStyleEditor } from '../../conditional-style-editor';
import { Preview } from '../../preview';
import stylesBase from '../index.module.less';
import type { IStyleEditorProps } from './type';

import styles from './index.module.less';

const createOptionItem = (text: string, localeService: LocaleService) => ({ label: localeService.t(`sheet.cf.operator.${text}`), value: text });
Expand Down
16 changes: 11 additions & 5 deletions packages/ui/src/components/range-selector/RangeSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface IRangeSelectorProps {
openForSheetUnitId?: Nullable<string>; // Configuring which workbook the selector defaults to opening in determines whether the ref includes a [unitId] prefix.
openForSheetSubUnitId?: Nullable<string>; // Configuring the default worksheet where the selector opens determines whether the ref includes a [unitId]sheet1 prefix.
width?: number; // The width of the selector.
size?: 'mini' | 'small' | 'middle' | 'large'; // The size of the selector.
size?: 'small' | 'middle' | 'large'; // The size of the selector.
placeholder?: string; // Placeholder text.
className?: string;
}
Expand Down Expand Up @@ -279,9 +279,7 @@ export function RangeSelector(props: IRangeSelectorProps) {
}

let height = 32;
if (size === 'mini') {
height = 24;
} else if (size === 'small') {
if (size === 'small') {
height = 28;
} else if (size === 'large') {
height = 36;
Expand Down Expand Up @@ -317,7 +315,15 @@ export function RangeSelector(props: IRangeSelectorProps) {
{rangeDataList.map((item, index) => (
<div key={index} className={styles.rangeSelectorModalContainer}>
<div style={{ width: rangeDataList.length === 1 ? '280px' : '252px' }} className={styles.rangeSelectorModalContainerInput}>
<Input className={currentInputIndex === index ? styles.rangeSelectorModalContainerInputActive : ((rangeDataList.length - 1 === index && currentInputIndex === -1) ? styles.rangeSelectorModalContainerInputActive : '')} placeholder={localeService.t('rangeSelector.placeHolder')} affixWrapperStyle={{ width: '100%' }} key={`input${index}`} onClick={() => setCurrentInputIndex(index)} value={item} onChange={(value) => changeItem(index, value)} />
<Input
className={currentInputIndex === index ? styles.rangeSelectorModalContainerInputActive : ((rangeDataList.length - 1 === index && currentInputIndex === -1) ? styles.rangeSelectorModalContainerInputActive : '')}
placeholder={localeService.t('rangeSelector.placeHolder')}
affixWrapperStyle={{ width: '100%' }}
key={`input${index}`}
onClick={() => setCurrentInputIndex(index)}
value={item}
onChange={(value) => changeItem(index, value)}
/>
</div>
<div style={{ display: rangeDataList.length === 1 ? 'none' : 'inline-block' }} className={styles.rangeSelectorModalContainerButton}>
<DeleteSingle onClick={() => removeItem(index)} />
Expand Down
1 change: 0 additions & 1 deletion packages/uniscript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
"@univerjs/design": "workspace:*",
"@univerjs/facade": "workspace:*",
"@univerjs/shared": "workspace:*",
"@univerjs/sheets": "workspace:*",
"@univerjs/ui": "workspace:*",
"@wendellhu/redi": "^0.13.0",
"less": "^4.2.0",
Expand Down
21 changes: 18 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading