mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
chore(storybook): upgrade storybook to 7.3 (#17078)
* feat(kea): typegen path cleanup and delete unused files * bump * 3.2.2 * typegen upgrade to 3.3.0 * storybook 7.3 * upgrade storybook to 7.3 * try using #storybook-root instead of #root * try using #storybook-root instead of #root (2) * try using #storybook-root instead of #root (3) * try using #storybook-root instead of #root (4) * switch out argTypes.defaultValue with args * Update UI snapshots for `chromium` (1) * Update UI snapshots for `chromium` (2) * Update UI snapshots for `chromium` (1) * Update UI snapshots for `chromium` (1) --------- Co-authored-by: Thomas Obermüller <thomas.obermueller@gmail.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,24 +1,20 @@
|
||||
import type { StorybookConfig } from '@storybook/react/types'
|
||||
import { createEntry } from '../webpack.config'
|
||||
import { StorybookConfig } from '@storybook/react-webpack5'
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../frontend/src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
||||
|
||||
addons: [
|
||||
{
|
||||
name: '@storybook/addon-docs',
|
||||
options: {
|
||||
sourceLoaderOptions: {
|
||||
injectStoryParameters: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
'@storybook/addon-docs',
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-storysource',
|
||||
'@storybook/addon-a11y',
|
||||
'storybook-addon-pseudo-states',
|
||||
],
|
||||
|
||||
staticDirs: ['public'],
|
||||
|
||||
webpackFinal: (config) => {
|
||||
const mainConfig = createEntry('main')
|
||||
return {
|
||||
@@ -32,23 +28,21 @@ const config: StorybookConfig = {
|
||||
...config.module,
|
||||
rules: [
|
||||
...mainConfig.module.rules,
|
||||
...config.module!.rules.filter((rule) => rule.test!.toString().includes('.mdx')),
|
||||
{
|
||||
test: /\.stories\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: { parser: 'typescript' },
|
||||
},
|
||||
],
|
||||
enforce: 'pre',
|
||||
},
|
||||
...(config.module?.rules?.filter(
|
||||
(rule: any) => 'test' in rule && rule.test.toString().includes('.mdx')
|
||||
) ?? []),
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
features: {
|
||||
postcss: false,
|
||||
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {},
|
||||
},
|
||||
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import '~/styles'
|
||||
import './storybook.scss'
|
||||
import type { Meta, Parameters } from '@storybook/react'
|
||||
import type { Meta, Parameters, Preview } from '@storybook/react'
|
||||
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks'
|
||||
import { worker } from '~/mocks/browser'
|
||||
import { loadPostHogJS } from '~/loadPostHogJS'
|
||||
import { getStorybookAppContext } from './app-context'
|
||||
@@ -75,3 +76,29 @@ export const decorators: Meta['decorators'] = [
|
||||
// Allow us to easily set feature flags in stories.
|
||||
withFeatureFlags,
|
||||
]
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
page: () => (
|
||||
<>
|
||||
<Title />
|
||||
<Subtitle />
|
||||
<Description />
|
||||
<Primary />
|
||||
<Controls />
|
||||
<Stories />
|
||||
</>
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default preview
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { toMatchImageSnapshot } from 'jest-image-snapshot'
|
||||
import { OptionsParameter } from '@storybook/addons'
|
||||
import { getStoryContext, TestRunnerConfig, TestContext } from '@storybook/test-runner'
|
||||
import type { Locator, Page, LocatorScreenshotOptions } from 'playwright-core'
|
||||
import type { Mocks } from '~/mocks/utils'
|
||||
import { StoryContext } from '@storybook/react'
|
||||
|
||||
type StoryContext = ReturnType<typeof getStoryContext> extends Promise<infer T> ? T : never
|
||||
// 'firefox' is technically supported too, but as of June 2023 it has memory usage issues that make is unusable
|
||||
type SupportedBrowserName = 'chromium' | 'webkit'
|
||||
|
||||
// Extend Storybook interface `Parameters` with Chromatic parameters
|
||||
declare module '@storybook/react' {
|
||||
interface Parameters {
|
||||
options?: OptionsParameter
|
||||
options?: any
|
||||
layout?: 'padded' | 'fullscreen' | 'centered'
|
||||
testOptions?: {
|
||||
/**
|
||||
@@ -146,10 +145,10 @@ async function expectStoryToMatchComponentSnapshot(
|
||||
page: Page,
|
||||
context: TestContext,
|
||||
browser: SupportedBrowserName,
|
||||
targetSelector: string = '#root'
|
||||
targetSelector: string = '#storybook-root'
|
||||
): Promise<void> {
|
||||
await page.evaluate(() => {
|
||||
const rootEl = document.getElementById('root')
|
||||
const rootEl = document.getElementById('storybook-root')
|
||||
if (!rootEl) {
|
||||
throw new Error('Could not find root element')
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
@@ -1,13 +1,15 @@
|
||||
import { useEffect } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { Exporter } from './Exporter'
|
||||
import { dashboard } from '~/exporter/__mocks__/Exporter.mocks'
|
||||
import { ExportType } from '~/exporter/types'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Exporter>
|
||||
const meta: Meta<typeof Exporter> = {
|
||||
title: 'Exporter/Exporter',
|
||||
component: Exporter,
|
||||
args: {
|
||||
type: 'embed',
|
||||
type: ExportType.Embed,
|
||||
whitelabel: false,
|
||||
noHeader: false,
|
||||
legend: false,
|
||||
@@ -19,9 +21,11 @@ export default {
|
||||
mockDate: '2023-02-01',
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as ComponentMeta<typeof Exporter>
|
||||
}
|
||||
|
||||
const Template: ComponentStory<typeof Exporter> = (props) => {
|
||||
export default meta
|
||||
|
||||
const Template: StoryFn<typeof Exporter> = (props) => {
|
||||
useEffect(() => {
|
||||
document.body.className = ''
|
||||
document.documentElement.className = `export-type-${props.type}`
|
||||
@@ -33,84 +37,84 @@ const Template: ComponentStory<typeof Exporter> = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const TrendsLineInsight = Template.bind({})
|
||||
export const TrendsLineInsight: Story = Template.bind({})
|
||||
TrendsLineInsight.args = { insight: require('../scenes/insights/__mocks__/trendsLine.json') }
|
||||
|
||||
export const TrendsLineBreakdownInsight = Template.bind({})
|
||||
export const TrendsLineBreakdownInsight: Story = Template.bind({})
|
||||
TrendsLineBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsLineBreakdown.json') }
|
||||
|
||||
export const TrendsBarInsight = Template.bind({})
|
||||
export const TrendsBarInsight: Story = Template.bind({})
|
||||
TrendsBarInsight.args = { insight: require('../scenes/insights/__mocks__/trendsBar.json') }
|
||||
|
||||
export const TrendsBarBreakdownInsight = Template.bind({})
|
||||
export const TrendsBarBreakdownInsight: Story = Template.bind({})
|
||||
TrendsBarBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsBarBreakdown.json') }
|
||||
|
||||
export const TrendsValueInsight = Template.bind({})
|
||||
export const TrendsValueInsight: Story = Template.bind({})
|
||||
TrendsValueInsight.args = { insight: require('../scenes/insights/__mocks__/trendsValue.json') }
|
||||
|
||||
export const TrendsValueBreakdownInsight = Template.bind({})
|
||||
export const TrendsValueBreakdownInsight: Story = Template.bind({})
|
||||
TrendsValueBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsValueBreakdown.json') }
|
||||
|
||||
export const TrendsAreaInsight = Template.bind({})
|
||||
export const TrendsAreaInsight: Story = Template.bind({})
|
||||
TrendsAreaInsight.args = { insight: require('../scenes/insights/__mocks__/trendsArea.json') }
|
||||
|
||||
export const TrendsAreaBreakdownInsight = Template.bind({})
|
||||
export const TrendsAreaBreakdownInsight: Story = Template.bind({})
|
||||
TrendsAreaBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsAreaBreakdown.json') }
|
||||
|
||||
export const TrendsNumberInsight = Template.bind({})
|
||||
export const TrendsNumberInsight: Story = Template.bind({})
|
||||
TrendsNumberInsight.args = { insight: require('../scenes/insights/__mocks__/trendsNumber.json') }
|
||||
|
||||
export const TrendsTableInsight = Template.bind({})
|
||||
export const TrendsTableInsight: Story = Template.bind({})
|
||||
TrendsTableInsight.args = { insight: require('../scenes/insights/__mocks__/trendsTable.json') }
|
||||
|
||||
export const TrendsTableBreakdownInsight = Template.bind({})
|
||||
export const TrendsTableBreakdownInsight: Story = Template.bind({})
|
||||
TrendsTableBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsTableBreakdown.json') }
|
||||
|
||||
export const TrendsPieInsight = Template.bind({})
|
||||
export const TrendsPieInsight: Story = Template.bind({})
|
||||
TrendsPieInsight.args = { insight: require('../scenes/insights/__mocks__/trendsPie.json') }
|
||||
|
||||
export const TrendsPieBreakdownInsight = Template.bind({})
|
||||
export const TrendsPieBreakdownInsight: Story = Template.bind({})
|
||||
TrendsPieBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/trendsPieBreakdown.json') }
|
||||
|
||||
export const TrendsWorldMapInsight = Template.bind({})
|
||||
export const TrendsWorldMapInsight: Story = Template.bind({})
|
||||
TrendsWorldMapInsight.args = { insight: require('../scenes/insights/__mocks__/trendsWorldMap.json') }
|
||||
|
||||
export const FunnelLeftToRightInsight = Template.bind({})
|
||||
export const FunnelLeftToRightInsight: Story = Template.bind({})
|
||||
FunnelLeftToRightInsight.args = { insight: require('../scenes/insights/__mocks__/funnelLeftToRight.json') }
|
||||
|
||||
export const FunnelLeftToRightBreakdownInsight = Template.bind({})
|
||||
export const FunnelLeftToRightBreakdownInsight: Story = Template.bind({})
|
||||
FunnelLeftToRightBreakdownInsight.args = {
|
||||
insight: require('../scenes/insights/__mocks__/funnelLeftToRightBreakdown.json'),
|
||||
}
|
||||
|
||||
export const FunnelTopToBottomInsight = Template.bind({})
|
||||
export const FunnelTopToBottomInsight: Story = Template.bind({})
|
||||
FunnelTopToBottomInsight.args = { insight: require('../scenes/insights/__mocks__/funnelTopToBottom.json') }
|
||||
|
||||
export const FunnelTopToBottomBreakdownInsight = Template.bind({})
|
||||
export const FunnelTopToBottomBreakdownInsight: Story = Template.bind({})
|
||||
FunnelTopToBottomBreakdownInsight.args = {
|
||||
insight: require('../scenes/insights/__mocks__/funnelTopToBottomBreakdown.json'),
|
||||
}
|
||||
|
||||
export const FunnelHistoricalTrendsInsight = Template.bind({})
|
||||
export const FunnelHistoricalTrendsInsight: Story = Template.bind({})
|
||||
FunnelHistoricalTrendsInsight.args = { insight: require('../scenes/insights/__mocks__/funnelHistoricalTrends.json') }
|
||||
|
||||
export const FunnelTimeToConvertInsight = Template.bind({})
|
||||
export const FunnelTimeToConvertInsight: Story = Template.bind({})
|
||||
FunnelTimeToConvertInsight.args = { insight: require('../scenes/insights/__mocks__/funnelTimeToConvert.json') }
|
||||
|
||||
export const RetentionInsight = Template.bind({})
|
||||
export const RetentionInsight: Story = Template.bind({})
|
||||
RetentionInsight.args = { insight: require('../scenes/insights/__mocks__/retention.json') }
|
||||
|
||||
export const RetentionBreakdownInsight = Template.bind({})
|
||||
export const RetentionBreakdownInsight: Story = Template.bind({})
|
||||
RetentionBreakdownInsight.args = { insight: require('../scenes/insights/__mocks__/retentionBreakdown.json') }
|
||||
|
||||
export const LifecycleInsight = Template.bind({})
|
||||
export const LifecycleInsight: Story = Template.bind({})
|
||||
LifecycleInsight.args = { insight: require('../scenes/insights/__mocks__/lifecycle.json') }
|
||||
|
||||
export const StickinessInsight = Template.bind({})
|
||||
export const StickinessInsight: Story = Template.bind({})
|
||||
StickinessInsight.args = { insight: require('../scenes/insights/__mocks__/stickiness.json') }
|
||||
|
||||
export const UserPathsInsight = Template.bind({})
|
||||
export const UserPathsInsight: Story = Template.bind({})
|
||||
UserPathsInsight.args = { insight: require('../scenes/insights/__mocks__/userPaths.json') }
|
||||
|
||||
export const Dashboard = Template.bind({})
|
||||
export const Dashboard: Story = Template.bind({})
|
||||
Dashboard.args = { dashboard }
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
import { Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { FeaturePreviewsModal as FeaturePreviewsModalComponent } from './FeaturePreviewsModal'
|
||||
import { useFeatureFlags, useStorybookMocks } from '~/mocks/browser'
|
||||
import { EarlyAccessFeature } from 'posthog-js'
|
||||
import { CONSTRAINED_PREVIEWS } from './featurePreviewsLogic'
|
||||
import { FeatureFlagKey } from 'lib/constants'
|
||||
|
||||
export default {
|
||||
interface StoryProps {
|
||||
earlyAccessFeatures: EarlyAccessFeature[]
|
||||
enabledFeatureFlags: string[]
|
||||
}
|
||||
|
||||
type Story = StoryObj<(props: StoryProps) => JSX.Element>
|
||||
const meta: Meta<(props: StoryProps) => JSX.Element> = {
|
||||
title: 'Layout/Feature Previews Modal',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
CONSTRAINED_PREVIEWS.add('constrained-test-1' as FeatureFlagKey)
|
||||
CONSTRAINED_PREVIEWS.add('constrained-test-2' as FeatureFlagKey)
|
||||
|
||||
const Template: StoryFn<{ earlyAccessFeatures: EarlyAccessFeature[]; enabledFeatureFlags: string[] }> = ({
|
||||
earlyAccessFeatures,
|
||||
enabledFeatureFlags,
|
||||
}) => {
|
||||
const Template: StoryFn<StoryProps> = ({ earlyAccessFeatures, enabledFeatureFlags }) => {
|
||||
useStorybookMocks({
|
||||
get: {
|
||||
'https://app.posthog.com/api/early_access_features/': { earlyAccessFeatures },
|
||||
@@ -35,7 +37,7 @@ const Template: StoryFn<{ earlyAccessFeatures: EarlyAccessFeature[]; enabledFeat
|
||||
)
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {
|
||||
earlyAccessFeatures: [
|
||||
{
|
||||
@@ -50,7 +52,7 @@ Basic.args = {
|
||||
enabledFeatureFlags: ['data-warehouse'],
|
||||
}
|
||||
|
||||
export const WithConstrainedFeature = Template.bind({})
|
||||
export const WithConstrainedFeature: Story = Template.bind({})
|
||||
WithConstrainedFeature.args = {
|
||||
earlyAccessFeatures: [
|
||||
{
|
||||
@@ -79,7 +81,7 @@ WithConstrainedFeature.args = {
|
||||
enabledFeatureFlags: ['constrained-test-1-preview', 'constrained-test-1', 'constrained-test-2'],
|
||||
}
|
||||
|
||||
export const Empty = Template.bind({})
|
||||
export const Empty: Story = Template.bind({})
|
||||
Empty.args = {
|
||||
earlyAccessFeatures: [],
|
||||
enabledFeatureFlags: [],
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useActions } from 'kea'
|
||||
import { themeLogic } from './themeLogic'
|
||||
import { with3000 } from 'storybook/decorators/with3000'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'PostHog 3000/Navigation',
|
||||
decorators: [
|
||||
mswDecorator({
|
||||
@@ -25,12 +25,11 @@ export default {
|
||||
],
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
mockDate: '2023-02-01',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export function LightMode(): JSX.Element {
|
||||
const { overrideTheme } = useActions(themeLogic)
|
||||
useEffect(() => {
|
||||
|
||||
@@ -12,31 +12,32 @@ export interface NavbarButtonProps {
|
||||
active?: boolean
|
||||
}
|
||||
|
||||
export const NavbarButton: FunctionComponent<NavbarButtonProps> = React.forwardRef<HTMLElement, NavbarButtonProps>(
|
||||
({ identifier, title, onClick, persistentTooltip, ...buttonProps }, ref): JSX.Element => {
|
||||
const [hasBeenClicked, setHasBeenClicked] = useState(false)
|
||||
export const NavbarButton: FunctionComponent<NavbarButtonProps> = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
NavbarButtonProps
|
||||
>(({ identifier, title, onClick, persistentTooltip, ...buttonProps }, ref): JSX.Element => {
|
||||
const [hasBeenClicked, setHasBeenClicked] = useState(false)
|
||||
|
||||
return (
|
||||
<li>
|
||||
<Tooltip
|
||||
title={title}
|
||||
placement="right"
|
||||
delayMs={0}
|
||||
visible={!persistentTooltip && hasBeenClicked ? false : undefined} // Force-hide tooltip after button click
|
||||
>
|
||||
<LemonButton
|
||||
ref={ref}
|
||||
data-attr={`menu-item-${identifier.toString().toLowerCase()}`}
|
||||
onMouseEnter={() => setHasBeenClicked(false)}
|
||||
onClick={() => {
|
||||
setHasBeenClicked(true)
|
||||
onClick?.()
|
||||
}}
|
||||
{...buttonProps}
|
||||
/>
|
||||
</Tooltip>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
)
|
||||
return (
|
||||
<li>
|
||||
<Tooltip
|
||||
title={title}
|
||||
placement="right"
|
||||
delayMs={0}
|
||||
visible={!persistentTooltip && hasBeenClicked ? false : undefined} // Force-hide tooltip after button click
|
||||
>
|
||||
<LemonButton
|
||||
ref={ref}
|
||||
data-attr={`menu-item-${identifier.toString().toLowerCase()}`}
|
||||
onMouseEnter={() => setHasBeenClicked(false)}
|
||||
onClick={() => {
|
||||
setHasBeenClicked(true)
|
||||
onClick?.()
|
||||
}}
|
||||
{...buttonProps}
|
||||
/>
|
||||
</Tooltip>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
NavbarButton.displayName = 'NavbarButton'
|
||||
|
||||
@@ -10,17 +10,16 @@ import dashboardsJson from '../../../scenes/dashboard/__mocks__/dashboards.json'
|
||||
import { with3000 } from 'storybook/decorators/with3000'
|
||||
import { SidebarNavbarItem } from '../types'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'PostHog 3000/Sidebar',
|
||||
parameters: {
|
||||
mockDate: '2023-02-01',
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
decorators: [with3000],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
/** featureFlagsJson * 6 to fill the sidebar up more. */
|
||||
const multipliedFeatureFlagsJson = {
|
||||
...featureFlagsJson,
|
||||
|
||||
@@ -7,15 +7,14 @@ import { useActions } from 'kea'
|
||||
import { navigationLogic } from './navigationLogic'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Layout/Navigation',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
function BaseAppPage(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -4,11 +4,11 @@ import {
|
||||
personActivityResponseJson,
|
||||
} from 'lib/components/ActivityLog/__mocks__/activityLogMocks'
|
||||
import { mswDecorator } from '~/mocks/browser'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { ActivityLog } from 'lib/components/ActivityLog/ActivityLog'
|
||||
import { ActivityScope } from 'lib/components/ActivityLog/humanizeActivity'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof ActivityLog> = {
|
||||
title: 'Components/ActivityLog',
|
||||
component: ActivityLog,
|
||||
parameters: { testOptions: { skip: true } }, // FIXME: Currently disabled as the Timeout story is flaky
|
||||
@@ -39,7 +39,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as ComponentMeta<typeof ActivityLog>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function FeatureFlagActivity(): JSX.Element {
|
||||
return <ActivityLog scope={ActivityScope.FEATURE_FLAG} id={7} />
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { SentenceList, SentenceListProps } from './SentenceList'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof SentenceList>
|
||||
const meta: Meta<typeof SentenceList> = {
|
||||
title: 'Components/SentenceList',
|
||||
component: SentenceList,
|
||||
parameters: {},
|
||||
} as ComponentMeta<typeof SentenceList>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof SentenceList> = (props: SentenceListProps) => {
|
||||
const Template: StoryFn<typeof SentenceList> = (props: SentenceListProps) => {
|
||||
return <SentenceList {...props} />
|
||||
}
|
||||
|
||||
export const FullSentence = Template.bind({})
|
||||
export const FullSentence: Story = Template.bind({})
|
||||
FullSentence.args = {
|
||||
prefix: 'Bob',
|
||||
suffix: 'on feature flag cool-flag',
|
||||
@@ -22,13 +24,13 @@ FullSentence.args = {
|
||||
],
|
||||
}
|
||||
|
||||
export const OneAction = Template.bind({})
|
||||
export const OneAction: Story = Template.bind({})
|
||||
OneAction.args = { listParts: ['changed description to "something cool"'] }
|
||||
|
||||
export const TwoActions = Template.bind({})
|
||||
export const TwoActions: Story = Template.bind({})
|
||||
TwoActions.args = { listParts: ['changed description to "something cool"', 'changed name to "woop"'] }
|
||||
|
||||
export const ThreeActions = Template.bind({})
|
||||
export const ThreeActions: Story = Template.bind({})
|
||||
ThreeActions.args = {
|
||||
listParts: [
|
||||
'changed description to "something cool"',
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { AnimationType } from 'lib/animations/animations'
|
||||
import { ComponentStory, Meta } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
import { Animation } from 'lib/components/Animation/Animation'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Animation>
|
||||
const meta: Meta<typeof Animation> = {
|
||||
title: 'Layout/Animations',
|
||||
parameters: {
|
||||
docs: {
|
||||
@@ -24,11 +25,13 @@ export default {
|
||||
control: { type: 'radio' },
|
||||
},
|
||||
},
|
||||
} as Meta<Animation>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof Animation> = ({ size, type }): JSX.Element => {
|
||||
const Template: StoryFn<typeof Animation> = ({ size, type }): JSX.Element => {
|
||||
return <Animation type={type} size={size} />
|
||||
}
|
||||
|
||||
export const Animations = Template.bind({})
|
||||
export const Animations: Story = Template.bind({})
|
||||
Animations.args = { size: 'large' }
|
||||
|
||||
@@ -31,7 +31,7 @@ const examples = [
|
||||
EXAMPLE_DATA_TABLE_NODE_EVENTS_QUERY,
|
||||
] as unknown as InsightModel[]
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Components/Cards/Insight Card',
|
||||
component: InsightCardComponent,
|
||||
parameters: {
|
||||
@@ -41,11 +41,9 @@ export default {
|
||||
argTypes: {
|
||||
insightName: {
|
||||
control: { type: 'text' },
|
||||
defaultValue: 'Insight title (edit in story controls)',
|
||||
},
|
||||
insightDescription: {
|
||||
control: { type: 'text' },
|
||||
defaultValue: 'Insight description (edit in story controls)',
|
||||
},
|
||||
loading: {
|
||||
control: { type: 'boolean' },
|
||||
@@ -60,8 +58,8 @@ export default {
|
||||
control: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const InsightCard: Story = (args) => {
|
||||
const [insightColor, setInsightColor] = useState<InsightColor | null>(null)
|
||||
const [wasItemRemoved, setWasItemRemoved] = useState(false)
|
||||
|
||||
@@ -2,12 +2,12 @@ import { Meta, Story } from '@storybook/react'
|
||||
import { DashboardTile, InsightColor } from '~/types'
|
||||
import { TextCard } from './TextCard'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Components/Cards/Text Card',
|
||||
component: TextCard,
|
||||
parameters: {},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
const makeTextTile = (body: string, color: InsightColor | null = null): DashboardTile => {
|
||||
return {
|
||||
id: 1,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
import { CompactList } from './CompactList'
|
||||
import { urls } from 'scenes/urls'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { PersonDisplay } from 'scenes/persons/PersonDisplay'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof CompactList> = {
|
||||
title: 'Components/Compact List',
|
||||
component: CompactList,
|
||||
argTypes: {
|
||||
@@ -15,7 +15,8 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof CompactList>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function CompactList_({ loading }: { loading: boolean }): JSX.Element {
|
||||
return (
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
import { EditableField as EditableFieldComponent } from './EditableField'
|
||||
import { PageHeader } from '../PageHeader'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof EditableFieldComponent> = {
|
||||
title: 'Components/Editable Field',
|
||||
component: EditableFieldComponent,
|
||||
} as ComponentMeta<typeof EditableFieldComponent>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function EditableField_(): JSX.Element {
|
||||
const [savedTitle, setSavedTitle] = useState('Foo')
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
import { EmptyMessage } from './EmptyMessage'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof EmptyMessage> = {
|
||||
title: 'Components/Empty Message',
|
||||
component: EmptyMessage,
|
||||
} as ComponentMeta<typeof EmptyMessage>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function EmptyMessage_(): JSX.Element {
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { ErrorDisplay } from 'lib/components/Errors/ErrorDisplay'
|
||||
import { EventType, RecordingEventType } from '~/types'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof ErrorDisplay> = {
|
||||
title: 'Components/Errors/Error Display',
|
||||
component: ErrorDisplay,
|
||||
} as ComponentMeta<typeof ErrorDisplay>
|
||||
}
|
||||
export default meta
|
||||
|
||||
function errorEvent(properties: Record<string, any>): EventType | RecordingEventType {
|
||||
return {
|
||||
|
||||
@@ -21,7 +21,7 @@ const eventDefinitions = [
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Filters',
|
||||
decorators: [
|
||||
mswDecorator({
|
||||
@@ -37,8 +37,8 @@ export default {
|
||||
}),
|
||||
],
|
||||
parameters: {},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export function EventSelect_(): JSX.Element {
|
||||
const [selectedEvents, setSelectedEvents] = useState<string[]>([])
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { ElementType } from '~/types'
|
||||
import { HTMLElementsDisplay } from './HTMLElementsDisplay'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof HTMLElementsDisplay> = {
|
||||
title: 'Components/Html Elements Display',
|
||||
component: HTMLElementsDisplay,
|
||||
} as ComponentMeta<typeof HTMLElementsDisplay>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function EmptyDisplay(): JSX.Element {
|
||||
return <HTMLElementsDisplay elements={[] as ElementType[]} />
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn } from '@storybook/react'
|
||||
import { HedgehogBuddy } from './HedgehogBuddy'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof HedgehogBuddy> = {
|
||||
title: 'Components/Hedgehog Buddy',
|
||||
component: HedgehogBuddy,
|
||||
parameters: {
|
||||
testOptions: { skip: true }, // Hedgehogs aren't particularly snapshotable
|
||||
},
|
||||
} as ComponentMeta<typeof HedgehogBuddy>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const TheHedgehog: ComponentStory<typeof HedgehogBuddy> = () => {
|
||||
export const TheHedgehog: StoryFn<typeof HedgehogBuddy> = () => {
|
||||
return (
|
||||
// eslint-disable-next-line react/forbid-dom-props
|
||||
<div style={{ height: 200 }}>
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import { ComponentStory, Meta } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
import { HogQLEditor } from './HogQLEditor'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof HogQLEditor>
|
||||
const meta: Meta<typeof HogQLEditor> = {
|
||||
title: 'Components/HogQLEditor',
|
||||
component: HogQLEditor,
|
||||
} as Meta<typeof HogQLEditor>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof HogQLEditor> = (props): JSX.Element => {
|
||||
const Template: StoryFn<typeof HogQLEditor> = (props): JSX.Element => {
|
||||
const [value, onChange] = useState(props.value ?? "countIf(properties.$browser = 'Chrome')")
|
||||
return <HogQLEditor {...props} value={value} onChange={onChange} />
|
||||
}
|
||||
|
||||
export const HogQLEditor_ = Template.bind({})
|
||||
export const HogQLEditor_: Story = Template.bind({})
|
||||
HogQLEditor_.args = {}
|
||||
|
||||
export const NoValue = Template.bind({})
|
||||
export const NoValue: Story = Template.bind({})
|
||||
NoValue.args = {
|
||||
value: '',
|
||||
disableAutoFocus: true,
|
||||
}
|
||||
|
||||
export const NoValuePersonPropertiesDisabled = Template.bind({})
|
||||
export const NoValuePersonPropertiesDisabled: Story = Template.bind({})
|
||||
NoValuePersonPropertiesDisabled.args = {
|
||||
disablePersonProperties: true,
|
||||
value: '',
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { NotFound } from './index'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof NotFound>
|
||||
const meta: Meta<typeof NotFound> = {
|
||||
title: 'Components/Not Found',
|
||||
component: NotFound,
|
||||
} as ComponentMeta<typeof NotFound>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof NotFound> = (args) => <NotFound {...args} />
|
||||
const Template: StoryFn<typeof NotFound> = (args) => <NotFound {...args} />
|
||||
|
||||
export const NotFound_ = Template.bind({})
|
||||
export const NotFound_: Story = Template.bind({})
|
||||
NotFound_.args = {
|
||||
object: 'Person',
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
import { ObjectTags, ObjectTagsProps } from './ObjectTags'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof ObjectTags>
|
||||
const meta: Meta<typeof ObjectTags> = {
|
||||
title: 'Lemon UI/Object Tags',
|
||||
component: ObjectTags,
|
||||
} as ComponentMeta<typeof ObjectTags>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof ObjectTags> = (props: Partial<ObjectTagsProps>) => {
|
||||
const BasicTemplate: StoryFn<typeof ObjectTags> = (props: Partial<ObjectTagsProps>) => {
|
||||
return <ObjectTags tags={['one', 'two', 'three']} {...props} />
|
||||
}
|
||||
|
||||
export const Default = BasicTemplate.bind({})
|
||||
export const Default: Story = BasicTemplate.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const StaticOnly = BasicTemplate.bind({})
|
||||
export const StaticOnly: Story = BasicTemplate.bind({})
|
||||
StaticOnly.args = { staticOnly: true }
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { PathCleaningFilter } from '~/types'
|
||||
|
||||
import { PathCleanFilters, PathCleanFiltersProps } from './PathCleanFilters'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof PathCleanFilters>
|
||||
const meta: Meta<typeof PathCleanFilters> = {
|
||||
title: 'Filters/PathCleanFilters',
|
||||
component: PathCleanFilters,
|
||||
} as ComponentMeta<typeof PathCleanFilters>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof PathCleanFilters> = (props: Partial<PathCleanFiltersProps>) => {
|
||||
const Template: StoryFn<typeof PathCleanFilters> = (props: Partial<PathCleanFiltersProps>) => {
|
||||
const [filters, setFilters] = useState<PathCleaningFilter[]>([
|
||||
{ alias: 'insights', regex: '/insights/w+/dashboard$' },
|
||||
{ regex: '/feature_flags/d+$' },
|
||||
@@ -18,5 +20,5 @@ const Template: ComponentStory<typeof PathCleanFilters> = (props: Partial<PathCl
|
||||
return <PathCleanFilters filters={filters} setFilters={setFilters} {...props} />
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
Default.args = {}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { mswDecorator } from '~/mocks/browser'
|
||||
import { PersonPropertySelect, PersonPropertySelectProps } from './PersonPropertySelect'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof PersonPropertySelect>
|
||||
const meta: Meta<typeof PersonPropertySelect> = {
|
||||
title: 'Filters/Person Property Select',
|
||||
component: PersonPropertySelect,
|
||||
decorators: [
|
||||
@@ -25,9 +26,10 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as ComponentMeta<typeof PersonPropertySelect>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof PersonPropertySelect> = (props: Partial<PersonPropertySelectProps>) => {
|
||||
const Template: StoryFn<typeof PersonPropertySelect> = (props: Partial<PersonPropertySelectProps>) => {
|
||||
const [selectedProperties, setSelectProperties] = useState<string[]>([
|
||||
'$initial_geoip_postal_code',
|
||||
'$initial_geoip_latitude',
|
||||
@@ -59,10 +61,10 @@ const Template: ComponentStory<typeof PersonPropertySelect> = (props: Partial<Pe
|
||||
)
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const Sortable = Template.bind({})
|
||||
export const Sortable: Story = Template.bind({})
|
||||
Sortable.args = {
|
||||
sortable: true,
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { ProductIntroduction } from './ProductIntroduction'
|
||||
import { ProductKey } from '~/types'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof ProductIntroduction> = {
|
||||
title: 'Components/Product Empty State',
|
||||
component: ProductIntroduction,
|
||||
} as ComponentMeta<typeof ProductIntroduction>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function ProductIntroduction_(): JSX.Element {
|
||||
return (
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { MOCK_TEAM_ID } from 'lib/api.mock'
|
||||
import { useStorybookMocks } from '~/mocks/browser'
|
||||
import { ChartDisplayType, PersonActorType } from '~/types'
|
||||
import { PropertiesTimeline } from '.'
|
||||
import { RawPropertiesTimelineResult } from './propertiesTimelineLogic'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof PropertiesTimeline> = {
|
||||
title: 'Components/Properties Timeline',
|
||||
component: PropertiesTimeline,
|
||||
} as ComponentMeta<typeof PropertiesTimeline>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const EXAMPLE_PERSON: Omit<PersonActorType, 'id' | 'uuid'> = {
|
||||
type: 'person',
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { PropertyFilters } from 'lib/components/PropertyFilters/PropertyFilters'
|
||||
import { AnyPropertyFilter, PropertyOperator } from '~/types'
|
||||
import PropertyFiltersDisplay from 'lib/components/PropertyFilters/components/PropertyFiltersDisplay'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof PropertyFilters> = {
|
||||
title: 'Filters/PropertyFilters',
|
||||
component: PropertyFilters,
|
||||
} as ComponentMeta<typeof PropertyFilters>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const propertyFilters = [
|
||||
{
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import {
|
||||
OperatorValueSelect,
|
||||
OperatorValueSelectProps,
|
||||
} from 'lib/components/PropertyFilters/components/OperatorValueSelect'
|
||||
import { PropertyDefinition, PropertyType } from '~/types'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof OperatorValueSelect> = {
|
||||
title: 'Filters/PropertyFilters/OperatorValueSelect',
|
||||
Component: OperatorValueSelect,
|
||||
} as ComponentMeta<typeof OperatorValueSelect>
|
||||
component: OperatorValueSelect,
|
||||
}
|
||||
export default meta
|
||||
|
||||
const makePropertyDefinition = (name: string, propertyType: PropertyType | undefined): PropertyDefinition => ({
|
||||
id: name,
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { FilterLogicalOperator, FilterType, AnyPropertyFilter, PropertyGroupFilter, PropertyOperator } from '~/types'
|
||||
import { useMountedLogic } from 'kea'
|
||||
import { PropertyGroupFilters } from './PropertyGroupFilters'
|
||||
import { TaxonomicFilterGroupType } from '../TaxonomicFilter/types'
|
||||
import { cohortsModel } from '~/models/cohortsModel'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof PropertyGroupFilters> = {
|
||||
title: 'Filters/PropertyGroupFilters',
|
||||
component: PropertyGroupFilters,
|
||||
} as ComponentMeta<typeof PropertyGroupFilters>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const propertyFilters = [
|
||||
{
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { PROPERTIES_ICON_MAP, PropertyIcon } from 'lib/components/PropertyIcon'
|
||||
import { LemonTable } from 'lib/lemon-ui/LemonTable'
|
||||
import { countryCodeToName } from 'scenes/insights/views/WorldMap'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof PropertyIcon>
|
||||
const meta: Meta<typeof PropertyIcon> = {
|
||||
title: 'Lemon UI/Icons/Property Icon',
|
||||
component: PropertyIcon,
|
||||
parameters: {
|
||||
testOptions: { skip: true }, // There are too many icons, the snapshots are huge in table form
|
||||
},
|
||||
} as ComponentMeta<typeof PropertyIcon>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof PropertyIcon> = (args) => {
|
||||
const Template: StoryFn<typeof PropertyIcon> = (args) => {
|
||||
if (args.value) {
|
||||
return <PropertyIcon {...args} />
|
||||
}
|
||||
@@ -52,28 +55,28 @@ const Template: ComponentStory<typeof PropertyIcon> = (args) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Default_ = Template.bind({})
|
||||
export const Default_: Story = Template.bind({})
|
||||
Default_.args = {
|
||||
property: '$browser',
|
||||
value: 'Chrome',
|
||||
}
|
||||
|
||||
export const Browser_ = Template.bind({})
|
||||
export const Browser_: Story = Template.bind({})
|
||||
Browser_.args = {
|
||||
property: '$browser',
|
||||
}
|
||||
|
||||
export const DeviceType_ = Template.bind({})
|
||||
export const DeviceType_: Story = Template.bind({})
|
||||
DeviceType_.args = {
|
||||
property: '$device_type',
|
||||
}
|
||||
|
||||
export const OS_ = Template.bind({})
|
||||
export const OS_: Story = Template.bind({})
|
||||
OS_.args = {
|
||||
property: '$os',
|
||||
}
|
||||
|
||||
export const Country_ = Template.bind({})
|
||||
export const Country_: Story = Template.bind({})
|
||||
Country_.args = {
|
||||
property: '$geoip_country_code',
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { PropertyKeyInfo } from './PropertyKeyInfo'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof PropertyKeyInfo>
|
||||
const meta: Meta<typeof PropertyKeyInfo> = {
|
||||
title: 'Components/Property Key Info',
|
||||
component: PropertyKeyInfo,
|
||||
} as ComponentMeta<typeof PropertyKeyInfo>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof PropertyKeyInfo> = (args) => {
|
||||
const Template: StoryFn<typeof PropertyKeyInfo> = (args) => {
|
||||
return args.value ? (
|
||||
<PropertyKeyInfo {...args} />
|
||||
) : (
|
||||
@@ -28,7 +30,7 @@ const Template: ComponentStory<typeof PropertyKeyInfo> = (args) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const PropertyKeyInfo_ = Template.bind({})
|
||||
export const PropertyKeyInfo_: Story = Template.bind({})
|
||||
PropertyKeyInfo_.args = {
|
||||
value: undefined,
|
||||
type: 'event',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { SharingModal, SharingModalProps } from './SharingModal'
|
||||
import { AvailableFeature, InsightModel, InsightShortId, InsightType } from '~/types'
|
||||
import { useStorybookMocks } from '~/mocks/browser'
|
||||
@@ -12,15 +12,15 @@ const fakeInsight: Partial<InsightModel> = {
|
||||
filters: { insight: InsightType.TRENDS },
|
||||
}
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof SharingModal> = {
|
||||
title: 'Components/Sharing',
|
||||
component: SharingModal,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as ComponentMeta<typeof SharingModal>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template = (args: Partial<SharingModalProps> & { licensed?: boolean }): JSX.Element => {
|
||||
const { licensed = false, ...props } = args
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useRef, useState } from 'react'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { SubscriptionsModal, SubscriptionsModalProps } from './SubscriptionsModal'
|
||||
import { AvailableFeature, InsightShortId, Realm } from '~/types'
|
||||
import preflightJson from '~/mocks/fixtures/_preflight.json'
|
||||
@@ -9,16 +9,16 @@ import { useStorybookMocks } from '~/mocks/browser'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { createMockSubscription, mockIntegration, mockSlackChannels } from '~/test/mocks'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof SubscriptionsModal> = {
|
||||
title: 'Components/Subscriptions',
|
||||
component: SubscriptionsModal,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
mockDate: '2023-01-31 12:00:00',
|
||||
},
|
||||
} as ComponentMeta<typeof SubscriptionsModal>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template = (
|
||||
args: Partial<SubscriptionsModalProps> & { noIntegrations?: boolean; featureAvailable?: boolean }
|
||||
|
||||
@@ -5,20 +5,21 @@ import { useActions, useMountedLogic } from 'kea'
|
||||
import { actionsModel } from '~/models/actionsModel'
|
||||
import { useEffect } from 'react'
|
||||
import { infiniteListLogic } from './infiniteListLogic'
|
||||
import { ComponentMeta, ComponentStoryFn } from '@storybook/react'
|
||||
import { Meta, StoryFn } from '@storybook/react'
|
||||
import { useAvailableFeatures } from '~/mocks/features'
|
||||
import { AvailableFeature } from '~/types'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof TaxonomicFilter> = {
|
||||
title: 'Filters/Taxonomic Filter',
|
||||
component: TaxonomicFilter,
|
||||
decorators: [taxonomicFilterMocksDecorator],
|
||||
parameters: {
|
||||
testOptions: { waitForLoadersToDisappear: '.definition-popover' },
|
||||
},
|
||||
} as ComponentMeta<typeof TaxonomicFilter>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const EventsFree: ComponentStoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
export const EventsFree: StoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
useMountedLogic(actionsModel)
|
||||
const { setIndex } = useActions(
|
||||
infiniteListLogic({
|
||||
@@ -43,7 +44,7 @@ EventsFree.args = {
|
||||
taxonomicGroupTypes: [TaxonomicFilterGroupType.Events, TaxonomicFilterGroupType.Actions],
|
||||
}
|
||||
|
||||
export const EventsPremium: ComponentStoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
export const EventsPremium: StoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
useAvailableFeatures([AvailableFeature.INGESTION_TAXONOMY])
|
||||
return <EventsFree {...args} />
|
||||
}
|
||||
@@ -52,7 +53,7 @@ EventsPremium.args = {
|
||||
taxonomicGroupTypes: [TaxonomicFilterGroupType.Events, TaxonomicFilterGroupType.Actions],
|
||||
}
|
||||
|
||||
export const Actions: ComponentStoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
export const Actions: StoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
useMountedLogic(actionsModel)
|
||||
const { setIndex } = useActions(
|
||||
infiniteListLogic({
|
||||
@@ -77,7 +78,7 @@ Actions.args = {
|
||||
taxonomicGroupTypes: [TaxonomicFilterGroupType.Actions],
|
||||
}
|
||||
|
||||
export const Properties: ComponentStoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
export const Properties: StoryFn<typeof TaxonomicFilter> = (args) => {
|
||||
return (
|
||||
<div className="w-fit border rounded p-2 bg-bg-light">
|
||||
<TaxonomicFilter {...args} />
|
||||
|
||||
@@ -5,13 +5,14 @@ import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
|
||||
import { PropertyKeyInfo } from 'lib/components/PropertyKeyInfo'
|
||||
import { useMountedLogic } from 'kea'
|
||||
import { taxonomicFilterMocksDecorator } from 'lib/components/TaxonomicFilter/__mocks__/taxonomicFilterMocksDecorator'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof TaxonomicPopover> = {
|
||||
title: 'Filters/TaxonomicPopover',
|
||||
component: TaxonomicPopover,
|
||||
decorators: [taxonomicFilterMocksDecorator],
|
||||
} as ComponentMeta<typeof TaxonomicPopover>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function TaxonomicStringPopoverOneCategory(): JSX.Element {
|
||||
useMountedLogic(cohortsModel)
|
||||
|
||||
@@ -12,10 +12,9 @@ const allHedgehogs: HedgehogDefinition[] = Object.entries(hedgehogs).map(([key,
|
||||
hedgehog: Hedgehog,
|
||||
}))
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Lemon UI/Hog illustrations',
|
||||
parameters: {
|
||||
options: { showPanel: false },
|
||||
testOptions: { skip: true }, // Not valuable to take snapshots of these hedgehogs
|
||||
docs: {
|
||||
description: {
|
||||
@@ -38,8 +37,9 @@ she will get to it dependant on work load.
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
export function Library(): JSX.Element {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { Field, PureField } from './Field'
|
||||
import { LemonButton, LemonCheckbox, LemonInput, LemonSelect, LemonTextArea } from '@posthog/lemon-ui'
|
||||
import { kea, path, useAllValues } from 'kea'
|
||||
@@ -6,7 +6,7 @@ import { Form, forms } from 'kea-forms'
|
||||
|
||||
import type { formLogicType } from './Field.storiesType'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof PureField> = {
|
||||
title: 'Lemon UI/Forms and Fields',
|
||||
component: PureField,
|
||||
parameters: {
|
||||
@@ -23,7 +23,9 @@ They can be used in a kea-forms controlled way via \`Field\` or a pure way via \
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof PureField>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const _PureFields = (): JSX.Element => {
|
||||
return (
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonBadge } from './LemonBadge'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { IconPlusMini } from 'lib/lemon-ui/icons'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonBadge>
|
||||
const meta: Meta<typeof LemonBadge> = {
|
||||
title: 'Lemon UI/Lemon Badge/Lemon Badge',
|
||||
component: LemonBadge,
|
||||
} as ComponentMeta<typeof LemonBadge>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonBadge> = (props) => (
|
||||
const Template: StoryFn<typeof LemonBadge> = (props) => (
|
||||
<div className="flex">
|
||||
<LemonBadge {...props} />
|
||||
</div>
|
||||
)
|
||||
|
||||
export const Standard = Template.bind({})
|
||||
export const Standard: Story = Template.bind({})
|
||||
Standard.args = { content: '@' }
|
||||
|
||||
export const Positioning: ComponentStory<typeof LemonBadge> = () => {
|
||||
export const Positioning: StoryFn<typeof LemonBadge> = () => {
|
||||
return (
|
||||
<div className="space-y-4 m-2">
|
||||
<LemonButton type="secondary">
|
||||
@@ -43,7 +46,7 @@ export const Positioning: ComponentStory<typeof LemonBadge> = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Sizes: ComponentStory<typeof LemonBadge> = () => {
|
||||
export const Sizes: StoryFn<typeof LemonBadge> = () => {
|
||||
return (
|
||||
<div className="flex space-x-2 items-center">
|
||||
<span>small:</span>
|
||||
@@ -56,7 +59,7 @@ export const Sizes: ComponentStory<typeof LemonBadge> = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Status: ComponentStory<typeof LemonBadge> = () => {
|
||||
export const Status: StoryFn<typeof LemonBadge> = () => {
|
||||
return (
|
||||
<div className="flex space-x-2 items-center">
|
||||
<span>primary:</span>
|
||||
@@ -69,7 +72,7 @@ export const Status: ComponentStory<typeof LemonBadge> = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Active: ComponentStory<typeof LemonBadge> = () => {
|
||||
export const Active: StoryFn<typeof LemonBadge> = () => {
|
||||
return (
|
||||
<div className="flex space-x-2 items-center my-1 mr-1">
|
||||
<span>inactive:</span>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonBadge, LemonBadgeNumberProps } from './LemonBadge'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonBadge.Number>
|
||||
const meta: Meta<typeof LemonBadge.Number> = {
|
||||
title: 'Lemon UI/Lemon Badge/Lemon Badge Number',
|
||||
component: LemonBadge.Number,
|
||||
} as ComponentMeta<typeof LemonBadge.Number>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonBadge.Number> = ({ count, ...props }: LemonBadgeNumberProps) => {
|
||||
const Template: StoryFn<typeof LemonBadge.Number> = ({ count, ...props }: LemonBadgeNumberProps) => {
|
||||
const [countOverride, setCount] = useState(count)
|
||||
|
||||
return (
|
||||
@@ -30,11 +33,11 @@ const Template: ComponentStory<typeof LemonBadge.Number> = ({ count, ...props }:
|
||||
)
|
||||
}
|
||||
|
||||
export const Standard = Template.bind({})
|
||||
export const Standard: Story = Template.bind({})
|
||||
Standard.args = { count: 1 }
|
||||
|
||||
export const MultipleDigits = Template.bind({})
|
||||
export const MultipleDigits: Story = Template.bind({})
|
||||
MultipleDigits.args = { count: 975, maxDigits: 3 }
|
||||
|
||||
export const ShowZero = Template.bind({})
|
||||
export const ShowZero: Story = Template.bind({})
|
||||
ShowZero.args = { count: 0, showZero: true }
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonBanner, LemonBannerProps } from './LemonBanner'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonBanner>
|
||||
const meta: Meta<typeof LemonBanner> = {
|
||||
title: 'Lemon UI/Lemon Banner',
|
||||
component: LemonBanner,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
actions: {
|
||||
// See https://github.com/storybookjs/addon-smart-knobs/issues/63#issuecomment-995798227
|
||||
argTypesRegex: null,
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonBanner>
|
||||
|
||||
const Template: ComponentStory<typeof LemonBanner> = (props: LemonBannerProps) => {
|
||||
}
|
||||
export default meta
|
||||
const Template: StoryFn<typeof LemonBanner> = (props: LemonBannerProps) => {
|
||||
return <LemonBanner {...props} />
|
||||
}
|
||||
|
||||
export const Info = Template.bind({})
|
||||
export const Info: Story = Template.bind({})
|
||||
Info.args = { type: 'info', children: 'PSA: Every dish can be improved by adding more garlic.' }
|
||||
|
||||
export const Warning = Template.bind({})
|
||||
export const Warning: Story = Template.bind({})
|
||||
Warning.args = { type: 'warning', children: 'This spacecraft is about to explode. Please evacuate immediately.' }
|
||||
|
||||
export const Error = Template.bind({})
|
||||
export const Error: Story = Template.bind({})
|
||||
Error.args = { type: 'error', children: 'This spacecraft has exploded. Too late...' }
|
||||
|
||||
export const Success = Template.bind({})
|
||||
export const Success: Story = Template.bind({})
|
||||
Success.args = { type: 'success', children: 'This spacecraft has recovered. Phew!' }
|
||||
|
||||
export const Closable = Template.bind({})
|
||||
export const Closable: Story = Template.bind({})
|
||||
Closable.args = {
|
||||
type: 'info',
|
||||
children: 'This is a one-time message. Acknowledge it and move on with your life.',
|
||||
onClose: () => alert('👋'),
|
||||
}
|
||||
|
||||
export const Dismissable = Template.bind({})
|
||||
export const Dismissable: Story = Template.bind({})
|
||||
Dismissable.args = {
|
||||
type: 'info',
|
||||
children: 'If you dismiss this message, it will be gone forever. (Clear the localstorage key to get it back)',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import {
|
||||
LemonButton,
|
||||
LemonButtonProps,
|
||||
@@ -12,32 +12,34 @@ import { LemonDivider } from 'lib/lemon-ui/LemonDivider'
|
||||
import { capitalizeFirstLetter, delay, range } from 'lib/utils'
|
||||
import { urls } from 'scenes/urls'
|
||||
import { Link } from '@posthog/lemon-ui'
|
||||
import { LemonBanner } from '../LemonBanner'
|
||||
import { useAsyncHandler } from 'lib/hooks/useAsyncHandler'
|
||||
import clsx from 'clsx'
|
||||
import { LemonBanner } from 'lib/lemon-ui/LemonBanner'
|
||||
|
||||
const statuses: LemonButtonProps['status'][] = ['primary', 'danger', 'primary-alt', 'muted']
|
||||
const types: LemonButtonProps['type'][] = ['primary', 'secondary', 'tertiary']
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonButton>
|
||||
const meta: Meta<typeof LemonButton> = {
|
||||
title: 'Lemon UI/Lemon Button',
|
||||
component: LemonButton,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
icon: {
|
||||
defaultValue: <IconCalculate />,
|
||||
},
|
||||
children: {
|
||||
defaultValue: 'Click me',
|
||||
type: 'function',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonButton>
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonButton> = (props: LemonButtonProps) => {
|
||||
}
|
||||
export default meta
|
||||
const BasicTemplate: StoryFn<typeof LemonButton> = (props: LemonButtonProps) => {
|
||||
return <LemonButton {...props} />
|
||||
}
|
||||
|
||||
export const Default = BasicTemplate.bind({})
|
||||
Default.args = {}
|
||||
export const Default: Story = BasicTemplate.bind({})
|
||||
Default.args = {
|
||||
icon: <IconCalculate />,
|
||||
children: 'Click me',
|
||||
}
|
||||
|
||||
const StatusesTemplate = ({
|
||||
noText,
|
||||
@@ -55,7 +57,7 @@ const StatusesTemplate = ({
|
||||
)
|
||||
}
|
||||
|
||||
const TypesAndStatusesTemplate: ComponentStory<typeof LemonButton> = (props) => {
|
||||
const TypesAndStatusesTemplate: StoryFn<typeof LemonButton> = (props) => {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
{types.map((type) => (
|
||||
@@ -68,10 +70,11 @@ const TypesAndStatusesTemplate: ComponentStory<typeof LemonButton> = (props) =>
|
||||
)
|
||||
}
|
||||
|
||||
export const TypesAndStatuses = TypesAndStatusesTemplate.bind({})
|
||||
TypesAndStatuses.args = {}
|
||||
export const TypesAndStatuses: Story = TypesAndStatusesTemplate.bind({})
|
||||
TypesAndStatuses.args = { ...Default.args }
|
||||
|
||||
const PopoverTemplate: ComponentStory<typeof LemonButtonWithDropdown> = (props: LemonButtonWithDropdownProps) => {
|
||||
type PopoverStory = StoryObj<typeof LemonButtonWithDropdown>
|
||||
const PopoverTemplate: StoryFn<typeof LemonButtonWithDropdown> = (props: LemonButtonWithDropdownProps) => {
|
||||
return <LemonButtonWithDropdown {...props} />
|
||||
}
|
||||
|
||||
@@ -261,8 +264,9 @@ export const AsLinks = (): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
export const WithDropdownToTheRight = PopoverTemplate.bind({})
|
||||
export const WithDropdownToTheRight: PopoverStory = PopoverTemplate.bind({})
|
||||
WithDropdownToTheRight.args = {
|
||||
...Default.args,
|
||||
dropdown: {
|
||||
overlay: (
|
||||
<>
|
||||
@@ -284,8 +288,9 @@ WithDropdownToTheRight.args = {
|
||||
},
|
||||
}
|
||||
|
||||
export const WithDropdownToTheBottom = PopoverTemplate.bind({})
|
||||
export const WithDropdownToTheBottom: PopoverStory = PopoverTemplate.bind({})
|
||||
WithDropdownToTheBottom.args = {
|
||||
...Default.args,
|
||||
dropdown: {
|
||||
overlay: (
|
||||
<>
|
||||
@@ -308,8 +313,9 @@ WithDropdownToTheBottom.args = {
|
||||
},
|
||||
}
|
||||
|
||||
export const WithVeryLongPopoverToTheBottom = PopoverTemplate.bind({})
|
||||
export const WithVeryLongPopoverToTheBottom: PopoverStory = PopoverTemplate.bind({})
|
||||
WithVeryLongPopoverToTheBottom.args = {
|
||||
...Default.args,
|
||||
dropdown: {
|
||||
overlay: (
|
||||
<>
|
||||
@@ -325,8 +331,9 @@ WithVeryLongPopoverToTheBottom.args = {
|
||||
},
|
||||
}
|
||||
|
||||
export const WithTooltip = BasicTemplate.bind({})
|
||||
export const WithTooltip: Story = BasicTemplate.bind({})
|
||||
WithTooltip.args = {
|
||||
...Default.args,
|
||||
tooltip: 'The flux capacitor will be reloaded. This might take up to 14 hours.',
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export interface LemonButtonProps extends LemonButtonPropsBase {
|
||||
}
|
||||
|
||||
/** Styled button. */
|
||||
export const LemonButton: React.FunctionComponent<LemonButtonProps & React.RefAttributes<HTMLElement>> =
|
||||
export const LemonButton: React.FunctionComponent<LemonButtonProps & React.RefAttributes<HTMLButtonElement>> =
|
||||
React.forwardRef(
|
||||
(
|
||||
{
|
||||
@@ -225,7 +225,7 @@ export interface LemonButtonWithSideActionProps extends LemonButtonPropsBase {
|
||||
* We can't use `LemonRow`'s `sideIcon` prop because putting `onClick` on it clashes with the parent`s `onClick`.
|
||||
*/
|
||||
export const LemonButtonWithSideAction: React.FunctionComponent<
|
||||
LemonButtonWithSideActionProps & React.RefAttributes<HTMLElement>
|
||||
LemonButtonWithSideActionProps & React.RefAttributes<HTMLButtonElement>
|
||||
> = React.forwardRef(({ sideAction, children, ...buttonProps }, ref) => {
|
||||
const { dropdown: sideDropdown, divider = !buttonProps.fullWidth, ...sideActionRest } = sideAction
|
||||
const SideComponent = sideDropdown ? LemonButtonWithDropdown : LemonButton
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCalendar, LemonCalendarProps } from './LemonCalendar'
|
||||
import { dayjs } from 'lib/dayjs'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCalendar>
|
||||
const meta: Meta<typeof LemonCalendar> = {
|
||||
title: 'Lemon UI/Lemon Calendar/Lemon Calendar',
|
||||
component: LemonCalendar,
|
||||
argTypes: {
|
||||
onClick: {
|
||||
defaultValue: (date: dayjs.Dayjs) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Clicked: ${date}`)
|
||||
},
|
||||
args: {
|
||||
onDateClick: (date: dayjs.Dayjs) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Clicked: ${date}`)
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
mockDate: '2023-01-26',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonCalendar>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonCalendar> = (props: LemonCalendarProps) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonCalendar> = (props: LemonCalendarProps) => {
|
||||
return <LemonCalendar {...props} />
|
||||
}
|
||||
|
||||
export const Default = BasicTemplate.bind({})
|
||||
export const Default: Story = BasicTemplate.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const MultipleMonths = BasicTemplate.bind({})
|
||||
export const MultipleMonths: Story = BasicTemplate.bind({})
|
||||
MultipleMonths.args = {
|
||||
months: 3,
|
||||
}
|
||||
|
||||
export const CustomStyles = BasicTemplate.bind({})
|
||||
export const CustomStyles: Story = BasicTemplate.bind({})
|
||||
CustomStyles.args = {
|
||||
getLemonButtonProps: ({ date, props }) => {
|
||||
return {
|
||||
@@ -42,37 +43,37 @@ CustomStyles.args = {
|
||||
},
|
||||
}
|
||||
|
||||
export const MondayFirst = BasicTemplate.bind({})
|
||||
export const MondayFirst: Story = BasicTemplate.bind({})
|
||||
MondayFirst.args = {
|
||||
weekStart: 1,
|
||||
}
|
||||
|
||||
export const TuesdayFirst = BasicTemplate.bind({})
|
||||
export const TuesdayFirst: Story = BasicTemplate.bind({})
|
||||
TuesdayFirst.args = {
|
||||
weekStart: 2,
|
||||
}
|
||||
|
||||
export const WednesdayFirst = BasicTemplate.bind({})
|
||||
export const WednesdayFirst: Story = BasicTemplate.bind({})
|
||||
WednesdayFirst.args = {
|
||||
weekStart: 3,
|
||||
}
|
||||
|
||||
export const ThursdayFirst = BasicTemplate.bind({})
|
||||
export const ThursdayFirst: Story = BasicTemplate.bind({})
|
||||
ThursdayFirst.args = {
|
||||
weekStart: 4,
|
||||
}
|
||||
|
||||
export const FridayFirst = BasicTemplate.bind({})
|
||||
export const FridayFirst: Story = BasicTemplate.bind({})
|
||||
FridayFirst.args = {
|
||||
weekStart: 5,
|
||||
}
|
||||
|
||||
export const SaturdayFirst = BasicTemplate.bind({})
|
||||
export const SaturdayFirst: Story = BasicTemplate.bind({})
|
||||
SaturdayFirst.args = {
|
||||
weekStart: 6,
|
||||
}
|
||||
|
||||
export const SundayFirst = BasicTemplate.bind({})
|
||||
export const SundayFirst: Story = BasicTemplate.bind({})
|
||||
SundayFirst.args = {
|
||||
weekStart: 0,
|
||||
}
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCalendarSelect, LemonCalendarSelectProps } from 'lib/lemon-ui/LemonCalendar/LemonCalendarSelect'
|
||||
import { Popover } from 'lib/lemon-ui/Popover/Popover'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { dayjs } from 'lib/dayjs'
|
||||
import { formatDate } from 'lib/utils'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCalendarSelect>
|
||||
const meta: Meta<typeof LemonCalendarSelect> = {
|
||||
title: 'Lemon UI/Lemon Calendar/Lemon Calendar Select',
|
||||
component: LemonCalendarSelect,
|
||||
parameters: {
|
||||
mockDate: '2023-01-26',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonCalendarSelect>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonCalendarSelect> = (props: LemonCalendarSelectProps) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonCalendarSelect> = (props: LemonCalendarSelectProps) => {
|
||||
const [value, setValue] = useState(dayjs().subtract(10, 'day'))
|
||||
const [visible, setVisible] = useState(true)
|
||||
|
||||
@@ -45,5 +48,5 @@ const BasicTemplate: ComponentStory<typeof LemonCalendarSelect> = (props: LemonC
|
||||
)
|
||||
}
|
||||
|
||||
export const LemonCalendarSelect_ = BasicTemplate.bind({})
|
||||
export const LemonCalendarSelect_: Story = BasicTemplate.bind({})
|
||||
LemonCalendarSelect_.args = {}
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCalendarRange, LemonCalendarRangeProps } from 'lib/lemon-ui/LemonCalendarRange/LemonCalendarRange'
|
||||
import { Popover } from 'lib/lemon-ui/Popover/Popover'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { dayjs } from 'lib/dayjs'
|
||||
import { formatDateRange } from 'lib/utils'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCalendarRange>
|
||||
const meta: Meta<typeof LemonCalendarRange> = {
|
||||
title: 'Lemon UI/Lemon Calendar/Lemon Calendar Range',
|
||||
component: LemonCalendarRange,
|
||||
parameters: {
|
||||
mockDate: '2023-01-26',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonCalendarRange>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonCalendarRange> = (props: LemonCalendarRangeProps) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonCalendarRange> = (props: LemonCalendarRangeProps) => {
|
||||
const [value, setValue] = useState([dayjs('2022-08-11'), dayjs('2022-08-26')] as LemonCalendarRangeProps['value'])
|
||||
const [visible, setVisible] = useState(true)
|
||||
|
||||
@@ -45,5 +48,5 @@ const BasicTemplate: ComponentStory<typeof LemonCalendarRange> = (props: LemonCa
|
||||
)
|
||||
}
|
||||
|
||||
export const LemonCalendarRange_ = BasicTemplate.bind({})
|
||||
export const LemonCalendarRange_: Story = BasicTemplate.bind({})
|
||||
LemonCalendarRange_.args = {}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCalendarRangeProps } from 'lib/lemon-ui/LemonCalendarRange/LemonCalendarRange'
|
||||
import { dayjs } from 'lib/dayjs'
|
||||
import { formatDateRange } from 'lib/utils'
|
||||
import { LemonCalendarRangeInline } from './LemonCalendarRangeInline'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCalendarRangeInline>
|
||||
const meta: Meta<typeof LemonCalendarRangeInline> = {
|
||||
title: 'Lemon UI/Lemon Calendar/Lemon Calendar Range Inline',
|
||||
component: LemonCalendarRangeInline,
|
||||
parameters: {
|
||||
mockDate: '2023-01-26',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonCalendarRangeInline>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonCalendarRangeInline> = (props: LemonCalendarRangeProps) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonCalendarRangeInline> = (props: LemonCalendarRangeProps) => {
|
||||
const [value, setValue] = useState([dayjs('2022-08-11'), dayjs('2022-08-26')] as [dayjs.Dayjs, dayjs.Dayjs] | null)
|
||||
|
||||
return (
|
||||
@@ -31,5 +34,5 @@ const BasicTemplate: ComponentStory<typeof LemonCalendarRangeInline> = (props: L
|
||||
)
|
||||
}
|
||||
|
||||
export const LemonCalendarRangeInline_ = BasicTemplate.bind({})
|
||||
export const LemonCalendarRangeInline_: Story = BasicTemplate.bind({})
|
||||
LemonCalendarRangeInline_.args = {}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCheckbox, LemonCheckboxProps } from './LemonCheckbox'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCheckbox>
|
||||
const meta: Meta<typeof LemonCheckbox> = {
|
||||
title: 'Lemon UI/Lemon Checkbox',
|
||||
component: LemonCheckbox,
|
||||
} as ComponentMeta<typeof LemonCheckbox>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonCheckbox> = (props: LemonCheckboxProps) => {
|
||||
const Template: StoryFn<typeof LemonCheckbox> = (props: LemonCheckboxProps) => {
|
||||
return <LemonCheckbox {...props} />
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {
|
||||
label: 'Check this out',
|
||||
}
|
||||
@@ -32,22 +35,22 @@ export const Overview = (): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = {
|
||||
label: "You can't check this out",
|
||||
disabled: true,
|
||||
}
|
||||
|
||||
export const DisabledWithReason = Template.bind({})
|
||||
export const DisabledWithReason: Story = Template.bind({})
|
||||
DisabledWithReason.args = {
|
||||
label: "You can't check this out",
|
||||
disabledReason: 'This is not the way to Amarillo',
|
||||
}
|
||||
|
||||
export const NoLabel = Template.bind({})
|
||||
export const NoLabel: Story = Template.bind({})
|
||||
NoLabel.args = {}
|
||||
|
||||
export const Bordered = Template.bind({})
|
||||
export const Bordered: Story = Template.bind({})
|
||||
Bordered.args = {
|
||||
label: 'A border makes for good visual separation if there is other content neighboring a checkbox. Probably not used as part of a form.',
|
||||
bordered: true,
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonCollapse as LemonCollapseComponent } from './LemonCollapse'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonCollapseComponent>
|
||||
const meta: Meta<typeof LemonCollapseComponent> = {
|
||||
title: 'Lemon UI/Lemon Collapse',
|
||||
component: LemonCollapseComponent,
|
||||
argTypes: {
|
||||
panels: {
|
||||
defaultValue: [
|
||||
{
|
||||
key: '1',
|
||||
header: 'Panel 1',
|
||||
content: <span>Panel 1 content</span>,
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
header: 'Panel 2',
|
||||
content: <span>Panel 2 content</span>,
|
||||
},
|
||||
],
|
||||
},
|
||||
args: {
|
||||
panels: [
|
||||
{
|
||||
key: '1',
|
||||
header: 'Panel 1',
|
||||
content: <span>Panel 1 content</span>,
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
header: 'Panel 2',
|
||||
content: <span>Panel 2 content</span>,
|
||||
},
|
||||
],
|
||||
},
|
||||
} as ComponentMeta<typeof LemonCollapseComponent>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonCollapseComponent> = (props) => {
|
||||
const Template: StoryFn<typeof LemonCollapseComponent> = (props) => {
|
||||
return <LemonCollapseComponent {...props} />
|
||||
}
|
||||
|
||||
export const Single = Template.bind({})
|
||||
export const Single: Story = Template.bind({})
|
||||
Single.args = { defaultActiveKey: '1' }
|
||||
|
||||
export const Multiple = Template.bind({})
|
||||
export const Multiple: Story = Template.bind({})
|
||||
Multiple.args = { defaultActiveKeys: ['1', '2'], multiple: true }
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonDialog, LemonDialogProps } from './LemonDialog'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { Link } from '@posthog/lemon-ui'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonDialog>
|
||||
const meta: Meta<typeof LemonDialog> = {
|
||||
title: 'Lemon UI/Lemon Dialog',
|
||||
component: LemonDialog,
|
||||
args: {
|
||||
@@ -40,9 +41,11 @@ Dialogs are opened imperatively (i.e. calling \`LemonDialog.open()\`) whereas Mo
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonDialog>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const Template: ComponentStory<typeof LemonDialog> = (props: LemonDialogProps) => {
|
||||
export const Template: StoryFn<typeof LemonDialog> = (props: LemonDialogProps) => {
|
||||
const onClick = (): void => {
|
||||
LemonDialog.open(props)
|
||||
}
|
||||
@@ -58,7 +61,7 @@ export const Template: ComponentStory<typeof LemonDialog> = (props: LemonDialogP
|
||||
)
|
||||
}
|
||||
|
||||
export const Minimal = Template.bind({})
|
||||
export const Minimal: Story = Template.bind({})
|
||||
Minimal.args = {
|
||||
title: 'Notice',
|
||||
description: undefined,
|
||||
@@ -67,7 +70,7 @@ Minimal.args = {
|
||||
tertiaryButton: undefined,
|
||||
}
|
||||
|
||||
export const Customised = Template.bind({})
|
||||
export const Customised: Story = Template.bind({})
|
||||
Customised.args = {
|
||||
title: 'Are you sure you want to delete “FakeOrganization”?',
|
||||
description: (
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonDivider, LemonDividerProps } from './LemonDivider'
|
||||
import { LemonRow } from 'lib/lemon-ui/LemonRow'
|
||||
import { Lettermark, LettermarkColor } from '../Lettermark/Lettermark'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
import { ProfileBubbles } from '../ProfilePicture'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonDivider>
|
||||
const meta: Meta<typeof LemonDivider> = {
|
||||
title: 'Lemon UI/Lemon Divider',
|
||||
component: LemonDivider,
|
||||
} as ComponentMeta<typeof LemonDivider>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const HorizontalTemplate: ComponentStory<typeof LemonDivider> = (props: LemonDividerProps) => {
|
||||
const HorizontalTemplate: StoryFn<typeof LemonDivider> = (props: LemonDividerProps) => {
|
||||
return (
|
||||
<>
|
||||
<LemonRow icon={<Lettermark name={1} color={LettermarkColor.Gray} />}>
|
||||
@@ -24,7 +27,7 @@ const HorizontalTemplate: ComponentStory<typeof LemonDivider> = (props: LemonDiv
|
||||
)
|
||||
}
|
||||
|
||||
const VerticalTemplate: ComponentStory<typeof LemonDivider> = (props: LemonDividerProps) => {
|
||||
const VerticalTemplate: StoryFn<typeof LemonDivider> = (props: LemonDividerProps) => {
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<ProfileBubbles
|
||||
@@ -44,17 +47,17 @@ const VerticalTemplate: ComponentStory<typeof LemonDivider> = (props: LemonDivid
|
||||
}
|
||||
VerticalTemplate.args = { vertical: true }
|
||||
|
||||
export const Default = HorizontalTemplate.bind({})
|
||||
export const Default: Story = HorizontalTemplate.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const Large = HorizontalTemplate.bind({})
|
||||
export const Large: Story = HorizontalTemplate.bind({})
|
||||
Large.args = { className: 'my-6' }
|
||||
|
||||
export const ThickDashed = HorizontalTemplate.bind({})
|
||||
export const ThickDashed: Story = HorizontalTemplate.bind({})
|
||||
ThickDashed.args = { thick: true, dashed: true }
|
||||
|
||||
export const Vertical = VerticalTemplate.bind({})
|
||||
export const Vertical: Story = VerticalTemplate.bind({})
|
||||
Vertical.args = { ...VerticalTemplate.args }
|
||||
|
||||
export const VerticalDashed = VerticalTemplate.bind({})
|
||||
export const VerticalDashed: Story = VerticalTemplate.bind({})
|
||||
VerticalDashed.args = { ...VerticalTemplate.args, dashed: true }
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonFileInput } from 'lib/lemon-ui/LemonFileInput/LemonFileInput'
|
||||
import { createRef, useState } from 'react'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonFileInput>
|
||||
const meta: Meta<typeof LemonFileInput> = {
|
||||
title: 'Lemon UI/Lemon File Input',
|
||||
component: LemonFileInput,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
loading: { type: 'boolean', defaultValue: false },
|
||||
accept: { type: 'string', defaultValue: '.json' },
|
||||
loading: { type: 'boolean' },
|
||||
accept: { type: 'string' },
|
||||
},
|
||||
} as ComponentMeta<typeof LemonFileInput>
|
||||
args: {
|
||||
loading: false,
|
||||
accept: '.json',
|
||||
},
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonFileInput> = (props) => {
|
||||
const Template: StoryFn<typeof LemonFileInput> = (props) => {
|
||||
const [singleValue, setSingleValue] = useState([] as any[])
|
||||
const [multipleValue, setMultipleValue] = useState([] as any[])
|
||||
const [extraTargetValue, setExtraTargetValue] = useState([] as any[])
|
||||
@@ -58,4 +65,4 @@ const Template: ComponentStory<typeof LemonFileInput> = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
|
||||
import { LemonInput } from './LemonInput'
|
||||
import { IconArrowDropDown, IconCalendar } from 'lib/lemon-ui/icons'
|
||||
import { LemonButtonWithDropdown } from 'lib/lemon-ui/LemonButton'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonInput>
|
||||
const meta: Meta<typeof LemonInput> = {
|
||||
title: 'Lemon UI/Lemon Input',
|
||||
component: LemonInput,
|
||||
argTypes: {
|
||||
value: { defaultValue: 'Foo' },
|
||||
tags: ['autodocs'],
|
||||
args: {
|
||||
value: 'Foo',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonInput>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonInput> = (props) => {
|
||||
const Template: StoryFn<typeof LemonInput> = (props) => {
|
||||
const [value, setValue] = useState(props.value)
|
||||
// @ts-expect-error – union variant inference around the `type` prop doesn't work here as `type` comes from above
|
||||
return <LemonInput {...props} value={value} onChange={(newValue) => setValue(newValue)} />
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
|
||||
export const WithPrefixAndSuffixAction = Template.bind({})
|
||||
export const WithPrefixAndSuffixAction: Story = Template.bind({})
|
||||
WithPrefixAndSuffixAction.args = {
|
||||
prefix: <IconCalendar />,
|
||||
suffix: (
|
||||
@@ -36,23 +39,23 @@ WithPrefixAndSuffixAction.args = {
|
||||
),
|
||||
}
|
||||
|
||||
export const Search = Template.bind({})
|
||||
export const Search: Story = Template.bind({})
|
||||
Search.args = { type: 'search', placeholder: 'Search your soul' }
|
||||
|
||||
export const Password = Template.bind({})
|
||||
export const Password: Story = Template.bind({})
|
||||
Password.args = { type: 'password', placeholder: 'Enter your password' }
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = { disabled: true }
|
||||
|
||||
export const DangerStatus = Template.bind({})
|
||||
export const DangerStatus: Story = Template.bind({})
|
||||
DangerStatus.args = { status: 'danger' }
|
||||
|
||||
export const Clearable = Template.bind({})
|
||||
export const Clearable: Story = Template.bind({})
|
||||
Clearable.args = { allowClear: true }
|
||||
|
||||
export const Numeric = Template.bind({})
|
||||
export const Numeric: Story = Template.bind({})
|
||||
Numeric.args = { type: 'number', min: 0, step: 1, value: 3 }
|
||||
|
||||
export const Small = Template.bind({})
|
||||
export const Small: Story = Template.bind({})
|
||||
Small.args = { allowClear: true, size: 'small' }
|
||||
|
||||
@@ -1,29 +1,34 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonLabel, LemonLabelProps } from './LemonLabel'
|
||||
import { LemonModal } from '@posthog/lemon-ui'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonLabel>
|
||||
const meta: Meta<typeof LemonLabel> = {
|
||||
title: 'Lemon UI/Lemon Label',
|
||||
component: LemonLabel,
|
||||
docs: {
|
||||
description: {
|
||||
component: `
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: `
|
||||
|
||||
[Related Figma area](https://www.figma.com/file/Y9G24U4r04nEjIDGIEGuKI/PostHog-Design-System-One?node-id=3139%3A1388)
|
||||
|
||||
Lemon Labels provide common styling and options for labeling form elements. They can be used directly but most commonly should be used via the \`Field\` component.
|
||||
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonLabel>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonLabel> = (props: LemonLabelProps) => {
|
||||
const Template: StoryFn<typeof LemonLabel> = (props: LemonLabelProps) => {
|
||||
return <LemonLabel {...props} />
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {
|
||||
info: 'This field is optional',
|
||||
showOptional: true,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import {
|
||||
LemonMenuOverlay as LemonMenuOverlayComponent,
|
||||
LemonMenuOverlayProps,
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
} from './LemonMenu'
|
||||
import { Splotch, SplotchColor } from '../Splotch'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonMenuOverlayComponent>
|
||||
const meta: Meta<typeof LemonMenuOverlayComponent> = {
|
||||
title: 'Lemon UI/Lemon Menu',
|
||||
component: LemonMenuOverlayComponent,
|
||||
parameters: {
|
||||
@@ -21,18 +22,18 @@ This enables intuitive preview of the component, along with snapshotting, but in
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
items: {
|
||||
defaultValue: [
|
||||
{ label: 'Alert', onClick: () => alert('Hello there.') },
|
||||
{ label: 'Do nothing' },
|
||||
{ label: 'Do nothing, with a highlight', active: true },
|
||||
] as LemonMenuItems,
|
||||
},
|
||||
args: {
|
||||
items: [
|
||||
{ label: 'Alert', onClick: () => alert('Hello there.') },
|
||||
{ label: 'Do nothing' },
|
||||
{ label: 'Do nothing, with a highlight', active: true },
|
||||
] as LemonMenuItems,
|
||||
},
|
||||
} as ComponentMeta<typeof LemonMenuOverlayComponent>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonMenuOverlayComponent> = (props: LemonMenuOverlayProps) => {
|
||||
const Template: StoryFn<typeof LemonMenuOverlayComponent> = (props: LemonMenuOverlayProps) => {
|
||||
return (
|
||||
<div className="Popover">
|
||||
<div
|
||||
@@ -49,10 +50,10 @@ const Template: ComponentStory<typeof LemonMenuOverlayComponent> = (props: Lemon
|
||||
)
|
||||
}
|
||||
|
||||
export const Flat = Template.bind({})
|
||||
export const Flat: Story = Template.bind({})
|
||||
Flat.args = {}
|
||||
|
||||
export const SectionedItems = Template.bind({})
|
||||
export const SectionedItems: Story = Template.bind({})
|
||||
SectionedItems.args = {
|
||||
items: [
|
||||
{
|
||||
@@ -79,7 +80,7 @@ SectionedItems.args = {
|
||||
] as LemonMenuSection[],
|
||||
}
|
||||
|
||||
export const NestedMenu = Template.bind({})
|
||||
export const NestedMenu: Story = Template.bind({})
|
||||
NestedMenu.args = {
|
||||
items: [
|
||||
{
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn } from '@storybook/react'
|
||||
import { LemonModal, LemonModalProps } from './LemonModal'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof LemonModal> = {
|
||||
title: 'Lemon UI/Lemon Modal',
|
||||
component: LemonModal,
|
||||
} as ComponentMeta<typeof LemonModal>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const _LemonModal: ComponentStory<typeof LemonModal> = (props: LemonModalProps) => {
|
||||
export const _LemonModal: StoryFn<typeof LemonModal> = (props: LemonModalProps) => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
return (
|
||||
<>
|
||||
@@ -59,7 +61,7 @@ export const _LemonModal: ComponentStory<typeof LemonModal> = (props: LemonModal
|
||||
)
|
||||
}
|
||||
|
||||
export const WithoutContent: ComponentStory<typeof LemonModal> = (props: LemonModalProps) => {
|
||||
export const WithoutContent: StoryFn<typeof LemonModal> = (props: LemonModalProps) => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
return (
|
||||
<>
|
||||
@@ -86,7 +88,7 @@ export const WithoutContent: ComponentStory<typeof LemonModal> = (props: LemonMo
|
||||
)
|
||||
}
|
||||
|
||||
export const Inline: ComponentStory<typeof LemonModal> = () => {
|
||||
export const Inline: StoryFn<typeof LemonModal> = () => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
return (
|
||||
<div className="bg-default p-4">
|
||||
@@ -109,7 +111,7 @@ export const Inline: ComponentStory<typeof LemonModal> = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export const WithCustomContent: ComponentStory<typeof LemonModal> = () => {
|
||||
export const WithCustomContent: StoryFn<typeof LemonModal> = () => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
return (
|
||||
<div className="bg-default p-4">
|
||||
|
||||
@@ -1,104 +1,117 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { IconInfo, IconPremium } from 'lib/lemon-ui/icons'
|
||||
import { LemonRow, LemonRowProps } from './LemonRow'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonRow>
|
||||
const meta: Meta<typeof LemonRow> = {
|
||||
title: 'Lemon UI/Lemon Row',
|
||||
component: LemonRow,
|
||||
argTypes: {
|
||||
icon: {
|
||||
defaultValue: <IconPremium />,
|
||||
},
|
||||
children: {
|
||||
defaultValue: 'Information',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonRow>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonRow> = (props: LemonRowProps<keyof JSX.IntrinsicElements>) => {
|
||||
const Template: StoryFn<typeof LemonRow> = (props: LemonRowProps<keyof JSX.IntrinsicElements>) => {
|
||||
return <LemonRow {...props} />
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
Default.args = {}
|
||||
export const Default: Story = Template.bind({})
|
||||
Default.args = {
|
||||
children: 'Information',
|
||||
icon: <IconPremium />,
|
||||
}
|
||||
|
||||
export const TextOnly = Template.bind({})
|
||||
export const TextOnly: Story = Template.bind({})
|
||||
TextOnly.args = {
|
||||
...Default.args,
|
||||
icon: null,
|
||||
}
|
||||
|
||||
export const IconOnly = Template.bind({})
|
||||
export const IconOnly: Story = Template.bind({})
|
||||
IconOnly.args = {
|
||||
...Default.args,
|
||||
children: null,
|
||||
}
|
||||
|
||||
export const Outlined = Template.bind({})
|
||||
export const Outlined: Story = Template.bind({})
|
||||
Outlined.args = {
|
||||
...Default.args,
|
||||
outlined: true,
|
||||
}
|
||||
|
||||
export const Success = Template.bind({})
|
||||
export const Success: Story = Template.bind({})
|
||||
Success.args = {
|
||||
...Default.args,
|
||||
status: 'success',
|
||||
}
|
||||
|
||||
export const Warning = Template.bind({})
|
||||
export const Warning: Story = Template.bind({})
|
||||
Warning.args = {
|
||||
...Default.args,
|
||||
status: 'warning',
|
||||
}
|
||||
|
||||
export const Danger = Template.bind({})
|
||||
export const Danger: Story = Template.bind({})
|
||||
Danger.args = {
|
||||
...Default.args,
|
||||
status: 'danger',
|
||||
}
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = {
|
||||
...Default.args,
|
||||
disabled: true,
|
||||
}
|
||||
|
||||
export const Loading = Template.bind({})
|
||||
export const Loading: Story = Template.bind({})
|
||||
Loading.args = {
|
||||
...Default.args,
|
||||
loading: true,
|
||||
}
|
||||
|
||||
export const Small = Template.bind({})
|
||||
export const Small: Story = Template.bind({})
|
||||
Small.args = {
|
||||
...Default.args,
|
||||
outlined: true,
|
||||
size: 'small',
|
||||
}
|
||||
|
||||
export const Tall = Template.bind({})
|
||||
export const Tall: Story = Template.bind({})
|
||||
Tall.args = {
|
||||
...Default.args,
|
||||
outlined: true,
|
||||
size: 'tall',
|
||||
}
|
||||
|
||||
export const Large = Template.bind({})
|
||||
export const Large: Story = Template.bind({})
|
||||
Large.args = {
|
||||
...Default.args,
|
||||
outlined: true,
|
||||
size: 'large',
|
||||
}
|
||||
|
||||
export const FullWidth = Template.bind({})
|
||||
export const FullWidth: Story = Template.bind({})
|
||||
FullWidth.args = {
|
||||
...Default.args,
|
||||
outlined: true,
|
||||
fullWidth: true,
|
||||
}
|
||||
|
||||
export const WithSideIcon = Template.bind({})
|
||||
export const WithSideIcon: Story = Template.bind({})
|
||||
WithSideIcon.args = {
|
||||
...Default.args,
|
||||
sideIcon: <IconInfo />,
|
||||
}
|
||||
|
||||
export const WithTooltip = Template.bind({})
|
||||
export const WithTooltip: Story = Template.bind({})
|
||||
WithTooltip.args = {
|
||||
...Default.args,
|
||||
tooltip:
|
||||
'The lifespan of kangaroos averages at six years in the wild to in excess of 20 years in captivity, varying by the species.',
|
||||
}
|
||||
|
||||
export const WithExtendedContent = Template.bind({})
|
||||
export const WithExtendedContent: Story = Template.bind({})
|
||||
WithExtendedContent.args = {
|
||||
...Default.args,
|
||||
type: 'stealth',
|
||||
extendedContent: "This is some extra info about this particular item. Hopefully it's helpful.",
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { IconCalculate, IconCalendar, IconLightBulb, IconSettings } from '../icons'
|
||||
import { LemonSegmentedButton, LemonSegmentedButtonOption, LemonSegmentedButtonProps } from './LemonSegmentedButton'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonSegmentedButton>
|
||||
const meta: Meta<typeof LemonSegmentedButton> = {
|
||||
title: 'Lemon UI/Lemon Segmented Button',
|
||||
component: LemonSegmentedButton,
|
||||
argTypes: {
|
||||
@@ -11,25 +12,29 @@ export default {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
defaultValue: [
|
||||
{ value: 'calendar', label: 'Calendar', icon: <IconCalendar /> },
|
||||
{ value: 'calculator', label: 'Calculator', icon: <IconCalculate /> },
|
||||
{
|
||||
value: 'banana',
|
||||
label: 'Banana',
|
||||
icon: <IconLightBulb />,
|
||||
disabledReason: 'Bananas are not allowed on these premises.',
|
||||
},
|
||||
{ value: 'settings', label: 'Settings', icon: <IconSettings /> },
|
||||
] as LemonSegmentedButtonOption<string>[],
|
||||
},
|
||||
// Show value and onChange, but disable editing as they're handled by the template
|
||||
value: { control: { disable: true } },
|
||||
onChange: { control: { disable: true } },
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSegmentedButton>
|
||||
args: {
|
||||
options: [
|
||||
{ value: 'calendar', label: 'Calendar', icon: <IconCalendar /> },
|
||||
{ value: 'calculator', label: 'Calculator', icon: <IconCalculate /> },
|
||||
{
|
||||
value: 'banana',
|
||||
label: 'Banana',
|
||||
icon: <IconLightBulb />,
|
||||
disabledReason: 'Bananas are not allowed on these premises.',
|
||||
},
|
||||
{ value: 'settings', label: 'Settings', icon: <IconSettings /> },
|
||||
] as LemonSegmentedButtonOption<string>[],
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonSegmentedButton> = (
|
||||
const Template: StoryFn<typeof LemonSegmentedButton> = (
|
||||
props: Omit<LemonSegmentedButtonProps<any>, 'value' | 'onChange'>
|
||||
) => {
|
||||
const [value, setValue] = useState(props.options[1]?.value)
|
||||
@@ -37,10 +42,10 @@ const Template: ComponentStory<typeof LemonSegmentedButton> = (
|
||||
return <LemonSegmentedButton {...props} value={value} onChange={(newValue) => setValue(newValue)} />
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const Small = Template.bind({})
|
||||
export const Small: Story = Template.bind({})
|
||||
Small.args = {
|
||||
size: 'small',
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonSelect, LemonSelectOptions, LemonSelectProps } from './LemonSelect'
|
||||
import { capitalizeFirstLetter } from 'lib/utils'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonSelect>
|
||||
const meta: Meta<typeof LemonSelect> = {
|
||||
title: 'Lemon UI/Lemon Select',
|
||||
component: LemonSelect,
|
||||
argTypes: {
|
||||
options: {
|
||||
defaultValue: [
|
||||
{ value: 'husky', label: 'Husky' },
|
||||
{ value: 'poodle', label: 'Poodle' },
|
||||
{ value: 'labrador', label: 'Labrador' },
|
||||
] as LemonSelectOptions<string>,
|
||||
},
|
||||
args: {
|
||||
options: [
|
||||
{ value: 'husky', label: 'Husky' },
|
||||
{ value: 'poodle', label: 'Poodle' },
|
||||
{ value: 'labrador', label: 'Labrador' },
|
||||
] as LemonSelectOptions<string>,
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSelect>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonSelect> = (props: LemonSelectProps<any>) => {
|
||||
const Template: StoryFn<typeof LemonSelect> = (props: LemonSelectProps<any>) => {
|
||||
return (
|
||||
<div className="flex flex-row items-center w-full border p-4 gap-2">
|
||||
{(['small', undefined] as const).map((size, index) => (
|
||||
@@ -29,10 +30,10 @@ const Template: ComponentStory<typeof LemonSelect> = (props: LemonSelectProps<an
|
||||
)
|
||||
}
|
||||
|
||||
export const Flat = Template.bind({})
|
||||
export const Flat: Story = Template.bind({})
|
||||
Flat.args = {}
|
||||
|
||||
export const SectionedOptions = Template.bind({})
|
||||
export const SectionedOptions: Story = Template.bind({})
|
||||
SectionedOptions.args = {
|
||||
dropdownMatchSelectWidth: false,
|
||||
options: [
|
||||
@@ -71,7 +72,7 @@ SectionedOptions.args = {
|
||||
] as LemonSelectOptions<string>,
|
||||
}
|
||||
|
||||
export const MixedValuesTypes = Template.bind({})
|
||||
export const MixedValuesTypes: Story = Template.bind({})
|
||||
MixedValuesTypes.args = {
|
||||
dropdownMatchSelectWidth: false,
|
||||
options: [
|
||||
@@ -84,7 +85,7 @@ MixedValuesTypes.args = {
|
||||
] as LemonSelectOptions<string | number>,
|
||||
}
|
||||
|
||||
export const NestedSelect = Template.bind({})
|
||||
export const NestedSelect: Story = Template.bind({})
|
||||
NestedSelect.args = {
|
||||
dropdownMatchSelectWidth: false,
|
||||
options: [
|
||||
@@ -99,17 +100,17 @@ NestedSelect.args = {
|
||||
] as LemonSelectOptions<string | number>,
|
||||
}
|
||||
|
||||
export const Clearable = Template.bind({})
|
||||
export const Clearable: Story = Template.bind({})
|
||||
Clearable.args = { allowClear: true, value: 'poodle' }
|
||||
|
||||
export const LongOptions = Template.bind({})
|
||||
export const LongOptions: Story = Template.bind({})
|
||||
LongOptions.args = {
|
||||
allowClear: true,
|
||||
value: '1',
|
||||
options: [...Array(100)].map((_, x) => ({ value: `${x}`, label: `${x}` })),
|
||||
}
|
||||
|
||||
export const CustomElement = Template.bind({})
|
||||
export const CustomElement: Story = Template.bind({})
|
||||
CustomElement.args = {
|
||||
value: 1,
|
||||
options: [
|
||||
@@ -126,7 +127,7 @@ CustomElement.args = {
|
||||
],
|
||||
}
|
||||
|
||||
export const FullWidth: ComponentStory<typeof LemonSelect> = (props: LemonSelectProps<any>) => {
|
||||
export const FullWidth: StoryFn<typeof LemonSelect> = (props: LemonSelectProps<any>) => {
|
||||
return (
|
||||
<div className="items-center w-full border p-4 gap-2">
|
||||
<LemonSelect {...props} fullWidth={true} allowClear={true} value={'poodle'} />
|
||||
|
||||
@@ -1,71 +1,72 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonSelectMultiple, LemonSelectMultipleProps } from './LemonSelectMultiple'
|
||||
import { ProfilePicture } from '../ProfilePicture'
|
||||
import { capitalizeFirstLetter } from 'lib/utils'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonSelectMultiple>
|
||||
const meta: Meta<typeof LemonSelectMultiple> = {
|
||||
title: 'Lemon UI/Lemon SelectMultiple',
|
||||
component: LemonSelectMultiple,
|
||||
argTypes: {
|
||||
options: {
|
||||
defaultValue: ['ben', 'marius', 'paul', 'tiina', 'li'].reduce(
|
||||
(acc, x, i) => ({
|
||||
...acc,
|
||||
[`user-${i}`]: {
|
||||
labelComponent: (
|
||||
<span className="flex gap-2 items-center">
|
||||
<ProfilePicture name={x} email={`${x}@posthog.com`} size="sm" />
|
||||
<span>
|
||||
{capitalizeFirstLetter(x)} <b>{`<${x}@posthog.com>`}</b>
|
||||
</span>
|
||||
args: {
|
||||
options: ['ben', 'marius', 'paul', 'tiina', 'li'].reduce(
|
||||
(acc, x, i) => ({
|
||||
...acc,
|
||||
[`user-${i}`]: {
|
||||
labelComponent: (
|
||||
<span className="flex gap-2 items-center">
|
||||
<ProfilePicture name={x} email={`${x}@posthog.com`} size="sm" />
|
||||
<span>
|
||||
{capitalizeFirstLetter(x)} <b>{`<${x}@posthog.com>`}</b>
|
||||
</span>
|
||||
),
|
||||
label: `${x} ${x}@posthog.com>`,
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
},
|
||||
</span>
|
||||
),
|
||||
label: `${x} ${x}@posthog.com>`,
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSelectMultiple>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonSelectMultiple> = (props: LemonSelectMultipleProps) => {
|
||||
const Template: StoryFn<typeof LemonSelectMultiple> = (props: LemonSelectMultipleProps) => {
|
||||
const [value, setValue] = useState(props.value || [])
|
||||
return <LemonSelectMultiple {...props} value={value} onChange={setValue} />
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
Default.args = {
|
||||
placeholder: 'Pick one email',
|
||||
}
|
||||
|
||||
export const MultipleSelect = Template.bind({})
|
||||
export const MultipleSelect: Story = Template.bind({})
|
||||
MultipleSelect.args = {
|
||||
placeholder: 'Enter emails...',
|
||||
mode: 'multiple',
|
||||
}
|
||||
|
||||
export const MultipleSelectWithCustom = Template.bind({})
|
||||
export const MultipleSelectWithCustom: Story = Template.bind({})
|
||||
MultipleSelectWithCustom.args = {
|
||||
placeholder: 'Enter any email...',
|
||||
mode: 'multiple-custom',
|
||||
}
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = {
|
||||
placeholder: 'Disabled...',
|
||||
disabled: true,
|
||||
}
|
||||
|
||||
export const Loading = Template.bind({})
|
||||
export const Loading: Story = Template.bind({})
|
||||
Loading.args = {
|
||||
placeholder: 'Loading...',
|
||||
options: [],
|
||||
loading: true,
|
||||
}
|
||||
|
||||
export const NoOptions = Template.bind({})
|
||||
export const NoOptions: Story = Template.bind({})
|
||||
NoOptions.args = {
|
||||
mode: 'multiple-custom',
|
||||
placeholder: 'No options...',
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
import { LemonSkeleton } from './LemonSkeleton'
|
||||
import { LemonLabel } from 'lib/lemon-ui/LemonLabel/LemonLabel'
|
||||
import { LemonModal } from 'lib/lemon-ui/LemonModal'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof LemonSkeleton> = {
|
||||
title: 'Lemon UI/Lemon Skeleton',
|
||||
component: LemonSkeleton,
|
||||
parameters: {
|
||||
@@ -17,7 +17,9 @@ Skeleton screens are used to indicate that a screen is loading, are perceived as
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSkeleton>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function Default(): JSX.Element {
|
||||
return <LemonSkeleton />
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonSnack, LemonSnackProps } from './LemonSnack'
|
||||
import { ProfilePicture } from '../ProfilePicture'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonSnack>
|
||||
const meta: Meta<typeof LemonSnack> = {
|
||||
title: 'Lemon UI/Lemon Snack',
|
||||
component: LemonSnack,
|
||||
argTypes: {
|
||||
children: {
|
||||
defaultValue: 'Tasty snacks',
|
||||
},
|
||||
args: {
|
||||
children: 'Tasty snacks',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSnack>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof LemonSnack> = (props: LemonSnackProps) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonSnack> = (props: LemonSnackProps) => {
|
||||
return <LemonSnack {...props} />
|
||||
}
|
||||
|
||||
export const Default = BasicTemplate.bind({})
|
||||
export const Default: Story = BasicTemplate.bind({})
|
||||
Default.args = {
|
||||
onClose: null as any,
|
||||
}
|
||||
@@ -38,7 +39,7 @@ export const Pill = (): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
export const ComplexContent = BasicTemplate.bind({})
|
||||
export const ComplexContent: Story = BasicTemplate.bind({})
|
||||
ComplexContent.args = {
|
||||
children: (
|
||||
<span className="flex gap-2 items-center">
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
|
||||
import { LemonSwitch as RawLemonSwitch, LemonSwitchProps } from './LemonSwitch'
|
||||
import { IconGlobeLock } from 'lib/lemon-ui/icons'
|
||||
|
||||
export default {
|
||||
title: 'Lemon UI/Lemon Switch',
|
||||
component: RawLemonSwitch,
|
||||
argTypes: {
|
||||
label: {
|
||||
defaultValue: 'Switch this!',
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof LemonSwitch>
|
||||
|
||||
const LemonSwitch = ({ checked, ...props }: Partial<LemonSwitchProps>): JSX.Element => {
|
||||
const [isChecked, setIsChecked] = useState(checked || false)
|
||||
return <RawLemonSwitch {...props} checked={isChecked} onChange={setIsChecked} />
|
||||
}
|
||||
|
||||
const Template: ComponentStory<typeof RawLemonSwitch> = (props: LemonSwitchProps) => {
|
||||
type Story = StoryObj<typeof RawLemonSwitch>
|
||||
const meta: Meta<typeof LemonSwitch> = {
|
||||
title: 'Lemon UI/Lemon Switch',
|
||||
component: LemonSwitch,
|
||||
args: {
|
||||
label: 'Switch this!',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: StoryFn<typeof RawLemonSwitch> = (props: LemonSwitchProps) => {
|
||||
return <LemonSwitch {...props} />
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
export const Overview = (): JSX.Element => {
|
||||
@@ -42,11 +43,11 @@ export const Overview = (): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
export const Standalone = Template.bind({})
|
||||
export const Standalone: Story = Template.bind({})
|
||||
Standalone.args = { label: undefined }
|
||||
|
||||
export const Bordered = Template.bind({})
|
||||
export const Bordered: Story = Template.bind({})
|
||||
Bordered.args = { bordered: true }
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = { disabled: true }
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { ComponentMeta, ComponentStory, Story } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonTable, LemonTableProps } from './LemonTable'
|
||||
import { LemonButton } from '../LemonButton'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonTable>
|
||||
const meta: Meta<typeof LemonTable> = {
|
||||
title: 'Lemon UI/Lemon Table',
|
||||
component: LemonTable,
|
||||
} as ComponentMeta<typeof LemonTable>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
interface MockPerson {
|
||||
name: string
|
||||
@@ -19,7 +22,7 @@ interface MockFunnelSeries {
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
const GroupedTemplate: ComponentStory<typeof LemonTable> = (props: LemonTableProps<MockFunnelSeries>) => {
|
||||
const GroupedTemplate: StoryFn<typeof LemonTable> = (props: LemonTableProps<MockFunnelSeries>) => {
|
||||
return (
|
||||
<LemonTable
|
||||
{...props}
|
||||
@@ -89,7 +92,7 @@ const GroupedTemplate: ComponentStory<typeof LemonTable> = (props: LemonTablePro
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
const BasicTemplate: ComponentStory<typeof LemonTable> = (props: LemonTableProps<MockPerson>) => {
|
||||
const BasicTemplate: StoryFn<typeof LemonTable> = (props: LemonTableProps<MockPerson>) => {
|
||||
return (
|
||||
<LemonTable
|
||||
{...props}
|
||||
@@ -134,7 +137,7 @@ const BasicTemplate: ComponentStory<typeof LemonTable> = (props: LemonTableProps
|
||||
)
|
||||
}
|
||||
|
||||
const EmptyTemplate: ComponentStory<typeof LemonTable> = (props: LemonTableProps<Record<string, any>>) => {
|
||||
const EmptyTemplate: StoryFn<typeof LemonTable> = (props: LemonTableProps<Record<string, any>>) => {
|
||||
return (
|
||||
<LemonTable
|
||||
{...props}
|
||||
@@ -147,19 +150,19 @@ const EmptyTemplate: ComponentStory<typeof LemonTable> = (props: LemonTableProps
|
||||
)
|
||||
}
|
||||
|
||||
export const Basic = BasicTemplate.bind({})
|
||||
export const Basic: Story = BasicTemplate.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
export const Grouped = GroupedTemplate.bind({})
|
||||
export const Grouped: Story = GroupedTemplate.bind({})
|
||||
Grouped.args = {}
|
||||
|
||||
export const Empty = EmptyTemplate.bind({})
|
||||
export const Empty: Story = EmptyTemplate.bind({})
|
||||
Empty.args = {}
|
||||
|
||||
export const PaginatedAutomatically = BasicTemplate.bind({})
|
||||
export const PaginatedAutomatically: Story = BasicTemplate.bind({})
|
||||
PaginatedAutomatically.args = { nouns: ['person', 'people'], pagination: { pageSize: 3 } }
|
||||
|
||||
export const WithExpandableRows = BasicTemplate.bind({})
|
||||
export const WithExpandableRows: Story = BasicTemplate.bind({})
|
||||
WithExpandableRows.args = {
|
||||
expandable: {
|
||||
rowExpandable: (record) => record.occupation !== 'Retired',
|
||||
@@ -169,34 +172,34 @@ WithExpandableRows.args = {
|
||||
},
|
||||
}
|
||||
|
||||
export const Small = BasicTemplate.bind({})
|
||||
export const Small: Story = BasicTemplate.bind({})
|
||||
Small.args = { size: 'small' }
|
||||
|
||||
export const XSmall = BasicTemplate.bind({})
|
||||
export const XSmall: Story = BasicTemplate.bind({})
|
||||
XSmall.args = { size: 'xs' }
|
||||
|
||||
export const Embedded = BasicTemplate.bind({})
|
||||
export const Embedded: Story = BasicTemplate.bind({})
|
||||
Embedded.args = { embedded: true }
|
||||
|
||||
export const BorderlessRows = BasicTemplate.bind({})
|
||||
export const BorderlessRows: Story = BasicTemplate.bind({})
|
||||
BorderlessRows.args = { borderedRows: false }
|
||||
|
||||
export const Loading = BasicTemplate.bind({})
|
||||
export const Loading: Story = BasicTemplate.bind({})
|
||||
Loading.args = { loading: true }
|
||||
|
||||
export const EmptyLoading = EmptyTemplate.bind({})
|
||||
export const EmptyLoading: Story = EmptyTemplate.bind({})
|
||||
EmptyLoading.args = { loading: true }
|
||||
|
||||
export const EmptyLoadingWithManySkeletonRows = EmptyTemplate.bind({})
|
||||
export const EmptyLoadingWithManySkeletonRows: Story = EmptyTemplate.bind({})
|
||||
EmptyLoadingWithManySkeletonRows.args = { loading: true, loadingSkeletonRows: 10 }
|
||||
|
||||
export const WithoutHeader = BasicTemplate.bind({})
|
||||
export const WithoutHeader: Story = BasicTemplate.bind({})
|
||||
WithoutHeader.args = { showHeader: false }
|
||||
|
||||
export const WithoutUppercasingInHeader = BasicTemplate.bind({})
|
||||
export const WithoutUppercasingInHeader: Story = BasicTemplate.bind({})
|
||||
WithoutUppercasingInHeader.args = { uppercaseHeader: false }
|
||||
|
||||
export const WithFooter = BasicTemplate.bind({})
|
||||
export const WithFooter: Story = BasicTemplate.bind({})
|
||||
WithFooter.args = {
|
||||
footer: (
|
||||
<>
|
||||
@@ -209,7 +212,7 @@ WithFooter.args = {
|
||||
),
|
||||
}
|
||||
|
||||
export const WithColorCodedRows = BasicTemplate.bind({})
|
||||
export const WithColorCodedRows: Story = BasicTemplate.bind({})
|
||||
WithColorCodedRows.args = {
|
||||
rowRibbonColor: ({ occupation }) =>
|
||||
occupation === 'Engineer'
|
||||
@@ -221,15 +224,15 @@ WithColorCodedRows.args = {
|
||||
: null,
|
||||
}
|
||||
|
||||
export const WithHighlightedRows = BasicTemplate.bind({})
|
||||
export const WithHighlightedRows: Story = BasicTemplate.bind({})
|
||||
WithHighlightedRows.args = {
|
||||
rowStatus: ({ occupation }) => (['Retired', 'Body-builder'].includes(occupation) ? 'highlighted' : null),
|
||||
}
|
||||
|
||||
export const WithMandatorySorting = BasicTemplate.bind({})
|
||||
export const WithMandatorySorting: Story = BasicTemplate.bind({})
|
||||
WithMandatorySorting.args = { defaultSorting: { columnKey: 'name', order: 1 }, noSortingCancellation: true }
|
||||
|
||||
export const WithStickyFirstColumn: Story = () => {
|
||||
export const WithStickyFirstColumn = (): JSX.Element => {
|
||||
useEffect(() => {
|
||||
const scrollableInner = document.querySelector(
|
||||
'#story--lemon-ui-lemon-table--with-sticky-first-column .scrollable__inner'
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { LemonTab, LemonTabs as LemonTabsComponent } from './LemonTabs'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonTabsComponent>
|
||||
const meta: Meta<typeof LemonTabsComponent> = {
|
||||
title: 'Lemon UI/Lemon Tabs',
|
||||
component: LemonTabsComponent,
|
||||
argTypes: {
|
||||
@@ -10,41 +11,43 @@ export default {
|
||||
control: {
|
||||
type: 'object',
|
||||
},
|
||||
defaultValue: [
|
||||
{
|
||||
key: 'calendar',
|
||||
label: 'Calendar',
|
||||
content: <div>Imagine some calendar here. 🗓️</div>,
|
||||
},
|
||||
{
|
||||
key: 'calculator',
|
||||
label: 'Calculator',
|
||||
tooltip: 'Calculate 2+2, as well as 1/0.',
|
||||
content: <div>Imagine some calculator here. 🔢</div>,
|
||||
},
|
||||
{
|
||||
key: 'banana',
|
||||
label: 'Banana',
|
||||
content: <div>Imagine some banana here. 🍌</div>,
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
label: 'Settings',
|
||||
content: <div>Imagine some settings here. ⚙️</div>,
|
||||
},
|
||||
] as LemonTab<'calendar' | 'calculator' | 'banana' | 'settings'>[],
|
||||
},
|
||||
// Show value and onChange, but disable editing as they're handled by the template
|
||||
value: { control: { disable: true } },
|
||||
onChange: { control: { disable: true } },
|
||||
},
|
||||
} as ComponentMeta<typeof LemonTabsComponent>
|
||||
tags: ['autodocs'],
|
||||
args: {
|
||||
tabs: [
|
||||
{
|
||||
key: 'calendar',
|
||||
label: 'Calendar',
|
||||
content: <div>Imagine some calendar here. 🗓️</div>,
|
||||
},
|
||||
{
|
||||
key: 'calculator',
|
||||
label: 'Calculator',
|
||||
tooltip: 'Calculate 2+2, as well as 1/0.',
|
||||
content: <div>Imagine some calculator here. 🔢</div>,
|
||||
},
|
||||
{
|
||||
key: 'banana',
|
||||
label: 'Banana',
|
||||
content: <div>Imagine some banana here. 🍌</div>,
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
label: 'Settings',
|
||||
content: <div>Imagine some settings here. ⚙️</div>,
|
||||
},
|
||||
] as LemonTab<'calendar' | 'calculator' | 'banana' | 'settings'>[],
|
||||
},
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonTabsComponent> = (props) => {
|
||||
const Template: StoryFn<typeof LemonTabsComponent> = (props) => {
|
||||
const [activeKey, setActiveKey] = useState((props.tabs[0] as LemonTab<string | number>).key)
|
||||
|
||||
return <LemonTabsComponent {...props} activeKey={activeKey} onChange={(newValue) => setActiveKey(newValue)} />
|
||||
}
|
||||
|
||||
export const LemonTabs = Template.bind({})
|
||||
export const LemonTabs: Story = Template.bind({})
|
||||
LemonTabs.args = {}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonTag as LemonTagComponent, LemonTagType } from './LemonTag'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonTagComponent>
|
||||
const meta: Meta<typeof LemonTagComponent> = {
|
||||
title: 'Lemon UI/Lemon Tag',
|
||||
component: LemonTagComponent,
|
||||
} as ComponentMeta<typeof LemonTagComponent>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const ALL_COLORS: LemonTagType[] = [
|
||||
'primary',
|
||||
@@ -18,7 +21,7 @@ const ALL_COLORS: LemonTagType[] = [
|
||||
'none',
|
||||
]
|
||||
|
||||
const Template: ComponentStory<typeof LemonTagComponent> = (props) => {
|
||||
const Template: StoryFn<typeof LemonTagComponent> = (props) => {
|
||||
return (
|
||||
<div className="flex gap-1 flex-wrap">
|
||||
{ALL_COLORS.map((type) => (
|
||||
@@ -30,5 +33,5 @@ const Template: ComponentStory<typeof LemonTagComponent> = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const LemonTag = Template.bind({})
|
||||
export const LemonTag: Story = Template.bind({})
|
||||
LemonTag.args = {}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory, Story } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
|
||||
import { LemonTextArea, LemonTextAreaProps, LemonTextMarkdown as _LemonTextMarkdown } from './LemonTextArea'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof LemonTextArea>
|
||||
const meta: Meta<typeof LemonTextArea> = {
|
||||
title: 'Lemon UI/Lemon Text Area',
|
||||
component: LemonTextArea,
|
||||
argTypes: {
|
||||
value: {
|
||||
defaultValue:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
|
||||
},
|
||||
args: {
|
||||
value: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
|
||||
},
|
||||
} as ComponentMeta<typeof LemonTextArea>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof LemonTextArea> = (props: LemonTextAreaProps) => {
|
||||
const Template: StoryFn<typeof LemonTextArea> = (props: LemonTextAreaProps) => {
|
||||
const [value, setValue] = useState(props.value)
|
||||
return <LemonTextArea {...props} value={value} onChange={(newValue) => setValue(newValue)} />
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
export const Disabled = Template.bind({})
|
||||
export const Disabled: Story = Template.bind({})
|
||||
Disabled.args = { disabled: true }
|
||||
|
||||
export const LemonTextMarkdown: Story = () => {
|
||||
export const LemonTextMarkdown = (): JSX.Element => {
|
||||
const [value, setValue] = useState('# Title\n\n**bold** _italic_')
|
||||
return <_LemonTextMarkdown value={value} onChange={(newValue) => setValue(newValue)} />
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { Lettermark, LettermarkColor, LettermarkProps } from './Lettermark'
|
||||
import { range } from 'lib/utils'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Lettermark>
|
||||
const meta: Meta<typeof Lettermark> = {
|
||||
title: 'Lemon UI/Lettermark',
|
||||
component: Lettermark,
|
||||
parameters: {
|
||||
@@ -13,13 +14,15 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Lettermark>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof Lettermark> = (props: LettermarkProps) => {
|
||||
const Template: StoryFn<typeof Lettermark> = (props: LettermarkProps) => {
|
||||
return <Lettermark {...props} />
|
||||
}
|
||||
|
||||
export const Base = Template.bind({})
|
||||
export const Base: Story = Template.bind({})
|
||||
Base.args = { name: 'Athena' }
|
||||
|
||||
export const Overview = (): JSX.Element => {
|
||||
@@ -47,14 +50,14 @@ export const Overview = (): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
export const String = Template.bind({})
|
||||
export const String: Story = Template.bind({})
|
||||
String.args = { name: 'Athena' }
|
||||
|
||||
export const Number = Template.bind({})
|
||||
export const Number: Story = Template.bind({})
|
||||
Number.args = { name: 42 }
|
||||
|
||||
export const Unknown = Template.bind({})
|
||||
export const Unknown: Story = Template.bind({})
|
||||
Unknown.args = { name: null }
|
||||
|
||||
export const Gray = Template.bind({})
|
||||
export const Gray: Story = Template.bind({})
|
||||
Gray.args = { name: 5, color: LettermarkColor.Gray }
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { Link, LinkProps } from './Link'
|
||||
import { urls } from 'scenes/urls'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Link>
|
||||
const meta: Meta<typeof Link> = {
|
||||
title: 'Lemon UI/Link',
|
||||
component: Link,
|
||||
argTypes: {
|
||||
children: {
|
||||
defaultValue: 'Click me',
|
||||
},
|
||||
args: {
|
||||
children: 'Click me',
|
||||
},
|
||||
} as ComponentMeta<typeof Link>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const BasicTemplate: ComponentStory<typeof Link> = (props: LinkProps) => {
|
||||
const BasicTemplate: StoryFn<typeof Link> = (props: LinkProps) => {
|
||||
return <Link {...props} />
|
||||
}
|
||||
|
||||
export const Default = BasicTemplate.bind({})
|
||||
export const Default: Story = BasicTemplate.bind({})
|
||||
Default.args = {}
|
||||
|
||||
export const ToLink = BasicTemplate.bind({})
|
||||
export const ToLink: Story = BasicTemplate.bind({})
|
||||
ToLink.args = {
|
||||
to: urls.projectHomepage(),
|
||||
}
|
||||
|
||||
export const DisabledWithReason = BasicTemplate.bind({})
|
||||
export const DisabledWithReason: Story = BasicTemplate.bind({})
|
||||
DisabledWithReason.args = {
|
||||
disabledReason: 'Not allowed',
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { PaginationControl, PaginationControlProps } from './PaginationControl'
|
||||
import { usePagination } from './usePagination'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof PaginationControl>
|
||||
const meta: Meta<typeof PaginationControl> = {
|
||||
title: 'Lemon UI/Pagination Control',
|
||||
component: PaginationControl,
|
||||
} as ComponentMeta<typeof PaginationControl>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const DATA_SOURCE = Array(43)
|
||||
.fill(null)
|
||||
.map((_, index) => index)
|
||||
|
||||
const Template: ComponentStory<typeof PaginationControl> = (props: Partial<PaginationControlProps<any>>) => {
|
||||
const Template: StoryFn<typeof PaginationControl> = (props: Partial<PaginationControlProps<any>>) => {
|
||||
const state = usePagination(DATA_SOURCE, { pageSize: 10 })
|
||||
return <PaginationControl {...state} {...props} />
|
||||
}
|
||||
@@ -19,5 +22,5 @@ const Template: ComponentStory<typeof PaginationControl> = (props: Partial<Pagin
|
||||
export const PaginationControl_ = Template.bind({})
|
||||
PaginationControl_.args = {}
|
||||
|
||||
export const Bordered = Template.bind({})
|
||||
export const Bordered: Story = Template.bind({})
|
||||
Bordered.args = { bordered: true }
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react'
|
||||
import { StoryFn, Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Popover } from './Popover'
|
||||
import { IconArrowDropDown } from 'lib/lemon-ui/icons'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Popover>
|
||||
const meta: Meta<typeof Popover> = {
|
||||
title: 'Lemon UI/Popover',
|
||||
component: Popover,
|
||||
parameters: {
|
||||
@@ -11,11 +12,13 @@ export default {
|
||||
skip: true, // FIXME: This story needs a play test for the popup to show up in snapshots
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Popover>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof Popover> = (args) => <Popover {...args} />
|
||||
const Template: StoryFn<typeof Popover> = (args) => <Popover {...args} />
|
||||
|
||||
export const Popover_ = Template.bind({})
|
||||
export const Popover_: Story = Template.bind({})
|
||||
Popover_.args = {
|
||||
visible: true,
|
||||
children: (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ProfileBubbles as ProfileBubblesComponent, ProfileBubblesProps } from './ProfileBubbles'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import { alphabet, range } from 'lib/utils'
|
||||
|
||||
const DUMMIES: ProfileBubblesProps['people'] = [
|
||||
@@ -9,15 +9,15 @@ const DUMMIES: ProfileBubblesProps['people'] = [
|
||||
{ email: 'joe@posthog.com', name: 'Joe' },
|
||||
]
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof ProfileBubblesComponent> = {
|
||||
title: 'Lemon UI/Profile Bubbles',
|
||||
component: ProfileBubblesComponent,
|
||||
argTypes: {
|
||||
people: {
|
||||
defaultValue: DUMMIES,
|
||||
},
|
||||
args: {
|
||||
people: DUMMIES,
|
||||
},
|
||||
} as ComponentMeta<typeof ProfileBubblesComponent>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function OneBubble(props: any): JSX.Element {
|
||||
return <ProfileBubblesComponent {...props} people={DUMMIES.slice(0, 1)} />
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
import { Spinner as Spinner, SpinnerOverlay } from './Spinner'
|
||||
import { LemonButton } from '@posthog/lemon-ui'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof Spinner> = {
|
||||
title: 'Lemon UI/Spinner',
|
||||
component: Spinner,
|
||||
} as ComponentMeta<typeof Spinner>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function Default(): JSX.Element {
|
||||
return <Spinner />
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn } from '@storybook/react'
|
||||
import { Splotch, SplotchColor, SplotchProps } from './Splotch'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof Splotch> = {
|
||||
title: 'Lemon UI/Splotch',
|
||||
component: Splotch,
|
||||
argTypes: {
|
||||
color: {
|
||||
defaultValue: SplotchColor.Purple,
|
||||
},
|
||||
args: {
|
||||
color: SplotchColor.Purple,
|
||||
},
|
||||
} as ComponentMeta<typeof Splotch>
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
export const _Splotch: ComponentStory<typeof Splotch> = (props: SplotchProps) => {
|
||||
export const _Splotch: StoryFn<typeof Splotch> = (props: SplotchProps) => {
|
||||
return <Splotch {...props} />
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@ import { Meta } from '@storybook/react'
|
||||
import { Popover } from './Popover/Popover'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Lemon UI/Colors',
|
||||
parameters: {
|
||||
options: { showPanel: false },
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Colors can be used in a variety of ways',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
const colorGroups = {
|
||||
primary: ['primary-highlight', 'primary-light', 'primary', 'primary-dark'],
|
||||
danger: ['danger-highlight', 'danger-light', 'danger', 'danger-dark'],
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import * as React from 'react'
|
||||
import * as icons from './icons'
|
||||
import { Meta, Story } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { LemonTable } from 'lib/lemon-ui/LemonTable'
|
||||
import { LemonCheckbox } from 'lib/lemon-ui/LemonCheckbox'
|
||||
import { LemonButton } from 'lib/lemon-ui/LemonButton'
|
||||
|
||||
const { IconGauge, IconWithCount } = icons
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Lemon UI/Icons',
|
||||
parameters: {
|
||||
options: { showPanel: false },
|
||||
docs: {
|
||||
description: {
|
||||
component: `
|
||||
@@ -28,7 +27,9 @@ When adding new icons from Figma please make sure to:
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
export default meta
|
||||
|
||||
interface IconDefinition {
|
||||
name: string
|
||||
@@ -40,7 +41,8 @@ const allIcons: IconDefinition[] = Object.entries(icons)
|
||||
.map(([key, Icon]) => ({ name: key, icon: Icon }))
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
||||
const LibraryTemplate: Story<{ letter?: string | null }> = ({ letter }) => {
|
||||
type LibraryType = StoryObj<{ letter?: string | null }>
|
||||
const LibraryTemplate: StoryFn<{ letter?: string | null }> = ({ letter }) => {
|
||||
const [showBorder, setShowBorder] = React.useState(true)
|
||||
const filteredIcons =
|
||||
letter === undefined
|
||||
@@ -101,90 +103,90 @@ const LibraryTemplate: Story<{ letter?: string | null }> = ({ letter }) => {
|
||||
}
|
||||
|
||||
// This is for actual Storybook users
|
||||
export const Library = LibraryTemplate.bind({})
|
||||
export const Library: LibraryType = LibraryTemplate.bind({})
|
||||
Library.parameters = { testOptions: { skip: true } }
|
||||
|
||||
// These are just for snapshots. As opposed to the full library, the stories below are segmented by the first letter
|
||||
// of the icon name, which greatly optimizes both the UX and storage aspects of diffing snapshots.
|
||||
export const ShelfA = LibraryTemplate.bind({})
|
||||
export const ShelfA: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfA.args = { letter: 'a' }
|
||||
ShelfA.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfB = LibraryTemplate.bind({})
|
||||
export const ShelfB: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfB.args = { letter: 'b' }
|
||||
ShelfB.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfC = LibraryTemplate.bind({})
|
||||
export const ShelfC: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfC.args = { letter: 'c' }
|
||||
ShelfC.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfD = LibraryTemplate.bind({})
|
||||
export const ShelfD: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfD.args = { letter: 'd' }
|
||||
ShelfD.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfE = LibraryTemplate.bind({})
|
||||
export const ShelfE: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfE.args = { letter: 'e' }
|
||||
ShelfE.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfF = LibraryTemplate.bind({})
|
||||
export const ShelfF: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfF.args = { letter: 'f' }
|
||||
ShelfF.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfG = LibraryTemplate.bind({})
|
||||
export const ShelfG: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfG.args = { letter: 'g' }
|
||||
ShelfG.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfH = LibraryTemplate.bind({})
|
||||
export const ShelfH: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfH.args = { letter: 'h' }
|
||||
ShelfH.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfI = LibraryTemplate.bind({})
|
||||
export const ShelfI: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfI.args = { letter: 'i' }
|
||||
ShelfI.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfJ = LibraryTemplate.bind({})
|
||||
export const ShelfJ: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfJ.args = { letter: 'j' }
|
||||
ShelfJ.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfK = LibraryTemplate.bind({})
|
||||
export const ShelfK: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfK.args = { letter: 'k' }
|
||||
ShelfK.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfL = LibraryTemplate.bind({})
|
||||
export const ShelfL: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfL.args = { letter: 'l' }
|
||||
ShelfL.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfM = LibraryTemplate.bind({})
|
||||
export const ShelfM: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfM.args = { letter: 'm' }
|
||||
ShelfM.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfN = LibraryTemplate.bind({})
|
||||
export const ShelfN: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfN.args = { letter: 'n' }
|
||||
ShelfN.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfO = LibraryTemplate.bind({})
|
||||
export const ShelfO: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfO.args = { letter: 'o' }
|
||||
ShelfO.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfP = LibraryTemplate.bind({})
|
||||
export const ShelfP: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfP.args = { letter: 'p' }
|
||||
ShelfP.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfQ = LibraryTemplate.bind({})
|
||||
export const ShelfQ: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfQ.args = { letter: 'q' }
|
||||
ShelfQ.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfR = LibraryTemplate.bind({})
|
||||
export const ShelfR: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfR.args = { letter: 'r' }
|
||||
ShelfR.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfS = LibraryTemplate.bind({})
|
||||
export const ShelfS: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfS.args = { letter: 's' }
|
||||
ShelfS.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfT = LibraryTemplate.bind({})
|
||||
export const ShelfT: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfT.args = { letter: 't' }
|
||||
ShelfT.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfU = LibraryTemplate.bind({})
|
||||
export const ShelfU: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfU.args = { letter: 'u' }
|
||||
ShelfU.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfV = LibraryTemplate.bind({})
|
||||
export const ShelfV: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfV.args = { letter: 'v' }
|
||||
ShelfV.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfW = LibraryTemplate.bind({})
|
||||
export const ShelfW: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfW.args = { letter: 'w' }
|
||||
ShelfW.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfX = LibraryTemplate.bind({})
|
||||
export const ShelfX: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfX.args = { letter: 'x' }
|
||||
ShelfX.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfY = LibraryTemplate.bind({})
|
||||
export const ShelfY: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfY.args = { letter: 'y' }
|
||||
ShelfY.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfZ = LibraryTemplate.bind({})
|
||||
export const ShelfZ: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfZ.args = { letter: 'z' }
|
||||
ShelfZ.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
export const ShelfOther = LibraryTemplate.bind({})
|
||||
export const ShelfOther: LibraryType = LibraryTemplate.bind({})
|
||||
ShelfOther.args = { letter: null }
|
||||
ShelfOther.parameters = { testOptions: { snapshotTargetSelector: '.LemonTable tbody' } }
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import { ModalPrompt, PopupPrompt, Prompt } from './Prompt'
|
||||
import { promptLogic } from './promptLogic'
|
||||
import BlankDashboardHog from 'public/blank-dashboard-hog.png'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Components/Prompts',
|
||||
component: Prompt,
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export function ModalPrompt_(): JSX.Element {
|
||||
// Ideally we'd instead mock the feature flag and payload but I couldn't get that to work
|
||||
const payload = {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { rest, setupWorker } from 'msw'
|
||||
import { handlers } from '~/mocks/handlers'
|
||||
import { Mocks, mocksToHandlers } from '~/mocks/utils'
|
||||
import { DecoratorFunction } from '@storybook/addons'
|
||||
import { DecoratorFunction } from '@storybook/types'
|
||||
|
||||
// Default handlers ensure no request is unhandled by msw
|
||||
export const worker = setupWorker(...handlers)
|
||||
|
||||
export const useStorybookMocks = (mocks: Mocks): void => worker.use(...mocksToHandlers(mocks))
|
||||
|
||||
export const mswDecorator = (mocks: Mocks): DecoratorFunction<JSX.Element> => {
|
||||
export const mswDecorator = (mocks: Mocks): DecoratorFunction<any> => {
|
||||
return function StoryMock(Story, { parameters }): JSX.Element {
|
||||
// merge the default mocks provided in `preview.tsx` with any provided by the story
|
||||
// allow the story to override defaults
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { examples } from '~/queries/examples'
|
||||
import { mswDecorator } from '~/mocks/browser'
|
||||
import events from './__mocks__/EventsNode.json'
|
||||
import persons from './__mocks__/PersonsNode.json'
|
||||
import { Query } from '~/queries/Query/Query'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Query>
|
||||
const meta: Meta<typeof Query> = {
|
||||
title: 'Queries/DataNode',
|
||||
component: Query,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
testOptions: { skip: true },
|
||||
},
|
||||
argTypes: {
|
||||
query: { defaultValue: {} },
|
||||
},
|
||||
decorators: [
|
||||
mswDecorator({
|
||||
get: {
|
||||
@@ -25,12 +22,13 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as ComponentMeta<typeof Query>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const QueryTemplate: ComponentStory<typeof Query> = (args) => <Query {...args} context={{ showQueryEditor: true }} />
|
||||
const QueryTemplate: StoryFn<typeof Query> = (args) => <Query {...args} context={{ showQueryEditor: true }} />
|
||||
|
||||
export const Events = QueryTemplate.bind({})
|
||||
export const Events: Story = QueryTemplate.bind({})
|
||||
Events.args = { query: examples['Events'] }
|
||||
|
||||
export const Persons = QueryTemplate.bind({})
|
||||
export const Persons: Story = QueryTemplate.bind({})
|
||||
Persons.args = { query: examples['Persons'] }
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { Query } from '~/queries/Query/Query'
|
||||
import { examples } from './DataTable.examples'
|
||||
import { mswDecorator } from '~/mocks/browser'
|
||||
import events from '../DataNode/__mocks__/EventsNode.json'
|
||||
import persons from '../DataNode/__mocks__/PersonsNode.json'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof Query>
|
||||
const meta: Meta<typeof Query> = {
|
||||
title: 'Queries/DataTable',
|
||||
component: Query,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
testOptions: { skip: true },
|
||||
},
|
||||
argTypes: {
|
||||
query: { defaultValue: {} },
|
||||
},
|
||||
decorators: [
|
||||
mswDecorator({
|
||||
get: {
|
||||
@@ -25,30 +22,31 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as ComponentMeta<typeof Query>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const QueryTemplate: ComponentStory<typeof Query> = (args) => <Query {...args} context={{ showQueryEditor: true }} />
|
||||
const QueryTemplate: StoryFn<typeof Query> = (args) => <Query {...args} context={{ showQueryEditor: true }} />
|
||||
|
||||
export const AllDefaults = QueryTemplate.bind({})
|
||||
export const AllDefaults: Story = QueryTemplate.bind({})
|
||||
AllDefaults.args = { query: examples['AllDefaults'] }
|
||||
|
||||
export const Minimalist = QueryTemplate.bind({})
|
||||
export const Minimalist: Story = QueryTemplate.bind({})
|
||||
Minimalist.args = { query: examples['Minimalist'] }
|
||||
|
||||
export const ManyColumns = QueryTemplate.bind({})
|
||||
export const ManyColumns: Story = QueryTemplate.bind({})
|
||||
ManyColumns.args = { query: examples['ManyColumns'] }
|
||||
|
||||
export const ShowFilters = QueryTemplate.bind({})
|
||||
export const ShowFilters: Story = QueryTemplate.bind({})
|
||||
ShowFilters.args = { query: examples['ShowFilters'] }
|
||||
|
||||
export const ShowTools = QueryTemplate.bind({})
|
||||
export const ShowTools: Story = QueryTemplate.bind({})
|
||||
ShowTools.args = { query: examples['ShowTools'] }
|
||||
|
||||
export const ShowAllTheThings = QueryTemplate.bind({})
|
||||
export const ShowAllTheThings: Story = QueryTemplate.bind({})
|
||||
ShowAllTheThings.args = { query: examples['ShowAllTheThings'] }
|
||||
|
||||
export const Persons = QueryTemplate.bind({})
|
||||
export const Persons: Story = QueryTemplate.bind({})
|
||||
Persons.args = { query: examples['Persons'] }
|
||||
|
||||
export const PersonsTable = QueryTemplate.bind({})
|
||||
export const PersonsTable: Story = QueryTemplate.bind({})
|
||||
PersonsTable.args = { query: examples['PersonsTable'] }
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { FilterLogicalOperator } from '~/types'
|
||||
|
||||
import { AndOrFilterSelect } from './AndOrFilterSelect'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof AndOrFilterSelect>
|
||||
const meta: Meta<typeof AndOrFilterSelect> = {
|
||||
title: 'Filters/PropertyGroupFilters (Data Exploration)/AndOrFilterSelect',
|
||||
component: AndOrFilterSelect,
|
||||
argTypes: {
|
||||
@@ -18,11 +19,12 @@ export default {
|
||||
args: {
|
||||
value: FilterLogicalOperator.And,
|
||||
},
|
||||
} as ComponentMeta<typeof AndOrFilterSelect>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof AndOrFilterSelect> = (args) => {
|
||||
const Template: StoryFn<typeof AndOrFilterSelect> = (args) => {
|
||||
const [value, setValue] = useState(args.value)
|
||||
return <AndOrFilterSelect {...args} value={value} onChange={setValue} />
|
||||
}
|
||||
|
||||
export const Default = Template.bind({})
|
||||
export const Default: Story = Template.bind({})
|
||||
|
||||
@@ -2,13 +2,12 @@ import { Meta } from '@storybook/react'
|
||||
|
||||
import { PreflightCheck } from './PreflightCheck'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Preflight',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const Preflight = (): JSX.Element => <PreflightCheck />
|
||||
|
||||
@@ -2,13 +2,12 @@ import { Meta } from '@storybook/react'
|
||||
|
||||
import { Unsubscribe } from './Unsubscribe'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Unsubscribe',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const UnsubscribeScene = (): JSX.Element => <Unsubscribe />
|
||||
|
||||
@@ -6,11 +6,10 @@ import { urls } from 'scenes/urls'
|
||||
import { mswDecorator } from '~/mocks/browser'
|
||||
import annotations from './__mocks__/annotations.json'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-App/Annotations',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
testOptions: {
|
||||
excludeNavigationFromSnapshot: true,
|
||||
},
|
||||
@@ -28,8 +27,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const Annotations = (): JSX.Element => {
|
||||
useEffect(() => {
|
||||
router.actions.push(urls.annotations())
|
||||
|
||||
@@ -8,11 +8,10 @@ import { urls } from 'scenes/urls'
|
||||
import { AvailableFeature } from '~/types'
|
||||
import { useAvailableFeatures } from '~/mocks/features'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-App/Apps/App Metrics',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
testOptions: {
|
||||
excludeNavigationFromSnapshot: true,
|
||||
},
|
||||
@@ -81,8 +80,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const AppMetrics: Story = () => {
|
||||
useAvailableFeatures([AvailableFeature.APP_METRICS])
|
||||
useEffect(() => {
|
||||
|
||||
@@ -6,11 +6,10 @@ import preflightJson from '~/mocks/fixtures/_preflight.json'
|
||||
import { InviteSignup } from './InviteSignup'
|
||||
import { inviteSignupLogic } from './inviteSignupLogic'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/InviteSignup',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
decorators: [
|
||||
@@ -33,8 +32,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const SelfHosted = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
get: {
|
||||
|
||||
@@ -9,11 +9,10 @@ import { urls } from 'scenes/urls'
|
||||
import { loginLogic } from './loginLogic'
|
||||
import { Login2FA } from './Login2FA'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Login',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
decorators: [
|
||||
@@ -23,8 +22,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const Cloud = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
get: {
|
||||
|
||||
@@ -7,15 +7,14 @@ import preflightJson from '~/mocks/fixtures/_preflight.json'
|
||||
import { passwordResetLogic } from 'scenes/authentication/passwordResetLogic'
|
||||
|
||||
// some metadata and optional parameters
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Password Reset',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
// export more stories with different state
|
||||
export const NoSMTP = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
|
||||
@@ -7,15 +7,14 @@ import { urls } from 'scenes/urls'
|
||||
import { useStorybookMocks } from '~/mocks/browser'
|
||||
|
||||
// some metadata and optional parameters
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Password Reset Complete',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
// export more stories with different state
|
||||
export const Default = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
|
||||
@@ -6,11 +6,10 @@ import { userLogic } from 'scenes/userLogic'
|
||||
import preflightJson from '~/mocks/fixtures/_preflight.json'
|
||||
import { SignupContainer } from './SignupContainer'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Signup',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
decorators: [
|
||||
@@ -19,8 +18,8 @@ export default {
|
||||
post: { '/api/signup': (_, __, ctx) => [ctx.delay(1000), ctx.status(200), ctx.json({ success: true })] },
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const SelfHosted = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
get: {
|
||||
|
||||
@@ -4,15 +4,14 @@ import { useEffect } from 'react'
|
||||
import { VerifyEmail } from './VerifyEmail'
|
||||
import { verifyEmailLogic } from './verifyEmailLogic'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Verify Email',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
},
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const VerifyEmailPending: Story = () => {
|
||||
useEffect(() => {
|
||||
verifyEmailLogic.actions.setView('pending')
|
||||
|
||||
@@ -5,11 +5,10 @@ import preflightJson from '~/mocks/fixtures/_preflight.json'
|
||||
import billingJson from '~/mocks/fixtures/_billing_v2.json'
|
||||
import billingJsonWithDiscount from '~/mocks/fixtures/_billing_v2_with_discount.json'
|
||||
|
||||
export default {
|
||||
const meta: Meta = {
|
||||
title: 'Scenes-Other/Billing v2',
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
options: { showPanel: false },
|
||||
viewMode: 'story',
|
||||
mockDate: '2023-05-25',
|
||||
},
|
||||
@@ -24,8 +23,8 @@ export default {
|
||||
},
|
||||
}),
|
||||
],
|
||||
} as Meta
|
||||
|
||||
}
|
||||
export default meta
|
||||
export const _BillingV2 = (): JSX.Element => {
|
||||
useStorybookMocks({
|
||||
get: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta } from '@storybook/react'
|
||||
import { Meta } from '@storybook/react'
|
||||
import {
|
||||
CohortCriteriaRowBuilder,
|
||||
CohortCriteriaRowBuilderProps,
|
||||
@@ -13,11 +13,12 @@ import { BehavioralEventType } from '~/types'
|
||||
import { Form } from 'kea-forms'
|
||||
import { cohortEditLogic } from 'scenes/cohorts/cohortEditLogic'
|
||||
|
||||
export default {
|
||||
const meta: Meta<typeof CohortCriteriaRowBuilder> = {
|
||||
title: 'Filters/Cohort Filters/Row Builder',
|
||||
component: CohortCriteriaRowBuilder,
|
||||
decorators: [taxonomicFilterMocksDecorator],
|
||||
} as ComponentMeta<typeof CohortCriteriaRowBuilder>
|
||||
}
|
||||
export default meta
|
||||
|
||||
export function _CohortCriteriaRowBuilder(props: CohortCriteriaRowBuilderProps): JSX.Element {
|
||||
useMountedLogic(actionsModel)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { CohortNumberField } from './CohortField'
|
||||
import { renderField } from 'scenes/cohorts/CohortFilters/constants'
|
||||
import { CohortNumberFieldProps, FilterType } from 'scenes/cohorts/CohortFilters/types'
|
||||
import { useMountedLogic } from 'kea'
|
||||
import { cohortEditLogic } from 'scenes/cohorts/cohortEditLogic'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof CohortNumberField>
|
||||
const meta: Meta<typeof CohortNumberField> = {
|
||||
title: 'Filters/Cohort Filters/Fields/Number',
|
||||
component: CohortNumberField,
|
||||
} as ComponentMeta<typeof CohortNumberField>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof CohortNumberField> = (props: CohortNumberFieldProps) => {
|
||||
const Template: StoryFn<typeof CohortNumberField> = (props: CohortNumberFieldProps) => {
|
||||
useMountedLogic(cohortEditLogic({ id: 1 }))
|
||||
const [value, setValue] = useState<number>(30)
|
||||
return renderField[FilterType.Number]({
|
||||
@@ -24,5 +26,5 @@ const Template: ComponentStory<typeof CohortNumberField> = (props: CohortNumberF
|
||||
})
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { CohortPersonPropertiesValuesField } from './CohortField'
|
||||
import { renderField } from 'scenes/cohorts/CohortFilters/constants'
|
||||
import { CohortPersonPropertiesValuesFieldProps, FilterType } from 'scenes/cohorts/CohortFilters/types'
|
||||
import { PropertyOperator } from '~/types'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof CohortPersonPropertiesValuesField>
|
||||
const meta: Meta<typeof CohortPersonPropertiesValuesField> = {
|
||||
title: 'Filters/Cohort Filters/Fields/Person Properties',
|
||||
component: CohortPersonPropertiesValuesField,
|
||||
} as ComponentMeta<typeof CohortPersonPropertiesValuesField>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof CohortPersonPropertiesValuesField> = (
|
||||
props: CohortPersonPropertiesValuesFieldProps
|
||||
) => {
|
||||
const Template: StoryFn<typeof CohortPersonPropertiesValuesField> = (props: CohortPersonPropertiesValuesFieldProps) => {
|
||||
const [value, setValue] = useState<string | undefined>('Chrome')
|
||||
return renderField[FilterType.PersonPropertyValues]({
|
||||
...props,
|
||||
@@ -23,5 +23,5 @@ const Template: ComponentStory<typeof CohortPersonPropertiesValuesField> = (
|
||||
})
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { CohortSelectorField } from './CohortField'
|
||||
import { CohortSelectorFieldProps, FieldOptionsType } from 'scenes/cohorts/CohortFilters/types'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof CohortSelectorField>
|
||||
const meta: Meta<typeof CohortSelectorField> = {
|
||||
title: 'Filters/Cohort Filters/Fields/Select',
|
||||
component: CohortSelectorField,
|
||||
} as ComponentMeta<typeof CohortSelectorField>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof CohortSelectorField> = (props: CohortSelectorFieldProps) => {
|
||||
const Template: StoryFn<typeof CohortSelectorField> = (props: CohortSelectorFieldProps) => {
|
||||
const [value, setValue] = useState<string | undefined>(
|
||||
Object.keys(props.fieldOptionGroupTypes?.[0] ?? {})?.[0] ?? null
|
||||
)
|
||||
@@ -22,19 +24,19 @@ const Template: ComponentStory<typeof CohortSelectorField> = (props: CohortSelec
|
||||
)
|
||||
}
|
||||
|
||||
export const AggregationSelector = Template.bind({})
|
||||
export const AggregationSelector: Story = Template.bind({})
|
||||
AggregationSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.EventAggregation, FieldOptionsType.PropertyAggregation],
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const ActorsSelector = Template.bind({})
|
||||
export const ActorsSelector: Story = Template.bind({})
|
||||
ActorsSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.Actors],
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const BehavioralSelector = Template.bind({})
|
||||
export const BehavioralSelector: Story = Template.bind({})
|
||||
BehavioralSelector.args = {
|
||||
fieldOptionGroupTypes: [
|
||||
FieldOptionsType.EventBehavioral,
|
||||
@@ -45,25 +47,25 @@ BehavioralSelector.args = {
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const TimeUnitSelector = Template.bind({})
|
||||
export const TimeUnitSelector: Story = Template.bind({})
|
||||
TimeUnitSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.TimeUnits],
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const DateOperatorSelector = Template.bind({})
|
||||
export const DateOperatorSelector: Story = Template.bind({})
|
||||
DateOperatorSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.DateOperators],
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const MathOperatorSelector = Template.bind({})
|
||||
export const MathOperatorSelector: Story = Template.bind({})
|
||||
MathOperatorSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.MathOperators],
|
||||
placeholder: 'Choose',
|
||||
}
|
||||
|
||||
export const ValueOptionSelector = Template.bind({})
|
||||
export const ValueOptionSelector: Story = Template.bind({})
|
||||
ValueOptionSelector.args = {
|
||||
fieldOptionGroupTypes: [FieldOptionsType.ValueOptions],
|
||||
placeholder: 'Choose',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { CohortTaxonomicField } from './CohortField'
|
||||
import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
|
||||
import { taxonomicFilterMocksDecorator } from 'lib/components/TaxonomicFilter/__mocks__/taxonomicFilterMocksDecorator'
|
||||
@@ -8,13 +8,15 @@ import { actionsModel } from '~/models/actionsModel'
|
||||
import { renderField } from 'scenes/cohorts/CohortFilters/constants'
|
||||
import { CohortTaxonomicFieldProps, FilterType } from 'scenes/cohorts/CohortFilters/types'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof CohortTaxonomicField>
|
||||
const meta: Meta<typeof CohortTaxonomicField> = {
|
||||
title: 'Filters/Cohort Filters/Fields/Taxonomic',
|
||||
component: CohortTaxonomicField,
|
||||
decorators: [taxonomicFilterMocksDecorator],
|
||||
} as ComponentMeta<typeof CohortTaxonomicField>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof CohortTaxonomicField> = (props: CohortTaxonomicFieldProps) => {
|
||||
const Template: StoryFn<typeof CohortTaxonomicField> = (props: CohortTaxonomicFieldProps) => {
|
||||
useMountedLogic(actionsModel)
|
||||
const [value, setValue] = useState<string | undefined>('')
|
||||
const type =
|
||||
@@ -33,13 +35,13 @@ const Template: ComponentStory<typeof CohortTaxonomicField> = (props: CohortTaxo
|
||||
})
|
||||
}
|
||||
|
||||
export const EventsAndActions = Template.bind({})
|
||||
export const EventsAndActions: Story = Template.bind({})
|
||||
EventsAndActions.args = {
|
||||
taxonomicGroupTypes: [TaxonomicFilterGroupType.Events, TaxonomicFilterGroupType.Actions],
|
||||
placeholder: 'Choose event or action',
|
||||
}
|
||||
|
||||
export const PersonProperties = Template.bind({})
|
||||
export const PersonProperties: Story = Template.bind({})
|
||||
PersonProperties.args = {
|
||||
taxonomicGroupTypes: [TaxonomicFilterGroupType.PersonProperties],
|
||||
placeholder: 'Choose person property',
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
||||
import { Meta, StoryFn, StoryObj } from '@storybook/react'
|
||||
import { CohortTextField } from './CohortField'
|
||||
import { renderField } from 'scenes/cohorts/CohortFilters/constants'
|
||||
import { CohortTextFieldProps, FilterType } from 'scenes/cohorts/CohortFilters/types'
|
||||
|
||||
export default {
|
||||
type Story = StoryObj<typeof CohortTextField>
|
||||
const meta: Meta<typeof CohortTextField> = {
|
||||
title: 'Filters/Cohort Filters/Fields/Text',
|
||||
component: CohortTextField,
|
||||
} as ComponentMeta<typeof CohortTextField>
|
||||
}
|
||||
export default meta
|
||||
|
||||
const Template: ComponentStory<typeof CohortTextField> = (props: CohortTextFieldProps) => {
|
||||
const Template: StoryFn<typeof CohortTextField> = (props: CohortTextFieldProps) => {
|
||||
return renderField[FilterType.Text]({
|
||||
...props,
|
||||
value: 'in the last',
|
||||
})
|
||||
}
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
export const Basic: Story = Template.bind({})
|
||||
Basic.args = {}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user