{"version":3,"sources":["webpack:///./src/Frontend/app/components/author-press-photos/author-press-photos.tsx","webpack:///./src/Frontend/storybook/custom-decorators/with-story-container.tsx","webpack:///./src/Frontend/app/components/author-details/author-details.tsx","webpack:///./src/Frontend/app/views/author-details/author-details-view.tsx","webpack:///./src/Frontend/app/components/icons/icon.tsx","webpack:///./src/Frontend/app/utils/image-utils.ts","webpack:///./src/Frontend/app/components/responsive-image/responsive-image.tsx","webpack:///./src/Frontend/app/components/spinner/spinner.tsx","webpack:///./src/Frontend/app/components/button/button.tsx","webpack:///./src/Frontend/app/components/author-image/author-image.tsx","webpack:///./src/Frontend/app/components/tabs/tabs.tsx","webpack:///./src/Frontend/app/components/tabs/tab-menu/tab-menu.tsx","webpack:///./src/Frontend/app/components/tabs/tab-content-container/tab-content-container.tsx","webpack:///./src/Frontend/app/components/tabs/tab-content/tab-content.tsx"],"names":["stories","module","addDecorator","Image","src","srcSet","alt","loading","setLoading","className","sizes","onLoad","decoding","pressPhotosDescription","pressPhotos","photos","setPhotos","visibleCount","setVisibleCount","slice","baseClass","dangerouslySetInnerHTML","__html","map","photo","url","downloadUrl","key","comment","description","href","target","download","iconId","viewBox","length","isLarge","isInverted","onClick","prevCount","withStoryContainer","story","name","imageUrl","descriptionTab","pressPhotosTab","tabs","label","content","defaultTab","render","tabClickHandler","selectedTabKey","selectedKey","tab","isCurrent","this","props","contextModel","spriteUrl","preserveAspectRatio","xmlnsXlink","xlinkHref","getQueryParamDelimiter","indexOf","hasExistingQueryParam","generateSrcSet","srcSetSizes","srcUrl","srcSetSize","parameterDelimiter","srcSetSizeHighDensity","Math","round","join","generateColumnImageProps","maxColumns","isFullWidth","gridMaxWidthFactor","defaultSize","ResponsiveImage","ref","size","componentClasses","isSecondary","type","disabled","e","children","state","tabId","setState","getRenderProps","bind","renderProps","rootClasses","btnClassName","preventDefault"],"mappings":"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","file":"16.d4b85b3377e1195f246f.js","sourcesContent":["import * as React from \"react\";\r\nimport { withKnobs } from \"@storybook/addon-knobs\";\r\nimport { storiesOf } from \"@storybook/react\";\r\nimport { IAuthorPressPhoto } from \"~/types/author-press-photo\";\r\nimport { withStoryContainer } from \"~storybook/custom-decorators/with-story-container\";\r\nimport Icon from \"../icons/icon\";\r\nimport Button from \"~/components/button/button\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nimport Spinner from \"../spinner/spinner\";\r\nimport classNames from \"classnames\";\r\n\r\nconst stories = storiesOf(\"Components|âœï¸ Author modules.âœï¸ Author Press\", module);\r\nstories.addDecorator(withKnobs);\r\nstories.addDecorator(withStoryContainer);\r\n\r\nexport interface AuthorPressPhotosProps {\r\n pressPhotosDescription?: string;\r\n pressPhotos: IAuthorPressPhoto[];\r\n}\r\n\r\nconst Image: React.FC<{ src: string; srcSet: string; alt: string }> = ({ src, srcSet, alt }) => {\r\n const [loading, setLoading] = useState(true);\r\n\r\n return (\r\n <>\r\n <div className={classNames(`author-press-photos__spinner`, loading ? \"visible\" : \"hidden\")}>\r\n <Spinner />\r\n </div>\r\n\r\n <img\r\n src={src}\r\n className={classNames(`author-press-photos__photo`, loading ? \"hidden\" : \"visible\")}\r\n sizes=\"(min-width: 368px) 50vw, (min-width: 544px) 33vw, (min-width: 640px) 50vw, (min-width: 768px) 168px, (min-width: 1152px) 160px, 100vw\"\r\n srcSet={srcSet}\r\n alt={alt}\r\n loading=\"lazy\"\r\n onLoad={() => setLoading(false)}\r\n decoding=\"async\"\r\n />\r\n </>\r\n );\r\n};\r\n\r\nconst AuthorPressPhotos: React.FC<AuthorPressPhotosProps> = ({ pressPhotosDescription, pressPhotos }) => {\r\n const itemsToShow = 20;\r\n const [photos, setPhotos] = useState<IAuthorPressPhoto[]>([]);\r\n const [visibleCount, setVisibleCount] = useState(itemsToShow);\r\n\r\n useEffect(() => {\r\n setPhotos(pressPhotos.slice(0, visibleCount));\r\n }, [visibleCount]);\r\n\r\n const loadMore = () => {\r\n setVisibleCount(prevCount => prevCount + itemsToShow);\r\n };\r\n\r\n const baseClass = \"author-press-photos\";\r\n const wrapperClass = `${baseClass}__wrapper`;\r\n const introText = `${baseClass}__introText`;\r\n const photoDescriptionClass = `${baseClass}__photoDescription`;\r\n const photoCommentClass = `${baseClass}__photoComment`;\r\n const photoPhotographerClass = `${baseClass}__photoPhotographer`;\r\n const linkClass = `${baseClass}__link`;\r\n\r\n return (\r\n <>\r\n {pressPhotosDescription && (\r\n <p className={introText} dangerouslySetInnerHTML={{ __html: pressPhotosDescription }} />\r\n )}\r\n\r\n <div className={baseClass}>\r\n {photos.map(photo => {\r\n if (!photo || !photo.url || !photo.downloadUrl) {\r\n return null;\r\n }\r\n\r\n const src = `${photo.url}&w=400`;\r\n const srcSet = `${photo.url}&w=400 400w, ${photo.url}&w=600 600w`;\r\n const alt = photo.alt || \"\";\r\n\r\n return (\r\n <div className={wrapperClass} key={`key-${photo.url}`}>\r\n <Image src={src} srcSet={srcSet} alt={alt} />\r\n\r\n <div className={photoDescriptionClass}>\r\n {photo.comment && <div className={photoCommentClass}>{photo.comment}</div>}\r\n {photo.description && (\r\n <div className={photoPhotographerClass}>{photo.description}</div>\r\n )}\r\n <a className={linkClass} href={photo.downloadUrl} target=\"_blank\" download>\r\n <span className=\"button button--round product-details__inner-play-button\">\r\n <Icon iconId=\"icon_download\" viewBox=\"0 0 16 16\" />\r\n </span>\r\n Hent foto\r\n </a>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n\r\n {pressPhotos.length >= visibleCount && (\r\n <>\r\n <div className=\"search-results__x-of-y\">\r\n Viser {visibleCount} ud af {pressPhotos.length} resultater\r\n </div>\r\n {visibleCount < pressPhotos.length && (\r\n <div className=\"search-results__button-wrapper\">\r\n <Button\r\n className=\"search-results__button\"\r\n isLarge={true}\r\n isInverted={true}\r\n onClick={loadMore}\r\n >\r\n Hent flere\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default AuthorPressPhotos;\r\n","import * as React from \"react\";\r\n\r\nexport function withStoryContainer(story: any) {\r\n return <div className=\"story-container\">{story()}</div>;\r\n}\r\n","import * as React from \"react\";\r\nimport { IAuthor } from \"~/types/author\";\r\nimport Icon from \"../icons/icon\";\r\nimport AuthorImage from \"../author-image/author-image\";\r\nimport Tabs, { ITab } from \"~/components/tabs/tabs\";\r\nimport TabMenu from \"~/components/tabs/tab-menu/tab-menu\";\r\nimport TabContentContainer from \"~/components/tabs/tab-content-container/tab-content-container\";\r\nimport TabContent from \"~/components/tabs/tab-content/tab-content\";\r\nimport classNames from \"classnames\";\r\nimport AuthorPressPhotos from \"../author-press-photos/author-press-photos\";\r\n\r\nexport interface AuthorDetailsProps extends IAuthor {\r\n descriptionTab: string;\r\n pressPhotosTab: string;\r\n}\r\n\r\nconst enum tabTypes {\r\n DESCRIPTION = \"description\",\r\n PHOTOS = \"photos\"\r\n}\r\n\r\nconst AuthorDetails = ({\r\n name,\r\n imageUrl,\r\n description,\r\n descriptionTab,\r\n pressPhotosTab,\r\n pressPhotosDescription,\r\n pressPhotos\r\n}: AuthorDetailsProps) => {\r\n const baseClass = \"author-details\";\r\n\r\n const tabs: ITab[] = [\r\n {\r\n key: tabTypes.DESCRIPTION,\r\n label: descriptionTab,\r\n content: (\r\n <>\r\n {description && (\r\n <div\r\n className={`${baseClass}__description`}\r\n dangerouslySetInnerHTML={{ __html: description }}\r\n />\r\n )}\r\n </>\r\n )\r\n },\r\n {\r\n key: tabTypes.PHOTOS,\r\n label: pressPhotosTab,\r\n content: (\r\n <>\r\n {pressPhotos && pressPhotos.length ? (\r\n <AuthorPressPhotos\r\n pressPhotosDescription={pressPhotosDescription}\r\n pressPhotos={pressPhotos}\r\n />\r\n ) : (\r\n \"Gyldendal rÃ¥der desværre ikke over et forfatterfoto, der mÃ¥ bruges eksternt.\"\r\n )}\r\n </>\r\n )\r\n }\r\n ];\r\n\r\n return (\r\n <section className={baseClass}>\r\n <div className={`${baseClass}__inner`}>\r\n <div className={`${baseClass}__image-section`}>\r\n <div className={`${baseClass}__image-section-inner`}>\r\n <div className={classNames(`${baseClass}__graphics`)}></div>\r\n <AuthorImage className={`${baseClass}__author-image`} imageUrl={imageUrl} />\r\n <div\r\n className={classNames(`${baseClass}__graphics`, `${baseClass}__graphics--quote`)}\r\n >\r\n <Icon iconId=\"icon_80x48_quotation-mark\" viewBox=\"0 0 80 48\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className={`${baseClass}__text-section`}>\r\n <div className={`${baseClass}__name`}>\r\n <h1 className=\"h1-style\">{name}</h1>\r\n </div>\r\n\r\n <Tabs\r\n className={`${baseClass}__tabs`}\r\n defaultTab={tabs[0]}\r\n render={({ tabClickHandler, selectedTabKey }) => (\r\n <>\r\n <TabMenu\r\n tabClickHandler={tabClickHandler}\r\n tabs={tabs}\r\n selectedKey={selectedTabKey}\r\n />\r\n <TabContentContainer>\r\n {tabs.map(tab => (\r\n <TabContent isCurrent={selectedTabKey === tab.key} key={tab.key}>\r\n {tab.content}\r\n </TabContent>\r\n ))}\r\n </TabContentContainer>\r\n </>\r\n )}\r\n />\r\n </div>\r\n </div>\r\n </section>\r\n );\r\n};\r\n\r\nexport default AuthorDetails;\r\n","import * as React from \"react\";\r\nimport AuthorDetails, { AuthorDetailsProps } from \"~/components/author-details/author-details\";\r\n\r\nexport interface IAuthorDetailsViewProps {\r\n contextModel: AuthorDetailsProps;\r\n}\r\n\r\nclass AuthorDetailsView extends React.PureComponent<IAuthorDetailsViewProps> {\r\n public render() {\r\n return <AuthorDetails {...this.props.contextModel} />;\r\n }\r\n}\r\n\r\nexport default AuthorDetailsView;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\nexport type TIconNames =\r\n | \"24_expand\"\r\n | \"24_play\"\r\n | \"24_star\"\r\n | \"24_trash\"\r\n | \"32_add-user\"\r\n | \"32_basket\"\r\n | \"32_checkmark-circle\"\r\n | \"32_checkmark\"\r\n | \"32_error\"\r\n | \"32_information\"\r\n | \"32_katalog\"\r\n | \"32_search\"\r\n | \"32_truck-in-motion\"\r\n | \"32_user\"\r\n | \"32_warning\"\r\n | \"icon_16_arrow-down\"\r\n | \"icon_16_arrow-left\"\r\n | \"icon_16_arrow-right-bold\"\r\n | \"icon_16_arrow-right\"\r\n | \"icon_16_arrow-up\"\r\n | \"icon_28_close\"\r\n | \"icon_32_thumbs-up\"\r\n | \"icon_80x41_quotation-mark-gyldendal-dk\"\r\n | \"icon_80x48_quotation-mark\"\r\n | \"icon_checkbox-black\"\r\n | \"icon_checkmark-black\"\r\n | \"icon_download\"\r\n | \"icon_herringbone-narrow\"\r\n | \"icon_herringbone-wide\"\r\n | \"icon_placeholder-email\"\r\n | \"icon_placeholder-lock\"\r\n | \"icon_placeholder-phone-small\"\r\n | \"icon_placeholder-vip-white\"\r\n | \"icon_placeholder_basket\"\r\n | \"icon_placeholder_checkmark\"\r\n | \"icon_placeholder_eye-closed\"\r\n | \"icon_placeholder_eye\"\r\n | \"icon_placeholder_facebook\"\r\n | \"icon_placeholder_filtering\"\r\n | \"icon_placeholder_hamburger\"\r\n | \"icon_placeholder_instagram\"\r\n | \"icon_placeholder_phone\"\r\n | \"icon_placeholder_user\"\r\n | \"icon_read\"\r\n | \"icon_listen\";\r\n\r\nexport interface IIconProps {\r\n iconId: TIconNames;\r\n spriteUrl?: string;\r\n viewBox?: string;\r\n className?: string;\r\n onClick?: () => void;\r\n}\r\n\r\nconst Icon: React.FC<IIconProps> = props => {\r\n const spriteUrl = props.spriteUrl || \"\";\r\n const viewBox = props.viewBox || \"0 0 32 32\";\r\n\r\n return (\r\n <svg\r\n viewBox={viewBox}\r\n className={classNames(props.className, \"icon\", `icon-${props.iconId}`)}\r\n preserveAspectRatio=\"xMidYMid\"\r\n onClick={() => props.onClick && props.onClick()}\r\n >\r\n <use xmlnsXlink=\"http://www.w3.org/1999/xlink\" xlinkHref={`${spriteUrl}#${props.iconId}`} />\r\n </svg>\r\n );\r\n};\r\n\r\nexport default Icon;\r\n","const hasExistingQueryParam = (url: string) => url.indexOf(\"?\") !== -1;\r\n\r\nexport const getQueryParamDelimiter = (url: string) => (hasExistingQueryParam(url) ? \"&\" : \"?\");\r\n\r\nexport const generateSrcSet = (srcSetSizes: number[], srcUrl: string) => {\r\n const generateSrcSetString = (srcSetSize: number) => {\r\n const parameterDelimiter = getQueryParamDelimiter(srcUrl);\r\n const srcSetSizeHighDensity = Math.round(srcSetSize * 1.5);\r\n\r\n return `\r\n ${srcUrl}${parameterDelimiter}w=${srcSetSize} ${srcSetSize}w,\r\n ${srcUrl}${parameterDelimiter}w=${srcSetSizeHighDensity} ${srcSetSizeHighDensity}w\r\n `;\r\n };\r\n\r\n return srcSetSizes.map(generateSrcSetString).join(\", \");\r\n};\r\n\r\nexport const generateColumnImageProps = (maxColumns: number, isFullWidth?: boolean) => {\r\n // The sizes are column-widths and are not considering padding\r\n const gridMaxWidthFactor = isFullWidth ? 1 : 0.75;\r\n const gridMaxWidth = 1366 * gridMaxWidthFactor;\r\n const defaultSize = gridMaxWidth / maxColumns;\r\n let sizes;\r\n\r\n switch (maxColumns) {\r\n case 5:\r\n sizes = `(max-width: 479px) 100vw, \r\n (max-width: 639px) 75vw,\r\n (max-width: 767px) 50vw,\r\n (max-width: 1023px) ${100 / 3}vw,\r\n (max-width: 1099px) ${(100 / 3) * gridMaxWidthFactor}vw,\r\n (max-width: 1279px) ${(100 / 4) * gridMaxWidthFactor}vw,\r\n ${defaultSize}px`;\r\n case 4:\r\n sizes = `(max-width: 479px) 100vw, \r\n (max-width: 639px) 75vw,\r\n (max-width: 767px) 50vw,\r\n (max-width: 1023px) ${100 / 3}vw,\r\n (max-width: 1099px) ${(100 / 3) * gridMaxWidthFactor}vw,\r\n (max-width: 1279px) ${(100 / 4) * gridMaxWidthFactor}vw,\r\n ${defaultSize}px`;\r\n case 3:\r\n sizes = `(max-width: 479px) 100vw,\r\n (max-width: 639px) 75vw,\r\n (max-width: 767px) 50vw,\r\n (max-width: 1023px) ${100 / 3}vw,\r\n (max-width: 1279px) ${(100 / 3) * gridMaxWidthFactor}vw,\r\n ${defaultSize}px`;\r\n case 2:\r\n sizes = `(max-width: 479px) 100vw,\r\n (max-width: 639px) 75vw,\r\n (max-width: 1023px) ${100 / 2}vw,\r\n (max-width: 1279px) ${(100 / 2) * gridMaxWidthFactor}vw, \r\n ${defaultSize}px`;\r\n case 1:\r\n sizes = `(max-width: 479px) 100vw,\r\n (max-width: 1023px) ${100 * 0.75}vw,\r\n (max-width: 1279px) ${100 * 0.75 * gridMaxWidthFactor}vw,\r\n ${defaultSize * 0.75}px`;\r\n }\r\n\r\n return {\r\n // The sizes are column-widths and are not considering padding\r\n defaultSize: defaultSize,\r\n srcSetSizes: [205, 257, 274, 342, 456, 513, 683, 769, 1025],\r\n sizes: sizes\r\n };\r\n};\r\n","import * as React from \"react\";\r\nimport { generateSrcSet, getQueryParamDelimiter } from \"~/utils/image-utils\";\r\n\r\nexport interface IResponsiveImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\r\n className?: string;\r\n srcUrl: string;\r\n defaultSize: number;\r\n srcSetSizes?: number[];\r\n sizes?: string;\r\n ref?: React.Ref<HTMLImageElement>;\r\n}\r\n\r\nconst ResponsiveImage: React.FC<IResponsiveImageProps> = React.forwardRef(\r\n ({ srcUrl, defaultSize, srcSetSizes, ...props }, ref: React.Ref<HTMLImageElement>) => {\r\n const src = `${srcUrl}${getQueryParamDelimiter(srcUrl)}w=${defaultSize}`;\r\n const srcSet = srcSetSizes ? generateSrcSet(srcSetSizes, srcUrl) : \"\";\r\n\r\n return <img ref={ref} src={src} srcSet={srcSet} {...props} loading=\"lazy\" />;\r\n }\r\n);\r\n\r\nexport default ResponsiveImage;\r\n","import classNames from \"classnames\";\r\nimport * as React from \"react\";\r\n\r\ninterface ISpinnerProps {\r\n size?: \"small\" | \"default\";\r\n className?: string;\r\n}\r\nconst Spinner = ({ size = \"default\", className }: ISpinnerProps) => {\r\n const baseClass = \"spinner\";\r\n const componentClasses = classNames(baseClass, className, {\r\n [`${baseClass}--${size}`]: size !== \"default\"\r\n });\r\n\r\n return <span className={componentClasses} />;\r\n};\r\n\r\nexport default Spinner;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\nimport Icon, { TIconNames } from \"../icons/icon\";\r\nimport Spinner from \"~/components/spinner/spinner\";\r\n\r\ntype IOnClickFunction = (e: React.MouseEvent<HTMLButtonElement>) => void;\r\n\r\nexport interface IButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n onClick?: IOnClickFunction;\r\n disabled?: boolean;\r\n className?: string;\r\n loading?: boolean;\r\n iconId?: TIconNames;\r\n isLarge?: boolean;\r\n isInverted?: boolean;\r\n isSecondary?: boolean;\r\n}\r\n\r\nconst Button: React.SFC<IButtonProps> = props => {\r\n const baseClass = \"button\";\r\n const componentClasses = classNames(baseClass, props.className, {\r\n [`${baseClass}--large`]: props.isLarge,\r\n [`${baseClass}--inverted`]: props.isInverted,\r\n [`${baseClass}--secondary`]: props.isSecondary,\r\n [`${baseClass}--loading`]: props.loading\r\n });\r\n\r\n return (\r\n <button\r\n className={componentClasses}\r\n type={props.type || \"button\"}\r\n disabled={!!(props.disabled || props.loading)}\r\n onClick={e => {\r\n if (props.onClick) {\r\n props.onClick(e);\r\n }\r\n }}\r\n >\r\n {props.iconId && <Icon iconId={props.iconId} className={`${baseClass}__icon`} />}\r\n {props.loading && <Spinner />}\r\n <span className={`${baseClass}__text`}>{props.children}</span>\r\n </button>\r\n );\r\n};\r\nexport default Button;\r\n","import * as React from \"react\";\r\nimport { IAuthor } from \"~/types/author\";\r\nimport classNames from \"classnames\";\r\nimport ResponsiveImage from \"../responsive-image/responsive-image\";\r\n\r\nexport interface IAuthorImageProps extends Pick<IAuthor, \"imageUrl\"> {\r\n className?: string;\r\n}\r\n\r\nconst AuthorImage = ({ imageUrl, className }: IAuthorImageProps) => {\r\n const baseClass = \"author-image\";\r\n const dummyImageUrl = \"/dist/styles/assets/gfx/author/fallback-author-foto.jpg\";\r\n\r\n return (\r\n <div className={classNames(baseClass, className)}>\r\n <ResponsiveImage\r\n srcUrl={imageUrl || dummyImageUrl}\r\n defaultSize={300}\r\n srcSetSizes={[300]}\r\n sizes=\"300px\"\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default AuthorImage;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\nexport interface ITab {\r\n key: string;\r\n label: string;\r\n content: React.ReactNode;\r\n}\r\n\r\nexport interface ITabsProps {\r\n render(state: ITabsRenderProps): React.ReactNode;\r\n defaultTab: ITab;\r\n className?: string;\r\n}\r\n\r\ninterface ITabsRenderProps {\r\n readonly tabClickHandler: () => void;\r\n readonly selectedTabKey: string;\r\n}\r\n\r\nclass Tabs extends React.Component<ITabsProps> {\r\n public state = {\r\n selectedTabKey: this.props.defaultTab.key\r\n };\r\n\r\n private tabClickHandler = (tabId: string) => {\r\n this.setState({\r\n selectedTabKey: tabId\r\n });\r\n };\r\n\r\n public getRenderProps(): ITabsRenderProps {\r\n return {\r\n tabClickHandler: this.tabClickHandler.bind(this),\r\n selectedTabKey: this.state.selectedTabKey\r\n };\r\n }\r\n\r\n public render() {\r\n const renderProps = this.getRenderProps();\r\n const rootClasses = classNames(\"tabs\", this.props.className);\r\n\r\n return <div className={rootClasses}>{this.props.render(renderProps)}</div>;\r\n }\r\n}\r\n\r\nexport default Tabs;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\nimport { ITab } from \"~/components/tabs/tabs\";\r\n\r\nexport interface ITabMenuProps {\r\n tabs: ITab[];\r\n selectedKey: string;\r\n tabClickHandler: (tabkey: string) => void;\r\n className?: string;\r\n}\r\n\r\nconst TabMenu: React.SFC<ITabMenuProps> = props => {\r\n return (\r\n <div className={classNames(\"tab-menu\", props.className)}>\r\n {props.tabs.map(tab => {\r\n const btnClassName = classNames(\"tab-menu__button\", {\r\n \"tab-menu__button--isSelected\": tab.key === props.selectedKey\r\n });\r\n\r\n return (\r\n <button\r\n className={btnClassName}\r\n key={tab.key}\r\n type=\"button\"\r\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\r\n e.preventDefault();\r\n props.tabClickHandler(tab.key);\r\n }}\r\n >\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n\r\nexport default TabMenu;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\ninterface ITabContentContainerProps {\r\n className?: string;\r\n}\r\n\r\nconst TabContentContainer: React.SFC<ITabContentContainerProps> = props => {\r\n const rootClasses = classNames(\"tab-content-container\", props.className);\r\n return <div className={rootClasses}>{props.children}</div>;\r\n};\r\n\r\nexport default TabContentContainer;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\ninterface ITabContentProps {\r\n isCurrent: boolean;\r\n className?: string;\r\n children: React.ReactNode;\r\n}\r\n\r\nconst TabContent: React.SFC<ITabContentProps> = props => {\r\n const rootClasses = classNames(\"tab-content\", props.className, {\r\n \"tab-content--isCurrent\": props.isCurrent\r\n });\r\n return <div className={rootClasses}>{props.children}</div>;\r\n};\r\n\r\nexport default TabContent;\r\n"],"sourceRoot":""}