Skip to content

Commit c846125

Browse files
akula-koteswaruduKoteswarudu Akula
andauthored
feat : added features to combobox , select , radio, tag , switch and slider (#33)
* updated antd select to radix select * changed switch from antd to radix * changed switch in formBuilder * added story for switch and fixed props for select in FormBuilder * Changed antd radio to radix * chore: changed storybook for Radio * fix: updated yarn lock to fix rollup plugin version issue * feat: replaced antd slider with radix slider * feat: removed antd from image * feat: removed antd tag and created a new tag component * feat: added a simple preview option to Image * feat: created a new component combobox combobox provides multi select and search features BREAKING CHANGE: select doesn't provide multi select or search feature. if we need them, we need to use combobox. combobox for multiselect and search feature #31 * style: minor styling changes * feat: added radio button feature to radio and changed combobox to hide content properly radio button feature supports to insert custom components into radio group and combobox will now hides the content using ellipsis when the screen is minimized. * feat: added tooltip for slider and changed tag to hide the content using ellipsis when required * fix: fixed select so that it will be rendered correctly even if no initial value is given * chore: added styles to radio and switch * feat: added enable tag feature for combobox in form and fixed placeholder content hiding Co-authored-by: Koteswarudu Akula <koteswaruduakula@koteswarudu-a.optilink>
1 parent 6f2b9cf commit c846125

File tree

13 files changed

+300
-94
lines changed

13 files changed

+300
-94
lines changed

packages/apsara-ui/src/Combobox/Combobox.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default {
99
};
1010

1111
const options = [
12-
{ value: "2", label: "Lamborghini Diablo" },
12+
{ value: "2", label: "pilotdata-integration:bq_smoke_test_json_insert_all_dataset - Bigquery Dataset" },
1313
{ value: "3", label: "Ford Raptor" },
1414
{ value: "4", label: "Ferrari Testarossa" },
1515
{ value: "5", label: "Porsche 911 Carrera" },

packages/apsara-ui/src/Combobox/Combobox.styles.tsx

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export const DropdownStyle = css`
2222
position: absolute;
2323
}
2424
25+
.rc-select-item-option-content {
26+
overflow: hidden;
27+
text-overflow: ellipsis;
28+
white-space: nowrap;
29+
}
2530
.rc-select-item {
2631
padding: 5px;
2732
padding-left: 10px;
@@ -133,10 +138,25 @@ export const DropdownStyle = css`
133138
transform: scaleY(0);
134139
}
135140
}
141+
142+
.rc-select-disabled .rc-select-selector {
143+
background-color: rgb(245, 245, 245);
144+
&:hover {
145+
border-color: ${({ theme }) => theme?.combobox?.border};
146+
cursor: not-allowed;
147+
}
148+
}
149+
150+
.rc-select-disabled .rc-select-selection-search-input {
151+
&:hover {
152+
cursor: not-allowed;
153+
}
154+
}
136155
`;
137156

138157
export const StyledMultiSelect = styled(Select)<{ showInputIcon?: boolean }>`
139158
.rc-select-selection-search-input {
159+
box-sizing: border-box;
140160
width: auto;
141161
border: none;
142162
font-size: 100%;
@@ -166,7 +186,7 @@ export const StyledMultiSelect = styled(Select)<{ showInputIcon?: boolean }>`
166186
background: transparent;
167187
border: 1px solid ${({ theme }) => theme?.combobox?.border};
168188
padding-right: 45px;
169-
overflow-x: hidden;
189+
overflow: hidden;
170190
171191
&:hover {
172192
border-color: ${({ theme }) => theme?.combobox?.focus};
@@ -175,12 +195,17 @@ export const StyledMultiSelect = styled(Select)<{ showInputIcon?: boolean }>`
175195
}
176196
177197
.rc-select-selection-placeholder {
198+
box-sizing: border-box;
199+
overflow: hidden;
200+
text-overflow: ellipsis;
201+
white-space: nowrap;
202+
display: inline-block;
178203
position: absolute;
179204
top: 0;
180205
left: 0px;
206+
padding-top: 3.5px;
181207
padding-left: 10px;
182-
display: flex;
183-
align-items: center;
208+
padding-right: 40px;
184209
width: 100%;
185210
height: 100%;
186211
color: ${({ theme }) => theme?.combobox?.placeholder};
@@ -199,13 +224,26 @@ export const StyledMultiSelect = styled(Select)<{ showInputIcon?: boolean }>`
199224
text-overflow: ellipsis;
200225
}
201226
227+
.rc-select-selection-overflow-item {
228+
overflow: hidden;
229+
text-overflow: ellipsis;
230+
white-space: nowrap;
231+
}
232+
233+
.rc-select-selection-overflow-item-suffix {
234+
overflow: visible;
235+
}
236+
202237
.rc-select-selection-search-mirror {
203238
display: none;
204239
}
205240
206241
.rc-select-selection-item {
207242
box-sizing: border-box;
208243
margin-left: 10px;
244+
overflow: hidden;
245+
text-overflow: ellipsis;
246+
white-space: nowrap;
209247
210248
${({ mode, theme }) =>
211249
mode == "multiple" || mode == "tags"
@@ -227,6 +265,12 @@ export const StyledMultiSelect = styled(Select)<{ showInputIcon?: boolean }>`
227265
`}
228266
}
229267
268+
.rc-select-selection-item-content {
269+
overflow: hidden;
270+
text-overflow: ellipsis;
271+
white-space: nowrap;
272+
}
273+
230274
.rc-select-selection-item-remove-icon {
231275
margin-left: 3px;
232276
font-size: 17px;

packages/apsara-ui/src/Combobox/Combobox.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ const Combobox = ({
2121
onSearch,
2222
onSelect,
2323
onDeselect,
24-
defaultValue,
25-
optionFilterProp,
26-
filterOption,
2724
allowClear = true,
2825
showSearch = true,
2926
showArrow = true,
@@ -67,6 +64,7 @@ const Combobox = ({
6764

6865
return (
6966
<StyledMultiSelect
67+
notFoundContent={notFoundContent}
7068
{...props}
7169
showInputIcon={showInputIcon || !allowClear}
7270
showSearch={showSearch}
@@ -83,7 +81,6 @@ const Combobox = ({
8381
onSelect={onValueSelect}
8482
onDeselect={onValueDeselect}
8583
options={options}
86-
notFoundContent={notFoundContent}
8784
animation="slide"
8885
>
8986
{props.children}

packages/apsara-ui/src/FormBuilder/FormBuilderField.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
22
// @ts-nocheck
3-
import React, { useMemo } from "react";
4-
import * as R from "ramda";
3+
import React from "react";
54
import { InputNumber, DatePicker } from "antd";
65
import Moment from "moment";
76
import Input from "../Input";
@@ -11,9 +10,9 @@ import Checkbox from "../Checkbox";
1110
import Switch from "../Switch";
1211
import Combobox from "../Combobox";
1312
import { getStringValue } from "./helper";
13+
import Tag from "../Tag";
1414

1515
const { RangePicker } = DatePicker;
16-
const { Option } = Select;
1716
export type Widget =
1817
| "range"
1918
| "radio"
@@ -50,7 +49,7 @@ const FormBuilderField = ({
5049
widgetType,
5150
component = null,
5251
rows,
53-
enableTag,
52+
enableTag, // eslint-disable-line
5453
...props
5554
}: FormBuilderFieldProps) => {
5655
if (widget === "range") return <InputNumber {...props} />;
@@ -66,7 +65,24 @@ const FormBuilderField = ({
6665
return <Select {...props} />;
6766
}
6867
if (widget === "combobox") {
69-
return <Combobox {...props} />;
68+
return (
69+
<React.Fragment>
70+
<Combobox {...props} />
71+
{enableTag &&
72+
props.value &&
73+
(props.value instanceof Array ? (
74+
props.value.map((singleVal) => (
75+
<Tag type="round" color="rgb(232, 239, 253)" key={singleVal} style={{ marginTop: "4px" }}>
76+
{singleVal}
77+
</Tag>
78+
))
79+
) : (
80+
<Tag type="round" color="rgb(232, 239, 253)" style={{ marginTop: "8px" }}>
81+
{props.value}
82+
</Tag>
83+
))}
84+
</React.Fragment>
85+
);
7086
}
7187
if (widget === "textarea") {
7288
return <Input.TextArea size="large" rows={rows} {...props} />;

packages/apsara-ui/src/Radio/Radio.styles.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ export const StyledRadioItem = styled(RadioGroupPrimitive.Item)`
88
height: 17px;
99
border-radius: 100%;
1010
border: 1px solid ${({ theme }) => theme?.radio?.border};
11+
transition: border-color 0.5s;
1112
&:hover {
1213
background-color: ${({ theme }) => theme?.radio?.hover};
1314
border-color: ${({ theme }) => theme?.radio?.focus};
15+
border-color: ${({ theme }) => theme?.radio?.focus};
1416
}
1517
1618
&[data-disabled] {
@@ -61,3 +63,29 @@ export const Flex = styled("div")`
6163
margin: 8px ${({ dir }) => (dir === "rtl" ? "0px" : "8px")};
6264
align-items: center;
6365
`;
66+
67+
export const StyledRadioButton = styled("button")`
68+
box-sizing: border-box;
69+
background-color: transparent;
70+
border: 1px solid #cacaca;
71+
color: black;
72+
transition: color 0.5s;
73+
margin: 5px;
74+
padding-right: 15px;
75+
padding-left: 15px;
76+
padding-bottom: 5px;
77+
padding-top: 5px;
78+
cursor: pointer;
79+
display: flex;
80+
align-items: center;
81+
justify-content: space-between;
82+
83+
&[data-state="checked"] {
84+
border-color: #4291ee;
85+
color: #4291ee;
86+
}
87+
&:focus {
88+
border-color: #4291ee;
89+
color: #4291ee;
90+
}
91+
`;
Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
2-
import { RadioGroup, StyledRadioItem, StyledIndicator, Label, Flex } from "./Radio.styles";
2+
import { RadioGroup, StyledRadioItem, StyledIndicator, Label, Flex, StyledRadioButton } from "./Radio.styles";
3+
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
34

45
type RadioItem = {
56
label?: string;
@@ -8,6 +9,14 @@ type RadioItem = {
89
required?: boolean;
910
};
1011

12+
type RadioButtonType = {
13+
label?: string;
14+
value: string;
15+
children?: React.ReactNode;
16+
style?: React.CSSProperties;
17+
className?: string;
18+
};
19+
1120
type styleProps = {
1221
className?: string;
1322
style?: React.CSSProperties;
@@ -16,7 +25,7 @@ type styleProps = {
1625
export type RadioProps = {
1726
defaultValue?: string;
1827
value?: string;
19-
items: RadioItem[];
28+
items?: RadioItem[];
2029
onChange?: (value: string) => void;
2130
name?: string;
2231
required?: boolean;
@@ -25,6 +34,7 @@ export type RadioProps = {
2534
className?: string;
2635
style?: React.CSSProperties;
2736
itemStyle?: styleProps;
37+
children?: React.ReactNode;
2838
};
2939

3040
const Radio = ({ defaultValue, value, items, onChange, required, orientation, dir, ...props }: RadioProps) => {
@@ -40,24 +50,42 @@ const Radio = ({ defaultValue, value, items, onChange, required, orientation, di
4050
style={props.style}
4151
aria-label="View density"
4252
>
43-
{items.map((item, i) => (
44-
<Flex dir={dir} key={i}>
45-
<StyledRadioItem
46-
value={item.value}
47-
disabled={item.disabled}
48-
required={item.required}
49-
{...props.itemStyle}
50-
id={i.toString()}
51-
>
52-
<StyledIndicator />
53-
</StyledRadioItem>
54-
<Label dir={dir} htmlFor={i.toString()}>
55-
{item.label}
56-
</Label>
57-
</Flex>
58-
))}
53+
{items &&
54+
items.map((item, i) => (
55+
<Flex dir={dir} key={item.value}>
56+
<StyledRadioItem
57+
value={item.value}
58+
disabled={item.disabled}
59+
required={item.required}
60+
{...props.itemStyle}
61+
id={i.toString()}
62+
>
63+
<StyledIndicator />
64+
</StyledRadioItem>
65+
<Label dir={dir} htmlFor={i.toString()}>
66+
{item.label}
67+
</Label>
68+
</Flex>
69+
))}
70+
{!items && props.children}
5971
</RadioGroup>
6072
);
6173
};
6274

75+
const RadioButton = ({ label, value, children, ...props }: RadioButtonType) => {
76+
return (
77+
<RadioGroupPrimitive.Item value={value} asChild={true}>
78+
<StyledRadioButton {...props}>
79+
{children}
80+
{label}
81+
</StyledRadioButton>
82+
</RadioGroupPrimitive.Item>
83+
);
84+
};
85+
86+
Radio.Root = RadioGroup;
87+
Radio.Item = StyledRadioItem;
88+
Radio.Indicator = StyledIndicator;
89+
Radio.Button = RadioButton;
90+
6391
export default Radio;

packages/apsara-ui/src/Select/Select.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useEffect, useState } from "react";
22
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
33
import {
44
SelectRoot,
@@ -50,7 +50,7 @@ export type SelectProps = {
5050
};
5151

5252
const Select = ({
53-
defaultValue,
53+
defaultValue = "",
5454
value,
5555
name,
5656
onChange,
@@ -61,12 +61,28 @@ const Select = ({
6161
...props
6262
}: SelectProps) => {
6363
const lastInd = groups.length - 1;
64+
const [showDefaultItem, setShowDefaultItem] = useState(true);
65+
66+
useEffect(() => {
67+
const val = value ? value : defaultValue;
68+
let bool = true;
69+
groups.forEach((group) => {
70+
group.items.forEach((item) => {
71+
bool = item.value != val ? (bool ? true : false) : false;
72+
});
73+
});
74+
setShowDefaultItem(bool);
75+
}, []);
76+
6477
return (
6578
<SelectRoot
6679
defaultValue={defaultValue}
6780
value={value}
6881
name={name}
69-
onValueChange={onChange}
82+
onValueChange={(value) => {
83+
if (value != "") setShowDefaultItem(false);
84+
onChange && onChange(value);
85+
}}
7086
defaultOpen={defaultOpen}
7187
open={open}
7288
onOpenChange={onOpenChange}
@@ -82,6 +98,14 @@ const Select = ({
8298
<ChevronUpIcon />
8399
</SelectScrollUpButton>
84100
<SelectViewport>
101+
{showDefaultItem && (
102+
<SelectItem value={value || defaultValue}>
103+
<SelectItemText>{value || defaultValue}</SelectItemText>
104+
<SelectItemIndicator>
105+
<CheckIcon />
106+
</SelectItemIndicator>
107+
</SelectItem>
108+
)}
85109
{groups.map((group: Group, i) => (
86110
<div key={i}>
87111
<SelectGroup>

0 commit comments

Comments
 (0)