Skip to content

Commit

Permalink
feat(blade): add PhoneNumber input (#2080)
Browse files Browse the repository at this point in the history
Co-authored-by: Chaitanya Deorukhkar <deorukhkarchaitanya@gmail.com>
  • Loading branch information
anuraghazra and chaitanyadeorukhkar authored Apr 2, 2024
1 parent f85b091 commit a75d2e3
Show file tree
Hide file tree
Showing 46 changed files with 40,090 additions and 213 deletions.
5 changes: 5 additions & 0 deletions .changeset/heavy-students-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@razorpay/blade": minor
---

feat(blade): add PhoneNumber input
1 change: 1 addition & 0 deletions .github/actions/install-dependencies/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: install npm packages
description: Installs npm packages and manages it's cache

runs:
using: composite
steps:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/blade-bundle-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Update Bundle Size Data
run: yarn generate-bundle-size-info
Expand All @@ -47,7 +51,11 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Build Blade React Production
run: yarn run-s build:clean build:generate-types build:react-prod
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/blade-chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Publish to Chromatic
uses: chromaui/action@v1
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/blade-interaction-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Run Interaction Tests
run: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/blade-tokens-upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Upload Tokens
working-directory: packages/blade
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/blade-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Build Blade
run: yarn build
Expand All @@ -41,7 +45,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Run Unit Tests
run: yarn test
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.12.1
# https://stackoverflow.com/a/73824182
registry-url: "https://npm.pkg.github.com"
- name: Setup Cache & Install Dependencies
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: ./.github/actions/install-dependencies
- name: Create Release Pull Request & Publish packages
id: changesets
Expand Down
6 changes: 3 additions & 3 deletions packages/blade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@
"typescript-transform-paths": "3.4.6",
"@types/body-scroll-lock": "3.1.0",
"ramda": "0.29.1",
"@razorpay/i18nify-js": "1.4.4",
"@razorpay/i18nify-react": "4.0.0"
"@razorpay/i18nify-js": "1.8.0",
"@razorpay/i18nify-react": "4.0.6"
},
"peerDependencies": {
"react": ">=18",
Expand All @@ -291,7 +291,7 @@
"react-hot-toast": "2.4.1",
"@gorhom/bottom-sheet": "^4.4.6",
"@gorhom/portal": "^1.0.14",
"@razorpay/i18nify-js": "^1.4.4"
"@razorpay/i18nify-js": "^1.8.0"
},
"peerDependenciesMeta": {
"react-native": {
Expand Down
5 changes: 4 additions & 1 deletion packages/blade/src/components/Box/BaseBox/BaseBox.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import type { BaseBoxProps } from './types';
import { useMemoizedStyles } from './useMemoizedStyles';
import { omitPropsFromHTML } from '~utils/omitPropsFromHTML';
import { metaAttribute, MetaConstants } from '~utils/metaAttribute';
import { assignWithoutSideEffects } from '~utils/assignWithoutSideEffects';

const BaseBox = styled.div
const _BaseBox = styled.div
.attrs<BaseBoxProps>((props) => {
return {
...metaAttribute({
Expand All @@ -21,4 +22,6 @@ const BaseBox = styled.div
return cssObject;
});

const BaseBox = assignWithoutSideEffects(_BaseBox, { componentId: 'BaseBox' });

export { BaseBox };
1 change: 1 addition & 0 deletions packages/blade/src/components/Box/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ const _Box: React.ForwardRefRenderFunction<BoxRefType, BoxProps> = (props, ref)

const Box = assignWithoutSideEffects(React.forwardRef(_Box), {
displayName: 'Box',
componentId: 'Box',
});

export { Box, makeBoxProps };
45 changes: 26 additions & 19 deletions packages/blade/src/components/Button/BaseButton/BaseButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ const getTextColorToken = ({

const getProps = ({
buttonTypographyTokens,
children,
childrenString,
isDisabled,
size,
theme,
Expand All @@ -177,7 +177,7 @@ const getProps = ({
hasIcon,
}: {
buttonTypographyTokens: ButtonTypography;
children?: string;
childrenString?: string;
isDisabled: boolean;
hasIcon: boolean;
theme: Theme;
Expand All @@ -192,7 +192,7 @@ const getProps = ({
});
}

const isIconOnly = hasIcon && (!children || children?.trim().length === 0);
const isIconOnly = hasIcon && (!childrenString || childrenString?.trim().length === 0);
const props: BaseButtonStyleProps = {
iconSize: isIconOnly ? buttonIconOnlySizeToIconSizeMap[size] : buttonSizeToIconSizeMap[size],
spinnerSize: buttonSizeToSpinnerSizeMap[size],
Expand All @@ -201,7 +201,8 @@ const getProps = ({
minHeight: makeSize(buttonMinHeight[size]),
height: isIconOnly ? buttonIconOnlyHeightWidth[size] : undefined,
width: isIconOnly ? buttonIconOnlyHeightWidth[size] : undefined,
iconPadding: hasIcon && children?.trim() ? `spacing.${buttonIconPadding[size]}` : undefined,
iconPadding:
hasIcon && childrenString?.trim() ? `spacing.${buttonIconPadding[size]}` : undefined,
iconColor: getTextColorToken({
property: 'icon',
variant,
Expand All @@ -224,7 +225,7 @@ const getProps = ({
buttonPaddingRight: isIconOnly
? makeSpace(0)
: makeSpace(theme.spacing[buttonPadding[size].right]),
text: size === 'xsmall' ? children?.trim().toUpperCase() : children?.trim(),
text: size === 'xsmall' ? childrenString?.trim().toUpperCase() : childrenString?.trim(),
defaultBackgroundColor: getIn(
theme.colors,
getBackgroundColorToken({ property: 'background', variant, color, state: 'default' }),
Expand Down Expand Up @@ -328,6 +329,8 @@ const _BaseButton: React.ForwardRefRenderFunction<BladeElementRef, BaseButtonPro
const [isPressed, setIsPressed] = React.useState(false);
const isLink = Boolean(href);
const childrenString = getStringFromReactText(children);
const isChildrenComponent = React.isValidElement(children);

// Button cannot be disabled when its rendered as Link
const disabled = buttonGroupProps.isDisabled ?? (isLoading || (isDisabled && !isLink));

Expand Down Expand Up @@ -377,7 +380,7 @@ const _BaseButton: React.ForwardRefRenderFunction<BladeElementRef, BaseButtonPro
motionEasing,
} = getProps({
buttonTypographyTokens: buttonTypography,
children: childrenString,
childrenString,
isDisabled: disabled,
size: buttonGroupProps.size ?? size,
variant: buttonGroupProps.variant ?? variant,
Expand Down Expand Up @@ -525,19 +528,23 @@ const _BaseButton: React.ForwardRefRenderFunction<BladeElementRef, BaseButtonPro
</BaseBox>
) : null}
{text ? (
<BaseText
lineHeight={lineHeight}
fontSize={fontSize}
// figma and web have different font-smoothing properties
// which causes web version of button text to look much bolder
// than figma version. To fix this we are changing font-weight from 600 to 500
// https://forum.figma.com/t/why-does-a-font-weight-in-figma-seem-lighter-than-the-same-weight-in-the-browser/2207
fontWeight="medium"
textAlign="center"
color={textColor}
>
{text}
</BaseText>
isChildrenComponent ? (
children
) : (
<BaseText
lineHeight={lineHeight}
fontSize={fontSize}
// figma and web have different font-smoothing properties
// which causes web version of button text to look much bolder
// than figma version. To fix this we are changing font-weight from 600 to 500
// https://forum.figma.com/t/why-does-a-font-weight-in-figma-seem-lighter-than-the-same-weight-in-the-browser/2207
fontWeight="medium"
textAlign="center"
color={textColor}
>
{text}
</BaseText>
)
) : null}
{Icon && iconPosition == 'right' ? (
<BaseBox
Expand Down
2 changes: 2 additions & 0 deletions packages/blade/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import type { ContainerElementType } from '~utils/types';
import { useControllableState } from '~utils/useControllable';

const validDropdownChildren = [
// TODO: Remove Box once CountrySelector's button sizing is fixed
dropdownComponentIds.BaseBox,
dropdownComponentIds.triggers.SelectInput,
dropdownComponentIds.triggers.DropdownButton,
dropdownComponentIds.triggers.DropdownLink,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const _DropdownOverlay = ({
testID,
zIndex = componentZIndices.dropdownOverlay,
width,
referenceRef,
defaultPlacement = 'bottom-start',
}: DropdownOverlayProps): React.ReactElement | null => {
const { isOpen, triggererRef, triggererWrapperRef, dropdownTriggerer, setIsOpen } = useDropdown();
Expand All @@ -42,7 +43,8 @@ const _DropdownOverlay = ({

const isMenu =
dropdownTriggerer !== dropdownComponentIds.triggers.SelectInput &&
dropdownTriggerer !== dropdownComponentIds.triggers.AutoComplete;
dropdownTriggerer !== dropdownComponentIds.triggers.AutoComplete &&
referenceRef == undefined;

const { refs, floatingStyles, context } = useFloating({
open: isOpen,
Expand All @@ -53,7 +55,9 @@ const _DropdownOverlay = ({
// Input triggers have their ref on internal input element but we want width height of overall visible input hence wrapperRef is needed
// We fallback to use `triggererRef` for triggers like button and link where wrapper is not needed
// Checkout: https://github.com/razorpay/blade/pull/1559#discussion_r1305438920
reference: triggererWrapperRef.current ?? triggererRef.current,
reference: (referenceRef?.current ??
triggererWrapperRef.current ??
triggererRef.current) as Element,
},
middleware: [
offset({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const dropdownComponentIds = {
DropdownOverlay: 'DropdownOverlay',
Dropdown: 'Dropdown',
BaseBox: 'BaseBox',
triggers: {
SelectInput: 'SelectInput',
DropdownButton: 'DropdownButton',
Expand Down
9 changes: 8 additions & 1 deletion packages/blade/src/components/Dropdown/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type React from 'react';
import type { Placement } from '@floating-ui/react';
import type { StyledPropsBlade } from '~components/Box/styledProps';
import type { TestID } from '~utils/types';
import type { ContainerElementType, TestID } from '~utils/types';
import type { BoxProps } from '~components/Box';

type DropdownProps = {
Expand Down Expand Up @@ -29,6 +29,13 @@ type DropdownOverlayProps = {
*/
zIndex?: number;
width?: BoxProps['width'];
/**
* Reference to the element which triggers the DropdownOverlay
*
* This is used to position the DropdownOverlay relative to a specific element,
* for example in PhoneNumberInput the DropdownOverlay is positioned relative to the input element
*/
referenceRef?: React.MutableRefObject<ContainerElementType | null>;
/**
* Sets the placement of the DropdownOverlay
*
Expand Down
17 changes: 13 additions & 4 deletions packages/blade/src/components/Input/BaseInput/BaseInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ type BaseInputCommonProps = FormInputLabelProps &
*
* eg: consumers can render a loader or they could render a clear button
*/
interactionElement?: ReactNode;
trailingInteractionElement?: ReactNode;
/**
* Element to be rendered before prefix. This is decided by the component which is extending BaseInput
*
* eg: consumers can render a country selector or button
*/
leadingInteractionElement?: ReactNode;
/**
* Suffix symbol to be displayed at the end of the input field. If trailingIcon is provided it'll be placed before it
*/
Expand Down Expand Up @@ -766,7 +772,8 @@ const _BaseInput: React.ForwardRefRenderFunction<BladeElementRef, BaseInputProps
isRequired,
leadingIcon,
prefix,
interactionElement,
trailingInteractionElement,
leadingInteractionElement,
suffix,
trailingIcon,
maxCharacters,
Expand Down Expand Up @@ -941,6 +948,7 @@ const _BaseInput: React.ForwardRefRenderFunction<BladeElementRef, BaseInputProps
leadingIcon={leadingIcon}
prefix={prefix}
isDisabled={isDisabled}
leadingInteractionElement={leadingInteractionElement}
/>
<BaseInputTagSlot
renderAs={as}
Expand Down Expand Up @@ -984,7 +992,8 @@ const _BaseInput: React.ForwardRefRenderFunction<BladeElementRef, BaseInputProps
handleOnClick={handleOnClick}
leadingIcon={leadingIcon}
prefix={prefix}
interactionElement={interactionElement}
trailingInteractionElement={trailingInteractionElement}
leadingInteractionElement={leadingInteractionElement}
suffix={suffix}
trailingIcon={trailingIcon}
maxCharacters={maxCharacters}
Expand All @@ -1010,7 +1019,7 @@ const _BaseInput: React.ForwardRefRenderFunction<BladeElementRef, BaseInputProps
/>
</BaseInputTagSlot>
<BaseInputVisuals
interactionElement={interactionElement}
trailingInteractionElement={trailingInteractionElement}
suffix={suffix}
trailingIcon={trailingIcon}
isDisabled={isDisabled}
Expand Down
Loading

0 comments on commit a75d2e3

Please sign in to comment.