Skip to content

Commit

Permalink
feat(ChoiceGroup): migrate to Tailwind
Browse files Browse the repository at this point in the history
Closes FEPLT-1707
  • Loading branch information
mvidalgarcia authored and oreqizer committed Nov 13, 2023
1 parent 453118e commit ee340dc
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 124 deletions.
2 changes: 1 addition & 1 deletion docs/src/data/tailwind-migration-status.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Card: true
CardSection: true
CarrierLogo: true
Checkbox: true
ChoiceGroup: false
ChoiceGroup: true
Collapse: true
Coupon: false
CountryFlag: true
Expand Down
2 changes: 1 addition & 1 deletion packages/orbit-components/src/ChoiceGroup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ For more realistic usage you can check out the "Render prop" example in Storyboo

## Functional specs

- onChange props in `<Radio />` or `<Checkbox />` will be overrode by internal onChange function
- onChange props in `<Radio />` or `<Checkbox />` will be overridden by internal onChange function
- If you want to handle selecting field, pass `onChange` to `<ChoiceGroup />` and it will be always triggered when `<Radio />` or `<Checkbox />` should change
- `onChange` will return `SyntheticEvent` of field that should change

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// @flow
import type { StyledComponent } from "styled-components";
import * as React from "react";

import type { Globals } from "../../common/common.js.flow";
Expand All @@ -10,5 +9,3 @@ export type Props = {|
|};

declare export default React.ComponentType<Props>;

declare export var StyledFormFeedback: StyledComponent<any, any, HTMLElement>;
60 changes: 23 additions & 37 deletions packages/orbit-components/src/ChoiceGroup/components/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import styled, { css } from "styled-components";
import cx from "clsx";

import defaultTheme from "../../defaultTheme";

Expand All @@ -8,44 +8,30 @@ interface Props {
children: React.ReactNode;
}

export const StyledFormFeedback = styled(props => <div {...props} />)`
${({ theme }) => css`
color: ${theme.orbit.colorTextError};
font-family: ${theme.orbit.fontFamily};
font-size: ${theme.orbit.fontSizeFormFeedback};
font-weight: ${theme.orbit.fontWeightMedium};
line-height: ${theme.orbit.lineHeightTextSmall};
width: 100%;
margin-top: 2px;
position: absolute;
top: 100%;
max-height: ${Math.floor(
theme.orbit.lineHeightText * parseInt(theme.orbit.fontSizeFormFeedback, 10),
)}px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
& a {
color: ${theme.orbit.colorTextError};
font-weight: ${theme.orbit.fontWeightMedium};
text-decoration: underline;
cursor: pointer;
}
strong,
b {
font-weight: ${theme.fontWeightMedium};
color: ${theme.paletteInkDark};
}
`}
`;

StyledFormFeedback.defaultProps = {
theme: defaultTheme,
};

const FormFeedback = (props: Props) => {
const { children, dataTest } = props;
return <StyledFormFeedback data-test={dataTest}>{children}</StyledFormFeedback>;
return (
<div
className={cx(
"orbit-choice-group-feedback",
"text-critical-foreground font-base leading-small text-small font-medium",
"mt-xxxs relative top-full max-h-[--max-height] w-full overflow-hidden overflow-ellipsis whitespace-nowrap",
"[&_a]:cursor-pointer [&_a]:underline",
"[&_strong]:text-ink-dark [&_b]:text-ink-dark [&_b]:font-medium [&_strong]:font-medium",
)}
style={
{
"--max-height": Math.floor(
parseFloat(defaultTheme.orbit.lineHeightText) *
parseInt(defaultTheme.orbit.fontSizeFormFeedback, 10),
),
} as React.CSSProperties
}
data-test={dataTest}
>
{children}
</div>
);
};

export default FormFeedback;
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import * as React from "react";
import styled, { css } from "styled-components";
import cx from "clsx";

import defaultTheme from "../../defaultTheme";
import ButtonLink from "../../ButtonLink";

const StyledOnlyButton = styled.div``;

interface Props {
readonly child: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
readonly children: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
Expand All @@ -16,67 +13,28 @@ interface Props {
) => void | Promise<void>;
}

const hoverAndFocus = () => css`
background-color: ${({ theme }) => theme.orbit.paletteBlueLight};
${StyledOnlyButton} {
visibility: visible;
opacity: 1;
}
`;

const StyledContentWrapper = styled.div<{ disabled: boolean }>`
${({ disabled }) => css`
box-sizing: border-box;
width: 100%;
padding-left: 4px;
border-radius: 4px;
display: flex;
align-items: center;
height: ${({ theme }) => theme.orbit.heightButtonSmall};
${StyledOnlyButton} {
visibility: hidden;
opacity: 0;
}
${!disabled &&
css`
@media (hover: none) {
${StyledOnlyButton} {
visibility: visible;
opacity: 0.3;
&:hover {
opacity: 1;
}
}
}
@media (hover) and (pointer: fine) {
&:hover {
${hoverAndFocus};
}
&:focus-within {
${hoverAndFocus}
}
}
`};
`}
`;

StyledContentWrapper.defaultProps = {
theme: defaultTheme,
};

const FilterWrapper = ({ child, children, onOnlySelection, onlySelectionText }: Props) => {
const { value, label, disabled } = child.props;

return (
<StyledContentWrapper disabled={disabled}>
<div
className={cx(
"h-form-box-small pl-xxs box-border flex w-full items-center rounded-[4px]",
!disabled &&
"hover:[@media(hover)_and_(pointer:fine)]:bg-blue-light focus-within:[@media(hover)_and_(pointer:fine)]:bg-blue-light group",
)}
>
{children}
{onOnlySelection && !disabled && (
<StyledOnlyButton>
<div
className={cx(
"orbit-choice-group-filter-wrapper",
"[@media(hover)_and_(pointer:fine)]:invisible [@media(hover)_and_(pointer:fine)]:opacity-0",
"[@media(hover:none)]:visible [@media(hover:none)]:opacity-30 hover:[@media(hover:none)]:opacity-100",
"group-hover:[@media(hover)_and_(pointer:fine)]:visible group-hover:[@media(hover)_and_(pointer:fine)]:opacity-100",
"group-focus-within:[@media(hover)_and_(pointer:fine)]:visible group-focus-within:[@media(hover)_and_(pointer:fine)]:opacity-100",
)}
>
<ButtonLink
type="secondary"
size="small"
Expand All @@ -86,9 +44,9 @@ const FilterWrapper = ({ child, children, onOnlySelection, onlySelectionText }:
>
{onlySelectionText}
</ButtonLink>
</StyledOnlyButton>
</div>
)}
</StyledContentWrapper>
</div>
);
};

Expand Down
29 changes: 8 additions & 21 deletions packages/orbit-components/src/ChoiceGroup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
"use client";

import * as React from "react";
import styled from "styled-components";
import cx from "clsx";

import Heading from "../Heading";
import type { Type } from "../Heading/types";
import Stack from "../Stack";
import { LABEL_SIZES, LABEL_ELEMENTS } from "./consts";
import Feedback, { StyledFormFeedback } from "./components/Feedback";
import defaultTheme from "../defaultTheme";
import Feedback from "./components/Feedback";
import FilterWrapper from "./components/FilterWrapper";
import useRandomId from "../hooks/useRandomId";
import useTheme from "../hooks/useTheme";
Expand All @@ -23,22 +22,6 @@ const getHeadingSize = (size: Size): Type => {
return SIZES[size];
};

const StyledChoiceGroup = styled.div`
width: 100%;
display: flex;
flex-direction: column;
${StyledFormFeedback} {
position: relative;
margin-top: ${({ theme }) => theme.orbit.spaceXSmall};
top: initial;
}
`;

StyledChoiceGroup.defaultProps = {
theme: defaultTheme,
};

const ItemContainer =
({ filter, itemProps, onOnlySelection, onlySelectionText }) =>
({ children }) => {
Expand Down Expand Up @@ -87,12 +70,16 @@ const ChoiceGroup = React.forwardRef<HTMLDivElement, Props>(
};

return (
<StyledChoiceGroup
<div
ref={ref}
data-test={dataTest}
role="group"
aria-labelledby={groupID}
id={id}
className={cx(
"flex w-full flex-col",
"[&_.orbit-choice-group-feedback]:mt-xs [&_.orbit-choice-group-feedback]:relative [&_.orbit-choice-group-feedback]:top-[initial]",
)}
>
{label && (
<Heading id={groupID} type={getHeadingSize(labelSize)} as={labelAs} spaceAfter="medium">
Expand Down Expand Up @@ -128,7 +115,7 @@ const ChoiceGroup = React.forwardRef<HTMLDivElement, Props>(
</Stack>
)}
{error && <Feedback>{error}</Feedback>}
</StyledChoiceGroup>
</div>
);
},
);
Expand Down

0 comments on commit ee340dc

Please sign in to comment.