Skip to content

Commit

Permalink
feat: UiKit error states (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo authored Jan 31, 2020
1 parent c750d5a commit d6b3842
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 43 deletions.
8 changes: 4 additions & 4 deletions packages/fuselage-ui-kit/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {

import { Block } from './Block';

export const Input = ({ label, element, parser, index }) => (
export const Input = ({ label, element, parser, index, error, hint }) => (
<Block>
<FieldGroup>
<Field>
{label && <Field.Label>{label}</Field.Label>}
{
parser.renderInputs(element, BLOCK_CONTEXT.FORM, parser, index)
}
{parser.renderInputs(element, BLOCK_CONTEXT.FORM, parser, index)}
{error && <Field.Error>{error}</Field.Error>}
{hint && <Field.Hint>{hint}</Field.Hint>}
</Field>
</FieldGroup>
</Block>
Expand Down
74 changes: 42 additions & 32 deletions packages/fuselage-ui-kit/src/UIKitModal.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Meta, Preview, Props, Story } from '@storybook/addon-docs/blocks';
import {
Modal,
} from '@rocket.chat/fuselage';
import { UiKitModal, kitContext, defaultContext } from './';
import { UiKitModal, kitContext, defaultContext, UiKitComponent } from './';
import { Demo } from './Demo';
import { withKnobs, text, boolean, number } from "@storybook/addon-knobs";

Expand All @@ -15,36 +15,42 @@ import { withKnobs, text, boolean, number } from "@storybook/addon-knobs";
<Preview>
<Story name='Input'>
<Demo visible={boolean('visible', true) ? 1 : 0}>
{UiKitModal([{
"type": "input",
"element": {
"type": "plain_text_input"
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}])}
<kitContext.Provider value={{...defaultContext, errors: {'input-test': text('error', 'asdas') } }}>
<UiKitComponent render={UiKitModal} blocks={[{
"type": "input",
"element": {
"type": "plain_text_input",
"actionId": "input-test",
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}]}/>
</kitContext.Provider>
</Demo>
</Story>
</Preview>

<Preview>
<Story name='Input Multiline'>
<Demo visible={boolean('visible', true) ? 1 : 0}>
{UiKitModal([{
<kitContext.Provider value={{...defaultContext, errors: {'input-test': text('error', 'asdas') } }}>
<UiKitComponent render={UiKitModal} blocks= {[{
"type": "input",
"element": {
"type": "plain_text_input",
"multiline": true
"multiline": true,
"actionId": "input-test"
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}])}
}]}/>
</kitContext.Provider>
</Demo>
</Story>
</Preview>
Expand All @@ -54,23 +60,27 @@ import { withKnobs, text, boolean, number } from "@storybook/addon-knobs";
<Preview>
<Story name='Input Datepicker'>
<Demo visible={boolean('visible', true) ? 1 : 0}>
{UiKitModal([{
"type": "input",
"element": {
"type": "datepicker",
"initial_date": "1990-04-28",
"placeholder": {
"type": "plain_text",
"text": "Select a date",
"emoji": true
}
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}])}
<kitContext.Provider value={{...defaultContext, errors: {'input-test': text('error', 'asdas') } }}>
<UiKitComponent render={UiKitModal} blocks= {[{
"type": "input",
"element": {
"type": "datepicker",
"initial_date": "1990-04-28",
"actionId": "input-test",
"placeholder": {
"type": "plain_text",
"text": "Select a date",
"emoji": true
}
},
"label": {
"type": "plain_text",
"text": "Label",
"emoji": true
}
}
]}/>
</kitContext.Provider>
</Demo>
</Story>
</Preview>
Expand Down
25 changes: 18 additions & 7 deletions packages/fuselage-ui-kit/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,26 @@ export const defaultContext = {
action: (...args) => console.log(JSON.stringify(args)),
state: console.log,
appId: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
errors: {}
};

export const kitContext = React.createContext(defaultContext);

const useBlockContext = ({ blockId, actionId, appId, initialValue }, context) => {
export const useBlockContext = ({ blockId, actionId, appId, initialValue }, context) => {
const [value, setValue] = useState(initialValue);
const [loading, setLoading] = useState(false);
const { action, appId: appIdFromContext, state } = useContext(kitContext);
const { action, appId: appIdFromContext, state, errors } = useContext(kitContext);
const error = errors && actionId && errors[actionId];

if ([BLOCK_CONTEXT.SECTION, BLOCK_CONTEXT.ACTION].includes(context)) {
return [{ loading, setLoading }, async ({ target: { value } }) => {
return [{ loading, setLoading, error }, async ({ target: { value } }) => {
setLoading(true);
await action({ blockId, appId: appId || appIdFromContext, actionId, value });
setLoading(false);
}];
}

return [{ loading, setLoading, value }, async ({ target: { value } }) => {
return [{ loading, setLoading, value, error }, async ({ target: { value } }) => {
setValue(value);
setLoading(true);
await state({ blockId, appId, actionId, value });
Expand Down Expand Up @@ -156,11 +159,12 @@ class MessageParser extends UiKitParserMessage {
}

datePicker(element, context, key) {
const [{ loading, value }, action] = useBlockContext(element, context);
const [{ loading, value, error }, action] = useBlockContext(element, context);
const { actionId, placeholder } = element;
return (
<InputBox
key={key}
error={error}
value={value}
mod-mod-loading={loading}
id={actionId}
Expand Down Expand Up @@ -244,12 +248,16 @@ class ModalParser extends UiKitParserModal {
});
}

input({ element, label, blockId, appId }, context, index) {
input({ element, label, blockId, appId, ...args }, context, index) {
const [{ loading, value, error }, action] = useBlockContext({ ...element, appId, blockId }, context);

return (
<InputLayoutBlock
error={error}
key={index}
index={index}
parser={this}
context={context}
element={{ ...element, appId, blockId }}
label={this.plainText(label)}
/>
Expand All @@ -261,7 +269,7 @@ class ModalParser extends UiKitParserModal {
}

plainInput(element, context, index) {
const [{ loading, value }, action] = useBlockContext(element, context);
const [{ loading, value, error }, action] = useBlockContext(element, context);
const { multiline, actionId, placeholder } = element;
const Component = multiline ? TextAreaInput : TextInput;
return (
Expand All @@ -271,6 +279,7 @@ class ModalParser extends UiKitParserModal {
id={actionId}
name={actionId}
rows={6}
error={error}
value={value}
onInput={action}
placeholder={this.plainText(placeholder)}
Expand All @@ -288,3 +297,5 @@ export const UiKitButtons = uiKitButtons();
export const UiKitText = uiKitText(textParser);
export const UiKitMessage = uiKitMessage(messageParser);
export const UiKitModal = uiKitModal(modalParser);

export const UiKitComponent = ({render, blocks}) => render(blocks);

0 comments on commit d6b3842

Please sign in to comment.