Skip to content

Commit

Permalink
Merge pull request elastic#18 from CoenWarmer/storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
CoenWarmer authored Aug 1, 2023
2 parents b061579 + 6cf0b70 commit 2b75771
Show file tree
Hide file tree
Showing 27 changed files with 490 additions and 74 deletions.
6 changes: 3 additions & 3 deletions packages/kbn-storybook/src/lib/decorators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'core_styles';
import { BehaviorSubject } from 'rxjs';
import { CoreTheme } from '@kbn/core-theme-browser';
import { I18nStart } from '@kbn/core-i18n-browser';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';

const theme$ = new BehaviorSubject<CoreTheme>({ darkMode: false });

Expand All @@ -34,9 +34,9 @@ const KibanaContextDecorator: DecoratorFn = (storyFn, { globals }) => {
}, [colorMode]);

return (
<KibanaRenderContextProvider {...{ theme: { theme$ }, i18n }}>
<KibanaRootContextProvider {...{ theme: { theme$ }, i18n }}>
{storyFn()}
</KibanaRenderContextProvider>
</KibanaRootContextProvider>
);
};

Expand Down
102 changes: 56 additions & 46 deletions packages/kbn-storybook/templates/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,74 @@
We use this one instead because we want to add the @kbn/ui-shared-deps-* tags here.
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title><%= htmlWebpackPlugin.options.title || 'Storybook'%></title>

<% if (htmlWebpackPlugin.files.favicon) { %>
<head>
<meta charset="utf-8" />
<title>
<%= htmlWebpackPlugin.options.title || 'Storybook' %>
</title>

<% if (htmlWebpackPlugin.files.favicon) { %>
<link rel="shortcut icon" href="<%= htmlWebpackPlugin.files.favicon%>" />
<% } %>

<meta name="viewport" content="width=device-width, initial-scale=1" />

<meta name="eui-global" />
<meta name="emotion" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<!-- Added for Kibana shared dependencies -->
<script>
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps-npm': '', 'kbn-ui-shared-deps-src': '' };
</script>
<script src="kbn-ui-shared-deps-npm.dll.js"></script>
<script src="kbn-ui-shared-deps-src.js"></script>
<link href="kbn-ui-shared-deps-src.css" rel="stylesheet" />
<link id="eui-theme-css" href="kbn-ui-shared-deps-npm.v8.light.css" rel="stylesheet" />
<!-- -->
<meta name="eui-global" />
<meta name="eui-utilities" />
<meta name="emotion" />

<% if (typeof headHtmlSnippet !== 'undefined') { %> <%= headHtmlSnippet %> <% } %> <%
htmlWebpackPlugin.files.css.forEach(file => { %>
<link href="<%= file %>" rel="stylesheet" />
<% }); %>
<!-- Added for Kibana shared dependencies -->
<script>
window.__kbnPublicPath__ = { 'kbn-ui-shared-deps-npm': '', 'kbn-ui-shared-deps-src': '' };
</script>
<script src="kbn-ui-shared-deps-npm.dll.js"></script>
<script src="kbn-ui-shared-deps-src.js"></script>
<link href="kbn-ui-shared-deps-src.css" rel="stylesheet" />
<link id="eui-theme-css" href="kbn-ui-shared-deps-npm.v8.light.css" rel="stylesheet" />
<!-- -->

<style>
#root[hidden],
#docs-root[hidden] {
display: none !important;
}
</style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:slnt,wght@-10,300..700;0,300..700&family=Roboto+Mono:ital,wght@0,400..700;1,400..700&display=swap" rel="stylesheet">
</head>
<body>
<% if (typeof bodyHtmlSnippet !== 'undefined') { %>
<%= bodyHtmlSnippet %>
<% } %>
<% if (typeof headHtmlSnippet !=='undefined' ) { %>
<%= headHtmlSnippet %>
<% } %>
<% htmlWebpackPlugin.files.css.forEach(file=> { %>
<link href="<%= file %>" rel="stylesheet" />
<% }); %>

<div id="root"></div>
<div id="docs-root"></div>
<style>
#root[hidden],
#docs-root[hidden] {
display: none !important;
}
</style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:slnt,wght@-10,300..700;0,300..700&family=Roboto+Mono:ital,wght@0,400..700;1,400..700&display=swap"
rel="stylesheet">
</head>

<% if (typeof globals !== 'undefined' && Object.keys(globals).length) { %>
<script>
<body>
<% if (typeof bodyHtmlSnippet !=='undefined' ) { %>
<%= bodyHtmlSnippet %>
<% } %>

<div id="root"></div>
<div id="docs-root"></div>

<% if (typeof globals !=='undefined' && Object.keys(globals).length) { %>
<script>
<% for (var varName in globals) { %>
<% if (globals[varName] != undefined) { %>
window['<%=varName%>'] = <%= JSON.stringify(globals[varName]) %>;
window['<%=varName%>'] = <%= JSON.stringify(globals[varName]) %>;
<% } %>
<% } %>
</script>
<% } %>
</script>
<% } %>

<% htmlWebpackPlugin.files.js.forEach(file=> { %>
<script src="<%= file %>"></script>
<% }); %>
</body>

<% htmlWebpackPlugin.files.js.forEach(file => { %>
<script src="<%= file %>"></script>
<% }); %>
</body>
</html>
2 changes: 2 additions & 0 deletions packages/react/kibana_context/styled/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ Before `emotion` was introduced, some components used `styled-components` to eas

It should _not_ be used in new code.

**NOTE:** plugins cannot use `styled-components` and `emotion` at the same time, their Babel plugins conflict. The EUI team has fielded many questions about this. The best solution is to migrate to `emotion` and not use `styled-components`.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiButtonEmpty } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

export function HideExpandConversationListButton(
props: React.ComponentProps<typeof EuiButtonEmpty> & { isExpanded: boolean }
) {
return (
<EuiButtonEmpty iconType={props.isExpanded ? 'menuLeft' : 'menuRight'} size="xs" {...props}>
{props.isExpanded
? i18n.translate('xpack.observabilityAiAssistant.hideExpandConversationButton.hide', {
defaultMessage: 'Hide chats',
})
: i18n.translate('xpack.observabilityAiAssistant.hideExpandConversationButton.show', {
defaultMessage: 'Show chats',
})}
</EuiButtonEmpty>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { NewChatButton as Component } from './new_chat_button';

const meta: ComponentMeta<typeof Component> = {
component: Component,
title: 'app/Atoms/NewChatButton',
};

export default meta;

export const NewChatButton: ComponentStoryObj<typeof Component> = {
args: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

export function NewChatButton(props: React.ComponentProps<typeof EuiButton>) {
return (
<EuiButton {...props} fill iconType="discuss">
{i18n.translate('xpack.observabilityAiAssistant.newChatButton', {
defaultMessage: 'New chat',
})}
</EuiButton>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { RegenerateResponseButton as Component } from './regenerate_response_button';

const meta: ComponentMeta<typeof Component> = {
component: Component,
title: 'app/Atoms/RegenerateResponseButton',
};

export default meta;

export const RegenerateResponseButton: ComponentStoryObj<typeof Component> = {
args: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { StartChatButton as Component } from './start_chat_button';

const meta: ComponentMeta<typeof Component> = {
component: Component,
title: 'app/Atoms/StartChatButton',
};

export default meta;

export const StartChatButton: ComponentStoryObj<typeof Component> = {
args: {},
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
* 2.0.
*/

import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/css';
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
import React from 'react';
import { type ConversationCreateRequest } from '../../../common/types';
import type { UseChatResult } from '../../hooks/use_chat';
import type { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors';
import { useTimeline } from '../../hooks/use_timeline';
import { HideExpandConversationListButton } from '../buttons/hide_expand_conversation_list_button';
import { ChatHeader } from './chat_header';
import { ChatPromptEditor } from './chat_prompt_editor';
import { ChatTimeline } from './chat_timeline';
Expand All @@ -30,12 +31,18 @@ export function ChatBody({
connectors,
currentUser,
chat,
isConversationListExpanded,
onToggleExpandConversationList,
}: {
initialConversation?: ConversationCreateRequest;
connectors: UseGenAIConnectorsResult;
currentUser?: Pick<AuthenticatedUser, 'full_name' | 'username'>;
chat: UseChatResult;
isConversationListExpanded?: boolean;
onToggleExpandConversationList?: () => void;
}) {
const { euiTheme } = useEuiTheme();

const timeline = useTimeline({
initialConversation,
connectors,
Expand All @@ -46,15 +53,31 @@ export function ChatBody({
return (
<EuiFlexGroup direction="column" gutterSize="none" className={containerClassName}>
<EuiFlexItem grow={false}>
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="l">
<ChatHeader title="foo" connectors={connectors} />
<EuiPanel
hasShadow={false}
hasBorder={false}
borderRadius="none"
css={{ borderBottom: `solid 1px ${euiTheme.border.color}` }}
>
<HideExpandConversationListButton
isExpanded={Boolean(isConversationListExpanded)}
onClick={onToggleExpandConversationList}
/>
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="m">
<ChatHeader
title={initialConversation?.conversation.title ?? ''}
connectors={connectors}
/>
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHorizontalRule margin="none" />
</EuiFlexItem>
<EuiFlexItem grow className={timelineClassName}>
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="l">
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="m">
<ChatTimeline
items={timeline.items}
onEdit={timeline.onEdit}
Expand All @@ -68,7 +91,7 @@ export function ChatBody({
<EuiHorizontalRule margin="none" />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="l">
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="m">
<ChatPromptEditor
loading={chat.loading}
disabled={!connectors.selectedConnector}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { ComponentStory } from '@storybook/react';
import React from 'react';
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
import { ChatFlyout as Component } from './chat_flyout';

export default {
component: Component,
title: 'app/Organisms/ChatFlyout',
decorators: [KibanaReactStorybookDecorator],
};

type ChatFlyoutProps = React.ComponentProps<typeof Component>;

const Template: ComponentStory<typeof Component> = (props: ChatFlyoutProps) => {
return (
<div style={{ display: 'flex', minHeight: 800 }}>
<Component {...props} />
</div>
);
};

const defaultProps: ChatFlyoutProps = {
isOpen: true,
initialConversation: {
'@timestamp': '',
conversation: {
title: 'How is this working',
},
messages: [],
labels: {},
numeric_labels: {},
},
onClose: () => {},
};

export const ChatFlyout = Template.bind({});
ChatFlyout.args = defaultProps;
Loading

0 comments on commit 2b75771

Please sign in to comment.