Skip to content
This repository was archived by the owner on Jan 1, 2023. It is now read-only.

wanna pull #26

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
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
29 changes: 0 additions & 29 deletions .babelrc

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ reports/
tmp/
yarn-error.log
.tern-port
.vscode
121 changes: 104 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# React Script Tag 💉
# React Script Tag Updated for React 18

# [NPM Package](https://www.npmjs.com/package/react-script-tag-18)



This react component is intended to be a drop-in replacement for the `<script>`
html native tag. After you add it in any location of your react-app, the component
Expand All @@ -7,6 +11,13 @@ It supports all the [native
attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) as
well.


# Outside Change Log
- May 2024
- Refactored for better extensibility, readability, and usage of React 18 features.
- Dec 2022
- This is a really well written little tool that actually allows for script loading to at least feel some what asynchronously loadable. Just saw it fall out of date with its packages so updated them and also using typescript now. Creating a seperate NPM package for now but if the original author wants to add these changes I'll be more than happy to delete the npm package.

Keywords: [Blazing fast](https://twitter.com/acdlite/status/974390255393505280)
🔥, Minimal 📦, and Simple 🤖

Expand All @@ -26,48 +37,124 @@ You can install this package thru [npm](https://www.npmjs.com/) or
[yarn](https://yarnpkg.com):

``` sh
yarn install @gumgum/react-script-tag
yarn install react-script-tag-18
```

## Usage

You can use the `Script` component anywhere. Once it is mounted, the component
will proceed to load your script.


### Example Usage

#### Run a demo in your browser, with code, using CodeSandbox [here!](https://codesandbox.io/s/react-script-tag-demo-as-a-time-based-excersize-y8nidw)
- [View Demo](https://y8nidw.csb.app/)

``` jsx
import React from 'react';
import Script from '@gumgum/react-script-tag';
import ScriptTag from 'react-script-tag-18';

class MyApp extends React.Component {
const MyProfileComponent = () => {

_onMyScriptLoad = () => {/* ... */};
_onMyScriptError = () => {/* ... */};

const [jsLoaded , setJsLoaded] = React.useState(false);

render() {
return (
<div>
{/* Your App's code */}
<Script
src="//url-to-your-site.com/script.js"
type="text/javascript"
onLoad={ this._onMyScriptLoad }
onError={ this._onMyScriptError }
async
/>
</div>
<div className="some-class-that-relies-on-profile-js" style={{
alignItems: 'center',
verticalAlign: 'middle',
textAlign: 'center',
display: 'flex-box',
justifyContent: 'center',
}}>

</div>

<ScriptTag src="https://platform.linkedin.com/badges/js/profile.js"
delayMs={500}
onLoad={() => {
console.log('My Profile.js script Loaded');
setJsLoaded(true); // set some state variable to initiate a re-render
}}
async={true}
/>

</div>
);
}
}

export default MyApp;
export default MyProfileComponent;
```

> It is **recommended** that the `Script` tag is placed in a component that only
> renders once in the entire life of your app. Otherwise, a new `<script>` tag
> will be appended each time the component mounts again. There are plans down
> the road to prevent this.

## Examples
### CDN Example

``` html
<!DOCTYPE html>
<html>
<head>
<title>react-script-tag-18 cdn demo</title>
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/react-script-tag.umd.min.js"></script>

</head>

<body>
<div id="root"></div>
<script async="true" type="text/javascript">
console.info('React version:', React.version);
const ScriptTag = window.ScriptTag;
// state loaded

const ScriptTagELemWrapperDiv = () => {
const [loaded, setLoaded] = React.useState(false);
const [countdown, setCountdown] = React.useState(5);
React.useEffect(() => {
const interval = setInterval(() => {
setCountdown((prevCountdown) => prevCountdown - 1);
}, 1000);
return () => clearInterval(interval);
}, []);
const ScriptTagElem = React.createElement('div', {
children: React.createElement(ScriptTag, {
src: 'https://platform.twitter.com/widgets.js',
type: 'text/javascript',
async: true,
delayMs: 4950,
onLoad:() => {
console.log('Script loaded');
setLoaded(true);
},
children: loaded ? 'Script loaded' : 'Script will be loaded in ' + countdown + (countdown === 1 ? ' second' : ' seconds'),
}),

});
return ScriptTagElem;
}



ReactDOM.render(React.createElement(ScriptTagELemWrapperDiv), document.getElementById('root'));




</script>
</body>

</html>
```

## ~~Deprecated Examples~~

At GumGum, we usually wrap the `Script` component as follow, to facilitate
adding 3rd-parties. Here is an example, on how we add [Qualaroo](https://qualaroo.com/):
Expand Down
21 changes: 21 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |

## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
21 changes: 21 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
// The root of your source code, typically /src
// `<rootDir>` is a token Jest substitutes
roots: ["<rootDir>/src"],

// Jest transformations -- this adds support for TypeScript
// using ts-jest
transform: {
"^.+\\.tsx?$": "ts-jest"
},

"testEnvironment": "jsdom",

// Test spec file resolution pattern
// Matches parent folder `__tests__` and filename
// should contain `test` or `spec`.
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",

// Module file extensions for importing
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"]
};
28 changes: 28 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
export type ScriptLoaderProps = {
delayMs?: number;
onCreate?: (() => void) | undefined;
className?: string;
id?: string;
onError?: OnErrorEventHandler;
children?: React.ReactNode;
onLoad?: ((e: Event) => void) | undefined;
src: string;
otherProps?: {
[key: string]: string;
};
};
/**
*
* @param delayMs - The delay in milliseconds before the script is loaded, optional, default is 0
* @param onCreate - Callback function to be called when the script is created, or right after the call that appends the script to the DOM is made, optional
* @param onError - Callback function to be called when the script fails to load, optional
* @param onLoad - Callback function to be called when the script is loaded, optional
* @param src - The source URL of the script to be loaded, required
* @param otherProps - Any other attributes to be added to the script tag, optional, e.g. { "data-foo": "bar" }
* @returns <></> - Returns an empty fragment
* @example
* <ScriptLoader src="https://www.example.com/script.js"
* delayMs={1000} onLoad={(e) => console.log("Script loaded successfully")} />
*/
export default function ScriptTag({ delayMs, onCreate, onError, onLoad, src, id, className, children, otherProps, }: ScriptLoaderProps): React.JSX.Element;
2 changes: 2 additions & 0 deletions lib/react-script-tag.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/react-script-tag.m.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/react-script-tag.umd.js

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions lib/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
export type ScriptLoaderProps = {
delayMs?: number;
onCreate?: (() => void) | undefined;
className?: string;
id?: string;
onError?: OnErrorEventHandler | undefined;
children?: React.ReactNode;
onLoad?: ((e: Event) => void) | undefined;
src: string;
[key: string]: any;
} & React.HTMLProps<HTMLScriptElement>;
/**
*
* @param delayMs - The delay in milliseconds before the script is loaded, optional, default is 0
* @param onCreate - Callback function to be called when the script is created, or right after the call that appends the script to the DOM is made, optional, useful if you need to handle something right when the delay timer begins and hence when the script has not yet been loaded. Not that useful if delayMs is 0 unless for some debugging purposes.
* @param onError - Callback function to be called when the script fails to load, optional
* @param onLoad - Callback function to be called when the script is loaded, or in other words when the script has succesfully loaded and executed its contents, optional
* @param src - The source URL of the script to be loaded, required
* @param ...otherProps - Any additional attributes to be added to the script tag, optional
* @param children - Any children to be rendered, optional, default is an empty fragment
* @returns <></> - Returns an empty fragment or fragment with children
* @example
* <ScriptLoader
* data-other-prop="other-prop-value"
* src="https://www.example.com/script.js"
* delayMs={1000} onLoad={(e) => console.log("Script loaded successfully")} />
*/
export default function ScriptTag({ delayMs, onCreate, onError, onLoad, src, id, className, children, ...otherProps }: ScriptLoaderProps): React.JSX.Element;
Loading