Skip to content

Commit 4ed59a9

Browse files
🪟 🎨 Updating styles for PillButton component according to new Figma design changes (#19303)
* Adds new styles for PillButton component with divider * Change labels to children property usage; Add new storybook component for PillSelect * Fixes pillLabel while PillSelect isMulti equals true; Fixes storybook for PillSelect * Removes pillLabel property for PillSelect options; Fixes case when PillSelect isMulti: true and have labels as array; Updates DropDown Option component to properly render label with array value * Fixes snapshot for BulkEditPanel after updating PillSelect component * Fixes key property for Option and SyncModeSelect components while rendering list items
1 parent 3fe3dea commit 4ed59a9

File tree

7 files changed

+152
-36
lines changed

7 files changed

+152
-36
lines changed

‎airbyte-webapp/src/components/connection/CatalogTree/next/SyncModeSelect.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ export const SyncModeSelect: React.FC<SyncModeSelectProps> = ({ className, optio
3131
return options.map(({ value }) => {
3232
const { syncMode, destinationSyncMode } = value;
3333
return {
34-
label: (
35-
<>
36-
<FormattedMessage id={`syncMode.${syncMode}`} />
37-
{` | `}
38-
<FormattedMessage id={`destinationSyncMode.${destinationSyncMode}`} />
39-
</>
40-
),
34+
label: [
35+
<FormattedMessage key={`syncMode.${syncMode}`} id={`syncMode.${syncMode}`} />,
36+
<FormattedMessage
37+
key={`destinationSyncMode.${destinationSyncMode}`}
38+
id={`destinationSyncMode.${destinationSyncMode}`}
39+
/>,
40+
],
4141
value,
4242
};
4343
});

‎airbyte-webapp/src/components/connection/CatalogTree/next/__snapshots__/BulkEditPanel.test.tsx.snap

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,13 @@ exports[`<BulkEditPanel /> should render 1`] = `
7878
class="<removed-for-snapshot-test>"
7979
type="button"
8080
>
81-
<span
81+
<div
8282
class="<removed-for-snapshot-test>"
83-
/>
83+
>
84+
<span
85+
class="<removed-for-snapshot-test>"
86+
/>
87+
</div>
8488
<svg
8589
aria-hidden="true"
8690
class="<removed-for-snapshot-test>"
@@ -136,9 +140,13 @@ exports[`<BulkEditPanel /> should render 1`] = `
136140
disabled=""
137141
type="button"
138142
>
139-
<span
143+
<div
140144
class="<removed-for-snapshot-test>"
141-
/>
145+
>
146+
<span
147+
class="<removed-for-snapshot-test>"
148+
/>
149+
</div>
142150
<svg
143151
aria-hidden="true"
144152
class="<removed-for-snapshot-test>"
@@ -194,9 +202,13 @@ exports[`<BulkEditPanel /> should render 1`] = `
194202
disabled=""
195203
type="button"
196204
>
197-
<span
205+
<div
198206
class="<removed-for-snapshot-test>"
199-
/>
207+
>
208+
<span
209+
class="<removed-for-snapshot-test>"
210+
/>
211+
</div>
200212
<svg
201213
aria-hidden="true"
202214
class="<removed-for-snapshot-test>"

‎airbyte-webapp/src/components/ui/DropDown/components/Option.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { Fragment } from "react";
22
import { components, OptionProps } from "react-select";
33
import styled from "styled-components";
44

@@ -73,7 +73,11 @@ export const DropDownOption: React.FC<DropDownOptionProps> = (props) => {
7373
<CheckBox checked={props.isSelected} onChange={() => props.selectOption(props.data)} />{" "}
7474
</>
7575
)}
76-
{props.label}
76+
{Array.isArray(props.label)
77+
? props.label
78+
.map<React.ReactNode>((node, index) => <Fragment key={index}>{node}</Fragment>)
79+
.reduce((prev, curr) => [prev, " | ", curr])
80+
: props.label}
7781
</DropDownText>
7882
{props.data.img || null}
7983
</OptionView>

‎airbyte-webapp/src/components/ui/PillSelect/PillButton.module.scss

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,46 @@
1919
}
2020
}
2121

22+
@mixin divider-theme($name, $background, $hover) {
23+
&.#{$name} {
24+
.divider {
25+
background-color: $background;
26+
}
27+
28+
&:not(:disabled) {
29+
&:hover,
30+
&.active {
31+
.divider {
32+
background: $hover;
33+
}
34+
}
35+
}
36+
}
37+
}
38+
39+
@mixin disabled-theme($name, $background, $text) {
40+
&.#{$name} {
41+
&.disabled {
42+
.icon {
43+
visibility: hidden;
44+
}
45+
46+
.text {
47+
color: $text;
48+
}
49+
50+
background-color: $background;
51+
}
52+
}
53+
}
54+
2255
.button {
56+
height: 19px;
2357
max-width: 100%;
2458
display: flex;
2559
flex-direction: row;
2660
align-items: center;
27-
padding: 3px 10px;
28-
gap: variables.$spacing-sm;
61+
padding: 0;
2962
border: none;
3063
border-radius: variables.$border-radius-pill;
3164
cursor: pointer;
@@ -38,11 +71,44 @@
3871
@include theme("red", colors.$red-50, colors.$red-600, colors.$red-100);
3972
@include theme("strongRed", colors.$red-300, colors.$white, colors.$red-400);
4073

41-
@include theme("disabled", colors.$grey-50, colors.$grey, colors.$grey-50);
74+
@include disabled-theme("grey", colors.$grey-50, colors.$grey-600);
75+
@include disabled-theme("blue", colors.$blue-50, colors.$blue-600);
76+
@include disabled-theme("strongBlue", colors.$blue-500, colors.$blue-200);
77+
@include disabled-theme("green", colors.$green-50, colors.$green-600);
78+
@include disabled-theme("red", colors.$red-50, colors.$red-600);
79+
@include disabled-theme("strongRed", colors.$red-300, colors.$white);
80+
81+
@include divider-theme("grey", colors.$grey-100, colors.$grey-200);
82+
@include divider-theme("blue", colors.$blue-100, colors.$blue-200);
83+
@include divider-theme("strongBlue", colors.$blue-200, colors.$blue-100);
84+
@include divider-theme("green", colors.$green-100, colors.$green-500);
85+
@include divider-theme("red", colors.$red-100, colors.$red-200);
86+
@include divider-theme("strongRed", colors.$red-100, colors.$red-100);
4287
}
4388

4489
.text {
45-
white-space: nowrap;
46-
overflow: hidden;
4790
text-overflow: ellipsis;
91+
overflow: hidden;
92+
}
93+
94+
.icon {
95+
margin-left: auto;
96+
margin-right: variables.$spacing-md;
97+
}
98+
99+
.labelContainer {
100+
display: flex;
101+
flex-direction: row;
102+
align-items: center;
103+
padding: variables.$spacing-xs variables.$spacing-md;
104+
justify-content: flex-start;
105+
flex: 1;
106+
overflow: hidden;
107+
white-space: nowrap;
108+
}
109+
110+
.divider {
111+
height: 100%;
112+
min-width: 1px;
113+
transition: background-color variables.$transition-out, color variables.$transition-out;
48114
}

‎airbyte-webapp/src/components/ui/PillSelect/PillButton.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
22
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
33
import classNames from "classnames";
4+
import { Children } from "react";
45

56
import { Text } from "../Text";
67
import styles from "./PillButton.module.scss";
@@ -21,27 +22,30 @@ interface PillButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
2122
variant?: PillButtonVariant;
2223
}
2324

24-
export const PillButton: React.FC<React.PropsWithChildren<PillButtonProps>> = ({
25-
children,
26-
active,
27-
variant = "grey",
28-
...buttonProps
29-
}) => {
25+
export const PillButton: React.FC<PillButtonProps> = ({ children, active, variant = "grey", ...buttonProps }) => {
3026
const buttonClassName = classNames(
3127
styles.button,
3228
{
3329
[styles.active]: active,
30+
[styles.disabled]: buttonProps.disabled,
3431
},
35-
buttonProps.disabled ? styles.disabled : STYLES_BY_VARIANT[variant],
32+
STYLES_BY_VARIANT[variant],
3633
buttonProps.className
3734
);
38-
35+
const arrayChildren = Children.toArray(children);
3936
return (
4037
<button type="button" {...buttonProps} className={buttonClassName}>
41-
<Text as="span" size="xs" className={styles.text}>
42-
{children}
43-
</Text>
44-
<FontAwesomeIcon icon={faCaretDown} />
38+
{Children.map(arrayChildren, (child, index) => (
39+
<>
40+
<div key={index} className={styles.labelContainer}>
41+
<Text as="span" size="xs" className={styles.text}>
42+
{child}
43+
</Text>
44+
</div>
45+
{index !== arrayChildren?.length - 1 && <div className={styles.divider} />}
46+
</>
47+
))}
48+
<FontAwesomeIcon className={styles.icon} icon={faCaretDown} />
4549
</button>
4650
);
4751
};

‎airbyte-webapp/src/components/ui/PillSelect/PillSelect.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,16 @@ interface PillSelectProps extends PickedPopoutProps {
1111

1212
export const PillSelect: React.FC<PillSelectProps> = ({ className, ...props }) => {
1313
const { isMulti, variant, disabled } = props;
14-
1514
return (
1615
<Popout
1716
{...props}
1817
isDisabled={disabled}
1918
targetComponent={({ onOpen, isOpen, value }) => {
2019
const label = value
2120
? isMulti
22-
? value.map(({ label }: { label: string }) => label).join(", ")
21+
? value.map(({ label }: { label: string }) => (Array.isArray(label) ? label.join(" | ") : label)).join(", ")
2322
: value.label
2423
: "";
25-
2624
return (
2725
<Tooltip
2826
control={

‎airbyte-webapp/src/components/ui/PillSelect/index.stories.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default {
88
} as ComponentMeta<typeof PillSelect>;
99

1010
const Template: ComponentStory<typeof PillSelect> = (args) => (
11-
<div style={{ width: "120px" }}>
11+
<div style={{ width: "300px" }}>
1212
<PillSelect {...args} />
1313
</div>
1414
);
@@ -48,3 +48,35 @@ Multi.args = {
4848
isMulti: true,
4949
value: ["first_name", "last_name"],
5050
};
51+
52+
const optionsWithTwoValues = [
53+
{
54+
value: "test1",
55+
label: ["dog", "cat"],
56+
},
57+
{
58+
value: "test2",
59+
label: ["dog", "cat", "rat"],
60+
},
61+
{
62+
value: "test3",
63+
label: "dog",
64+
},
65+
{
66+
value: "test4",
67+
label: ["cat"],
68+
},
69+
];
70+
71+
export const PrimaryWithTwoValue = Template.bind({});
72+
PrimaryWithTwoValue.args = {
73+
options: optionsWithTwoValues,
74+
value: "test1",
75+
};
76+
77+
export const PrimaryMultiWithTwoValue = Template.bind({});
78+
PrimaryMultiWithTwoValue.args = {
79+
options: optionsWithTwoValues,
80+
isMulti: true,
81+
value: ["test1", "test2"],
82+
};

0 commit comments

Comments
 (0)