razorpay / blade Goto Github PK
View Code? Open in Web Editor NEWDesign System that powers Razorpay
Home Page: https://blade.razorpay.com
License: MIT License
Design System that powers Razorpay
Home Page: https://blade.razorpay.com
License: MIT License
Issue: aliased imports from ~components/Form
breaks the type generation
Workaround(not ideal but unblocking release for now): replace alias imports with relative imports ~components/Form
➡️ ../../Form
Ideal solution: the alias imports shall work too
Temporary workaround in #700
It will be cool to have a <Form>
component like Remix in blade.
Remix Form Docs: https://remix.run/docs/en/v1/guides/data-writes
Example API
import { Form, Input, Button } from '@razorpay/blade';
// ...
<Form method="post" action="/user/signin" onResponse={(res) => {/* do something with response */ }}>
<Input name="email" />
<Input name="password" />
<Button type="submit">Login</Button>
</Form>
This will reduce the JavaScript the consumer has to write to build forms.
For Radio/react controlled variant components, the implementation seems to be wrong. useState
as seen here https://github.com/razorpay/blade/blob/master/src/atoms/Radio/Radio.web.js#L9 would only be called once, so even if the value
prop is updated by the consumer, the selected
value remains the same.
This could be the same case with Radio/native, as the same logic is used https://github.com/razorpay/blade/blob/master/src/atoms/Radio/Radio.native.js.
Bundlephobia currently doesn't work for blade, it's a useful tool in the JS ecosystem for finding bundle size. We should take this as a low priority.
Ugh prettier messes this up every time
Originally posted by @chaitanyadeorukhkar in #671 (comment)
Tested on latest master
onChange
isn't getting called when we clear the input field.
TextInput
is behaving bit weirdly on Android (in uncontrolled mode with clear button enabled). It swallows the first character that is typed in the input field. So you've to type the character again. In the screenshot check the last 4 lines of logs and notice the "T" had to be typed twice to complete "The".
TextInput uncontrolled story is also behaving weirdly on Android. It doesn't clear the input on pressing clear button.
Reference: #544 (comment)
This will help us prefix [blade component name]
and will be maintainable on long run.
We need create a way to strip off development logs while building the library. This will also save us tons on bundlesize
<Size width="100px">
<View>
<TextInput
type="number"
width="auto"
name="card_number"
label="Card number"
variant="filled"
labelPosition="top"
placeholder="Enter 16 digit card number"
errorText={formikProps.touched.card_number && formikProps.errors.card_number}
/>
</View>
</Size>
TextInput overflowing the parent
If we don't give width=100%
for input, it is will overflow the parent if parent width is smaller than 153px
I think, in order to fix this we wrote this code https://github.com/razorpay/blade/blob/master/src/atoms/TextInput/TextInput.web.js#L435. But its not working
Here we are supposed to make input
element width=100% instead we are doing it for its parent InputContainer
Just like Universe
I see that we're using focus ring in different ways, in some components as CSS and at some places via helper functions. Probably can be taken up as a separate PR.
Originally posted by @divyanshu013 in #613 (comment)
Isn't that only for user facing components? Otherwise we should add a linting rule to enforce this
Originally posted by @divyanshu013 in #654 (comment)
When prefers reduced motion is enabled we should disable transitions like button colors, loaders, etc.
Let's export at the end, easier to track what we are exporting.
Originally posted by @anuraghazra in #666 (comment)
Currently how blade-old's Icon
component work is that we are importing all the icons and accessing them in runtime via icons[name]
This method lets us reference the icons via their name so we can do <Icon name="download" />
But the downside to this approach is that, this prevents treeshaking.
Causing all the icons to be present on the final bundle even if we are not using them.
https://github.com/razorpay/blade/blob/master/packages/blade-old/src/atoms/Icon/Icon.web.js#L17
Total size of all the icons gzipped is around 12kb which is a lot:
After discussing with @kamleshchandnani we decided that we can move onto a more flexible approach to directly using the icon component in the codebase. This way users would only import what they need.
Users would do something like this:
import { DownloadIcon, LeftArrow, ChevronLeft } from 'blade-old/icons';
<DownloadIcon></DownloadIcon>
<LeftArrow></LeftArrow>
<ChevronLeft></ChevronLeft>
We will first create a BaseIcon component which will hold the common properties like width, height, viewbox, handle a11y and render a svg component.
The implementation would look something like this:
const Icon = ({ label, hidden, viewbox, size, children }) => {
const iconSize = {
xsmall: 12,
small: 16,
};
const theme = useTheme();
return (
<svg
aria-label={label}
aria-hidden={hidden}
fill={getColor(theme, fill)}
height={iconSize[size]}
width={iconSize[size]}
viewBox={viewbox}
>
{children}
</svg>
);
};
Then we will wrap all the icons with BaseIcon and reexport each of them separately.
// DownloadIcon.js
export function DownloadIcon({ size }) {
return (
<Icon size={size} viewBox="0 0 24" fill="none">
<path
fillRule="evenodd"
clipRule="evenodd"
d="..."
fill={fill}
/>
</Icon>
);
}
Questions:
Will we expose the Icon
component too?
A: I think we can expose the Icon too, if users wants to build their own Icon component they don't have to recreate an wrapper and worry about size
, fill
& accessibility if we provide the Icon component for them.
How will the directory structure be impacted?
A: We will reexport all the icons to index.js so I think there shouldn't need a huge refactor to the directory structure, only change will be needed which is mentioned in "Migration" section.
This change should introduce a major breaking change
Replace Icon component with their respective icons.
- import Icon from 'blade-old/icon';
+ import { DownloadIcon } from 'blade-old/icons';
- <Icon name="download" />
+ <DownloadIcon />
I'll explore this improvement later on after solving the bundle size issue mentioned above, on a different PR
Further more we also discussed a few ideas to reduce the duplicate code between all the icons web and native variant, currently we are duplicating the SVG code in both places for example:
To solve the duplicity, we can create a JSON representation of the svg and render that JSON in both places consistently
For example:
// AlertCircle.json
{
viewBox: "0 0 24 24",
path: [
{
fillRule: "evenodd",
d: "....",
},
{
fillRule: "evenodd",
d: "....",
}
]
}
Then on we will loop over the json and render it in as JSX. (we can even create helper factory method like a createIcon function to reduce the code further)
function AlertCircle({ width, height, fill }) {
return (
<BaseIcon width={width} height={height} viewBox={icon.viewBox} fill="none">
{icon.path.map((path) => <Path {...path} fill={fill} />)}
</BaseIcon>
);
}
For TextArea the TextInput's accessory components are aware of multiline props which ideally they shouldn't.
Check this discussion for more details
Keypress
to block invalid number inputs?Input type=number
is handled differently in Chrome vs Firefox.
Chrome
If input has a type of number
, in Chrome, any kind of invalid inputs like abc
etc would be blocked and the same would not be rendered as the value inside the input.
Firefox
If input has type of number
, even if the user input is invalid like abc
, it still gets rendered on the input value even though the value does not actually change, because firefox does not fire the change
event even if it is rendering it. After rendering, on blur, firefox will render a red border on the input signifying that the input was invalid.
This is not the behaviour we want, hence we use keyPress
event for listening for the input and then prevent the default behaviour if it is an invalid value.
Demo: https://codesandbox.io/s/typenumberinconsistencies-mfgq5?file=/src/App.js
Uncomment the onKeypress handlers to check the fix
In both firefox & chrome, number inputs can have -
sign in the start of the input but not at the end. Some input like 123456-
makes the input invalid and calls onChange
with an empty string value ""
. This especially is a problem with the Floating Label Style
, as it marks the value is empty, thus when the user blurs the input, the label comes down to initial position breaking styles.
To fix this, we use type=text
and keep blocking invalid numbers using the Keypress
handler as mentioned above. Since we are using type=text
, we need some way to open up the number keyboard by default on mobile browsers. For this we use the inputMode
attribute. There is decent support for inputMode and due to lack of other solutions not found during dev, this seemed like the most viable solution.
Demo: https://codesandbox.io/s/invalid-character-minus-pmobk?file=/src/App.js:710-716
Try using a string like 1232424-
and see console output
More on inputMode here: https://css-tricks.com/everything-you-ever-wanted-to-know-about-inputmode/
Currently we're not setting up all the a11y props correctly on native. Uncovered this while writing test cases. For example, we can't use getByLabelText
and instead have to rely on getByPlaceholderText
.
accessibilityLabel
correctly to inputAdd a story to showcase all icons so it makes it easier to identify which already exist
When running blade with vite setup it's throwing error:
Pre-bundling dependencies:
react
react-dom
@razorpay/blade/components
@razorpay/blade/tokens
react/jsx-dev-runtime
(this will be run only when your dependencies or config have changed)
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/defineProperty"
node_modules/@razorpay/blade/build/components/index.web.js:1:30:
1 │ import _defineProperty$1 from '@babel/runtime-corejs3/helpers/defineProperty';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/defineProperty" as external to exclude it
from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/typeof"
node_modules/@razorpay/blade/build/components/index.web.js:2:20:
2 │ import _typeof from '@babel/runtime-corejs3/helpers/typeof';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/typeof" as external to exclude it from the
bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/includes"
node_modules/@razorpay/blade/build/components/index.web.js:3:38:
3 │ import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/includes" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/keys"
node_modules/@razorpay/blade/build/tokens/index.web.js:1:25:
1 │ import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/keys" as external to exclude
it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/concat"
node_modules/@razorpay/blade/build/components/index.web.js:4:36:
4 │ import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/concat" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols"
node_modules/@razorpay/blade/build/tokens/index.web.js:2:42:
2 │ ...t _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols" as
external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/keys"
node_modules/@razorpay/blade/build/components/index.web.js:5:25:
5 │ import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/keys" as external to exclude
it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/filter"
node_modules/@razorpay/blade/build/tokens/index.web.js:3:36:
3 │ import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/filter" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols"
node_modules/@razorpay/blade/build/components/index.web.js:6:42:
6 │ ...t _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols" as
external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor"
node_modules/@razorpay/blade/build/tokens/index.web.js:4:45:
4 │ ...ect$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor"
as external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/filter"
node_modules/@razorpay/blade/build/components/index.web.js:7:36:
7 │ import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/filter" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/for-each"
node_modules/@razorpay/blade/build/tokens/index.web.js:5:37:
5 │ import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/for-each" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor"
node_modules/@razorpay/blade/build/components/index.web.js:8:45:
8 │ ...ect$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor"
as external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors"
node_modules/@razorpay/blade/build/tokens/index.web.js:6:46:
6 │ ...t$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors"
as external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/for-each"
node_modules/@razorpay/blade/build/components/index.web.js:9:37:
9 │ import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/for-each" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/define-properties"
node_modules/@razorpay/blade/build/tokens/index.web.js:7:37:
7 │ import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/define-properties" as external
to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors"
node_modules/@razorpay/blade/build/components/index.web.js:10:46:
10 │ ...$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors"
as external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/define-property"
node_modules/@razorpay/blade/build/tokens/index.web.js:8:35:
8 │ import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/define-property" as external
to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/define-properties"
node_modules/@razorpay/blade/build/components/index.web.js:11:37:
11 │ import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/define-properties" as external
to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/defineProperty"
node_modules/@razorpay/blade/build/tokens/index.web.js:9:30:
9 │ import _defineProperty$1 from '@babel/runtime-corejs3/helpers/defineProperty';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/defineProperty" as external to exclude it
from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/define-property"
node_modules/@razorpay/blade/build/components/index.web.js:12:35:
12 │ import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/define-property" as external
to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/typeof"
node_modules/@razorpay/blade/build/tokens/index.web.js:10:20:
10 │ import _typeof from '@babel/runtime-corejs3/helpers/typeof';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/typeof" as external to exclude it from the
bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/slicedToArray"
node_modules/@razorpay/blade/build/components/index.web.js:13:27:
13 │ import _slicedToArray from '@babel/runtime-corejs3/helpers/slicedToArray';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/slicedToArray" as external to exclude it
from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/helpers/slicedToArray"
node_modules/@razorpay/blade/build/tokens/index.web.js:11:27:
11 │ import _slicedToArray from '@babel/runtime-corejs3/helpers/slicedToArray';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/helpers/slicedToArray" as external to exclude it
from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/entries"
node_modules/@razorpay/blade/build/components/index.web.js:14:7:
14 │ import '@babel/runtime-corejs3/core-js-stable/object/entries';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/entries" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/object/entries"
node_modules/@razorpay/blade/build/tokens/index.web.js:12:29:
12 │ import _Object$entries2 from '@babel/runtime-corejs3/core-js-stable/object/entries';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/object/entries" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/array/is-array"
node_modules/@razorpay/blade/build/components/index.web.js:15:7:
15 │ import '@babel/runtime-corejs3/core-js-stable/array/is-array';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/array/is-array" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/array/is-array"
node_modules/@razorpay/blade/build/tokens/index.web.js:13:27:
13 │ import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/array/is-array" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/json/stringify"
node_modules/@razorpay/blade/build/components/index.web.js:16:7:
16 │ import '@babel/runtime-corejs3/core-js-stable/json/stringify';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/json/stringify" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/concat"
node_modules/@razorpay/blade/build/tokens/index.web.js:14:36:
14 │ import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/concat" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/every"
node_modules/@razorpay/blade/build/components/index.web.js:17:7:
17 │ import '@babel/runtime-corejs3/core-js-stable/instance/every';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/every" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/json/stringify"
node_modules/@razorpay/blade/build/tokens/index.web.js:15:28:
15 │ import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/json/stringify" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/map"
node_modules/@razorpay/blade/build/components/index.web.js:18:33:
18 │ import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/map" as external to exclude
it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/every"
node_modules/@razorpay/blade/build/tokens/index.web.js:16:35:
16 │ import _everyInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/every';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/every" as external to
exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/slice"
node_modules/@razorpay/blade/build/components/index.web.js:19:35:
19 │ import _sliceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/slice';
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@babel/runtime-corejs3/core-js-stable/instance/slice" as external to
exclude it from the bundle, which will remove this error.
error when starting dev server:
Error: Build failed with 35 errors:
node_modules/@razorpay/blade/build/components/index.web.js:1:30: ERROR: Could not resolve "@babel/runtime-corejs3/helpers/defineProperty"
node_modules/@razorpay/blade/build/components/index.web.js:2:20: ERROR: Could not resolve "@babel/runtime-corejs3/helpers/typeof"
node_modules/@razorpay/blade/build/components/index.web.js:3:38: ERROR: Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/includes"
node_modules/@razorpay/blade/build/components/index.web.js:4:36: ERROR: Could not resolve "@babel/runtime-corejs3/core-js-stable/instance/concat"
node_modules/@razorpay/blade/build/components/index.web.js:5:25: ERROR: Could not resolve "@babel/runtime-corejs3/core-js-stable/object/keys"
...
at failureErrorWithLog (/Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:1605:15)
at /Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:1251:28
at runOnEndCallbacks (/Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:1036:63)
at buildResponseToResult (/Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:1249:7)
at /Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:1358:14
at /Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:668:9
at handleIncomingPacket (/Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:765:9)
at Socket.readFromStdout (/Users/anurag.hazra/Documents/razorpay/experiments/test-blade-tokens/node_modules/esbuild/lib/main.js:635:7)
at Socket.emit (node:events:394:28)
at addChunk (node:internal/streams/readable:315:12)
Installing blade fails for all versions on npm 7. Problem is with peerDependencies which are now installable by default, and there's a conflict because of the strict versions present in package.json
Another issue is downloading of react-native
in web projects and vice-versa, causing more time to download in all builds.
Possible solution: empty peerDependencies object in package.json
Add strict checks to ensure icon
props in components are being used as intended.
✅ Intended usage:
import { Button, CreditCardIcon } from '@razorpay/components';
<Button icon={CreditCardIcon} />
❌ Misuse:
import { Button, CreditCardIcon } from '@razorpay/components';
<Button icon={() => <CreditCardIcon size="small" color="feedback.positive.icon.lowContrast"/>} />
Blade provides a useTheme hook to consume the theme and use it in the Application at each component level. This gives a lot of flexibility to use the theme in a function component.
Setup theme using BladeProvider
<BladeProvider themeTokens={paymentTheme} colorScheme="system">
<Card />
</BladeProvider>
And then inside the Card component,
const { theme } = useTheme();
return (
<StyledCard theme={theme}>
<LeadBold theme={theme}>Total Repayable Amount</LeadBold>
<DisplayMedium theme={theme}>₹16,666.67</DisplayMedium>
<AlertInformation theme={theme}>...</AlertInformation>
<Divider theme={theme} />
<CaptionRegular theme={theme}>...</CaptionRegular>
</StyledCard>
);
However, it is a little cumbersome for projects where large parts are using the same theme. Each core component will have to get the theme value from the useTheme hook and then pass it to individual components.
Instead of the aforementioned example usage of theme, there is an alternate approach that we can take for projects using StyledComponents. We can supply the theme once to styled-components's built-in ThemeProvider. This will automatically make the theme object available to each component.
Setup theme using BladeProvider
<BladeProvider themeTokens={paymentTheme} colorScheme="system">
<StyledThemeProvider theme={theme}> // Somehow get the theme here from Blade
<Card />
</StyledThemeProvider>
</BladeProvider>
And then inside the Card component,
return (
<StyledCard>
<LeadBold>Total Repayable Amount</LeadBold>
<DisplayMedium>₹16,666.67</DisplayMedium>
<AlertInformation>...</AlertInformation>
<Divider />
<CaptionRegular>...</CaptionRegular>
</StyledCard>
);
This approach has two advantages
While this approach can still be followed with the current API provided by Blade, it is cumbersome to get the Theme value as an additional component is required to get the theme.
For example
<BladeProvider themeTokens={paymentTheme} colorScheme="system">
<MyThemeProvider />
</BladeProvider>
Then, inside MyThemeProvider
const { theme } = useTheme();
return (
<StyledThemeProvider theme={theme}> // Somehow get the theme here from Blade
<Card />
</StyledThemeProvider>
)
The proposed solution removes the aforementioned extra component in the usage. If we expose ThemeContext.Consumer from within useTheme.js, the aforementioned solution can be reduced to the following
<BladeProvider themeTokens={paymentTheme} colorScheme="system">
<BladeThemeConsumer> // example name for the exposed ContextConsumer
{(theme) => (
<StyledThemeProvider theme={theme}> // Somehow get the theme here from Blade
<Card />
</StyledThemeProvider>
)}
<MyThemeProvider />
</BladeProvider>
While there is not a significant functional benefit of adding this API, there are cosmetic benefits from the libraries' usage point of view.
Blade will be a low-level library used in almost every Razorpay app. To make sure that blade stays performant, I think we should explore some other CSS solutions as well. Changing the CSS framework will become too difficult once we start building components.
Although in this issue I am proposing stitches (this is just my unresearched opinion), maybe an RFC on comparison of different CSS frameworks would be great since this will play a major role in the consumer apps.
We now have stitches which is a no/low-runtime CSS-in-JS solution. Time to Interactivity is one of the biggest unsolvable problems in React SSR/SSGs. We have hit several roadblocks on frontend-website because of chakra and framer-motion's runtime performance and bundle size. Having a low-runtime framework will help us improve a lot on that front.
It's bundle size is almost half of the styled-components and it is more performant on runtime. This will allow us to write base UI components without worrying too much about the performance.
I have used it in SSR and the setup with SSR is great! It is also one of their focus areas and they will keep on improving the SSR setup.
Their API is not too far from styled components so there won't be any major learning curve
There is a typo in exports field in package.json for the ./tokens
package.
This causes issues while bundling code for webpack 5 as webpack 5 supports export maps defined in package.json.
This is not an issue when working with webpack 4.
Fix the typo by changing deafult -> default
The BaseInput
decision doc mentions numeric
as a valid value for keyboardType
but the BaseInput
implementation doesn't support numeric
as a valid value. Is this intentional? Can we add support for numeric
? Due to this constraint, we've added default keyboardType
as decimal
instead of numeric
for OTPInput
. After adding support for numeric
, we should also change the default for OTPInput
as numeric
Right now we don't throw any error if the consumers passes SecondaryAction
without PrimaryAction
we want to restrict this behaviour. We can't do it with TS but we shall add it as a runtime check.
Example for BaseButton story
Initial height should be 64px unlike text input which is 36px
This commit broke the edge case where consumers can render components other than Tabs.Tab
but without it tabs render empty in production
I think these should be fillRule
, clipRule
(TS should ideally be warning these). Similarly at other places.
Originally posted by @divyanshu013 in #645 (comment)
Due to this at places we're adding ts-expect-error
On getting any error in the App component itself, (usual error, let's say any typo) sometimes the terminal starts printing infinitely something and ended up at loop.
Attaching a screenshot for the same.
In that case, I had to kill the server and restart it. This happens about like 5-7 times since yesterday.
We need to add support for https://www.npmjs.com/package/dotenv for storing tokens like the one needed in the figma plugin created by @saurav12 here https://github.com/razorpay/blade/blob/master/packages/tools/figma-plugin-version-history/package.json
Since there is no support for gap
on React Native yet, adding support for gap
on Box
would lead to UI breakage on native components. We have already used gap
with Box
at multiple places and we need to remove those instances and replace them with other appropriate spacings.
Running the app on react native throws a warning that we need to use styled-components/native
instead of styled-components
A possible fix could be adding 'react-native'
resolverMainFields
array to storybookjs/react-native#57
Tried doing this but ran into some other issues like no stories being rendered. Would need to debug further.
The clickable area is too small for a thumb to be able to record a press. Should add a hitSlop
here?
Originally posted by @chaitanyadeorukhkar in #613 (comment)
Seeing a weird bug in RadioButton
storybook URL
Environment - Firefox on Windows (works fine on Chromium)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.