@lit-labs/react
Advanced tools
Comparing version 1.0.9 to 1.1.0
@@ -16,4 +16,11 @@ /** | ||
declare type ElementWithoutPropsOrEventListeners<I, E> = Omit<I, keyof E | keyof ReactProps<I, E>>; | ||
declare type WebComponentProps<I extends HTMLElement, E extends EventNames = {}> = Partial<ReactProps<I, E> & ElementWithoutPropsOrEventListeners<I, E> & EventListeners<E>>; | ||
export declare type WebComponentProps<I extends HTMLElement, E extends EventNames = {}> = Partial<ReactProps<I, E> & ElementWithoutPropsOrEventListeners<I, E> & EventListeners<E>>; | ||
export declare type ReactWebComponent<I extends HTMLElement, E extends EventNames = {}> = React.ForwardRefExoticComponent<React.PropsWithoutRef<WebComponentProps<I, E>> & React.RefAttributes<I>>; | ||
interface Options<I extends HTMLElement, E extends EventNames = {}> { | ||
tagName: string; | ||
elementClass: Constructor<I>; | ||
react: typeof window.React; | ||
events?: E; | ||
displayName?: string; | ||
} | ||
declare type Constructor<T> = { | ||
@@ -27,2 +34,29 @@ new (): T; | ||
* | ||
* @param options An options bag containing the parameters needed to generate | ||
* a wrapped web component. | ||
* | ||
* @param options.react The React module, typically imported from the `react` npm | ||
* package. | ||
* @param options.tagName The custom element tag name registered via | ||
* `customElements.define`. | ||
* @param options.elementClass The custom element class registered via | ||
* `customElements.define`. | ||
* @param options.events An object listing events to which the component can listen. The | ||
* object keys are the event property names passed in via React props and the | ||
* object values are the names of the corresponding events generated by the | ||
* custom element. For example, given `{onactivate: 'activate'}` an event | ||
* function may be passed via the component's `onactivate` prop and will be | ||
* called when the custom element fires its `activate` event. | ||
* @param options.displayName A React component display name, used in debugging | ||
* messages. Default value is inferred from the name of custom element class | ||
* registered via `customElements.define`. | ||
*/ | ||
export declare function createComponent<I extends HTMLElement, E extends EventNames = {}>(options: Options<I, E>): ReactWebComponent<I, E>; | ||
/** | ||
* @deprecated Use `createComponent(options)` instead of individual arguments. | ||
* | ||
* Creates a React component for a custom element. Properties are distinguished | ||
* from attributes automatically, and events can be configured so they are | ||
* added to the custom element as event listeners. | ||
* | ||
* @param React The React module, typically imported from the `react` npm | ||
@@ -44,4 +78,4 @@ * package. | ||
*/ | ||
export declare const createComponent: <I extends HTMLElement, E extends EventNames = {}>(React: typeof import("react"), tagName: string, elementClass: Constructor<I>, events?: E | undefined, displayName?: string) => ReactWebComponent<I, E>; | ||
export declare function createComponent<I extends HTMLElement, E extends EventNames = {}>(ReactOrOptions: typeof window.React, tagName: string, elementClass: Constructor<I>, events?: E, displayName?: string): ReactWebComponent<I, E>; | ||
export {}; | ||
//# sourceMappingURL=create-component.d.ts.map |
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
const t=new Set(["children","localName","ref","style","className"]),n=new WeakMap,e=(t,e,i,s,o)=>{const l=null==o?void 0:o[e];void 0!==l?i!==s&&((t,e,i)=>{let s=n.get(t);void 0===s&&n.set(t,s=new Map);let o=s.get(e);void 0!==i?void 0===o?(s.set(e,o={handleEvent:i}),t.addEventListener(e,o)):o.handleEvent=i:void 0!==o&&(s.delete(e),t.removeEventListener(e,o))})(t,l,i):t[e]=i},i=(n,i,s,o,l)=>{const d=n.Component,c=n.createElement,h=new Set(Object.keys(null!=o?o:{}));class r extends d{constructor(){super(...arguments),this.o=null}t(t){if(null!==this.o)for(const n in this.i)e(this.o,n,this.props[n],t?t[n]:void 0,o)}componentDidMount(){this.t()}componentDidUpdate(t){this.t(t)}render(){var n;const e=null!==(n=this.props._$Gl)&&void 0!==n?n:null;void 0!==this.h&&this.u===e||(this.h=t=>{null===this.o&&(this.o=t),null!==e&&((t,n)=>{"function"==typeof t?t(n):t.current=n})(e,t),this.u=e});const o={ref:this.h};this.i={};for(const[n,e]of Object.entries(this.props))"__forwardedRef"!==n&&(h.has(n)||!t.has(n)&&!(n in HTMLElement.prototype)&&n in s.prototype?this.i[n]=e:o["className"===n?"class":n]=e);return c(i,o)}}r.displayName=null!=l?l:s.name;const u=n.forwardRef(((t,n)=>c(r,{...t,_$Gl:n},null==t?void 0:t.children)));return u.displayName=r.displayName,u};export{i as createComponent}; | ||
const t=new Set(["children","localName","ref","style","className"]),e=new WeakMap,n=(t,n,s,i,l)=>{const o=null==l?void 0:l[n];void 0===o||s===i?null==s&&n in HTMLElement.prototype?t.removeAttribute(n):t[n]=s:((t,n,s)=>{let i=e.get(t);void 0===i&&e.set(t,i=new Map);let l=i.get(n);void 0!==s?void 0===l?(i.set(n,l={handleEvent:s}),t.addEventListener(n,l)):l.handleEvent=s:void 0!==l&&(i.delete(n),t.removeEventListener(n,l))})(t,o,s)};function s(e=window.React,s,i,l,o){let d,c,a;if(void 0===s){const t=e;({tagName:c,elementClass:a,events:l,displayName:o}=t),d=t.react}else d=e,a=i,c=s;const h=d.Component,r=d.createElement,u=new Set(Object.keys(null!=l?l:{}));class f extends h{constructor(){super(...arguments),this.o=null}t(t){if(null!==this.o)for(const e in this.i)n(this.o,e,this.props[e],t?t[e]:void 0,l)}componentDidMount(){this.t()}componentDidUpdate(t){this.t(t)}render(){var e;const n=null!==(e=this.props._$Gl)&&void 0!==e?e:null;void 0!==this.h&&this.u===n||(this.h=t=>{null===this.o&&(this.o=t),null!==n&&((t,e)=>{"function"==typeof t?t(e):t.current=e})(n,t),this.u=n});const s={ref:this.h};this.i={};for(const[e,n]of Object.entries(this.props))"__forwardedRef"!==e&&(t.has(e)?s["className"===e?"class":e]=n:u.has(e)||e in a.prototype?this.i[e]=n:s[e]=n);return r(c,s)}}f.displayName=null!=o?o:a.name;const v=d.forwardRef(((t,e)=>r(f,{...t,_$Gl:e},null==t?void 0:t.children)));return v.displayName=f.displayName,v}export{s as createComponent}; | ||
//# sourceMappingURL=create-component.js.map |
@@ -16,4 +16,11 @@ /** | ||
declare type ElementWithoutPropsOrEventListeners<I, E> = Omit<I, keyof E | keyof ReactProps<I, E>>; | ||
declare type WebComponentProps<I extends HTMLElement, E extends EventNames = {}> = Partial<ReactProps<I, E> & ElementWithoutPropsOrEventListeners<I, E> & EventListeners<E>>; | ||
export declare type WebComponentProps<I extends HTMLElement, E extends EventNames = {}> = Partial<ReactProps<I, E> & ElementWithoutPropsOrEventListeners<I, E> & EventListeners<E>>; | ||
export declare type ReactWebComponent<I extends HTMLElement, E extends EventNames = {}> = React.ForwardRefExoticComponent<React.PropsWithoutRef<WebComponentProps<I, E>> & React.RefAttributes<I>>; | ||
interface Options<I extends HTMLElement, E extends EventNames = {}> { | ||
tagName: string; | ||
elementClass: Constructor<I>; | ||
react: typeof window.React; | ||
events?: E; | ||
displayName?: string; | ||
} | ||
declare type Constructor<T> = { | ||
@@ -27,2 +34,29 @@ new (): T; | ||
* | ||
* @param options An options bag containing the parameters needed to generate | ||
* a wrapped web component. | ||
* | ||
* @param options.react The React module, typically imported from the `react` npm | ||
* package. | ||
* @param options.tagName The custom element tag name registered via | ||
* `customElements.define`. | ||
* @param options.elementClass The custom element class registered via | ||
* `customElements.define`. | ||
* @param options.events An object listing events to which the component can listen. The | ||
* object keys are the event property names passed in via React props and the | ||
* object values are the names of the corresponding events generated by the | ||
* custom element. For example, given `{onactivate: 'activate'}` an event | ||
* function may be passed via the component's `onactivate` prop and will be | ||
* called when the custom element fires its `activate` event. | ||
* @param options.displayName A React component display name, used in debugging | ||
* messages. Default value is inferred from the name of custom element class | ||
* registered via `customElements.define`. | ||
*/ | ||
export declare function createComponent<I extends HTMLElement, E extends EventNames = {}>(options: Options<I, E>): ReactWebComponent<I, E>; | ||
/** | ||
* @deprecated Use `createComponent(options)` instead of individual arguments. | ||
* | ||
* Creates a React component for a custom element. Properties are distinguished | ||
* from attributes automatically, and events can be configured so they are | ||
* added to the custom element as event listeners. | ||
* | ||
* @param React The React module, typically imported from the `react` npm | ||
@@ -44,4 +78,4 @@ * package. | ||
*/ | ||
export declare const createComponent: <I extends HTMLElement, E extends EventNames = {}>(React: typeof import("react"), tagName: string, elementClass: Constructor<I>, events?: E | undefined, displayName?: string) => ReactWebComponent<I, E>; | ||
export declare function createComponent<I extends HTMLElement, E extends EventNames = {}>(ReactOrOptions: typeof window.React, tagName: string, elementClass: Constructor<I>, events?: E, displayName?: string): ReactWebComponent<I, E>; | ||
export {}; | ||
//# sourceMappingURL=create-component.d.ts.map |
@@ -49,12 +49,20 @@ /** | ||
const event = events === null || events === void 0 ? void 0 : events[name]; | ||
if (event !== undefined) { | ||
if (event !== undefined && value !== old) { | ||
// Dirty check event value. | ||
if (value !== old) { | ||
addOrUpdateEventListener(node, event, value); | ||
} | ||
addOrUpdateEventListener(node, event, value); | ||
return; | ||
} | ||
else { | ||
// But don't dirty check properties; elements are assumed to do this. | ||
node[name] = value; | ||
// Note, the attribute removal here for `undefined` and `null` values is done | ||
// to match React's behavior on non-custom elements. It needs special | ||
// handling because it does not match platform behavior. For example, | ||
// setting the `id` property to `undefined` sets the attribute to the string | ||
// "undefined." React "fixes" that odd behavior and the code here matches | ||
// React's convention. | ||
if ((value === undefined || value === null) && | ||
name in HTMLElement.prototype) { | ||
node.removeAttribute(name); | ||
return; | ||
} | ||
// But don't dirty check properties; elements are assumed to do this. | ||
node[name] = value; | ||
}; | ||
@@ -71,24 +79,17 @@ // Set a React ref. Note, there are 2 kinds of refs and there's no built in | ||
}; | ||
/** | ||
* Creates a React component for a custom element. Properties are distinguished | ||
* from attributes automatically, and events can be configured so they are | ||
* added to the custom element as event listeners. | ||
* | ||
* @param React The React module, typically imported from the `react` npm | ||
* package. | ||
* @param tagName The custom element tag name registered via | ||
* `customElements.define`. | ||
* @param elementClass The custom element class registered via | ||
* `customElements.define`. | ||
* @param events An object listing events to which the component can listen. The | ||
* object keys are the event property names passed in via React props and the | ||
* object values are the names of the corresponding events generated by the | ||
* custom element. For example, given `{onactivate: 'activate'}` an event | ||
* function may be passed via the component's `onactivate` prop and will be | ||
* called when the custom element fires its `activate` event. | ||
* @param displayName A React component display name, used in debugging | ||
* messages. Default value is inferred from the name of custom element class | ||
* registered via `customElements.define`. | ||
*/ | ||
export const createComponent = (React, tagName, elementClass, events, displayName) => { | ||
export function createComponent(ReactOrOptions = window.React, tagName, elementClass, events, displayName) { | ||
// digest overloaded parameters | ||
let React; | ||
let tag; | ||
let element; | ||
if (tagName === undefined) { | ||
const options = ReactOrOptions; | ||
({ tagName: tag, elementClass: element, events, displayName } = options); | ||
React = options.react; | ||
} | ||
else { | ||
React = ReactOrOptions; | ||
element = elementClass; | ||
tag = tagName; | ||
} | ||
const Component = React.Component; | ||
@@ -164,18 +165,18 @@ const createElement = React.createElement; | ||
continue; | ||
if (eventProps.has(k) || | ||
(!reservedReactProperties.has(k) && | ||
!(k in HTMLElement.prototype) && | ||
k in elementClass.prototype)) { | ||
this._elementProps[k] = v; | ||
} | ||
else { | ||
if (reservedReactProperties.has(k)) { | ||
// React does *not* handle `className` for custom elements so | ||
// coerce it to `class` so it's handled correctly. | ||
props[k === 'className' ? 'class' : k] = v; | ||
continue; | ||
} | ||
if (eventProps.has(k) || k in element.prototype) { | ||
this._elementProps[k] = v; | ||
continue; | ||
} | ||
props[k] = v; | ||
} | ||
return createElement(tagName, props); | ||
return createElement(tag, props); | ||
} | ||
} | ||
ReactComponent.displayName = displayName !== null && displayName !== void 0 ? displayName : elementClass.name; | ||
ReactComponent.displayName = displayName !== null && displayName !== void 0 ? displayName : element.name; | ||
const ForwardedComponent = React.forwardRef((props, ref) => createElement(ReactComponent, { ...props, __forwardedRef: ref }, props === null || props === void 0 ? void 0 : props.children)); | ||
@@ -185,3 +186,3 @@ // To ease debugging in the React Developer Tools | ||
return ForwardedComponent; | ||
}; | ||
} | ||
//# sourceMappingURL=create-component.js.map |
{ | ||
"name": "@lit-labs/react", | ||
"version": "1.0.9", | ||
"version": "1.1.0", | ||
"description": "A React component wrapper for web components.", | ||
@@ -5,0 +5,0 @@ "license": "BSD-3-Clause", |
@@ -37,11 +37,11 @@ # @lit-labs/react | ||
export const MyElementComponent = createComponent( | ||
React, | ||
'my-element', | ||
MyElement, | ||
{ | ||
export const MyElementComponent = createComponent({ | ||
tagName: 'my-element', | ||
elementClass: MyElement, | ||
react: React, | ||
events: { | ||
onactivate: 'activate', | ||
onchange: 'change', | ||
} | ||
); | ||
}, | ||
}); | ||
``` | ||
@@ -74,11 +74,11 @@ | ||
export const MyElementComponent = createComponent( | ||
React, | ||
'my-element', | ||
MyElement, | ||
{ | ||
export const MyElementComponent = createComponent({ | ||
tagName: 'my-element', | ||
elementClass: MyElement, | ||
react: React, | ||
events: { | ||
onClick: 'pointerdown' as EventName<PointerEvent>, | ||
onChange: 'input', | ||
} | ||
); | ||
}, | ||
}); | ||
``` | ||
@@ -85,0 +85,0 @@ |
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
const t=Promise.resolve();class s{constructor(t,s){this.v=[],this._=!0,this.p=!1,this.m=t,this.C=s,this.j=new Promise(((t,s)=>{this.O=t}))}addController(t){this.v.push(t)}removeController(t){var s;null===(s=this.v)||void 0===s||s.splice(this.v.indexOf(t)>>>0,1)}requestUpdate(){this._||(this._=!0,t.then((()=>this.C(++this.m))))}get updateComplete(){return this.j}M(){this.p=!0,this.v.forEach((t=>{var s;return null===(s=t.hostConnected)||void 0===s?void 0:s.call(t)}))}N(){this.p=!1,this.v.forEach((t=>{var s;return null===(s=t.hostDisconnected)||void 0===s?void 0:s.call(t)}))}P(){this.v.forEach((t=>{var s;return null===(s=t.hostUpdate)||void 0===s?void 0:s.call(t)}))}S(){this._=!1;const t=this.O;this.j=new Promise(((t,s)=>{this.O=t})),this.v.forEach((t=>{var s;return null===(s=t.hostUpdated)||void 0===s?void 0:s.call(t)})),t(this._)}}const i=(i,e)=>{const{useState:r,useLayoutEffect:o}=i,[n,h]=r(0);let u=!1;const[d]=r((()=>{const i=new s(n,h),r=e(i);return i.D=r,i.M(),u=!0,t.then((()=>{u&&i.N()})),i}));return d._=!0,o((()=>(u=!1,d.p||d.M(),()=>d.N())),[]),o((()=>d.S())),d.P(),d.D};export{i as useController}; | ||
const t=Promise.resolve();class s{constructor(t,s){this.v=[],this._=!0,this.p=!1,this.m=t,this.C=s,this.j=new Promise(((t,s)=>{this.N=t}))}addController(t){this.v.push(t)}removeController(t){var s;null===(s=this.v)||void 0===s||s.splice(this.v.indexOf(t)>>>0,1)}requestUpdate(){this._||(this._=!0,t.then((()=>this.C(++this.m))))}get updateComplete(){return this.j}O(){this.p=!0,this.v.forEach((t=>{var s;return null===(s=t.hostConnected)||void 0===s?void 0:s.call(t)}))}M(){this.p=!1,this.v.forEach((t=>{var s;return null===(s=t.hostDisconnected)||void 0===s?void 0:s.call(t)}))}P(){this.v.forEach((t=>{var s;return null===(s=t.hostUpdate)||void 0===s?void 0:s.call(t)}))}S(){this._=!1;const t=this.N;this.j=new Promise(((t,s)=>{this.N=t})),this.v.forEach((t=>{var s;return null===(s=t.hostUpdated)||void 0===s?void 0:s.call(t)})),t(this._)}}const i=(i,e)=>{const{useState:r,useLayoutEffect:o}=i,[n,h]=r(0);let u=!1;const[d]=r((()=>{const i=new s(n,h),r=e(i);return i.g=r,i.O(),u=!0,t.then((()=>{u&&i.M()})),i}));return d._=!0,o((()=>(u=!1,d.p||d.O(),()=>d.M())),[]),o((()=>d.S())),d.P(),d.g};export{i as useController}; | ||
//# sourceMappingURL=use-controller.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
94645
573