Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/client/src/components/ads/IconSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Size } from "./Button";
import { CommonComponentProps, Classes } from "./common";
import ScrollIndicator from "components/ads/ScrollIndicator";

type IconSelectorProps = CommonComponentProps & {
export type IconSelectorProps = CommonComponentProps & {
onSelect?: (icon: AppIconName) => void;
selectedColor: string;
selectedIcon?: AppIconName;
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/components/ads/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Popover } from "@blueprintjs/core/lib/esm/components/popover/popover";
import { Position } from "@blueprintjs/core/lib/esm/common/position";
import { PopperModifiers } from "@blueprintjs/core";

type MenuProps = CommonComponentProps & {
export type MenuProps = CommonComponentProps & {
children?: ReactNode[];
target: JSX.Element;
position?: Position;
Expand Down
18 changes: 7 additions & 11 deletions app/client/src/components/ads/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ const StyledInput = styled((props) => {
inputStyle: boxReturnType;
isValid: boolean;
rightSideComponentWidth: number;
hasLeftIcon: boolean;
}
>`
width: ${(props) => (props.fill ? "100%" : "260px")};
Expand All @@ -113,25 +114,19 @@ const StyledInput = styled((props) => {
padding: 0px ${(props) => props.theme.spaces[5]}px;
height: 36px;
padding-right: ${(props) =>
props.rightSideComponentWidth + props.theme.spaces[6]}px;
props.rightSideComponentWidth + props.theme.spaces[5]}px;
padding-left: ${(props) =>
props.hasLeftIcon ? "35" : props.theme.spaces[5]}px;
background-color: ${(props) => props.inputStyle.bgColor};
color: ${(props) => props.inputStyle.color};
${(props) =>
props.leftIcon &&
IconCollection.includes(props.leftIcon) &&
`
padding-left: 35px;`};

&:-internal-autofill-selected,
&:-webkit-autofill,
&:-webkit-autofill:hover,
&:-webkit-autofill:focus {
-webkit-box-shadow: 0 0 0 30px ${(props) =>
props.inputStyle.bgColor} inset !important;
-webkit-box-shadow: 0 0 0 30px ${(props) => props.inputStyle.bgColor} inset !important;
-webkit-text-fill-color: ${(props) => props.inputStyle.color} !important;
}
&:hover {
background-color: ${(props) =>
props.disabled
Expand Down Expand Up @@ -267,6 +262,7 @@ const TextInput = forwardRef(
type={props.dataType || "text"}
{...props}
data-cy={props.cypressSelector}
hasLeftIcon={IconCollection.includes(props.leftIcon)}
inputRef={ref}
onChange={memoizedChangeHandler}
placeholder={props.placeholder}
Expand Down
77 changes: 47 additions & 30 deletions app/client/src/components/stories/IconSelector.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,57 @@
import React from "react";
import { withKnobs, select, boolean } from "@storybook/addon-knobs";
import { withDesign } from "storybook-addon-designs";
import IconSelector from "components/ads/IconSelector";
import IconSelector, { IconSelectorProps } from "components/ads/IconSelector";
import { action } from "@storybook/addon-actions";
import { AppIconCollection } from "components/ads/AppIcon";
import { StoryWrapper } from "components/ads/common";
import { storyName } from "./config/constants";
import { controlType, statusType } from "./config/types";

export default {
title: "IconSelector",
title: storyName.platform.icons.iconSelector.PATH,
component: IconSelector,
decorators: [withKnobs, withDesign],
decorators: [withDesign],
parameters: {
status: {
type: statusType.STABLE,
},
},
};

export function IconPicker() {
return (
<StoryWrapper>
<IconSelector
fill={boolean("fill", false)}
onSelect={action("icon-selected")}
selectedColor={select(
"select color",
[
"#4F70FD",
"#54A9FB",
"#5ED3DA",
"#F56AF4",
"#F36380",
"#FE9F44",
"#E9C951",
"#A8D76C",
"#6C4CF1",
],
"#54A9FB",
)}
selectedIcon={select("select icon", AppIconCollection, "bag")}
/>
</StoryWrapper>
);
export function IconSelectorStory(args: IconSelectorProps) {
return <IconSelector {...args} onSelect={action("icon-selected")} />;
}

IconSelectorStory.args = {
selectedColor: "#54A9FB",
selectedIcon: "bag",
iconPalette: AppIconCollection,
fill: false,
};

IconSelectorStory.argTypes = {
selectedColor: {
control: controlType.SELECT,
options: [
"#4F70FD",
"#54A9FB",
"#5ED3DA",
"#F56AF4",
"#F36380",
"#FE9F44",
"#E9C951",
"#A8D76C",
"#6C4CF1",
],
},
selectedIcon: {
control: controlType.SELECT,
options: AppIconCollection,
},
iconPalette: {
control: controlType.ARRAY,
options: AppIconCollection,
},
fill: { control: controlType.BOOLEAN },
};

IconSelectorStory.storyName = storyName.platform.icons.iconSelector.NAME;
85 changes: 48 additions & 37 deletions app/client/src/components/stories/Menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import React, { useState } from "react";
import { boolean, select, text, withKnobs } from "@storybook/addon-knobs";
import { withDesign } from "storybook-addon-designs";
import Menu from "components/ads/Menu";
import Menu, { MenuProps } from "components/ads/Menu";
import { action } from "@storybook/addon-actions";
import MenuDivider from "components/ads/MenuDivider";
import MenuItem from "components/ads/MenuItem";
import { Position } from "@blueprintjs/core/lib/esm/common/position";
import ColorSelector from "components/ads/ColorSelector";
import { AppIconCollection } from "components/ads/AppIcon";
import IconSelector from "components/ads/IconSelector";
import EditableText, {
SavingState,
EditInteractionKind,
} from "components/ads/EditableText";
import { IconCollection, IconName } from "components/ads/Icon";
import { theme } from "constants/DefaultTheme";
import { storyName } from "./config/constants";
import { controlType, statusType } from "./config/types";

export default {
title: "Menu",
component: Menu,
decorators: [withKnobs, withDesign],
title: storyName.platform.menus.menu.PATH,
component: IconSelector,
decorators: [withDesign],
parameters: {
status: {
type: statusType.STABLE,
},
},
};

const errorFunction = (name: string) => {
Expand All @@ -30,14 +34,10 @@ const errorFunction = (name: string) => {
}
};

export function MenuStory() {
export function MenuStory(args: MenuProps) {
const [selectedColor, setSelectedColor] = useState<string>(
theme.colors.appCardColors[0],
);
const [savingState, SetSavingState] = useState<SavingState>(
SavingState.NOT_STARTED,
);

return (
<div
style={{
Expand All @@ -49,7 +49,6 @@ export function MenuStory() {
}}
>
<Menu
position={select("Position", Object.values(Position), Position.RIGHT)}
target={
<div>
<svg
Expand All @@ -69,6 +68,9 @@ export function MenuStory() {
</svg>
</div>
}
{...args}
onClose={action("menu-closed")}
onOpening={action("menu-opended")}
>
<EditableText
defaultValue="Product design app"
Expand All @@ -77,15 +79,10 @@ export function MenuStory() {
hideEditIcon={false}
isEditingDefault={false}
isInvalid={(name: any) => errorFunction(name)}
onBlur={() => {
SetSavingState(SavingState.STARTED);
setTimeout(() => {
SetSavingState(SavingState.SUCCESS);
}, 2000);
}}
onBlur={action("editable-input-blured")}
onTextChanged={action("editable-input-changed")}
placeholder={"Edit text input"}
savingState={savingState}
savingState={SavingState.NOT_STARTED}
valueTransform={(value: any) => value.toUpperCase()}
/>
<ColorSelector
Expand All @@ -98,37 +95,51 @@ export function MenuStory() {
fill={false}
onSelect={action("icon-selected")}
selectedColor={selectedColor}
selectedIcon={select("Select app icon", AppIconCollection, "bag")}
selectedIcon="bag"
/>
<MenuDivider />
<MenuItem
disabled={boolean("First option disabled", false)}
icon={select(
"First Icon",
["Select icon" as IconName, ...IconCollection],
"Select icon" as IconName,
)}
label={<span>W</span>}
onSelect={action("clicked-first-option")}
text={text("First option", "Invite user")}
text="Invite user"
/>
{boolean("First menu item divider", false) ? <MenuDivider /> : null}
<MenuItem
icon={select(
"Second Icon",
["Select icon" as IconName, ...IconCollection],
"Select icon" as IconName,
)}
icon="bug"
label={<span>W</span>}
onSelect={action("clicked-second-option")}
text={text("Second option", "Are you sure")}
text="Are you sure"
/>
{boolean("Second menu item divider", false) ? <MenuDivider /> : null}
<MenuDivider />
<MenuItem
onSelect={action("clicked-third-option")}
text={text("Third option", "Third option text only")}
text="Third option text only"
/>
</Menu>
</div>
);
}

MenuStory.args = {
position: Position.RIGHT,
isOpen: false,
canEscapeKeyClose: true,
canOutsideClickClose: true,
menuItemWrapperWidth: 200,
};

MenuStory.argTypes = {
target: {
control: controlType.OBJECT,
description: "JSX.Element",
},
position: {
control: controlType.SELECT,
options: Object.values(Position),
},
isOpen: { control: controlType.BOOLEAN },
canEscapeKeyClose: { control: controlType.BOOLEAN },
canOutsideClickClose: { control: controlType.BOOLEAN },
menuItemWrapperWidth: { control: controlType.NUMBER },
};

MenuStory.storyName = storyName.platform.menus.menu.NAME;
56 changes: 56 additions & 0 deletions app/client/src/components/stories/MenuItem.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import { withDesign } from "storybook-addon-designs";
import { action } from "@storybook/addon-actions";
import MenuItem, { MenuItemProps } from "components/ads/MenuItem";
import { IconCollection, IconName } from "components/ads/Icon";
import { storyName } from "./config/constants";
import { controlType, statusType } from "./config/types";

export default {
title: storyName.platform.menus.menuItem.PATH,
component: MenuItem,
decorators: [withDesign],
parameters: {
status: {
type: statusType.STABLE,
},
},
};

export function MenuItemStory(args: MenuItemProps) {
if (args.label) {
args.label = <span>{args.label}</span>;
}
return <MenuItem {...args} onSelect={action("menu-item-selected")} />;
}

MenuItemStory.args = {
icon: "Select a icon" as IconName,
text: "Menu Item",
label: "W",
href: "",
type: "warning",
ellipsize: 0,
selected: true,
};

MenuItemStory.argTypes = {
icon: {
control: controlType.SELECT,
options: ["Select a icon" as IconName, ...IconCollection],
},
text: { control: controlType.TEXT },
label: {
control: controlType.TEXT,
description: "ReactNode",
},
href: {
control: controlType.TEXT,
description: "url link",
},
type: { control: controlType.TEXT },
ellipsize: { control: controlType.NUMBER },
selected: { control: controlType.BOOLEAN },
};

MenuItemStory.storyName = storyName.platform.menus.menuItem.NAME;
4 changes: 4 additions & 0 deletions app/client/src/components/stories/TextInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ Primary.argTypes = {
description: "function",
defaultValue: true,
},
rightSideComponent: {
control: controlType.OBJECT,
description: "React.ReactNode",
},
};

Primary.storyName = storyName.platform.form.textInput.NAME;
14 changes: 14 additions & 0 deletions app/client/src/components/stories/config/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ export const storyName = {
PATH: "Platform/Icons/AppIcon",
NAME: "AppIcon",
},
iconSelector: {
PATH: "Platform/Icons/IconSelector",
NAME: "IconSelector",
},
},
menus: {
menu: {
PATH: "Platform/Menus/Menu",
NAME: "Menu",
},
menuItem: {
PATH: "Platform/Menus/MenuItem",
NAME: "MenuItem",
},
},
},
};