From f5f65dd89e31754aac01739cd7873a497d451ea9 Mon Sep 17 00:00:00 2001 From: devrk96 Date: Mon, 24 Aug 2020 11:30:22 +0530 Subject: [PATCH] table dropdown functionalities and UI implemented (#407) --- .../src/components/ads/TableDropdown.tsx | 109 ++++++++++++++++++ .../stories/TableDropdown.stories.tsx | 37 ++++++ 2 files changed, 146 insertions(+) create mode 100644 app/client/src/components/ads/TableDropdown.tsx create mode 100644 app/client/src/components/stories/TableDropdown.stories.tsx diff --git a/app/client/src/components/ads/TableDropdown.tsx b/app/client/src/components/ads/TableDropdown.tsx new file mode 100644 index 0000000000..ae55039dd9 --- /dev/null +++ b/app/client/src/components/ads/TableDropdown.tsx @@ -0,0 +1,109 @@ +import React, { useCallback, useState } from "react"; +import { CommonComponentProps, hexToRgba } from "./common"; +import { ReactComponent as DownArrow } from "../../assets/icons/ads/down_arrow.svg"; +import Text, { TextType } from "./Text"; +import styled from "styled-components"; + +type DropdownOption = { + label: string; + value: string; +}; + +type DropdownProps = CommonComponentProps & { + options: DropdownOption[]; + onSelect: (selectedValue: string) => void; + selectedOption: DropdownOption; +}; + +const DropdownWrapper = styled.div` + width: 100%; + position: relative; +`; + +const SelectedItem = styled.div` + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + + span { + margin-right: ${props => props.theme.spaces[1] + 1}px; + } +`; + +const OptionsWrapper = styled.div` + position: absolute; + margin-top: ${props => props.theme.spaces[8]}px; + left: -60px; + width: 200px; + display: flex; + flex-direction: column; + background-color: ${props => props.theme.colors.blackShades[3]}; + box-shadow: ${props => props.theme.spaces[0]}px + ${props => props.theme.spaces[5]}px ${props => props.theme.spaces[13] - 2}px + ${props => hexToRgba(props.theme.colors.blackShades[0], 0.75)}; +`; + +const DropdownOption = styled.div<{ + selected: DropdownOption; + option: DropdownOption; +}>` + display: flex; + flex-direction: column; + padding: 10px 12px; + cursor: pointer; + background-color: ${props => + props.option.label === props.selected.label + ? props.theme.colors.blackShades[4] + : "transparent"}; + + span:last-child { + margin-top: ${props => props.theme.spaces[1] + 1}px; + } + + &:hover { + span { + color: ${props => props.theme.colors.blackShades[9]}; + } + } +`; + +const TableDropdown = (props: DropdownProps) => { + const [selected, setSelected] = useState(props.selectedOption); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + const dropdownHandler = () => { + setIsDropdownOpen(!isDropdownOpen); + }; + + const optionSelector = (option: DropdownOption) => { + setSelected(option); + setIsDropdownOpen(false); + }; + + return ( + + dropdownHandler()}> + {selected.label} + + + {isDropdownOpen ? ( + + {props.options.map((el: DropdownOption, index: number) => ( + optionSelector(el)} + > + {el.label} + {el.value} + + ))} + + ) : null} + + ); +}; + +export default TableDropdown; diff --git a/app/client/src/components/stories/TableDropdown.stories.tsx b/app/client/src/components/stories/TableDropdown.stories.tsx new file mode 100644 index 0000000000..6756d92b73 --- /dev/null +++ b/app/client/src/components/stories/TableDropdown.stories.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { withKnobs, select, boolean, text } from "@storybook/addon-knobs"; +import { withDesign } from "storybook-addon-designs"; +import TableDropdown from "../ads/TableDropdown"; + +export default { + title: "Dropdown", + component: TableDropdown, + decorators: [withKnobs, withDesign], +}; + +const options = [ + { + label: "Admin", + value: "Can edit, view and invite other user to an app", + }, + { + label: "Developer", + value: "Can view and invite other user to an app", + }, + { + label: "User", + value: "Can view and invite other user to an app and...", + }, +]; + +export const TableDropdownStory = () => ( +
+ console.log(selectedValue)} + selectedOption={options[0]} + > +
+);