-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: i18nify SDK integrated for Amount
component
#2003
Changes from 16 commits
31a3e05
b9c23c8
a13df00
82d6490
d26b19e
3ff6855
e21eb0f
8221c55
184b8fb
67a1172
67ca36c
b983083
b2a390d
cba99d7
5e8686d
dd61843
82bdb6b
d9462bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
'@razorpay/blade': minor | ||
--- | ||
|
||
**feat: Added internationalization in Amount component via i18nify. | ||
References** | ||
|
||
- **i18nify-js:** https://www.npmjs.com/package/@razorpay/i18nify-js | ||
- **i18nify-react:** https://www.npmjs.com/package/@razorpay/i18nify-react | ||
|
||
**What changes ?** | ||
|
||
1. The `<Amount />` component will now automatically format numbers based on the user's browser locale. For example, `<Amount value={123456.789} currency="INR">` will render `₹1,23,456.79` for browsers with the `en-IN` default locale, whereas it will render `₹123,456.79` for browsers with the `en-US` locale. | ||
|
||
2. If you want to enable users to change the locale of your page, add the `@razorpay/i18nify-react` package and wrap your app inside the `I18nProvider`. Utilize the `setI18nState` utility to modify the locale. For more details, please refer to the [documentation](https://www.npmjs.com/package/@razorpay/i18nify-react). | ||
|
||
3. Additionally, if you prefer to maintain a fixed locale for your page and amount component, enclose your app within `<I18nProvider initData={{locale: 'locale-you-want'}}>..`. For more details, please refer to the [documentation](https://www.npmjs.com/package/@razorpay/i18nify-react). | ||
|
||
**How to update ?** | ||
|
||
1. Install i18nify as dependency `yarn add @razorpay/i18nify-js` | ||
2. _[Optional]_: Install i18nify-react as dependency to manage state effectively `yarn add @razorpay/i18nify-react` | ||
3. Install latest Blade `yarn add @razorpay/blade@latest` | ||
tarun-khanna marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,47 +40,62 @@ Before you install the package, make sure that you have performed the following | |
|
||
## ⬇ Add blade to your application | ||
|
||
1. Install blade as a dependency. | ||
Blade has a peer dependency on a few libraries, you can skip adding it if you already have it installed in your project. | ||
1. Install blade as a dependency. | ||
Blade has a peer dependency on a few libraries, you can skip adding it if you already have it installed in your project. | ||
|
||
- `styled-components` | ||
- `styled-components` | ||
> **Note** | ||
> | ||
> Currently, blade only supports styled-components v5 only | ||
|
||
```shell | ||
yarn add @razorpay/blade styled-components@5.3.11 | ||
``` | ||
2. Follow [this guide](#-install-fonts) to install the fonts. | ||
```shell | ||
yarn add @razorpay/blade styled-components@5.3.11 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move this shell block before styled components and put all the dependencies including i18nify in one shell block itself as we have done in React native section below and then you can use bullt points to describe all the dependencies together There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
``` | ||
|
||
3. For **React Native** projects you need to do additional setup for the peer dependencies: | ||
- `@razorpay/i18nify-js` | ||
- Blade uses this library for formatting capabilities in [Amount](https://blade.razorpay.com/?path=/docs/components-amount--docs) and other components based on the locale. Follow [this guide](https://www.npmjs.com/package/@razorpay/i18nify-js) to install it. | ||
|
||
```shell | ||
yarn add @floating-ui/react-native@0.10.0 react-native-reanimated@3.4.1 react-native-tab-view@3.5.2 react-native-pager-view@6.2.1 react-native-svg@12.3.0 react-native-gesture-handler@2.9.0 @gorhom/bottom-sheet@4.4.6 @gorhom/portal@1.0.1 | ||
``` | ||
```shell | ||
yarn add @razorpay/i18nify-js | ||
``` | ||
|
||
- `react-native-reanimated` | ||
- Follow [this guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) to install it on Android & iOS which is required by Blade. | ||
- `react-native-svg` | ||
- Follow [this guide](https://github.com/react-native-svg/react-native-svg#with-react-native-cli) to install it on Android & iOS which is required by Blade. | ||
- `react-native-gesture-handler` | ||
- Follow [this guide](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) to install it, note that you don't need to add `<GestureHandlerRootView style={{ flex: 1 }}>` again on the root because BladeProvider already adds that out of the box. | ||
- `@gorhom/bottom-sheet` | ||
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up. | ||
- `@gorhom/portal` | ||
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up. | ||
- `@floating-ui/react-native` | ||
- Add this as peer dependency, no need to do additional setup. | ||
- `react-native-tab-view` | ||
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation). | ||
- `react-native-pager-view` | ||
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation). | ||
|
||
And finally run `pod install` command so that blade's RN dependencies are linked to your project: | ||
|
||
```shell | ||
cd ios && pod install | ||
``` | ||
- `@razorpay/i18nify-react` | ||
- A state management React wrapper for `@razorpay/i18nify-js` that maintains locale state of your page. Follow [this guide](https://www.npmjs.com/package/@razorpay/i18nify-react) to configure and install it. | ||
|
||
```shell | ||
yarn add @razorpay/i18nify-react | ||
``` | ||
|
||
2. Follow [this guide](#-install-fonts) to install the fonts. | ||
|
||
3. For **React Native** projects you need to do additional setup for the peer dependencies: | ||
|
||
```shell | ||
yarn add @floating-ui/react-native@0.10.0 react-native-reanimated@3.4.1 react-native-tab-view@3.5.2 react-native-pager-view@6.2.1 react-native-svg@12.3.0 react-native-gesture-handler@2.9.0 @gorhom/bottom-sheet@4.4.6 @gorhom/portal@1.0.1 | ||
``` | ||
|
||
- `react-native-reanimated` | ||
- Follow [this guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) to install it on Android & iOS which is required by Blade. | ||
- `react-native-svg` | ||
- Follow [this guide](https://github.com/react-native-svg/react-native-svg#with-react-native-cli) to install it on Android & iOS which is required by Blade. | ||
- `react-native-gesture-handler` | ||
- Follow [this guide](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) to install it, note that you don't need to add `<GestureHandlerRootView style={{ flex: 1 }}>` again on the root because BladeProvider already adds that out of the box. | ||
- `@gorhom/bottom-sheet` | ||
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up. | ||
- `@gorhom/portal` | ||
- Add this as peer dependency, no need to do additional setup since BladeProvider already sets everything up. | ||
- `@floating-ui/react-native` | ||
- Add this as peer dependency, no need to do additional setup. | ||
- `react-native-tab-view` | ||
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation). | ||
- `react-native-pager-view` | ||
- Add this as peer dependency, no need to do additional setup. This is needed for react-native Tabs component as per [this guide](https://reactnavigation.org/docs/tab-view/#installation). | ||
|
||
And finally run `pod install` command so that blade's RN dependencies are linked to your project: | ||
|
||
```shell | ||
cd ios && pod install | ||
``` | ||
|
||
## 🔜 Add blade libraries to your Figma project | ||
|
||
|
@@ -162,4 +177,4 @@ We use 2 fonts. [TASA Orbiter](https://tasatype.localremote.co/) (for our headin | |
ReactFontManager.getInstance().addCustomFont(this, "TASA Orbiter Display", R.font.tasa); | ||
// rest of the content of the method | ||
} | ||
``` | ||
``` |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,23 +1,30 @@ | ||||||
import type { StoryFn, Meta } from '@storybook/react'; | ||||||
import { Title } from '@storybook/addon-docs'; | ||||||
import { getCurrencyList } from '@razorpay/i18nify-js/currency'; | ||||||
import { I18nProvider, useI18nContext } from '@razorpay/i18nify-react'; | ||||||
import { useState } from 'react'; | ||||||
import type { AmountProps } from './Amount'; | ||||||
import { Amount as AmountComponent } from './Amount'; | ||||||
import type { AmountHeadingProps, AmountDisplayProps, AmountBodyProps } from './amountTokens'; | ||||||
import { currencyIndicatorMapping } from './amountTokens'; | ||||||
import { getStyledPropsArgTypes } from '~components/Box/BaseBox/storybookArgTypes'; | ||||||
import BaseBox from '~components/Box/BaseBox'; | ||||||
import { Sandbox } from '~utils/storybook/Sandbox'; | ||||||
import { Display, Text } from '~components/Typography'; | ||||||
import StoryPageWrapper from '~utils/storybook/StoryPageWrapper'; | ||||||
import { Box } from '~components/Box'; | ||||||
import { objectKeysWithType } from '~utils/objectKeysWithType'; | ||||||
import { ActionList, ActionListItem } from '~components/ActionList'; | ||||||
import { SelectInput } from '~components/Input/DropdownInputTriggers'; | ||||||
import { Dropdown, DropdownOverlay } from '~components/Dropdown'; | ||||||
import { Divider } from '~components/Divider'; | ||||||
import { Link } from '~components/Link'; | ||||||
|
||||||
const Page = (): React.ReactElement => { | ||||||
return ( | ||||||
<StoryPageWrapper | ||||||
componentName="Amount" | ||||||
componentDescription="Amounts are used to show small amount of color coded metadata, which are ideal for getting user attention." | ||||||
note="This component only displays the provided value in the specified currency, it does not perform any currency conversion." | ||||||
note="This component only displays the provided value in the specified currency with the formatting capabilities enabled by @razorpay/i18nify-js (https://www.npmjs.com/package/@razorpay/i18nify-js), it does not perform any currency conversion." | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
figmaURL="https://www.figma.com/file/jubmQL9Z8V7881ayUD95ps/Blade-DSL?type=design&node-id=73328-558626&mode=design&t=JkDSnlo8KJOBJimR-4" | ||||||
> | ||||||
<Title>Usage</Title> | ||||||
|
@@ -31,6 +38,22 @@ const Page = (): React.ReactElement => { | |||||
export default App; | ||||||
`} | ||||||
</Sandbox> | ||||||
<Box marginBottom="spacing.10"> | ||||||
<Text> | ||||||
The Amount component automatically formats numbers based on the user's browser locale | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can use the propname There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you update the messaging a bit? for more details of what? please refer to the documentation of what? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
enabled by{' '} | ||||||
<Link href="https://www.npmjs.com/package/@razorpay/i18nify-js"> | ||||||
@razorpay/i18nify-js | ||||||
</Link> | ||||||
. To adjust the locale according to your page, add{' '} | ||||||
<Link href="https://www.npmjs.com/package/@razorpay/i18nify-react"> | ||||||
@razorpay/i18nify-react | ||||||
</Link>{' '} | ||||||
library and utilise its hooks for updating the locale. For more details, please refer to | ||||||
the{' '} | ||||||
<Link href="https://www.npmjs.com/package/@razorpay/i18nify-react">documentation.</Link> | ||||||
</Text> | ||||||
</Box> | ||||||
</StoryPageWrapper> | ||||||
); | ||||||
}; | ||||||
|
@@ -176,7 +199,7 @@ HumanizeSuffix.args = { | |||||
HumanizeSuffix.storyName = 'Humanize Suffix'; | ||||||
|
||||||
const AmountCurrencyTemplate: StoryFn<typeof AmountComponent> = (args) => { | ||||||
const values = Object.keys(currencyIndicatorMapping); | ||||||
const values = Object.keys(getCurrencyList()); | ||||||
|
||||||
return ( | ||||||
<BaseBox justifyContent="flex-start" maxHeight="300px" overflowY="auto"> | ||||||
|
@@ -217,3 +240,98 @@ StrikeThrough.args = { | |||||
isStrikethrough: true, | ||||||
}; | ||||||
StrikeThrough.storyName = 'Strike Through'; | ||||||
|
||||||
// TODO: Replace below with i18nify getDefaultLocales API | ||||||
saurabhdaware marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
const localeList = [ | ||||||
{ | ||||||
country: 'India', | ||||||
locale: 'en-IN', | ||||||
}, | ||||||
{ | ||||||
country: 'USA', | ||||||
locale: 'en-US', | ||||||
}, | ||||||
{ | ||||||
country: 'Malaysia', | ||||||
locale: 'ms-MY', | ||||||
}, | ||||||
{ | ||||||
country: 'France', | ||||||
locale: 'fr-FR', | ||||||
}, | ||||||
{ | ||||||
country: 'Germany', | ||||||
locale: 'de-DE', | ||||||
}, | ||||||
]; | ||||||
|
||||||
const I18nAmountWrapper = (args: AmountProps): JSX.Element => { | ||||||
const { setI18nState } = useI18nContext(); | ||||||
const [currency, setCurrency] = useState('INR'); | ||||||
|
||||||
return ( | ||||||
<> | ||||||
<AmountComponent {...args} currency={currency as AmountProps['currency']} /> | ||||||
<Divider marginY="spacing.4" marginTop="spacing.8" /> | ||||||
<Dropdown selectionType="single"> | ||||||
<SelectInput label="Select currency" /> | ||||||
<DropdownOverlay> | ||||||
<ActionList> | ||||||
{Object.keys(getCurrencyList()).map((value) => ( | ||||||
<ActionListItem | ||||||
key={value} | ||||||
title={value} | ||||||
value={value} | ||||||
onClick={({ name }) => { | ||||||
setCurrency(name); | ||||||
}} | ||||||
/> | ||||||
))} | ||||||
</ActionList> | ||||||
</DropdownOverlay> | ||||||
</Dropdown> | ||||||
<Divider marginY="spacing.4" /> | ||||||
<Dropdown selectionType="single"> | ||||||
<SelectInput label="Select locale" /> | ||||||
<DropdownOverlay> | ||||||
<ActionList> | ||||||
{localeList.map((item) => ( | ||||||
<ActionListItem | ||||||
key={item.locale} | ||||||
title={`${item.country}(${item.locale})`} | ||||||
value={item.locale} | ||||||
onClick={({ name }) => { | ||||||
setI18nState?.({ locale: name }); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tarun-khanna this is setting the context at a global amount's level ideally we shall scope it within this story itself? Why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting a state by I18nProvider's To deal with this,
Thoughts ? @kamleshchandnani There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay i'm saying keep it simple from demonstration point of view because right now there's no co-relation to the end consumer that changes in one story is affecting other. what I'm suggesting is wrap another i18n context around just the locale story so the state changes is only affected to that story and not goes all the stories of amount component. No changes in implementation, just how the story is written There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed earlier, there is no finalised approach here that will resolve this issue so we will be addressing this issue in the next PR. The current one can still go as it is. |
||||||
}} | ||||||
/> | ||||||
))} | ||||||
</ActionList> | ||||||
</DropdownOverlay> | ||||||
</Dropdown> | ||||||
</> | ||||||
); | ||||||
}; | ||||||
|
||||||
const I18nAmountTemplate: StoryFn<typeof AmountComponent> = (args) => { | ||||||
return ( | ||||||
<I18nProvider> | ||||||
<BaseBox justifyContent="flex-start" minHeight="300px" overflowY="auto"> | ||||||
<BaseBox | ||||||
display="flex" | ||||||
alignItems="baseline" | ||||||
paddingRight="spacing.3" | ||||||
paddingTop="spacing.3" | ||||||
flexDirection="column" | ||||||
> | ||||||
<I18nAmountWrapper {...args} /> | ||||||
</BaseBox> | ||||||
</BaseBox> | ||||||
</I18nProvider> | ||||||
); | ||||||
}; | ||||||
|
||||||
export const I18nAmount = I18nAmountTemplate.bind({}); | ||||||
I18nAmount.args = { | ||||||
...defaultArgs, | ||||||
}; | ||||||
I18nAmount.storyName = 'Amount in diff locales'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shall also update the installation guide with installation of i18nify. its located at
packages/blade/docs/guides/Installation.stories.mdx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I was planning to send this in a separate PR, but we can incorporate these changes into this one.
I'll need your assist to finalize the content and format for inclusion here. @kamleshchandnani
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes please add it in this PR itself because everything is related to Amount in this context. Let me know what exactly do you need help with?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.