Unverified Commit f21c940e authored by Andrey Azov's avatar Andrey Azov Committed by GitHub
Browse files

Shaded form elements (#534)

parent 0abc367d
Pipeline #179544 passed with stages
in 4 minutes and 21 seconds
@import 'src/styles/common';
.input { .input {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
...@@ -6,4 +8,16 @@ ...@@ -6,4 +8,16 @@
&:active { &:active {
outline: none; outline: none;
} }
&::placeholder {
color: $black;
font-weight: $light;
}
}
.shadedInput {
box-shadow: $form-field-shadow;
border: none;
padding: 0 15px;
height: 30px;
} }
/**
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* 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 React from 'react';
import classNames from 'classnames';
import Input, { Props as InputProps } from './Input';
import styles from './Input.scss';
const ShadedInput = (props: InputProps) => {
const { className, ...otherProps } = props;
const inputClasses = classNames(styles.shadedInput, className);
return <Input className={inputClasses} {...otherProps} />;
};
export default ShadedInput;
/**
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* 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 React from 'react';
import classNames from 'classnames';
import Textarea, { Props as TextareaProps } from './Textarea';
import styles from './Textarea.scss';
const ShadedTextarea = (props: TextareaProps) => {
const { className, ...otherProps } = props;
const inputClasses = classNames(styles.shadedTextarea, className);
return <Textarea className={inputClasses} {...otherProps} />;
};
export default ShadedTextarea;
@import 'src/styles/common';
.textarea { .textarea {
border: none; border: none;
padding: 7px; padding: 7px;
...@@ -7,8 +9,19 @@ ...@@ -7,8 +9,19 @@
&:active { &:active {
outline: none; outline: none;
} }
&::placeholder {
color: $black;
font-weight: $light;
}
} }
.disableResize { .disableResize {
resize: none; resize: none;
} }
.shadedTextarea {
box-shadow: $form-field-shadow;
padding: 7px 15px;
border: none;
}
...@@ -36,7 +36,7 @@ type PropsForRespondingWithData = { ...@@ -36,7 +36,7 @@ type PropsForRespondingWithData = {
type OnChangeProps = PropsForRespondingWithEvents | PropsForRespondingWithData; type OnChangeProps = PropsForRespondingWithEvents | PropsForRespondingWithData;
type Props = { export type Props = {
value: string | number; value: string | number;
id?: string; id?: string;
name?: string; name?: string;
...@@ -50,21 +50,23 @@ type Props = { ...@@ -50,21 +50,23 @@ type Props = {
} & OnChangeProps; } & OnChangeProps;
const Textarea = (props: Props) => { const Textarea = (props: Props) => {
const eventHandler = (eventName: string) => ( const eventHandler =
e: (eventName: string) =>
| React.ChangeEvent<HTMLTextAreaElement> (
| React.FocusEvent<HTMLTextAreaElement> e:
) => { | React.ChangeEvent<HTMLTextAreaElement>
const value = e.target.value; | React.FocusEvent<HTMLTextAreaElement>
) => {
const value = e.target.value;
if (eventName === 'change') { if (eventName === 'change') {
props.callbackWithEvent ? props.onChange(e) : props.onChange(value); props.callbackWithEvent ? props.onChange(e) : props.onChange(value);
} else if (eventName === 'focus') { } else if (eventName === 'focus') {
props.callbackWithEvent ? props.onFocus(e) : props.onFocus(value); props.callbackWithEvent ? props.onFocus(e) : props.onFocus(value);
} else if (eventName === 'blur') { } else if (eventName === 'blur') {
props.callbackWithEvent ? props.onBlur(e) : props.onBlur(value); props.callbackWithEvent ? props.onBlur(e) : props.onBlur(value);
} }
}; };
const className = classNames(styles.textarea, props.className, { const className = classNames(styles.textarea, props.className, {
[styles.disableResize]: !props.resizable [styles.disableResize]: !props.resizable
......
...@@ -39,6 +39,7 @@ $mustard: #cc9933; ...@@ -39,6 +39,7 @@ $mustard: #cc9933;
$green: #47d147; $green: #47d147;
$global-box-shadow: $medium-light-grey; $global-box-shadow: $medium-light-grey;
$form-field-shadow: inset 2px 2px 4px -2px $medium-dark-grey, inset -2px -2px 1px -2px $dark-grey;
/* stylelint-disable */ /* stylelint-disable */
:export { :export {
......
@import 'src/styles/common';
.wrapper {
max-width: 500px;
}
.stage {
padding: 50px;
& + .stage {
margin-top: 4ch;
}
}
.greyStage {
background-color: $light-grey;
}
.customizedInput { .customizedInput {
color: rosybrown; color: rosybrown;
font-size: 36px; font-size: 36px;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import Input from 'src/shared/components/input/Input'; import Input from 'src/shared/components/input/Input';
import ShadedInput from 'src/shared/components/input/ShadedInput';
import styles from './Input.stories.scss'; import styles from './Input.stories.scss';
...@@ -34,7 +35,7 @@ const Wrapper = (props: any) => { ...@@ -34,7 +35,7 @@ const Wrapper = (props: any) => {
}; };
return ( return (
<div> <div className={styles.wrapper}>
<Input value={value} {...otherProps} onChange={onChange} /> <Input value={value} {...otherProps} onChange={onChange} />
</div> </div>
); );
...@@ -64,6 +65,29 @@ export const FocusAndBlurStory = (args: DefaultArgs) => ( ...@@ -64,6 +65,29 @@ export const FocusAndBlurStory = (args: DefaultArgs) => (
FocusAndBlurStory.storyName = 'handling focus and blur'; FocusAndBlurStory.storyName = 'handling focus and blur';
export const ShadedInputStory = (args: DefaultArgs) => (
<>
<div className={styles.stage}>
<p>Against white background</p>
<Wrapper
input={ShadedInput}
placeholder="Placeholder for dev..."
{...args}
/>
</div>
<div className={`${styles.stage} ${styles.greyStage}`}>
<p>Against grey background</p>
<Wrapper
input={ShadedInput}
placeholder="Placeholder for dev..."
{...args}
/>
</div>
</>
);
ShadedInputStory.storyName = 'shaded input';
export const CustomInputStory = (args: DefaultArgs) => ( export const CustomInputStory = (args: DefaultArgs) => (
<Wrapper <Wrapper
input={Input} input={Input}
......
...@@ -12,3 +12,15 @@ ...@@ -12,3 +12,15 @@
padding: 40px; padding: 40px;
background: $light-grey; background: $light-grey;
} }
.stage {
padding: 30px;
& + .stage {
margin-top: 3ch;
}
}
.greyStage {
background: $light-grey;
}
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import Textarea from 'src/shared/components/textarea/Textarea'; import Textarea from 'src/shared/components/textarea/Textarea';
import ShadedTextarea from 'src/shared/components/textarea/ShadedTextarea';
import styles from './Textarea.stories.scss'; import styles from './Textarea.stories.scss';
...@@ -27,21 +28,27 @@ type DefaultArgs = { ...@@ -27,21 +28,27 @@ type DefaultArgs = {
const Wrapper = (props: any) => { const Wrapper = (props: any) => {
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const { textarea: Textarea, ...otherProps } = props; const { textarea: Textarea, wrapperClassName, ...otherProps } = props;
return ( return (
<div className={styles.defaultWrapper}> <div className={wrapperClassName}>
<Textarea value={value} onChange={setValue} {...otherProps} /> <Textarea value={value} onChange={setValue} {...otherProps} />
</div> </div>
); );
}; };
export const DefaultStory = () => <Wrapper textarea={Textarea} />; export const DefaultStory = () => (
<Wrapper textarea={Textarea} wrapperClassName={styles.defaultWrapper} />
);
DefaultStory.storyName = 'default'; DefaultStory.storyName = 'default';
export const WithPlaceholderStory = () => ( export const WithPlaceholderStory = () => (
<Wrapper textarea={Textarea} placeholder="Enter something..." /> <Wrapper
textarea={Textarea}
placeholder="Enter something..."
wrapperClassName={styles.defaultWrapper}
/>
); );
WithPlaceholderStory.storyName = 'with placeholder'; WithPlaceholderStory.storyName = 'with placeholder';
...@@ -50,6 +57,7 @@ export const NoResizeStory = () => ( ...@@ -50,6 +57,7 @@ export const NoResizeStory = () => (
<Wrapper <Wrapper
textarea={Textarea} textarea={Textarea}
placeholder="Enter something..." placeholder="Enter something..."
wrapperClassName={styles.defaultWrapper}
resizable={false} resizable={false}
/> />
); );
...@@ -60,6 +68,7 @@ export const FocusBlurStory = (args: DefaultArgs) => ( ...@@ -60,6 +68,7 @@ export const FocusBlurStory = (args: DefaultArgs) => (
<Wrapper <Wrapper
textarea={Textarea} textarea={Textarea}
placeholder="Enter something..." placeholder="Enter something..."
wrapperClassName={styles.defaultWrapper}
onFocus={args.onFocus()} onFocus={args.onFocus()}
onBlur={args.onBlur()} onBlur={args.onBlur()}
/> />
...@@ -67,10 +76,36 @@ export const FocusBlurStory = (args: DefaultArgs) => ( ...@@ -67,10 +76,36 @@ export const FocusBlurStory = (args: DefaultArgs) => (
FocusBlurStory.storyName = 'with onFocus and onBlur'; FocusBlurStory.storyName = 'with onFocus and onBlur';
export const ShadedTextareaStory = (args: DefaultArgs) => (
<>
<div className={styles.stage}>
<p>Against a white background</p>
<Wrapper
textarea={ShadedTextarea}
placeholder="Enter something..."
onFocus={args.onFocus()}
onBlur={args.onBlur()}
/>
</div>
<div className={`${styles.stage} ${styles.greyStage}`}>
<p>Against a grey background</p>
<Wrapper
textarea={ShadedTextarea}
placeholder="Enter something..."
onFocus={args.onFocus()}
onBlur={args.onBlur()}
/>
</div>
</>
);
ShadedTextareaStory.storyName = 'shaded textarea';
export const CustomStyledStory = () => ( export const CustomStyledStory = () => (
<Wrapper <Wrapper
textarea={Textarea} textarea={Textarea}
placeholder="Enter something..." placeholder="Enter something..."
wrapperClassName={styles.defaultWrapper}
className={styles.customizedTextarea} className={styles.customizedTextarea}
/> />
); );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment