odontogram 0.0.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/index.d.mts +35 -0
  2. package/dist/index.mjs +297 -0
  3. package/package.json +48 -100
  4. package/readme.md +140 -0
  5. package/src/index.ts +2 -0
  6. package/src/og-odontogram.ts +109 -0
  7. package/src/og-tooth.ts +76 -0
  8. package/src/stories/Layout.stories.ts +64 -0
  9. package/src/stories/Odontogram.stories.ts +68 -0
  10. package/LICENSE +0 -21
  11. package/README.md +0 -299
  12. package/cdn/components/button/button.d.ts +0 -25
  13. package/cdn/components/button/button.d.ts.map +0 -1
  14. package/cdn/components/button/button.js +0 -598
  15. package/cdn/components/button/button.styles.d.ts +0 -3
  16. package/cdn/components/button/button.styles.d.ts.map +0 -1
  17. package/cdn/components/button/index.d.ts +0 -2
  18. package/cdn/components/button/index.d.ts.map +0 -1
  19. package/cdn/components/button/index.js +0 -2
  20. package/cdn/components/index.d.ts +0 -2
  21. package/cdn/components/index.d.ts.map +0 -1
  22. package/cdn/components/index.js +0 -1
  23. package/cdn/index.d.ts +0 -2
  24. package/cdn/index.d.ts.map +0 -1
  25. package/cdn/index.js +0 -1
  26. package/cdn/loader.js +0 -118
  27. package/custom-elements.json +0 -152
  28. package/dist/components/button/button.d.ts +0 -25
  29. package/dist/components/button/button.d.ts.map +0 -1
  30. package/dist/components/button/button.js +0 -47
  31. package/dist/components/button/button.js.map +0 -1
  32. package/dist/components/button/button.styles.d.ts +0 -3
  33. package/dist/components/button/button.styles.d.ts.map +0 -1
  34. package/dist/components/button/button.styles.js +0 -43
  35. package/dist/components/button/button.styles.js.map +0 -1
  36. package/dist/components/button/index.d.ts +0 -2
  37. package/dist/components/button/index.d.ts.map +0 -1
  38. package/dist/components/button/index.js +0 -3
  39. package/dist/components/button/index.js.map +0 -1
  40. package/dist/components/index.d.ts +0 -2
  41. package/dist/components/index.d.ts.map +0 -1
  42. package/dist/components/index.js +0 -2
  43. package/dist/components/index.js.map +0 -1
  44. package/dist/index.d.ts +0 -2
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/index.js +0 -2
  47. package/dist/index.js.map +0 -1
  48. package/react/MyButton.d.ts +0 -90
  49. package/react/MyButton.js +0 -32
  50. package/react/index.d.ts +0 -1
  51. package/react/index.js +0 -1
  52. package/react/react-utils.js +0 -67
  53. package/types/custom-element-jsx.d.ts +0 -236
  54. package/types/custom-element-svelte.d.ts +0 -70
  55. package/types/custom-element-vuejs.d.ts +0 -40
package/cdn/loader.js DELETED
@@ -1,118 +0,0 @@
1
-
2
- let observer;
3
- let components = {
4
- "my-button": {
5
- "importPath": "../dist/components/button/button.js",
6
- "dependencies": []
7
- }
8
- };
9
- const eagerLoad = [];
10
-
11
- /** Update the lazy-loader configuration at runtime */
12
- export async function updateConfig(config) {
13
- if (config.components) {
14
- components = { ...components, ...config.components };
15
- }
16
-
17
- if(config.prefix || config.suffix) {
18
- components = getScopedComponents(config.prefix, config.suffix);
19
- }
20
-
21
- if (config.rootElement) {
22
- if (observer) {
23
- observer.disconnect();
24
- }
25
- start(config.rootElement);
26
- }
27
-
28
- if (config.eagerLoad) {
29
- await Promise.allSettled(eagerLoad?.map((tagName) => register(tagName)));
30
- }
31
- }
32
-
33
- function getScopedComponents(prefix = "", suffix = "") {
34
- const scopedComponents = {};
35
- for (const [key, value] of Object.entries(components)) {
36
- const newKey = prefix + key + suffix;
37
- scopedComponents[newKey] = value;
38
- }
39
-
40
- return scopedComponents;
41
- }
42
-
43
- /** Load any undefined custom elements and load the components in the list */
44
- async function load(root) {
45
- const rootTagName = root instanceof Element ? root.tagName.toLowerCase() : "";
46
- const tags = [...root.querySelectorAll(":not(:defined)")]?.map((el) =>
47
- el.tagName.toLowerCase()
48
- ) || [];
49
- if (rootTagName.includes("-") && !customElements.get(rootTagName)) {
50
- tags.push(rootTagName);
51
- }
52
- const tagsToRegister = [...new Set(tags)];
53
- await Promise.allSettled(tagsToRegister?.map((tagName) => register(tagName)));
54
- }
55
-
56
- /** Register the component and any dependencies */
57
- function register(tagName) {
58
- const component = components[tagName];
59
-
60
- if (customElements.get(tagName)) {
61
-
62
- cleanUp(component, tagName);
63
- return Promise.resolve();
64
- }
65
-
66
- if (!component) {
67
-
68
- return Promise.resolve();
69
- }
70
-
71
- return new Promise((resolve, reject) => {
72
- import(component.importPath)
73
- .then(() => {
74
-
75
- cleanUp(component, tagName);
76
- resolve();
77
- })
78
- .catch(() => {
79
- console.error(`Unable to load <${tagName}> from ${component.importPath}`);
80
- reject();
81
- });
82
- });
83
- }
84
-
85
- /** Remove the component from the list of components to load */
86
- function cleanUp(component, tagName) {
87
- delete components[tagName];
88
- component.dependencies?.forEach((dependency) => {
89
- delete components[dependency];
90
- });
91
-
92
- if (!Object.keys(component).length) {
93
- observer.disconnect();
94
- }
95
- }
96
-
97
- /** Initialize the loader */
98
- async function start(root = document.body) {
99
-
100
- // Eager load any components that are not defined in the Custom Elements Manifest
101
- await Promise.allSettled(eagerLoad?.map((tagName) => register(tagName)));
102
-
103
- // Watch for any new elements that are added to the DOM
104
- observer = new MutationObserver((mutations) => {
105
- for (const { addedNodes } of mutations) {
106
- for (const node of addedNodes) {
107
- if (node.nodeType === Node.ELEMENT_NODE) {
108
- load(node);
109
- }
110
- }
111
- }
112
- });
113
-
114
- load(root);
115
- observer.observe(root, { subtree: true, childList: true });
116
- }
117
-
118
- start();
@@ -1,152 +0,0 @@
1
- {
2
- "schemaVersion": "1.0.0",
3
- "readme": "",
4
- "modules": [
5
- {
6
- "kind": "javascript-module",
7
- "path": "src/components/button/button.ts",
8
- "declarations": [
9
- {
10
- "kind": "class",
11
- "description": "An example button component",
12
- "name": "MyButton",
13
- "cssProperties": [
14
- {
15
- "description": "The background color of the button",
16
- "name": "--button-bg-color",
17
- "default": "#f0f0f0"
18
- },
19
- {
20
- "description": "The text color of the button",
21
- "name": "--button-fg-color",
22
- "default": "#333"
23
- },
24
- {
25
- "description": "The border color of the button",
26
- "name": "--button-border-color",
27
- "default": "transparent"
28
- }
29
- ],
30
- "cssParts": [
31
- {
32
- "description": "The button element",
33
- "name": "control"
34
- }
35
- ],
36
- "slots": [
37
- {
38
- "description": "The main content for the button",
39
- "name": ""
40
- }
41
- ],
42
- "members": [
43
- {
44
- "kind": "field",
45
- "name": "disabled",
46
- "type": {
47
- "text": "boolean"
48
- },
49
- "default": "false",
50
- "description": "Controls the disabled property of the button",
51
- "attribute": "disabled"
52
- },
53
- {
54
- "kind": "field",
55
- "name": "variation",
56
- "type": {
57
- "text": "'default' | 'primary' | 'hollow' | 'transparent' | undefined"
58
- },
59
- "description": "Changes the display of the button",
60
- "attribute": "variation"
61
- }
62
- ],
63
- "attributes": [
64
- {
65
- "name": "disabled",
66
- "type": {
67
- "text": "boolean"
68
- },
69
- "default": "false",
70
- "description": "Controls the disabled property of the button",
71
- "fieldName": "disabled",
72
- "propName": "disabled"
73
- },
74
- {
75
- "name": "variation",
76
- "type": {
77
- "text": "'default' | 'primary' | 'hollow' | 'transparent' | undefined"
78
- },
79
- "description": "Changes the display of the button",
80
- "fieldName": "variation",
81
- "propName": "variation"
82
- }
83
- ],
84
- "superclass": {
85
- "name": "LitElement",
86
- "package": "lit"
87
- },
88
- "tagName": "my-button",
89
- "customElement": true,
90
- "modulePath": "src/components/button/button.ts",
91
- "definitionPath": "src/components/button/index.ts"
92
- }
93
- ],
94
- "exports": [
95
- {
96
- "kind": "js",
97
- "name": "default",
98
- "declaration": {
99
- "name": "MyButton",
100
- "module": "src/components/button/button.ts"
101
- }
102
- },
103
- {
104
- "kind": "js",
105
- "name": "MyButton",
106
- "declaration": {
107
- "name": "MyButton",
108
- "module": "src/components/button/button.ts"
109
- }
110
- }
111
- ]
112
- },
113
- {
114
- "kind": "javascript-module",
115
- "path": "src/components/button/index.ts",
116
- "declarations": [],
117
- "exports": [
118
- {
119
- "kind": "js",
120
- "name": "*",
121
- "declaration": {
122
- "name": "*",
123
- "module": "src/components/button/button.js"
124
- }
125
- },
126
- {
127
- "kind": "custom-element-definition",
128
- "name": "my-button",
129
- "declaration": {
130
- "name": "MyButton",
131
- "module": "/src/components/button/button.js"
132
- }
133
- }
134
- ]
135
- },
136
- {
137
- "kind": "javascript-module",
138
- "path": "src/components/index.ts",
139
- "declarations": [],
140
- "exports": [
141
- {
142
- "kind": "js",
143
- "name": "*",
144
- "declaration": {
145
- "name": "*",
146
- "module": "src/components/button/index.js"
147
- }
148
- }
149
- ]
150
- }
151
- ]
152
- }
@@ -1,25 +0,0 @@
1
- import { LitElement } from 'lit';
2
- /**
3
- * An example button component
4
- *
5
- * @tag my-button
6
- *
7
- * @csspart control - The button element
8
- *
9
- * @cssproperty [--button-bg-color=#f0f0f0] - The background color of the button
10
- * @cssproperty [--button-fg-color=#333] - The text color of the button
11
- * @cssproperty [--button-border-color=transparent] - The border color of the button
12
- *
13
- * @slot - The main content for the button
14
- *
15
- */
16
- export default class MyButton extends LitElement {
17
- static styles: import("lit").CSSResult;
18
- /** Changes the display of the button */
19
- variation?: 'default' | 'primary' | 'hollow' | 'transparent';
20
- /** Controls the disabled property of the button */
21
- disabled: boolean;
22
- render(): import("lit").TemplateResult<1>;
23
- }
24
- export { MyButton };
25
- //# sourceMappingURL=button.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;AAIvC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,UAAU;IAC9C,OAAgB,MAAM,0BAAU;IAEhC,wCAAwC;IAExC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;IAE7D,mDAAmD;IAEnD,QAAQ,UAAS;IAER,MAAM;CAOhB;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,47 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { html, LitElement } from 'lit';
8
- import { property } from 'lit/decorators.js';
9
- import styles from './button.styles.js';
10
- /**
11
- * An example button component
12
- *
13
- * @tag my-button
14
- *
15
- * @csspart control - The button element
16
- *
17
- * @cssproperty [--button-bg-color=#f0f0f0] - The background color of the button
18
- * @cssproperty [--button-fg-color=#333] - The text color of the button
19
- * @cssproperty [--button-border-color=transparent] - The border color of the button
20
- *
21
- * @slot - The main content for the button
22
- *
23
- */
24
- class MyButton extends LitElement {
25
- constructor() {
26
- super(...arguments);
27
- /** Controls the disabled property of the button */
28
- this.disabled = false;
29
- }
30
- render() {
31
- return html `
32
- <button part="control" ?disabled=${this.disabled}>
33
- <slot></slot>
34
- </button>
35
- `;
36
- }
37
- }
38
- MyButton.styles = styles;
39
- export default MyButton;
40
- __decorate([
41
- property()
42
- ], MyButton.prototype, "variation", void 0);
43
- __decorate([
44
- property({ type: Boolean })
45
- ], MyButton.prototype, "disabled", void 0);
46
- export { MyButton };
47
- //# sourceMappingURL=button.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../../../src/components/button/button.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAqB,QAAS,SAAQ,UAAU;IAAhD;;QAOE,mDAAmD;QAEnD,aAAQ,GAAG,KAAK,CAAC;IASnB,CAAC;IAPU,MAAM;QACb,OAAO,IAAI,CAAA;yCAC0B,IAAI,CAAC,QAAQ;;;KAGjD,CAAC;IACJ,CAAC;;AAhBe,eAAM,GAAG,MAAM,AAAT,CAAU;eADb,QAAQ;AAK3B;IADC,QAAQ,EAAE;2CACkD;AAI7D;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0CACX;AAWnB,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,3 +0,0 @@
1
- declare const _default: import("lit").CSSResult;
2
- export default _default;
3
- //# sourceMappingURL=button.styles.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button.styles.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.styles.ts"],"names":[],"mappings":";AAEA,wBAwCE"}
@@ -1,43 +0,0 @@
1
- import { css } from 'lit';
2
- export default css `
3
- :host {
4
- --button-bg-color: #f0f0f0;
5
- --button-fg-color: #333;
6
- --button-border-color: transparent;
7
-
8
- display: inline-flex;
9
- }
10
-
11
- button {
12
- cursor: pointer;
13
- background-color: var(--button-bg-color);
14
- border: 1px solid var(--button-border-color);
15
- border-radius: 4px;
16
- color: var(--button-fg-color);
17
- padding: 8px 16px;
18
- }
19
-
20
- button:disabled {
21
- cursor: not-allowed;
22
- opacity: 0.5;
23
- }
24
-
25
- :host([variation='primary']) {
26
- --button-bg-color: #024996;
27
- --button-fg-color: white;
28
- --button-border-color: #024996;
29
- }
30
-
31
- :host([variation='hollow']) {
32
- --button-bg-color: transparent;
33
- --button-fg-color: #024996;
34
- --button-border-color: #024996;
35
- }
36
-
37
- :host([variation='transparent']) {
38
- --button-bg-color: transparent;
39
- --button-fg-color: #024996;
40
- --button-border-color: transparent;
41
- }
42
- `;
43
- //# sourceMappingURL=button.styles.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button.styles.js","sourceRoot":"","sources":["../../../src/components/button/button.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCjB,CAAC"}
@@ -1,2 +0,0 @@
1
- export type * from './button.js';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAEA,mBAAmB,aAAa,CAAC"}
@@ -1,3 +0,0 @@
1
- import { MyButton } from './button.js';
2
- customElements.define('my-button', MyButton);
3
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export * from './button/index.js';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -1,2 +0,0 @@
1
- export * from './button/index.js';
2
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './components/index.js';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
package/dist/index.js DELETED
@@ -1,2 +0,0 @@
1
- export * from './components/index.js';
2
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
@@ -1,90 +0,0 @@
1
- import React from "react";
2
- import { MyButton as MyButtonElement } from "../dist/components/button/index.js";
3
-
4
- export type { MyButtonElement };
5
-
6
- export interface MyButtonProps extends Pick<
7
- React.AllHTMLAttributes<HTMLElement>,
8
- | "children"
9
- | "dir"
10
- | "hidden"
11
- | "id"
12
- | "lang"
13
- | "slot"
14
- | "style"
15
- | "title"
16
- | "translate"
17
- | "onClick"
18
- | "onFocus"
19
- | "onBlur"
20
- > {
21
- /** Controls the disabled property of the button */
22
- disabled?: boolean;
23
-
24
- /** Changes the display of the button */
25
- variation?: MyButtonElement["variation"];
26
-
27
- /** A space-separated list of the classes of the element. Classes allows CSS and JavaScript to select and access specific elements via the class selectors or functions like the method `Document.getElementsByClassName()`. */
28
- className?: string;
29
-
30
- /** Contains a space-separated list of the part names of the element that should be exposed on the host element. */
31
- exportparts?: string;
32
-
33
- /** Used for labels to link them with their inputs (using input id). */
34
- htmlFor?: string;
35
-
36
- /** Used to help React identify which items have changed, are added, or are removed within a list. */
37
- key?: number | string;
38
-
39
- /** Contains a space-separated list of the part names of the element. Part names allows CSS to select and style specific elements in a shadow tree via the ::part pseudo-element. */
40
- part?: string;
41
-
42
- /** A mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. */
43
- ref?: React.Ref<MyButtonElement>;
44
-
45
- /** Allows developers to make HTML elements focusable, allow or prevent them from being sequentially focusable (usually with the `Tab` key, hence the name) and determine their relative ordering for sequential focus navigation. */
46
- tabIndex?: number;
47
- }
48
-
49
- declare module "react" {
50
- interface CSSProperties {
51
- /** The background color of the button */
52
- "--button-bg-color"?: string | number;
53
- /** The text color of the button */
54
- "--button-fg-color"?: string | number;
55
- /** The border color of the button */
56
- "--button-border-color"?: string | number;
57
- }
58
- }
59
-
60
- /**
61
- * An example button component
62
- *
63
- * ## Attributes & Properties
64
- *
65
- * Component attributes and properties that can be applied to the element or by using JavaScript.
66
- *
67
- * - `variation`: Changes the display of the button
68
- * - `disabled`: Controls the disabled property of the button
69
- *
70
- * ## Slots
71
- *
72
- * Areas where markup can be added to the component.
73
- *
74
- * - `(default)`: The main content for the button
75
- *
76
- * ## CSS Custom Properties
77
- *
78
- * CSS variables available for styling the component.
79
- *
80
- * - `--button-bg-color`: The background color of the button (default: `#f0f0f0`)
81
- * - `--button-fg-color`: The text color of the button (default: `#333`)
82
- * - `--button-border-color`: The border color of the button (default: `transparent`)
83
- *
84
- * ## CSS Parts
85
- *
86
- * Custom selectors for styling elements within the component.
87
- *
88
- * - `control`: The button element
89
- */
90
- export const MyButton: React.ForwardRefExoticComponent<MyButtonProps>;
package/react/MyButton.js DELETED
@@ -1,32 +0,0 @@
1
- import React, { forwardRef, useRef } from "react";
2
- import "../dist/components/button/index.js";
3
- import { createForwardedRefHandler } from "./react-utils.js";
4
-
5
- export const MyButton = forwardRef((props, forwardedRef) => {
6
- const ref = useRef(null);
7
- const {
8
- disabled,
9
- variation,
10
- exportparts,
11
- htmlFor,
12
- part,
13
- tabIndex,
14
- ...restProps
15
- } = props;
16
-
17
- return React.createElement(
18
- "my-button",
19
- {
20
- ref: createForwardedRefHandler(ref, forwardedRef),
21
- ...restProps,
22
- variation: variation,
23
- exportparts: exportparts,
24
- for: htmlFor,
25
- part: part,
26
- tabindex: tabIndex,
27
- disabled: disabled ? true : undefined,
28
- style: { ...props.style },
29
- },
30
- props.children,
31
- );
32
- });
package/react/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./MyButton.js";
package/react/index.js DELETED
@@ -1 +0,0 @@
1
- export * from "./MyButton.js";
@@ -1,67 +0,0 @@
1
- import { useEffect, useLayoutEffect, useRef } from "react";
2
-
3
- export function mergeRefs(target, forwardedRef) {
4
- if (!forwardedRef) {
5
- return;
6
- }
7
-
8
- if (typeof forwardedRef === "function") {
9
- forwardedRef(target);
10
- } else {
11
- forwardedRef.current = target;
12
- }
13
- }
14
-
15
- export function createForwardedRefHandler(localRef, forwardedRef) {
16
- return (node) => {
17
- localRef.current = node;
18
- mergeRefs(node, forwardedRef);
19
- };
20
- }
21
-
22
- export function useProperties(targetElement, propName, value) {
23
- useEffect(() => {
24
- const el = targetElement?.current;
25
- if (!el || value === undefined || el[propName] === value) {
26
- return;
27
- }
28
-
29
- try {
30
- el[propName] = value;
31
- } catch (e) {
32
- console.warn(e);
33
- }
34
- }, [targetElement, propName, value]);
35
- }
36
-
37
- export function useEventListener(targetElement, eventName, eventHandler) {
38
- // keep a ref to the latest handler so we don't need to re-register the event listener
39
- // whenever the handler changes (avoids duplicate listeners on re-renders)
40
- const handlerRef = useRef(eventHandler);
41
- handlerRef.current = eventHandler;
42
-
43
- useLayoutEffect(() => {
44
- const el = targetElement?.current;
45
- if (!el || eventName === undefined) {
46
- return;
47
- }
48
-
49
- // capture the handler at the time the listener is attached so we can call cancel on it
50
- const eventListener = (event) => {
51
- const handler = handlerRef.current;
52
- if (handler) {
53
- handler(event);
54
- }
55
- };
56
-
57
- el.addEventListener(eventName, eventListener);
58
-
59
- return () => {
60
- const handler = handlerRef.current;
61
- if (handler?.cancel) {
62
- handler.cancel();
63
- }
64
- el.removeEventListener(eventName, eventListener);
65
- };
66
- }, [eventName, targetElement?.current]);
67
- }