feat: adding Storybook to Superset (#10383)

* Storybook added!

* starting to configure junk....

* Storybook works!!!

* Now with theme!

* apache boilerplate

* more apache comments

* lots o' knobs for the Button.... taking stock of the codebase

* more classes, but killing the knob for now.

* nixing unused module

* linting

* fresh package-lock

* now with tooltip!

* adding path and zlip because the linter told me to

* upgrading storybook packages from devdeps

* linting

* removing cruft

* killing an annoying (and old?) lint issue

* lint fix, take 2.

* removing zlib/path

* package lock reset from master

* re-adding new packages for this here PR

* nixing console log, simplifying

* nixing comment TODOs (done enough!)

* basic docs.
This commit is contained in:
Evan Rusackas
2020-07-22 10:21:25 -07:00
committed by GitHub
parent 961108625e
commit ca71d4d6ee
9 changed files with 6663 additions and 239 deletions

View File

@@ -0,0 +1,140 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { action } from '@storybook/addon-actions';
import { withKnobs, boolean, select, text } from '@storybook/addon-knobs';
import Button from './index';
export default {
title: 'Button',
component: Button,
decorators: [withKnobs],
};
const bsStyleKnob = {
label: 'Types',
options: {
Primary: 'primary',
Secondary: 'secondary',
Danger: 'danger',
Warning: 'warning',
Success: 'success',
Link: 'link',
Default: 'default',
None: null,
},
defaultValue: null,
// groupId: 'ButtonType',
};
const bsSizeKnob = {
label: 'Sizes',
options: {
XS: 'xsmall',
S: 'small',
M: 'medium',
L: 'large',
None: null,
},
defaultValue: null,
};
// TODO remove the use of these in the codebase where they're not necessary
// const classKnob = {
// label: 'Known Classes',
// options: {
// Refresh: 'refresh-btn',
// Primary: 'btn-primary',
// Reset: 'reset',
// Fetch: 'fetch',
// Query: 'query',
// saveBtn: 'save-btn',
// MR3: 'm-r-3',
// cancelQuery: 'cancelQuery',
// toggleSave: 'toggleSave',
// toggleSchedule: 'toggleSchedule',
// autocomplete: 'autocomplete',
// OK: 'ok',
// None: null,
// },
// defaultValue: null,
// };
const typeKnob = {
label: 'Type',
options: {
Submit: 'submit',
Button: 'button',
None: null,
},
defaultValue: null,
};
const targetKnob = {
label: 'Target',
options: {
Blank: '_blank',
None: null,
},
defaultValue: null,
};
const hrefKnob = {
label: 'HREF',
options: {
Superset: 'http://https://superset.incubator.apache.org/',
None: null,
},
defaultValue: null,
};
export const SupersetButton = () => (
<Button
disabled={boolean('Disabled', false)}
bsStyle={select(
bsStyleKnob.label,
bsStyleKnob.options,
bsStyleKnob.defaultValue,
bsStyleKnob.groupId,
)}
bsSize={select(
bsSizeKnob.label,
bsSizeKnob.options,
bsSizeKnob.defaultValue,
bsSizeKnob.groupId,
)}
onClick={action('clicked')}
type={select(
typeKnob.label,
typeKnob.options,
typeKnob.defaultValue,
typeKnob.groupId,
)}
target={select(
targetKnob.label,
targetKnob.options,
targetKnob.defaultValue,
targetKnob.groupId,
)}
href={select(
hrefKnob.label,
hrefKnob.options,
hrefKnob.defaultValue,
hrefKnob.groupId,
)}
tooltip={boolean('Tooltip', false) === true ? 'This is a tooltip!' : null}
>
{text('Label', 'Button!')}
</Button>
);

View File

@@ -0,0 +1,114 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { kebabCase } from 'lodash';
import {
Button as BootstrapButton,
Tooltip,
OverlayTrigger,
} from 'react-bootstrap';
import styled from '@superset-ui/style';
export type OnClickHandler = React.MouseEventHandler<BootstrapButton>;
export interface ButtonProps {
className?: string;
tooltip?: string;
placement?: string;
onClick?: OnClickHandler;
disabled?: boolean;
bsStyle?: string;
btnStyles?: string;
bsSize?: BootstrapButton.ButtonProps['bsSize'];
style?: BootstrapButton.ButtonProps['style'];
children?: React.ReactNode;
}
const BUTTON_WRAPPER_STYLE = { display: 'inline-block', cursor: 'not-allowed' };
const SupersetButton = styled(BootstrapButton)`
&.supersetButton {
border-radius: ${({ theme }) => theme.borderRadius}px;
border: none;
color: ${({ theme }) => theme.colors.secondary.light5};
font-size: ${({ theme }) => theme.typography.sizes.s};
font-weight: ${({ theme }) => theme.typography.weights.bold};
min-width: ${({ theme }) => theme.gridUnit * 36}px;
min-height: ${({ theme }) => theme.gridUnit * 8}px;
text-transform: uppercase;
margin-left: ${({ theme }) => theme.gridUnit * 4}px;
&:first-of-type {
margin-left: 0;
}
i {
padding: 0 ${({ theme }) => theme.gridUnit * 2}px 0 0;
}
&.primary {
background-color: ${({ theme }) => theme.colors.primary.base};
}
&.secondary {
color: ${({ theme }) => theme.colors.primary.base};
background-color: ${({ theme }) => theme.colors.primary.light4};
}
&.danger {
background-color: ${({ theme }) => theme.colors.error.base};
}
}
`;
export default function Button(props: ButtonProps) {
const buttonProps = {
...props,
bsSize: props.bsSize || 'sm',
placement: props.placement || 'top',
};
const tooltip = props.tooltip;
const placement = props.placement;
delete buttonProps.tooltip;
delete buttonProps.placement;
let button = (
<SupersetButton {...buttonProps}>{props.children}</SupersetButton>
);
if (tooltip) {
if (props.disabled) {
// Working around the fact that tooltips don't get triggered when buttons are disabled
// https://github.com/react-bootstrap/react-bootstrap/issues/1588
buttonProps.style = { pointerEvents: 'none' };
button = (
<div style={BUTTON_WRAPPER_STYLE}>
<SupersetButton {...buttonProps}>{props.children}</SupersetButton>
</div>
);
}
return (
<OverlayTrigger
placement={placement}
overlay={
<Tooltip id={`${kebabCase(tooltip)}-tooltip`}>{tooltip}</Tooltip>
}
>
{button}
</OverlayTrigger>
);
}
return button;
}