Skip to content
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

3.0.0! 🥳 #11

Merged
merged 9 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resources
77 changes: 14 additions & 63 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,27 @@
module.exports = {
"root": true,
"env": {
"es2021": true,
"node": true
"node": true,
"react-native/react-native": true // *2
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/recommended-requiring-type-checking", // *1
"eslint-config-gev/react-native", // https://github.com/SrBrahma/eslint-config-gev
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"tsconfigRootDir": __dirname, // *1
"project": ['./tsconfig.json'], // *1
"ecmaVersion": 12,
"sourceType": "module",
"tsconfigRootDir": __dirname,
"project": "./tsconfig.json",
"ecmaFeatures": { // *2
"jsx": true
}
},
"plugins": [
"react",
"react-native",
"@typescript-eslint"
],
"rules": {
"indent": ["warn", 2],
"linebreak-style": ["error", "unix"],
"quotes": ["warn", "single", { "allowTemplateLiterals": true }],
"semi": ["warn", "always"],
"comma-spacing": ["warn"],
"object-curly-spacing": ["warn", "always"], // Spacing { beforeAndAfter }

// "no-prototype-builtins": "off", // Dont allow obj.hasOwnProperty https://eslint.org/docs/rules/no-prototype-builtins

"react/prop-types": "off",
"react/display-name": "off",

"@typescript-eslint/ban-ts-comment": "off", // Else would complain about // @ts-ignore in .js files. If I didn't need this ts-comment, this could be removed
"@typescript-eslint/no-inferrable-types": "off", // ?
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off", // ?
"@typescript-eslint/no-non-null-assertion": "off", // ?

// TS doesn't allow "== false" yet (4.1.2), so, this rule isn't good enough to test for falsy values.
// // "@typescript-eslint/strict-boolean-expressions": ["warn", {
// // allowNullableBoolean: true,
// // }],

"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unsafe-assignment": "off", // ?


"@typescript-eslint/no-floating-promises": "off",

// This wasn't allowing different data types in `templates string`. Why the fuck not?
"@typescript-eslint/restrict-template-expressions": "off",

// wasn't allowing eg setTimeout(async () =>...). Any good reason to keep it on? https://stackoverflow.com/a/63488201/10247962
"@typescript-eslint/no-misused-promises": "off",

// Allow acessing props of any type var. Useful for if ((X as any).Y), to check if it exists.
"@typescript-eslint/no-unsafe-member-access": "off",

// To allow the return as any. I know what I am doing!
"@typescript-eslint/no-unsafe-return": "off",

// To allow calling new (Intl as any).RelativeTimeFormat(...), as TS doesn't know it yet.
"@typescript-eslint/no-unsafe-call": "off",

// Wasn't simply allowing `const a = x.y.functionA`.
"@typescript-eslint/unbound-method": "off"
}
};
};

// [*1] - https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/TYPED_LINTING.md#getting-started---linting-with-type-information
// [*2] - https://github.com/Intellicode/eslint-plugin-react-native#configuration
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/node_modules
node_modules
/lib
.vscode
22 changes: 20 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
### 1.1.1 - March 23th 2021
### 3.0.0 - 2021/07/17

* **Shadow with automatic size is applied on the same render!**. Lib rewritten to allow it. 1 month of pure suffering and despair trying to find new html/svg/react hacks to do what I wanted. :') #7, #8, #9,
* Now it works on Web (React Native Web / Expo)
* Added `getChildRadius` prop.
* Added `paintInside` prop.
* Added `viewStyle` prop.
* Removed `contentViewStyle` prop.
* Changed default `startColor` from `'#00000010'` to `'#00000020'`, so it's more noticeable when first trying the lib.
* Looks like the pixel gaps/overlaps are all solved. It was a very long and frustrating marathon to achieve this!
* [code] Added a partial README filler, using [this](https://github.com/tgreyuk/typedoc-plugin-markdown/issues/59#issuecomment-867300957) (mine!)
* Added Sandbox! Used it a lot while developing this lib.
* Changed minor functionalities
* Minor fixes

> We are calling this 3.0.0 because 2.0.0 would be ambiguous. One could think that the 1.0.0 is a reference to the original react-native-shadow package and the 2.0.0 would just be the react-native-shadow-2.


### 1.1.1 - 2021/03/23

* Fixed sides shadow position when not having top/left side shadow.

## 1.1.0 - March 6th 2021
## 1.1.0 - 2021/03/06

* Added offset
55 changes: 0 additions & 55 deletions README.MD

This file was deleted.

123 changes: 123 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<!--
README generated with handlebars, typedoc-plugin-markdown and my
temporary typedoc-plugin-markdown to table code.

The README.hbs is in resources/README.hbs.

DO NOT edit the README.md, but the README.hbs and then run `npm run readme`.
-->


<div align="center">

[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![TypeScript](https://badgen.net/npm/types/env-var)](http://www.typescriptlang.org/)
[![npm](https://img.shields.io/npm/v/react-native-shadow-2)](https://www.npmjs.com/package/react-native-shadow-2)
[![npm](https://img.shields.io/npm/dw/react-native-shadow-2)](https://www.npmjs.com/package/react-native-shadow-2)

</div>


# react-native-shadow-2

[react-native-shadow](https://github.com/879479119/react-native-shadow) is dead for years. This one is an improved version with more functionalities, Typescript support and written from scratch.

It solves the old React Native issue of not having the same shadow appearence and implementation for Android, iOS and Web.

The [ethercreative/react-native-shadow-generator](https://ethercreative.github.io/react-native-shadow-generator) website won't give you very similar results between the two platforms, for the reasons I described [here](https://github.com/ethercreative/react-native-shadow-generator/issues/2#issuecomment-738130722), when I started to think about the solution to this shadow issue.

Compatible with Android, iOS and Web. And Expo!

Implementation: [./src/index.tsx](./src/index.tsx)


## 🥳 New version 3.0.0! (2021-07-17) 🥳

### The long waited and most wanted feature is out!

Before this new version, it was required to manually enter your component size or leave it as undefined and the integrated onLayout would get its size and apply the shadow on the next render.

Now, **the shadow is applied on the same render without entering its size!**


## 💿 Installation

### 1. First install [react-native-svg](https://github.com/react-native-svg/react-native-svg).

### 2. Then install react-native-shadow-2:

```bash
npm i react-native-shadow-2
# or
yarn add react-native-shadow-2
```


## 📖 Usage

### Structure
```tsx
import { Shadow } from 'react-native-shadow-2';

<Shadow>
{/* Your component */}
</Shadow>
```

### Basic
```tsx
<Shadow>
<View>
<Text style={{ margin: 20, fontSize: 20 }}>🙂</Text>
</View>
</Shadow>
```

![Example 1](./resources/README/react-native-shadow-2-ex-1.png)

### Advanced
```tsx
<Shadow distance={15} startColor={'#eb9066d8'} finalColor={'#ff00ff10'} offset={[3, 4]} paintInside>
<View style={{ borderTopLeftRadius: 24, borderBottomRightRadius: 0, borderRadius: 10, backgroundColor: '#c454f0dd' }}>
<Text style={{ margin: 20, fontSize: 20 }}>🤯</Text>
</View>
</Shadow>
```

![Example 2](./resources/README/react-native-shadow-2-ex-2.png)

## Properties

| Property | Type | Default | Description
| --- | --- | --- | ---
| **startColor** | `string` | `'#00000020'` | The color of the shadow when it's right next to the given content, leaving it.<br/>Accepts alpha channel.
| **finalColor** | `string` | `'#0000', transparent.` | The color of the shadow at the maximum distance from the content. Accepts alpha channel.
| **distance** | `number` | `10` | How far the shadow will go.
| **radius** | `number \| { default?: number ; topLeft?: number ; topRight?: number ; bottomLeft?: number ; bottomRight?: number }` | `undefined` | The radius of each corner of your child component. Passing a number will apply it to all corners.<br/><br/>If passing an object, undefined corners will have the radius of the `default` property if it's defined.<br/><br/>If undefined and if getChildRadius, it will attempt to get the child radius from the borderRadius style.<br/><br/>Fallbacks to 0.
| **getChildRadiusStyle** | `boolean` | `true` | If it should try to get the radius from the child view **`style`** if `radius` property is undefined. It will get the values for each<br/>corner, like `borderTopLeftRadius`, and also `borderRadius`. If a specific corner isn't defined, `borderRadius` value is used.
| **sides** | `("left" \| "right" \| "top" \| "bottom")[]` | `['left', 'right', 'top', 'bottom']` | The sides of your content that will have the shadows drawn. Doesn't include corners.
| **corners** | `("topLeft" \| "topRight" \| "bottomLeft" \| "bottomRight")[]` | `['topLeft', 'topRight', 'bottomLeft', 'bottomRight']` | The corners that will have the shadows drawn.
| **offset** | `[x: string \| number, y: string \| number]` | `[0, 0]` | Moves the shadow. Negative x moves it to the left, negative y moves it up.<br/><br/>Accepts `'x%'` values, in relation to the child's size.<br/><br/>Read `paintInside` property description for related configuration.
| **paintInside** | `boolean` | `false` | If the shadow should be applied inside the external shadows, below the child. `startColor` is used as fill color.<br/><br/>You may want this as true when using offset or if your child have some transparency.
| **viewStyle** | `ViewStyle` | `undefined` | The style of the view that wraps your child component.
| **containerViewStyle** | `StyleProp<ViewStyle>` | `undefined` | The style of the view that contains the shadow and your child component.
| **size** | `[width: number, height: number]` | `undefined` | If you don't want the 2 renders of the shadow (first applies the relative positioning and sizing that may contain a quick pixel gap, second uses exact pixel size from onLayout) or you are having noticeable gaps/overlaps on the first render,<br/>you can use this property. Using this won't trigger the onLayout, so only 1 render is made.<br/><br/>It's also good if you want an animated view.<br/><br/>It will apply the corresponding `width` and `height` styles to the `viewStyle` property.<br/><br/>The values will be properly rounded using our R() function.


## 🐛 Notes / Known Issues

* Setting (or obtaining from the child) a too high `radius` (`> size/2`) will mess the shadow.

* **`[Mobile]`** The shadow, since v3, will be applied on the first render even if no size is passed to it, as we now (v3) magically use relative positions and sizings.
There may be a pixel wide gap on the first render on the right and bottom SVG parts connections, due to how React Native and react-native-svg handles percentage sizings and roundings. It's fixed automatically
on the following render, as this lib will get the exact pixel size of the child component using onLayout.
This gap won't always happen and it's usually hardly noticeable.
If you don't want to this to happen at all, you can use the `size` property.

* **`[Web]`** If your child have a decimal size, there may be a pixel wide gap between the child and the right/bottom shadow, as browsers usually allow decimal sizings and will blur the last pixel line/row.
You can either fix it by using `paintInside` prop to hide the possible imperfections or use the `size` property to avoid it from happening.

## 📰 [Changelog](./CHANGELOG.md)

## 🦉 Alternatives
* [react-native-neomorph-shadows](https://github.com/tokkozhin/react-native-neomorph-shadows) looks great and has different possibilities. It doesn't support Expo though, as `react-native-shadow-2` does.
Loading