@just-web/toolkits 2.1.0 → 3.0.0

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 (34) hide show
  1. package/dist/attributes/observe-attribute.cjs +10 -7
  2. package/dist/attributes/observe-attribute.cjs.map +1 -1
  3. package/dist/attributes/observe-attribute.d.cts +6 -6
  4. package/dist/attributes/observe-attribute.d.cts.map +1 -1
  5. package/dist/attributes/observe-attribute.d.mts +6 -6
  6. package/dist/attributes/observe-attribute.d.mts.map +1 -1
  7. package/dist/attributes/observe-attribute.mjs +10 -7
  8. package/dist/attributes/observe-attribute.mjs.map +1 -1
  9. package/dist/attributes/observe-data-attribute.cjs +7 -10
  10. package/dist/attributes/observe-data-attribute.cjs.map +1 -1
  11. package/dist/attributes/observe-data-attribute.d.cts +8 -11
  12. package/dist/attributes/observe-data-attribute.d.cts.map +1 -1
  13. package/dist/attributes/observe-data-attribute.d.mts +8 -11
  14. package/dist/attributes/observe-data-attribute.d.mts.map +1 -1
  15. package/dist/attributes/observe-data-attribute.mjs +7 -10
  16. package/dist/attributes/observe-data-attribute.mjs.map +1 -1
  17. package/dist/react/hooks/use-attribute.cjs +1 -2
  18. package/dist/react/hooks/use-attribute.cjs.map +1 -1
  19. package/dist/react/hooks/use-attribute.mjs +1 -2
  20. package/dist/react/hooks/use-attribute.mjs.map +1 -1
  21. package/dist/theme/class-name/subscribe-class-name.cjs +1 -2
  22. package/dist/theme/class-name/subscribe-class-name.cjs.map +1 -1
  23. package/dist/theme/class-name/subscribe-class-name.mjs +1 -2
  24. package/dist/theme/class-name/subscribe-class-name.mjs.map +1 -1
  25. package/dist/theme/data-attribute/subscribe-data-attribute.cjs +1 -2
  26. package/dist/theme/data-attribute/subscribe-data-attribute.cjs.map +1 -1
  27. package/dist/theme/data-attribute/subscribe-data-attribute.mjs +1 -2
  28. package/dist/theme/data-attribute/subscribe-data-attribute.mjs.map +1 -1
  29. package/package.json +1 -1
  30. package/src/attributes/observe-attribute.ts +13 -8
  31. package/src/attributes/observe-data-attribute.ts +7 -10
  32. package/src/react/hooks/use-attribute.ts +1 -2
  33. package/src/theme/class-name/subscribe-class-name.ts +1 -2
  34. package/src/theme/data-attribute/subscribe-data-attribute.ts +1 -2
@@ -5,21 +5,24 @@
5
5
  *
6
6
  * @param handlers - An object mapping attribute names to handler functions.
7
7
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
8
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
8
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
9
9
  *
10
10
  * @example
11
11
  * ```ts
12
- * const observer = observeAttributes({
13
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
14
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
12
+ * const unsubscribe = observeAttributes({
13
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
14
+ * 'class': (value) => console.log(`class changed to: ${value}`)
15
15
  * });
16
16
  *
17
17
  * // Later, to stop observing:
18
- * observer.disconnect();
18
+ * unsubscribe();
19
19
  * ```
20
20
  */
21
21
  function observeAttributes(handlers, element) {
22
- element = element ?? globalThis.document.documentElement;
22
+ /* c8 ignore start */
23
+ if (typeof document === "undefined") return () => {};
24
+ /* c8 ignore end */
25
+ element = element ?? document.documentElement;
23
26
  const observer = new MutationObserver((mutations) => {
24
27
  for (const mutation of mutations) {
25
28
  const attribute = mutation.attributeName;
@@ -32,7 +35,7 @@ function observeAttributes(handlers, element) {
32
35
  attributes: true,
33
36
  attributeFilter: Object.keys(handlers)
34
37
  });
35
- return observer;
38
+ return () => observer.disconnect();
36
39
  }
37
40
 
38
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"observe-attribute.cjs","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":["/**\n * Observes attributes changes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.\n * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.\n *\n * @example\n * ```ts\n * const observer = observeAttributes({\n * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),\n * 'class': (attr, value) => console.log(`class changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * observer.disconnect();\n * ```\n */\nexport function observeAttributes<T extends string>(\n\thandlers: Record<string, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\telement = element ?? globalThis.document.documentElement\n\tconst observer = new MutationObserver((mutations) => {\n\t\tfor (const mutation of mutations) {\n\t\t\tconst attribute = mutation.attributeName\n\t\t\tif (!attribute) continue\n\t\t\tconst value = element.getAttribute(attribute) as T | null\n\t\t\thandlers[attribute]?.(value)\n\t\t}\n\t})\n\tobserver.observe(element, {\n\t\tattributes: true,\n\t\tattributeFilter: Object.keys(handlers)\n\t})\n\treturn observer\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,kBACf,UACA,SACC;AACD,WAAU,WAAW,WAAW,SAAS;CACzC,MAAM,WAAW,IAAI,kBAAkB,cAAc;AACpD,OAAK,MAAM,YAAY,WAAW;GACjC,MAAM,YAAY,SAAS;AAC3B,OAAI,CAAC,UAAW;GAChB,MAAM,QAAQ,QAAQ,aAAa,UAAU;AAC7C,YAAS,aAAa,MAAM;;GAE5B;AACF,UAAS,QAAQ,SAAS;EACzB,YAAY;EACZ,iBAAiB,OAAO,KAAK,SAAS;EACtC,CAAC;AACF,QAAO"}
1
+ {"version":3,"file":"observe-attribute.cjs","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":["/**\n * Observes attributes changes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.\n * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.\n *\n * @example\n * ```ts\n * const unsubscribe = observeAttributes({\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'class': (value) => console.log(`class changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * unsubscribe();\n * ```\n */\nexport function observeAttributes<T extends string>(\n\thandlers: Record<string, (value: T | null) => void>,\n\telement?: Element | null | undefined\n): () => void {\n\t/* c8 ignore start */\n\tif (typeof document === 'undefined') {\n\t\treturn () => {}\n\t}\n\t/* c8 ignore end */\n\telement = element ?? document.documentElement\n\tconst observer = new MutationObserver((mutations) => {\n\t\tfor (const mutation of mutations) {\n\t\t\tconst attribute = mutation.attributeName\n\t\t\tif (!attribute) continue\n\t\t\tconst value = element.getAttribute(attribute) as T | null\n\t\t\thandlers[attribute]?.(value)\n\t\t}\n\t})\n\tobserver.observe(element, {\n\t\tattributes: true,\n\t\tattributeFilter: Object.keys(handlers)\n\t})\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,kBACf,UACA,SACa;;AAEb,KAAI,OAAO,aAAa,YACvB,cAAa;;AAGd,WAAU,WAAW,SAAS;CAC9B,MAAM,WAAW,IAAI,kBAAkB,cAAc;AACpD,OAAK,MAAM,YAAY,WAAW;GACjC,MAAM,YAAY,SAAS;AAC3B,OAAI,CAAC,UAAW;GAChB,MAAM,QAAQ,QAAQ,aAAa,UAAU;AAC7C,YAAS,aAAa,MAAM;;GAE5B;AACF,UAAS,QAAQ,SAAS;EACzB,YAAY;EACZ,iBAAiB,OAAO,KAAK,SAAS;EACtC,CAAC;AACF,cAAa,SAAS,YAAY"}
@@ -4,20 +4,20 @@
4
4
  *
5
5
  * @param handlers - An object mapping attribute names to handler functions.
6
6
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
7
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
7
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * const observer = observeAttributes({
12
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
13
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
11
+ * const unsubscribe = observeAttributes({
12
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
13
+ * 'class': (value) => console.log(`class changed to: ${value}`)
14
14
  * });
15
15
  *
16
16
  * // Later, to stop observing:
17
- * observer.disconnect();
17
+ * unsubscribe();
18
18
  * ```
19
19
  */
20
- declare function observeAttributes<T extends string>(handlers: Record<string, (value: T | null) => void>, element?: Element | null | undefined): MutationObserver;
20
+ declare function observeAttributes<T extends string>(handlers: Record<string, (value: T | null) => void>, element?: Element | null | undefined): () => void;
21
21
  //#endregion
22
22
  export { observeAttributes };
23
23
  //# sourceMappingURL=observe-attribute.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe-attribute.d.cts","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":[],"mappings":";;AAkBA;;;;;;;;;;;;;;;;;iBAAgB,8CACL,uBAAuB,8BACvB,6BAA0B"}
1
+ {"version":3,"file":"observe-attribute.d.cts","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":[],"mappings":";;AAkBA;;;;;;;;;;;;;;;;;iBAAgB,8CACL,uBAAuB,8BACvB"}
@@ -4,20 +4,20 @@
4
4
  *
5
5
  * @param handlers - An object mapping attribute names to handler functions.
6
6
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
7
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
7
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * const observer = observeAttributes({
12
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
13
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
11
+ * const unsubscribe = observeAttributes({
12
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
13
+ * 'class': (value) => console.log(`class changed to: ${value}`)
14
14
  * });
15
15
  *
16
16
  * // Later, to stop observing:
17
- * observer.disconnect();
17
+ * unsubscribe();
18
18
  * ```
19
19
  */
20
- declare function observeAttributes<T extends string>(handlers: Record<string, (value: T | null) => void>, element?: Element | null | undefined): MutationObserver;
20
+ declare function observeAttributes<T extends string>(handlers: Record<string, (value: T | null) => void>, element?: Element | null | undefined): () => void;
21
21
  //#endregion
22
22
  export { observeAttributes };
23
23
  //# sourceMappingURL=observe-attribute.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe-attribute.d.mts","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":[],"mappings":";;AAkBA;;;;;;;;;;;;;;;;;iBAAgB,8CACL,uBAAuB,8BACvB,6BAA0B"}
1
+ {"version":3,"file":"observe-attribute.d.mts","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":[],"mappings":";;AAkBA;;;;;;;;;;;;;;;;;iBAAgB,8CACL,uBAAuB,8BACvB"}
@@ -4,21 +4,24 @@
4
4
  *
5
5
  * @param handlers - An object mapping attribute names to handler functions.
6
6
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
7
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
7
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
- * const observer = observeAttributes({
12
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
13
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
11
+ * const unsubscribe = observeAttributes({
12
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
13
+ * 'class': (value) => console.log(`class changed to: ${value}`)
14
14
  * });
15
15
  *
16
16
  * // Later, to stop observing:
17
- * observer.disconnect();
17
+ * unsubscribe();
18
18
  * ```
19
19
  */
20
20
  function observeAttributes(handlers, element) {
21
- element = element ?? globalThis.document.documentElement;
21
+ /* c8 ignore start */
22
+ if (typeof document === "undefined") return () => {};
23
+ /* c8 ignore end */
24
+ element = element ?? document.documentElement;
22
25
  const observer = new MutationObserver((mutations) => {
23
26
  for (const mutation of mutations) {
24
27
  const attribute = mutation.attributeName;
@@ -31,7 +34,7 @@ function observeAttributes(handlers, element) {
31
34
  attributes: true,
32
35
  attributeFilter: Object.keys(handlers)
33
36
  });
34
- return observer;
37
+ return () => observer.disconnect();
35
38
  }
36
39
 
37
40
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"observe-attribute.mjs","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":["/**\n * Observes attributes changes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.\n * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.\n *\n * @example\n * ```ts\n * const observer = observeAttributes({\n * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),\n * 'class': (attr, value) => console.log(`class changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * observer.disconnect();\n * ```\n */\nexport function observeAttributes<T extends string>(\n\thandlers: Record<string, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\telement = element ?? globalThis.document.documentElement\n\tconst observer = new MutationObserver((mutations) => {\n\t\tfor (const mutation of mutations) {\n\t\t\tconst attribute = mutation.attributeName\n\t\t\tif (!attribute) continue\n\t\t\tconst value = element.getAttribute(attribute) as T | null\n\t\t\thandlers[attribute]?.(value)\n\t\t}\n\t})\n\tobserver.observe(element, {\n\t\tattributes: true,\n\t\tattributeFilter: Object.keys(handlers)\n\t})\n\treturn observer\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,kBACf,UACA,SACC;AACD,WAAU,WAAW,WAAW,SAAS;CACzC,MAAM,WAAW,IAAI,kBAAkB,cAAc;AACpD,OAAK,MAAM,YAAY,WAAW;GACjC,MAAM,YAAY,SAAS;AAC3B,OAAI,CAAC,UAAW;GAChB,MAAM,QAAQ,QAAQ,aAAa,UAAU;AAC7C,YAAS,aAAa,MAAM;;GAE5B;AACF,UAAS,QAAQ,SAAS;EACzB,YAAY;EACZ,iBAAiB,OAAO,KAAK,SAAS;EACtC,CAAC;AACF,QAAO"}
1
+ {"version":3,"file":"observe-attribute.mjs","names":[],"sources":["../../src/attributes/observe-attribute.ts"],"sourcesContent":["/**\n * Observes attributes changes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.\n * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.\n *\n * @example\n * ```ts\n * const unsubscribe = observeAttributes({\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'class': (value) => console.log(`class changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * unsubscribe();\n * ```\n */\nexport function observeAttributes<T extends string>(\n\thandlers: Record<string, (value: T | null) => void>,\n\telement?: Element | null | undefined\n): () => void {\n\t/* c8 ignore start */\n\tif (typeof document === 'undefined') {\n\t\treturn () => {}\n\t}\n\t/* c8 ignore end */\n\telement = element ?? document.documentElement\n\tconst observer = new MutationObserver((mutations) => {\n\t\tfor (const mutation of mutations) {\n\t\t\tconst attribute = mutation.attributeName\n\t\t\tif (!attribute) continue\n\t\t\tconst value = element.getAttribute(attribute) as T | null\n\t\t\thandlers[attribute]?.(value)\n\t\t}\n\t})\n\tobserver.observe(element, {\n\t\tattributes: true,\n\t\tattributeFilter: Object.keys(handlers)\n\t})\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,kBACf,UACA,SACa;;AAEb,KAAI,OAAO,aAAa,YACvB,cAAa;;AAGd,WAAU,WAAW,SAAS;CAC9B,MAAM,WAAW,IAAI,kBAAkB,cAAc;AACpD,OAAK,MAAM,YAAY,WAAW;GACjC,MAAM,YAAY,SAAS;AAC3B,OAAI,CAAC,UAAW;GAChB,MAAM,QAAQ,QAAQ,aAAa,UAAU;AAC7C,YAAS,aAAa,MAAM;;GAE5B;AACF,UAAS,QAAQ,SAAS;EACzB,YAAY;EACZ,iBAAiB,OAAO,KAAK,SAAS;EACtC,CAAC;AACF,cAAa,SAAS,YAAY"}
@@ -4,22 +4,19 @@ const require_observe_attribute = require('./observe-attribute.cjs');
4
4
  /**
5
5
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
6
6
  *
7
- * @param options - Configuration options
8
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
9
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
10
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
7
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
8
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
9
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
11
10
  *
12
11
  * @example
13
12
  * ```ts
14
- * const observer = observeDataAttributes({
15
- * handlers: {
16
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
17
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
18
- * }
13
+ * const unsubscribe = observeDataAttributes({
14
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
15
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
19
16
  * });
20
17
  *
21
18
  * // Later, to stop observing:
22
- * observer.disconnect();
19
+ * unsubscribe();
23
20
  * ```
24
21
  */
25
22
  function observeDataAttributes(handlers, element) {
@@ -1 +1 @@
1
- {"version":3,"file":"observe-data-attribute.cjs","names":["observeAttributes"],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":["import { observeAttributes } from './observe-attribute.ts'\n\n/**\n * Observes changes to `data-*` attributes on an element and calls corresponding handlers.\n *\n * @param options - Configuration options\n * @param options.handlers - An object mapping `data-*` attribute names to handler functions.\n * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`\n * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer\n *\n * @example\n * ```ts\n * const observer = observeDataAttributes({\n * handlers: {\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)\n * }\n * });\n *\n * // Later, to stop observing:\n * observer.disconnect();\n * ```\n */\nexport function observeDataAttributes<T extends string, K extends `data-${string}`>(\n\thandlers: Record<K, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\treturn observeAttributes(handlers, element)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,sBACf,UACA,SACC;AACD,QAAOA,4CAAkB,UAAU,QAAQ"}
1
+ {"version":3,"file":"observe-data-attribute.cjs","names":["observeAttributes"],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":["import { observeAttributes } from './observe-attribute.ts'\n\n/**\n * Observes changes to `data-*` attributes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping `data-*` attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`\n * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.\n *\n * @example\n * ```ts\n * const unsubscribe = observeDataAttributes({\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * unsubscribe();\n * ```\n */\nexport function observeDataAttributes<T extends string, K extends `data-${string}`>(\n\thandlers: Record<K, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\treturn observeAttributes(handlers, element)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,sBACf,UACA,SACC;AACD,QAAOA,4CAAkB,UAAU,QAAQ"}
@@ -2,25 +2,22 @@
2
2
  /**
3
3
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
4
4
  *
5
- * @param options - Configuration options
6
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
7
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
8
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
5
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
6
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
7
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
9
8
  *
10
9
  * @example
11
10
  * ```ts
12
- * const observer = observeDataAttributes({
13
- * handlers: {
14
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
15
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
16
- * }
11
+ * const unsubscribe = observeDataAttributes({
12
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
13
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
17
14
  * });
18
15
  *
19
16
  * // Later, to stop observing:
20
- * observer.disconnect();
17
+ * unsubscribe();
21
18
  * ```
22
19
  */
23
- declare function observeDataAttributes<T extends string, K extends `data-${string}`>(handlers: Record<K, (value: T | null) => void>, element?: Element | null | undefined): MutationObserver;
20
+ declare function observeDataAttributes<T extends string, K extends `data-${string}`>(handlers: Record<K, (value: T | null) => void>, element?: Element | null | undefined): () => void;
24
21
  //#endregion
25
22
  export { observeDataAttributes };
26
23
  //# sourceMappingURL=observe-data-attribute.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe-data-attribute.d.cts","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":[],"mappings":";;AAuBA;;;;;;;;;;;;;;;;;;;;iBAAgB,8EACL,OAAO,WAAW,8BAClB,6BAA0B"}
1
+ {"version":3,"file":"observe-data-attribute.d.cts","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":[],"mappings":";;AAoBA;;;;;;;;;;;;;;;;;iBAAgB,8EACL,OAAO,WAAW,8BAClB"}
@@ -2,25 +2,22 @@
2
2
  /**
3
3
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
4
4
  *
5
- * @param options - Configuration options
6
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
7
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
8
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
5
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
6
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
7
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
9
8
  *
10
9
  * @example
11
10
  * ```ts
12
- * const observer = observeDataAttributes({
13
- * handlers: {
14
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
15
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
16
- * }
11
+ * const unsubscribe = observeDataAttributes({
12
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
13
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
17
14
  * });
18
15
  *
19
16
  * // Later, to stop observing:
20
- * observer.disconnect();
17
+ * unsubscribe();
21
18
  * ```
22
19
  */
23
- declare function observeDataAttributes<T extends string, K extends `data-${string}`>(handlers: Record<K, (value: T | null) => void>, element?: Element | null | undefined): MutationObserver;
20
+ declare function observeDataAttributes<T extends string, K extends `data-${string}`>(handlers: Record<K, (value: T | null) => void>, element?: Element | null | undefined): () => void;
24
21
  //#endregion
25
22
  export { observeDataAttributes };
26
23
  //# sourceMappingURL=observe-data-attribute.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe-data-attribute.d.mts","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":[],"mappings":";;AAuBA;;;;;;;;;;;;;;;;;;;;iBAAgB,8EACL,OAAO,WAAW,8BAClB,6BAA0B"}
1
+ {"version":3,"file":"observe-data-attribute.d.mts","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":[],"mappings":";;AAoBA;;;;;;;;;;;;;;;;;iBAAgB,8EACL,OAAO,WAAW,8BAClB"}
@@ -4,22 +4,19 @@ import { observeAttributes } from "./observe-attribute.mjs";
4
4
  /**
5
5
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
6
6
  *
7
- * @param options - Configuration options
8
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
9
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
10
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
7
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
8
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
9
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
11
10
  *
12
11
  * @example
13
12
  * ```ts
14
- * const observer = observeDataAttributes({
15
- * handlers: {
16
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
17
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
18
- * }
13
+ * const unsubscribe = observeDataAttributes({
14
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
15
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
19
16
  * });
20
17
  *
21
18
  * // Later, to stop observing:
22
- * observer.disconnect();
19
+ * unsubscribe();
23
20
  * ```
24
21
  */
25
22
  function observeDataAttributes(handlers, element) {
@@ -1 +1 @@
1
- {"version":3,"file":"observe-data-attribute.mjs","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":["import { observeAttributes } from './observe-attribute.ts'\n\n/**\n * Observes changes to `data-*` attributes on an element and calls corresponding handlers.\n *\n * @param options - Configuration options\n * @param options.handlers - An object mapping `data-*` attribute names to handler functions.\n * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`\n * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer\n *\n * @example\n * ```ts\n * const observer = observeDataAttributes({\n * handlers: {\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)\n * }\n * });\n *\n * // Later, to stop observing:\n * observer.disconnect();\n * ```\n */\nexport function observeDataAttributes<T extends string, K extends `data-${string}`>(\n\thandlers: Record<K, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\treturn observeAttributes(handlers, element)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,sBACf,UACA,SACC;AACD,QAAO,kBAAkB,UAAU,QAAQ"}
1
+ {"version":3,"file":"observe-data-attribute.mjs","names":[],"sources":["../../src/attributes/observe-data-attribute.ts"],"sourcesContent":["import { observeAttributes } from './observe-attribute.ts'\n\n/**\n * Observes changes to `data-*` attributes on an element and calls corresponding handlers.\n *\n * @param handlers - An object mapping `data-*` attribute names to handler functions.\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`\n * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.\n *\n * @example\n * ```ts\n * const unsubscribe = observeDataAttributes({\n * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),\n * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)\n * });\n *\n * // Later, to stop observing:\n * unsubscribe();\n * ```\n */\nexport function observeDataAttributes<T extends string, K extends `data-${string}`>(\n\thandlers: Record<K, (value: T | null) => void>,\n\telement?: Element | null | undefined\n) {\n\treturn observeAttributes(handlers, element)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,sBACf,UACA,SACC;AACD,QAAO,kBAAkB,UAAU,QAAQ"}
@@ -24,10 +24,9 @@ function useAttribute(attributeName, element = typeof document !== "undefined" ?
24
24
  (0, react.useEffect)(() => {
25
25
  if (!element) return;
26
26
  setValueState(element.getAttribute(attributeName) ?? void 0);
27
- const observer = require_observe_attribute.observeAttributes({ [attributeName]: (next) => {
27
+ return require_observe_attribute.observeAttributes({ [attributeName]: (next) => {
28
28
  setValueState(next ?? void 0);
29
29
  } }, element);
30
- return () => observer.disconnect();
31
30
  }, [element, attributeName]);
32
31
  return [value, (0, react.useCallback)((next) => {
33
32
  if (!element) return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-attribute.cjs","names":["observeAttributes"],"sources":["../../../src/react/hooks/use-attribute.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { observeAttributes } from '../../attributes/observe-attribute.ts'\n\n/**\n * React hook that returns the current value of an attribute on a target element\n * and a setter to update it. Stays in sync when the attribute changes (e.g. from elsewhere).\n *\n * @param attributeName - The attribute to observe (e.g. `'class'`, `'data-theme'`).\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement` when omitted.\n * @returns Tuple of [value, setValue]. Pass null or undefined to setValue to remove the attribute.\n *\n * @example\n * ```tsx\n * const [className, setClassName] = useAttribute('class')\n * const [theme, setTheme] = useAttribute('data-theme', myElement)\n * setTheme('dark')\n * setClassName(undefined) // removes class attribute\n * ```\n */\nexport function useAttribute(\n\tattributeName: string,\n\telement: Element | null | undefined = typeof document !== 'undefined'\n\t\t? document.documentElement\n\t\t: undefined\n): [string | undefined, (value: string | null | undefined) => void] {\n\tconst [value, setValueState] = useState<string | undefined>(\n\t\t() => element?.getAttribute(attributeName) ?? undefined\n\t)\n\n\tuseEffect(() => {\n\t\tif (!element) return\n\n\t\tsetValueState(element.getAttribute(attributeName) ?? undefined)\n\n\t\tconst observer = observeAttributes(\n\t\t\t{\n\t\t\t\t[attributeName]: (next) => {\n\t\t\t\t\tsetValueState(next ?? undefined)\n\t\t\t\t}\n\t\t\t},\n\t\t\telement\n\t\t)\n\t\treturn () => observer.disconnect()\n\t}, [element, attributeName])\n\n\tconst setValue = useCallback(\n\t\t(next: string | null | undefined) => {\n\t\t\tif (!element) return\n\t\t\tif (next == null) {\n\t\t\t\telement.removeAttribute(attributeName)\n\t\t\t} else {\n\t\t\t\telement.setAttribute(attributeName, next)\n\t\t\t}\n\t\t},\n\t\t[element, attributeName]\n\t)\n\n\treturn [value, setValue]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aACf,eACA,UAAsC,OAAO,aAAa,cACvD,SAAS,kBACT,QACgE;CACnE,MAAM,CAAC,OAAO,2CACP,SAAS,aAAa,cAAc,IAAI,OAC9C;AAED,4BAAgB;AACf,MAAI,CAAC,QAAS;AAEd,gBAAc,QAAQ,aAAa,cAAc,IAAI,OAAU;EAE/D,MAAM,WAAWA,4CAChB,GACE,iBAAiB,SAAS;AAC1B,iBAAc,QAAQ,OAAU;KAEjC,EACD,QACA;AACD,eAAa,SAAS,YAAY;IAChC,CAAC,SAAS,cAAc,CAAC;AAc5B,QAAO,CAAC,+BAXN,SAAoC;AACpC,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,KACX,SAAQ,gBAAgB,cAAc;MAEtC,SAAQ,aAAa,eAAe,KAAK;IAG3C,CAAC,SAAS,cAAc,CACxB,CAEuB"}
1
+ {"version":3,"file":"use-attribute.cjs","names":["observeAttributes"],"sources":["../../../src/react/hooks/use-attribute.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { observeAttributes } from '../../attributes/observe-attribute.ts'\n\n/**\n * React hook that returns the current value of an attribute on a target element\n * and a setter to update it. Stays in sync when the attribute changes (e.g. from elsewhere).\n *\n * @param attributeName - The attribute to observe (e.g. `'class'`, `'data-theme'`).\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement` when omitted.\n * @returns Tuple of [value, setValue]. Pass null or undefined to setValue to remove the attribute.\n *\n * @example\n * ```tsx\n * const [className, setClassName] = useAttribute('class')\n * const [theme, setTheme] = useAttribute('data-theme', myElement)\n * setTheme('dark')\n * setClassName(undefined) // removes class attribute\n * ```\n */\nexport function useAttribute(\n\tattributeName: string,\n\telement: Element | null | undefined = typeof document !== 'undefined'\n\t\t? document.documentElement\n\t\t: undefined\n): [string | undefined, (value: string | null | undefined) => void] {\n\tconst [value, setValueState] = useState<string | undefined>(\n\t\t() => element?.getAttribute(attributeName) ?? undefined\n\t)\n\n\tuseEffect(() => {\n\t\tif (!element) return\n\n\t\tsetValueState(element.getAttribute(attributeName) ?? undefined)\n\n\t\treturn observeAttributes(\n\t\t\t{\n\t\t\t\t[attributeName]: (next) => {\n\t\t\t\t\tsetValueState(next ?? undefined)\n\t\t\t\t}\n\t\t\t},\n\t\t\telement\n\t\t)\n\t}, [element, attributeName])\n\n\tconst setValue = useCallback(\n\t\t(next: string | null | undefined) => {\n\t\t\tif (!element) return\n\t\t\tif (next == null) {\n\t\t\t\telement.removeAttribute(attributeName)\n\t\t\t} else {\n\t\t\t\telement.setAttribute(attributeName, next)\n\t\t\t}\n\t\t},\n\t\t[element, attributeName]\n\t)\n\n\treturn [value, setValue]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aACf,eACA,UAAsC,OAAO,aAAa,cACvD,SAAS,kBACT,QACgE;CACnE,MAAM,CAAC,OAAO,2CACP,SAAS,aAAa,cAAc,IAAI,OAC9C;AAED,4BAAgB;AACf,MAAI,CAAC,QAAS;AAEd,gBAAc,QAAQ,aAAa,cAAc,IAAI,OAAU;AAE/D,SAAOA,4CACN,GACE,iBAAiB,SAAS;AAC1B,iBAAc,QAAQ,OAAU;KAEjC,EACD,QACA;IACC,CAAC,SAAS,cAAc,CAAC;AAc5B,QAAO,CAAC,+BAXN,SAAoC;AACpC,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,KACX,SAAQ,gBAAgB,cAAc;MAEtC,SAAQ,aAAa,eAAe,KAAK;IAG3C,CAAC,SAAS,cAAc,CACxB,CAEuB"}
@@ -23,10 +23,9 @@ function useAttribute(attributeName, element = typeof document !== "undefined" ?
23
23
  useEffect(() => {
24
24
  if (!element) return;
25
25
  setValueState(element.getAttribute(attributeName) ?? void 0);
26
- const observer = observeAttributes({ [attributeName]: (next) => {
26
+ return observeAttributes({ [attributeName]: (next) => {
27
27
  setValueState(next ?? void 0);
28
28
  } }, element);
29
- return () => observer.disconnect();
30
29
  }, [element, attributeName]);
31
30
  return [value, useCallback((next) => {
32
31
  if (!element) return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-attribute.mjs","names":[],"sources":["../../../src/react/hooks/use-attribute.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { observeAttributes } from '../../attributes/observe-attribute.ts'\n\n/**\n * React hook that returns the current value of an attribute on a target element\n * and a setter to update it. Stays in sync when the attribute changes (e.g. from elsewhere).\n *\n * @param attributeName - The attribute to observe (e.g. `'class'`, `'data-theme'`).\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement` when omitted.\n * @returns Tuple of [value, setValue]. Pass null or undefined to setValue to remove the attribute.\n *\n * @example\n * ```tsx\n * const [className, setClassName] = useAttribute('class')\n * const [theme, setTheme] = useAttribute('data-theme', myElement)\n * setTheme('dark')\n * setClassName(undefined) // removes class attribute\n * ```\n */\nexport function useAttribute(\n\tattributeName: string,\n\telement: Element | null | undefined = typeof document !== 'undefined'\n\t\t? document.documentElement\n\t\t: undefined\n): [string | undefined, (value: string | null | undefined) => void] {\n\tconst [value, setValueState] = useState<string | undefined>(\n\t\t() => element?.getAttribute(attributeName) ?? undefined\n\t)\n\n\tuseEffect(() => {\n\t\tif (!element) return\n\n\t\tsetValueState(element.getAttribute(attributeName) ?? undefined)\n\n\t\tconst observer = observeAttributes(\n\t\t\t{\n\t\t\t\t[attributeName]: (next) => {\n\t\t\t\t\tsetValueState(next ?? undefined)\n\t\t\t\t}\n\t\t\t},\n\t\t\telement\n\t\t)\n\t\treturn () => observer.disconnect()\n\t}, [element, attributeName])\n\n\tconst setValue = useCallback(\n\t\t(next: string | null | undefined) => {\n\t\t\tif (!element) return\n\t\t\tif (next == null) {\n\t\t\t\telement.removeAttribute(attributeName)\n\t\t\t} else {\n\t\t\t\telement.setAttribute(attributeName, next)\n\t\t\t}\n\t\t},\n\t\t[element, attributeName]\n\t)\n\n\treturn [value, setValue]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aACf,eACA,UAAsC,OAAO,aAAa,cACvD,SAAS,kBACT,QACgE;CACnE,MAAM,CAAC,OAAO,iBAAiB,eACxB,SAAS,aAAa,cAAc,IAAI,OAC9C;AAED,iBAAgB;AACf,MAAI,CAAC,QAAS;AAEd,gBAAc,QAAQ,aAAa,cAAc,IAAI,OAAU;EAE/D,MAAM,WAAW,kBAChB,GACE,iBAAiB,SAAS;AAC1B,iBAAc,QAAQ,OAAU;KAEjC,EACD,QACA;AACD,eAAa,SAAS,YAAY;IAChC,CAAC,SAAS,cAAc,CAAC;AAc5B,QAAO,CAAC,OAZS,aACf,SAAoC;AACpC,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,KACX,SAAQ,gBAAgB,cAAc;MAEtC,SAAQ,aAAa,eAAe,KAAK;IAG3C,CAAC,SAAS,cAAc,CACxB,CAEuB"}
1
+ {"version":3,"file":"use-attribute.mjs","names":[],"sources":["../../../src/react/hooks/use-attribute.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport { observeAttributes } from '../../attributes/observe-attribute.ts'\n\n/**\n * React hook that returns the current value of an attribute on a target element\n * and a setter to update it. Stays in sync when the attribute changes (e.g. from elsewhere).\n *\n * @param attributeName - The attribute to observe (e.g. `'class'`, `'data-theme'`).\n * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement` when omitted.\n * @returns Tuple of [value, setValue]. Pass null or undefined to setValue to remove the attribute.\n *\n * @example\n * ```tsx\n * const [className, setClassName] = useAttribute('class')\n * const [theme, setTheme] = useAttribute('data-theme', myElement)\n * setTheme('dark')\n * setClassName(undefined) // removes class attribute\n * ```\n */\nexport function useAttribute(\n\tattributeName: string,\n\telement: Element | null | undefined = typeof document !== 'undefined'\n\t\t? document.documentElement\n\t\t: undefined\n): [string | undefined, (value: string | null | undefined) => void] {\n\tconst [value, setValueState] = useState<string | undefined>(\n\t\t() => element?.getAttribute(attributeName) ?? undefined\n\t)\n\n\tuseEffect(() => {\n\t\tif (!element) return\n\n\t\tsetValueState(element.getAttribute(attributeName) ?? undefined)\n\n\t\treturn observeAttributes(\n\t\t\t{\n\t\t\t\t[attributeName]: (next) => {\n\t\t\t\t\tsetValueState(next ?? undefined)\n\t\t\t\t}\n\t\t\t},\n\t\t\telement\n\t\t)\n\t}, [element, attributeName])\n\n\tconst setValue = useCallback(\n\t\t(next: string | null | undefined) => {\n\t\t\tif (!element) return\n\t\t\tif (next == null) {\n\t\t\t\telement.removeAttribute(attributeName)\n\t\t\t} else {\n\t\t\t\telement.setAttribute(attributeName, next)\n\t\t\t}\n\t\t},\n\t\t[element, attributeName]\n\t)\n\n\treturn [value, setValue]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aACf,eACA,UAAsC,OAAO,aAAa,cACvD,SAAS,kBACT,QACgE;CACnE,MAAM,CAAC,OAAO,iBAAiB,eACxB,SAAS,aAAa,cAAc,IAAI,OAC9C;AAED,iBAAgB;AACf,MAAI,CAAC,QAAS;AAEd,gBAAc,QAAQ,aAAa,cAAc,IAAI,OAAU;AAE/D,SAAO,kBACN,GACE,iBAAiB,SAAS;AAC1B,iBAAc,QAAQ,OAAU;KAEjC,EACD,QACA;IACC,CAAC,SAAS,cAAc,CAAC;AAc5B,QAAO,CAAC,OAZS,aACf,SAAoC;AACpC,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,KACX,SAAQ,gBAAgB,cAAc;MAEtC,SAAQ,aAAa,eAAe,KAAK;IAG3C,CAAC,SAAS,cAAc,CACxB,CAEuB"}
@@ -16,14 +16,13 @@ function subscribeClassName(themes, handler, options) {
16
16
  if (!element) return () => {};
17
17
  const parse = options?.parse ?? require_parse_class_name.parseClassName;
18
18
  let lastEmitted = null;
19
- const observer = require_observe_attribute.observeAttributes({ class: (value) => {
19
+ return require_observe_attribute.observeAttributes({ class: (value) => {
20
20
  const entry = parse(themes, value ?? void 0);
21
21
  const key = entry?.theme ?? void 0;
22
22
  if (lastEmitted === key) return;
23
23
  lastEmitted = key;
24
24
  handler(entry);
25
25
  } }, element);
26
- return () => observer.disconnect();
27
26
  }
28
27
 
29
28
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"subscribe-class-name.cjs","names":["parseClassName","lastEmitted: keyof Themes | undefined | null","observeAttributes"],"sources":["../../../src/theme/class-name/subscribe-class-name.ts"],"sourcesContent":["import { observeAttributes } from '../../attributes/observe-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { parseClassName } from './parse-class-name.ts'\n\n/**\n * Subscribes to changes on the class attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param handler - Callback invoked when the class attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseClassName)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeClassName<Themes extends ThemeMap>(\n\tthemes: Themes,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse = options?.parse ?? parseClassName\n\tlet lastEmitted: keyof Themes | undefined | null = null\n\tconst observer = observeAttributes(\n\t\t{\n\t\t\tclass: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\tconst key = entry?.theme ?? undefined\n\t\t\t\tif (lastEmitted === key) return\n\t\t\t\tlastEmitted = key\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,mBACf,QACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QAAQ,SAAS,SAASA;CAChC,IAAIC,cAA+C;CACnD,MAAM,WAAWC,4CAChB,EACC,QAAQ,UAAU;EACjB,MAAM,QAAQ,MAAM,QAAQ,SAAS,OAAU;EAC/C,MAAM,MAAM,OAAO,SAAS;AAC5B,MAAI,gBAAgB,IAAK;AACzB,gBAAc;AACd,UAAQ,MAAM;IAEf,EACD,QACA;AACD,cAAa,SAAS,YAAY"}
1
+ {"version":3,"file":"subscribe-class-name.cjs","names":["parseClassName","lastEmitted: keyof Themes | undefined | null","observeAttributes"],"sources":["../../../src/theme/class-name/subscribe-class-name.ts"],"sourcesContent":["import { observeAttributes } from '../../attributes/observe-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { parseClassName } from './parse-class-name.ts'\n\n/**\n * Subscribes to changes on the class attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param handler - Callback invoked when the class attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseClassName)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeClassName<Themes extends ThemeMap>(\n\tthemes: Themes,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse = options?.parse ?? parseClassName\n\tlet lastEmitted: keyof Themes | undefined | null = null\n\treturn observeAttributes(\n\t\t{\n\t\t\tclass: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\tconst key = entry?.theme ?? undefined\n\t\t\t\tif (lastEmitted === key) return\n\t\t\t\tlastEmitted = key\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,mBACf,QACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QAAQ,SAAS,SAASA;CAChC,IAAIC,cAA+C;AACnD,QAAOC,4CACN,EACC,QAAQ,UAAU;EACjB,MAAM,QAAQ,MAAM,QAAQ,SAAS,OAAU;EAC/C,MAAM,MAAM,OAAO,SAAS;AAC5B,MAAI,gBAAgB,IAAK;AACzB,gBAAc;AACd,UAAQ,MAAM;IAEf,EACD,QACA"}
@@ -16,14 +16,13 @@ function subscribeClassName(themes, handler, options) {
16
16
  if (!element) return () => {};
17
17
  const parse = options?.parse ?? parseClassName;
18
18
  let lastEmitted = null;
19
- const observer = observeAttributes({ class: (value) => {
19
+ return observeAttributes({ class: (value) => {
20
20
  const entry = parse(themes, value ?? void 0);
21
21
  const key = entry?.theme ?? void 0;
22
22
  if (lastEmitted === key) return;
23
23
  lastEmitted = key;
24
24
  handler(entry);
25
25
  } }, element);
26
- return () => observer.disconnect();
27
26
  }
28
27
 
29
28
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"subscribe-class-name.mjs","names":["lastEmitted: keyof Themes | undefined | null"],"sources":["../../../src/theme/class-name/subscribe-class-name.ts"],"sourcesContent":["import { observeAttributes } from '../../attributes/observe-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { parseClassName } from './parse-class-name.ts'\n\n/**\n * Subscribes to changes on the class attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param handler - Callback invoked when the class attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseClassName)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeClassName<Themes extends ThemeMap>(\n\tthemes: Themes,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse = options?.parse ?? parseClassName\n\tlet lastEmitted: keyof Themes | undefined | null = null\n\tconst observer = observeAttributes(\n\t\t{\n\t\t\tclass: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\tconst key = entry?.theme ?? undefined\n\t\t\t\tif (lastEmitted === key) return\n\t\t\t\tlastEmitted = key\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,mBACf,QACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QAAQ,SAAS,SAAS;CAChC,IAAIA,cAA+C;CACnD,MAAM,WAAW,kBAChB,EACC,QAAQ,UAAU;EACjB,MAAM,QAAQ,MAAM,QAAQ,SAAS,OAAU;EAC/C,MAAM,MAAM,OAAO,SAAS;AAC5B,MAAI,gBAAgB,IAAK;AACzB,gBAAc;AACd,UAAQ,MAAM;IAEf,EACD,QACA;AACD,cAAa,SAAS,YAAY"}
1
+ {"version":3,"file":"subscribe-class-name.mjs","names":["lastEmitted: keyof Themes | undefined | null"],"sources":["../../../src/theme/class-name/subscribe-class-name.ts"],"sourcesContent":["import { observeAttributes } from '../../attributes/observe-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { parseClassName } from './parse-class-name.ts'\n\n/**\n * Subscribes to changes on the class attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param handler - Callback invoked when the class attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseClassName)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeClassName<Themes extends ThemeMap>(\n\tthemes: Themes,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse = options?.parse ?? parseClassName\n\tlet lastEmitted: keyof Themes | undefined | null = null\n\treturn observeAttributes(\n\t\t{\n\t\t\tclass: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\tconst key = entry?.theme ?? undefined\n\t\t\t\tif (lastEmitted === key) return\n\t\t\t\tlastEmitted = key\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,mBACf,QACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QAAQ,SAAS,SAAS;CAChC,IAAIA,cAA+C;AACnD,QAAO,kBACN,EACC,QAAQ,UAAU;EACjB,MAAM,QAAQ,MAAM,QAAQ,SAAS,OAAU;EAC/C,MAAM,MAAM,OAAO,SAAS;AAC5B,MAAI,gBAAgB,IAAK;AACzB,gBAAc;AACd,UAAQ,MAAM;IAEf,EACD,QACA"}
@@ -17,10 +17,9 @@ function subscribeDataAttribute(themes, attributeName, handler, options) {
17
17
  const element = options?.element ?? document?.documentElement;
18
18
  if (!element) return () => {};
19
19
  const parse = options?.parse ?? ((t, v) => require_parse_data_attribute.parseDataAttribute(t, v, { separator: require__constant.SEPARATOR_SPACE }));
20
- const observer = require_observe_data_attribute.observeDataAttributes({ [attributeName]: (value) => {
20
+ return require_observe_data_attribute.observeDataAttributes({ [attributeName]: (value) => {
21
21
  handler(parse(themes, value ?? void 0));
22
22
  } }, element);
23
- return () => observer.disconnect();
24
23
  }
25
24
 
26
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"subscribe-data-attribute.cjs","names":["parseDataAttribute","SEPARATOR_SPACE","observeDataAttributes"],"sources":["../../../src/theme/data-attribute/subscribe-data-attribute.ts"],"sourcesContent":["import { observeDataAttributes } from '../../attributes/observe-data-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { SEPARATOR_SPACE } from './_constant.ts'\nimport { parseDataAttribute } from './parse-data-attribute.ts'\n\n/**\n * Subscribes to changes on a data attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param attributeName - Data attribute name (e.g. `data-theme`)\n * @param handler - Callback invoked when the attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeDataAttribute<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tattributeName: `data-${string}`,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse =\n\t\toptions?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))\n\tconst observer = observeDataAttributes<string, `data-${string}`>(\n\t\t{\n\t\t\t[attributeName]: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,uBACf,QACA,eACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QACL,SAAS,WAAW,GAAG,MAAMA,gDAAmB,GAAG,GAAG,EAAE,WAAWC,mCAAiB,CAAC;CACtF,MAAM,WAAWC,qDAChB,GACE,iBAAiB,UAAU;AAE3B,UADc,MAAM,QAAQ,SAAS,OAAU,CACjC;IAEf,EACD,QACA;AACD,cAAa,SAAS,YAAY"}
1
+ {"version":3,"file":"subscribe-data-attribute.cjs","names":["parseDataAttribute","SEPARATOR_SPACE","observeDataAttributes"],"sources":["../../../src/theme/data-attribute/subscribe-data-attribute.ts"],"sourcesContent":["import { observeDataAttributes } from '../../attributes/observe-data-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { SEPARATOR_SPACE } from './_constant.ts'\nimport { parseDataAttribute } from './parse-data-attribute.ts'\n\n/**\n * Subscribes to changes on a data attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param attributeName - Data attribute name (e.g. `data-theme`)\n * @param handler - Callback invoked when the attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeDataAttribute<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tattributeName: `data-${string}`,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse =\n\t\toptions?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))\n\treturn observeDataAttributes<string, `data-${string}`>(\n\t\t{\n\t\t\t[attributeName]: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,uBACf,QACA,eACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QACL,SAAS,WAAW,GAAG,MAAMA,gDAAmB,GAAG,GAAG,EAAE,WAAWC,mCAAiB,CAAC;AACtF,QAAOC,qDACN,GACE,iBAAiB,UAAU;AAE3B,UADc,MAAM,QAAQ,SAAS,OAAU,CACjC;IAEf,EACD,QACA"}
@@ -17,10 +17,9 @@ function subscribeDataAttribute(themes, attributeName, handler, options) {
17
17
  const element = options?.element ?? document?.documentElement;
18
18
  if (!element) return () => {};
19
19
  const parse = options?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }));
20
- const observer = observeDataAttributes({ [attributeName]: (value) => {
20
+ return observeDataAttributes({ [attributeName]: (value) => {
21
21
  handler(parse(themes, value ?? void 0));
22
22
  } }, element);
23
- return () => observer.disconnect();
24
23
  }
25
24
 
26
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"subscribe-data-attribute.mjs","names":[],"sources":["../../../src/theme/data-attribute/subscribe-data-attribute.ts"],"sourcesContent":["import { observeDataAttributes } from '../../attributes/observe-data-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { SEPARATOR_SPACE } from './_constant.ts'\nimport { parseDataAttribute } from './parse-data-attribute.ts'\n\n/**\n * Subscribes to changes on a data attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param attributeName - Data attribute name (e.g. `data-theme`)\n * @param handler - Callback invoked when the attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeDataAttribute<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tattributeName: `data-${string}`,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse =\n\t\toptions?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))\n\tconst observer = observeDataAttributes<string, `data-${string}`>(\n\t\t{\n\t\t\t[attributeName]: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n\treturn () => observer.disconnect()\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,uBACf,QACA,eACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QACL,SAAS,WAAW,GAAG,MAAM,mBAAmB,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC;CACtF,MAAM,WAAW,sBAChB,GACE,iBAAiB,UAAU;AAE3B,UADc,MAAM,QAAQ,SAAS,OAAU,CACjC;IAEf,EACD,QACA;AACD,cAAa,SAAS,YAAY"}
1
+ {"version":3,"file":"subscribe-data-attribute.mjs","names":[],"sources":["../../../src/theme/data-attribute/subscribe-data-attribute.ts"],"sourcesContent":["import { observeDataAttributes } from '../../attributes/observe-data-attribute.ts'\nimport type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\nimport { SEPARATOR_SPACE } from './_constant.ts'\nimport { parseDataAttribute } from './parse-data-attribute.ts'\n\n/**\n * Subscribes to changes on a data attribute and invokes the handler with parsed theme entries.\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param attributeName - Data attribute name (e.g. `data-theme`)\n * @param handler - Callback invoked when the attribute changes\n * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).\n */\nexport function subscribeDataAttribute<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tattributeName: `data-${string}`,\n\thandler: (entry: ThemeEntry<Themes> | undefined) => void,\n\toptions?:\n\t\t| { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }\n\t\t| undefined\n): () => void {\n\tconst element = options?.element ?? document?.documentElement\n\tif (!element) return () => {}\n\tconst parse =\n\t\toptions?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))\n\treturn observeDataAttributes<string, `data-${string}`>(\n\t\t{\n\t\t\t[attributeName]: (value) => {\n\t\t\t\tconst entry = parse(themes, value ?? undefined)\n\t\t\t\thandler(entry)\n\t\t\t}\n\t\t},\n\t\telement\n\t)\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,uBACf,QACA,eACA,SACA,SAGa;CACb,MAAM,UAAU,SAAS,WAAW,UAAU;AAC9C,KAAI,CAAC,QAAS,cAAa;CAC3B,MAAM,QACL,SAAS,WAAW,GAAG,MAAM,mBAAmB,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC;AACtF,QAAO,sBACN,GACE,iBAAiB,UAAU;AAE3B,UADc,MAAM,QAAQ,SAAS,OAAU,CACjC;IAEf,EACD,QACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@just-web/toolkits",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Toolkits for web applications",
5
5
  "homepage": "https://github.com/justland/just-web-foundation/tree/main/libs/toolkits",
6
6
  "repository": {
@@ -3,24 +3,29 @@
3
3
  *
4
4
  * @param handlers - An object mapping attribute names to handler functions.
5
5
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
6
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
6
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * const observer = observeAttributes({
11
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
12
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
10
+ * const unsubscribe = observeAttributes({
11
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
12
+ * 'class': (value) => console.log(`class changed to: ${value}`)
13
13
  * });
14
14
  *
15
15
  * // Later, to stop observing:
16
- * observer.disconnect();
16
+ * unsubscribe();
17
17
  * ```
18
18
  */
19
19
  export function observeAttributes<T extends string>(
20
20
  handlers: Record<string, (value: T | null) => void>,
21
21
  element?: Element | null | undefined
22
- ) {
23
- element = element ?? globalThis.document.documentElement
22
+ ): () => void {
23
+ /* c8 ignore start */
24
+ if (typeof document === 'undefined') {
25
+ return () => {}
26
+ }
27
+ /* c8 ignore end */
28
+ element = element ?? document.documentElement
24
29
  const observer = new MutationObserver((mutations) => {
25
30
  for (const mutation of mutations) {
26
31
  const attribute = mutation.attributeName
@@ -33,5 +38,5 @@ export function observeAttributes<T extends string>(
33
38
  attributes: true,
34
39
  attributeFilter: Object.keys(handlers)
35
40
  })
36
- return observer
41
+ return () => observer.disconnect()
37
42
  }
@@ -3,22 +3,19 @@ import { observeAttributes } from './observe-attribute.ts'
3
3
  /**
4
4
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
5
5
  *
6
- * @param options - Configuration options
7
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
8
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
9
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
6
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
7
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
8
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
10
9
  *
11
10
  * @example
12
11
  * ```ts
13
- * const observer = observeDataAttributes({
14
- * handlers: {
15
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
16
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
17
- * }
12
+ * const unsubscribe = observeDataAttributes({
13
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
14
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
18
15
  * });
19
16
  *
20
17
  * // Later, to stop observing:
21
- * observer.disconnect();
18
+ * unsubscribe();
22
19
  * ```
23
20
  */
24
21
  export function observeDataAttributes<T extends string, K extends `data-${string}`>(
@@ -32,7 +32,7 @@ export function useAttribute(
32
32
 
33
33
  setValueState(element.getAttribute(attributeName) ?? undefined)
34
34
 
35
- const observer = observeAttributes(
35
+ return observeAttributes(
36
36
  {
37
37
  [attributeName]: (next) => {
38
38
  setValueState(next ?? undefined)
@@ -40,7 +40,6 @@ export function useAttribute(
40
40
  },
41
41
  element
42
42
  )
43
- return () => observer.disconnect()
44
43
  }, [element, attributeName])
45
44
 
46
45
  const setValue = useCallback(
@@ -23,7 +23,7 @@ export function subscribeClassName<Themes extends ThemeMap>(
23
23
  if (!element) return () => {}
24
24
  const parse = options?.parse ?? parseClassName
25
25
  let lastEmitted: keyof Themes | undefined | null = null
26
- const observer = observeAttributes(
26
+ return observeAttributes(
27
27
  {
28
28
  class: (value) => {
29
29
  const entry = parse(themes, value ?? undefined)
@@ -35,5 +35,4 @@ export function subscribeClassName<Themes extends ThemeMap>(
35
35
  },
36
36
  element
37
37
  )
38
- return () => observer.disconnect()
39
38
  }
@@ -26,7 +26,7 @@ export function subscribeDataAttribute<Themes extends ThemeMap>(
26
26
  if (!element) return () => {}
27
27
  const parse =
28
28
  options?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))
29
- const observer = observeDataAttributes<string, `data-${string}`>(
29
+ return observeDataAttributes<string, `data-${string}`>(
30
30
  {
31
31
  [attributeName]: (value) => {
32
32
  const entry = parse(themes, value ?? undefined)
@@ -35,5 +35,4 @@ export function subscribeDataAttribute<Themes extends ThemeMap>(
35
35
  },
36
36
  element
37
37
  )
38
- return () => observer.disconnect()
39
38
  }