Skip to content

Instantly share code, notes, and snippets.

@vvscode
Created June 26, 2019 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vvscode/be98fb5072b498172913e3703edb7e16 to your computer and use it in GitHub Desktop.
Save vvscode/be98fb5072b498172913e3703edb7e16 to your computer and use it in GitHub Desktop.
Add fallback to `any` / `unknown` in case of errors in generating `.d.ts`
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Link from '@tamm/ui-lib-link';
import Icon from '@tamm/ui-lib-icon';
import FeedbackModal from '@tamm/ui-lib-feedback-modal';
import nop from '@tamm/ui-lib-utils/nop';
import './Feedback.less';
import { STEP } from '@tamm/ui-lib-feedback-modal/FeedbackModal.const';
const MENU_ITEMS = [
{ translationKey: 'feedback.chat', icon: 'feedback_chat', label: 'chat' },
{ translationKey: 'feedback.message', icon: 'send', label: 'message' },
{
translationKey: 'feedback.feedback',
icon: 'feedback',
label: 'feedback',
},
{
translationKey: 'feedback.co_create',
icon: 'announce',
label: 'co-create',
},
];
class Feedback extends React.PureComponent {
static propTypes = {
/**
* chat link
* */
chatLink: PropTypes.string.isRequired,
/**
* message link
* */
messageLink: PropTypes.string.isRequired,
/**
* co-create link
* */
coCreateLink: PropTypes.string.isRequired,
/**
* chat link target
* */
chatLinkTarget: PropTypes.string,
/**
* message link target
* */
messageLinkTarget: PropTypes.string,
/**
* co-create link target
* */
coCreateLinkTarget: PropTypes.string,
/**
* function to get appropriate translation by key
* */
i18n: PropTypes.func.isRequired,
/**
* on feedback event handler
* */
onFeedbackRate: PropTypes.func,
/**
* on feedback submit event handler
* */
onFeedbackCommentsSubmit: PropTypes.func,
/**
* feedback field options
* */
feedbackFieldsOptions: PropTypes.shape({
/**
* feedback phone
* */
phone: PropTypes.shape(),
/**
* feedback comments
* */
comments: PropTypes.shape(),
}),
/**
* feedback active step
* */
feedbackActiveStep: PropTypes.oneOf(Object.values(STEP)),
/**
* feedback rate header
* */
feedbackRateHeader: PropTypes.string,
/**
* feedback comments form header
* */
feedbackCommentsFormHeader: PropTypes.string,
/**
* feedback comments label
* */
feedbackCommentsLabel: PropTypes.string,
/**
* feedback modal width
* */
feedbackModalWidth: PropTypes.string,
/**
* whether to open fdedback modal
* */
feedbackModalOpen: PropTypes.bool,
};
static defaultProps = {
onFeedbackRate: nop,
onFeedbackCommentsSubmit: nop,
feedbackFieldsOptions: {
phone: {},
comments: {},
},
feedbackActiveStep: STEP.RATING,
feedbackRateHeader: '',
feedbackCommentsFormHeader: '',
feedbackCommentsLabel: '',
feedbackModalWidth: undefined,
feedbackModalOpen: false,
chatLinkTarget: undefined,
messageLinkTarget: undefined,
coCreateLinkTarget: undefined,
};
state = {
feedbackMenuVisibility: false,
feedBackModalVisible: this.props.feedbackModalOpen,
};
static getDerivedStateFromProps({ feedbackModalOpen }, { oldOpenState }) {
if (feedbackModalOpen !== oldOpenState)
return {
feedBackModalVisible: feedbackModalOpen,
oldOpenState: feedbackModalOpen,
};
return null;
}
/**
*
* @param {string} label: link label
* @returns {Object}
*/
getLinkAttrByLabel = label => {
const {
chatLink,
chatLinkTarget,
messageLink,
messageLinkTarget,
coCreateLink,
coCreateLinkTarget,
} = this.props;
switch (label) {
case 'chat':
return { href: chatLink, target: chatLinkTarget };
case 'message':
return { href: messageLink, target: messageLinkTarget };
case 'feedback':
return { onClick: this.toggleFeedback };
case 'co-create':
return { href: coCreateLink, target: coCreateLinkTarget };
default:
return '';
}
};
toggleMenu = () => {
this.setState(state => ({
feedbackMenuVisibility: !state.feedbackMenuVisibility,
}));
};
toggleFeedback = () => {
this.setState({ feedBackModalVisible: !this.state.feedBackModalVisible });
};
render() {
const { feedbackMenuVisibility, feedBackModalVisible } = this.state;
const {
i18n,
onFeedbackCommentsSubmit,
onFeedbackRate,
feedbackFieldsOptions,
feedbackActiveStep,
feedbackCommentsFormHeader,
feedbackCommentsLabel,
feedbackRateHeader,
feedbackModalWidth,
} = this.props;
const toggleClass = feedbackMenuVisibility
? 'uil-feedback__close'
: 'uil-feedback__toggle';
const toggleIcon = feedbackMenuVisibility ? 'close' : '247';
return (
<Fragment>
<div
className={classnames('uil-feedback', 'qa-feedback', {
'uil-feedback_visible': feedbackMenuVisibility,
})}
>
<button
type="button"
title="feedback-icon"
onClick={this.toggleMenu}
className={`${toggleClass} qa-feedback-toggle`}
>
<Icon className="uil-feedback__toggle-icon" source={toggleIcon} />
</button>
<div className="uil-feedback__slide-panel">
{MENU_ITEMS.map(({ translationKey, icon, label }) => (
<Link
key={label}
className={`uil-feedback__item uil-feedback__item_${label} qa-feedback-item qa-feedback-item-${label}`}
{...this.getLinkAttrByLabel(label)}
>
<Icon className="uil-feedback__icon" source={icon} />
{i18n(translationKey)}
</Link>
))}
</div>
</div>
{feedbackMenuVisibility && (
<div
role="button"
tabIndex={0}
onClick={this.toggleMenu}
onKeyDown={this.toggleMenu}
className="uil-feedback__overlay qa-feedback-overlay"
aria-label="feedback overlay"
/>
)}
<FeedbackModal
fieldsOptions={feedbackFieldsOptions}
visible={feedBackModalVisible}
onCancel={this.toggleFeedback}
onCommentsSubmit={onFeedbackCommentsSubmit}
onRateSubmit={onFeedbackRate}
activeStep={feedbackActiveStep}
rateHeader={feedbackRateHeader}
commentsFormHeader={feedbackCommentsFormHeader}
commentsLabel={feedbackCommentsLabel}
modalWidth={feedbackModalWidth}
/>
</Fragment>
);
}
}
export default Feedback;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment