@rcarls/rc-disclosure 0.4.0 → 0.4.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.
- package/CHANGELOG.md +42 -0
- package/dist/rc-disclosure.js +4 -4
- package/dist/rc-disclosure.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @rcarls/rc-disclosure
|
|
2
|
+
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b12bf1b: Fix `rc-disclosure` silently discarding an initial `<details open>` on connect.
|
|
8
|
+
`_setupDetails()` always synced the wrapped `<details>`'s open state from the host's own
|
|
9
|
+
`open` attribute, defaulting to closed whenever the host had no explicit `open` of its
|
|
10
|
+
own, even if the `<details>` markup said otherwise. Plain `<details open>` inside
|
|
11
|
+
`<rc-disclosure>` (no `open` on the host) now opens as expected, and the host adopts that
|
|
12
|
+
state instead of defaulting to closed. The host's own `open` attribute still wins whenever
|
|
13
|
+
it's set explicitly.
|
|
14
|
+
|
|
15
|
+
## 0.4.1
|
|
16
|
+
|
|
17
|
+
## 0.4.0
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 1161caa: Document the `open` and deprecated `fragment` attributes, and give the
|
|
22
|
+
deprecated `fragment` accessor a real summary line instead of only
|
|
23
|
+
`@deprecated` text, so the generated API reference shows a description
|
|
24
|
+
instead of a blank one.
|
|
25
|
+
|
|
26
|
+
## 0.3.2
|
|
27
|
+
|
|
28
|
+
## 0.3.1
|
|
29
|
+
|
|
30
|
+
## 0.3.0
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Open and scroll automatically when the URL hash targets content inside the disclosure.
|
|
35
|
+
- Deprecate the `fragment` attribute; fragment targeting is now always enabled.
|
|
36
|
+
- Update package metadata, README intro, and docs links.
|
|
37
|
+
|
|
38
|
+
### Migration
|
|
39
|
+
|
|
40
|
+
- Remove `fragment`; it no longer changes behavior.
|
|
41
|
+
|
|
42
|
+
## 0.2.0
|
package/dist/rc-disclosure.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const
|
|
1
|
+
const n = "rc-disclosure-toggle", r = ":scope > details", i = ":scope > summary";
|
|
2
2
|
class a extends HTMLElement {
|
|
3
3
|
constructor() {
|
|
4
4
|
super(...arguments), this._observer = new MutationObserver(() => this._setupDetails()), this._$details = null, this._scrollFrame = 0, this._onToggle = () => {
|
|
5
5
|
const e = this._$details?.open ?? !1;
|
|
6
6
|
this._reflectOpen(e), this.dispatchEvent(
|
|
7
|
-
new CustomEvent(
|
|
7
|
+
new CustomEvent(n, {
|
|
8
8
|
bubbles: !0,
|
|
9
9
|
composed: !0,
|
|
10
10
|
detail: { open: e }
|
|
@@ -56,10 +56,10 @@ class a extends HTMLElement {
|
|
|
56
56
|
const e = this.querySelector(r);
|
|
57
57
|
if (e === this._$details || (this._teardownDetails(), this._$details = e, !e))
|
|
58
58
|
return;
|
|
59
|
-
e.id || (e.id = crypto.randomUUID()), e.querySelector(
|
|
59
|
+
e.id || (e.id = crypto.randomUUID()), e.querySelector(i)?.setAttribute("aria-controls", e.id), e.addEventListener("toggle", this._onToggle), !this.hasAttribute("open") && e.open && this._reflectOpen(!0), this._syncDetailsOpen(), this._reflectOpen(e.open), this._openForCurrentHash();
|
|
60
60
|
}
|
|
61
61
|
_teardownDetails() {
|
|
62
|
-
this._$details?.querySelector(
|
|
62
|
+
this._$details?.querySelector(i)?.removeAttribute("aria-controls"), this._$details?.removeEventListener("toggle", this._onToggle), this._$details = null;
|
|
63
63
|
}
|
|
64
64
|
_syncDetailsOpen() {
|
|
65
65
|
const e = this._$details;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rc-disclosure.js","sources":["../src/rc-disclosure.ts"],"sourcesContent":["export interface RCDisclosureToggleEvent {\n /** Whether the disclosure is now open. */\n open: boolean;\n}\n\nconst TOGGLE_EVENT = 'rc-disclosure-toggle';\nconst DETAILS_SELECTOR = ':scope > details';\nconst SUMMARY_SELECTOR = ':scope > summary';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-disclosure': RCDisclosure;\n }\n}\n\n/**\n * Disclosure wrapper for a native <details>/<summary> pair with controlled open state,\n * following the WAI-ARIA Disclosure pattern.\n *\n * The browser keeps ownership of open/close behavior, keyboard support, and\n * accessibility. This element mirrors state, emits a consistent custom event,\n * and automatically opens when the URL hash matches any id within its subtree.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-disclosure rc-disclosure docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/ WAI-ARIA Disclosure pattern}\n *\n * @fires rc-disclosure-toggle - Fires when the child `<details>` toggles.\n *\n * @attr open - Current open state mirrored to the child `<details>`.\n * @attr fragment - Deprecated legacy opt-in for URL-fragment auto-open; removed before v1.0.\n */\nexport class RCDisclosure extends HTMLElement {\n private _observer = new MutationObserver(() => this._setupDetails());\n\n private _$details: HTMLDetailsElement | null = null;\n\n private _scrollFrame = 0;\n\n static get observedAttributes(): string[] {\n return ['open', 'fragment'];\n }\n\n /** Current open state mirrored to the child `<details>`. */\n get open(): boolean {\n return this._$details?.open ?? this.hasAttribute('open');\n }\n\n set open(value: boolean) {\n this._setOpen(value, true);\n }\n\n /**\n * Legacy manual opt-in for URL-fragment auto-open.\n *\n * @deprecated No longer required. `rc-disclosure` now automatically opens and\n * scrolls when the URL hash matches any id within its subtree. Will be removed\n * in v1.0 release.\n */\n get fragment(): boolean {\n return this.hasAttribute('fragment');\n }\n\n set fragment(value: boolean) {\n this.toggleAttribute('fragment', value);\n }\n\n connectedCallback(): void {\n this._observer.observe(this, { childList: true });\n window.addEventListener('hashchange', this._onHashChange);\n this._setupDetails();\n }\n\n disconnectedCallback(): void {\n this._observer.disconnect();\n window.removeEventListener('hashchange', this._onHashChange);\n cancelAnimationFrame(this._scrollFrame);\n this._teardownDetails();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) {\n return;\n }\n\n if (name === 'open') {\n this._syncDetailsOpen();\n\n return;\n }\n\n if (name === 'fragment') {\n this._openForCurrentHash();\n }\n }\n\n private _setupDetails(): void {\n const $details = this.querySelector<HTMLDetailsElement>(DETAILS_SELECTOR);\n if ($details === this._$details) {\n return;\n }\n\n this._teardownDetails();\n this._$details = $details;\n\n if (!$details) {\n if (import.meta.env.DEV) {\n console.warn(\n '[rc-disclosure] No direct child <details> found. Place native ' +\n '<details><summary>...</summary>...</details> inside <rc-disclosure>.',\n this,\n );\n }\n\n return;\n }\n\n if (!$details.id) {\n $details.id = crypto.randomUUID();\n }\n\n const $summary = $details.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n $summary?.setAttribute('aria-controls', $details.id);\n\n $details.addEventListener('toggle', this._onToggle);\n this._syncDetailsOpen();\n this._reflectOpen($details.open);\n this._openForCurrentHash();\n }\n\n private _teardownDetails(): void {\n const $summary = this._$details?.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n $summary?.removeAttribute('aria-controls');\n\n this._$details?.removeEventListener('toggle', this._onToggle);\n this._$details = null;\n }\n\n private _syncDetailsOpen(): void {\n const $details = this._$details;\n if (!$details) {\n return;\n }\n\n const nextOpen = this.hasAttribute('open');\n if ($details.open !== nextOpen) {\n $details.open = nextOpen;\n }\n }\n\n private _setOpen(value: boolean, reflect: boolean): void {\n const $details = this._$details;\n if ($details && $details.open !== value) {\n $details.open = value;\n }\n\n // _reflectOpen is called here for programmatic opens because the <details>\n // toggle event is async (queued task per HTML spec). _onToggle also calls\n // _reflectOpen for user-initiated clicks, but that arrives after a tick.\n if (reflect) {\n this._reflectOpen(value);\n }\n }\n\n private _reflectOpen(value: boolean): void {\n if (value) {\n if (!this.hasAttribute('open')) {\n this.setAttribute('open', '');\n }\n\n return;\n }\n\n if (this.hasAttribute('open')) {\n this.removeAttribute('open');\n }\n }\n\n private _onToggle = (): void => {\n const open = this._$details?.open ?? false;\n\n this._reflectOpen(open);\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open },\n }),\n );\n };\n\n private _onHashChange = (): void => {\n this._openForCurrentHash();\n };\n\n private _openForCurrentHash(): void {\n if (!location.hash) {\n return;\n }\n\n const targetId = decodeURIComponent(location.hash.slice(1));\n if (!targetId) {\n return;\n }\n\n const $target = this.querySelector(`#${CSS.escape(targetId)}`);\n if (!$target) {\n return;\n }\n\n const wasOpen = this.open;\n\n this.open = true;\n\n if (wasOpen) {\n return;\n }\n\n cancelAnimationFrame(this._scrollFrame);\n this._scrollFrame = requestAnimationFrame(() => {\n document.getElementById(targetId)?.scrollIntoView();\n });\n }\n}\n\nexport default RCDisclosure;\n"],"names":["TOGGLE_EVENT","DETAILS_SELECTOR","SUMMARY_SELECTOR","RCDisclosure","open","value","name","oldValue","newValue","$details","nextOpen","reflect","targetId","wasOpen"],"mappings":"AAKA,MAAMA,IAAe,wBACfC,IAAmB,oBACnBC,IAAmB;AAwBlB,MAAMC,UAAqB,YAAY;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA,GACL,KAAQ,YAAY,IAAI,iBAAiB,MAAM,KAAK,eAAe,GAEnE,KAAQ,YAAuC,MAE/C,KAAQ,eAAe,
|
|
1
|
+
{"version":3,"file":"rc-disclosure.js","sources":["../src/rc-disclosure.ts"],"sourcesContent":["export interface RCDisclosureToggleEvent {\n /** Whether the disclosure is now open. */\n open: boolean;\n}\n\nconst TOGGLE_EVENT = 'rc-disclosure-toggle';\nconst DETAILS_SELECTOR = ':scope > details';\nconst SUMMARY_SELECTOR = ':scope > summary';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-disclosure': RCDisclosure;\n }\n}\n\n/**\n * Disclosure wrapper for a native <details>/<summary> pair with controlled open state,\n * following the WAI-ARIA Disclosure pattern.\n *\n * The browser keeps ownership of open/close behavior, keyboard support, and\n * accessibility. This element mirrors state, emits a consistent custom event,\n * and automatically opens when the URL hash matches any id within its subtree.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-disclosure rc-disclosure docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/ WAI-ARIA Disclosure pattern}\n *\n * @fires rc-disclosure-toggle - Fires when the child `<details>` toggles.\n *\n * @attr open - Current open state mirrored to the child `<details>`.\n * @attr fragment - Deprecated legacy opt-in for URL-fragment auto-open; removed before v1.0.\n */\nexport class RCDisclosure extends HTMLElement {\n private _observer = new MutationObserver(() => this._setupDetails());\n\n private _$details: HTMLDetailsElement | null = null;\n\n private _scrollFrame = 0;\n\n static get observedAttributes(): string[] {\n return ['open', 'fragment'];\n }\n\n /** Current open state mirrored to the child `<details>`. */\n get open(): boolean {\n return this._$details?.open ?? this.hasAttribute('open');\n }\n\n set open(value: boolean) {\n this._setOpen(value, true);\n }\n\n /**\n * Legacy manual opt-in for URL-fragment auto-open.\n *\n * @deprecated No longer required. `rc-disclosure` now automatically opens and\n * scrolls when the URL hash matches any id within its subtree. Will be removed\n * in v1.0 release.\n */\n get fragment(): boolean {\n return this.hasAttribute('fragment');\n }\n\n set fragment(value: boolean) {\n this.toggleAttribute('fragment', value);\n }\n\n connectedCallback(): void {\n this._observer.observe(this, { childList: true });\n window.addEventListener('hashchange', this._onHashChange);\n this._setupDetails();\n }\n\n disconnectedCallback(): void {\n this._observer.disconnect();\n window.removeEventListener('hashchange', this._onHashChange);\n cancelAnimationFrame(this._scrollFrame);\n this._teardownDetails();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) {\n return;\n }\n\n if (name === 'open') {\n this._syncDetailsOpen();\n\n return;\n }\n\n if (name === 'fragment') {\n this._openForCurrentHash();\n }\n }\n\n private _setupDetails(): void {\n const $details = this.querySelector<HTMLDetailsElement>(DETAILS_SELECTOR);\n if ($details === this._$details) {\n return;\n }\n\n this._teardownDetails();\n this._$details = $details;\n\n if (!$details) {\n if (import.meta.env.DEV) {\n console.warn(\n '[rc-disclosure] No direct child <details> found. Place native ' +\n '<details><summary>...</summary>...</details> inside <rc-disclosure>.',\n this,\n );\n }\n\n return;\n }\n\n if (!$details.id) {\n $details.id = crypto.randomUUID();\n }\n\n const $summary = $details.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n $summary?.setAttribute('aria-controls', $details.id);\n\n $details.addEventListener('toggle', this._onToggle);\n\n // If the host hasn't been given an explicit initial `open` of its own,\n // adopt whatever the wrapped <details> markup already says instead of\n // silently forcing it closed on connect — plain `<details open>`\n // should still behave the way it always has when nothing overrides it.\n if (!this.hasAttribute('open') && $details.open) {\n this._reflectOpen(true);\n }\n\n this._syncDetailsOpen();\n this._reflectOpen($details.open);\n this._openForCurrentHash();\n }\n\n private _teardownDetails(): void {\n const $summary = this._$details?.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n $summary?.removeAttribute('aria-controls');\n\n this._$details?.removeEventListener('toggle', this._onToggle);\n this._$details = null;\n }\n\n private _syncDetailsOpen(): void {\n const $details = this._$details;\n if (!$details) {\n return;\n }\n\n const nextOpen = this.hasAttribute('open');\n if ($details.open !== nextOpen) {\n $details.open = nextOpen;\n }\n }\n\n private _setOpen(value: boolean, reflect: boolean): void {\n const $details = this._$details;\n if ($details && $details.open !== value) {\n $details.open = value;\n }\n\n // _reflectOpen is called here for programmatic opens because the <details>\n // toggle event is async (queued task per HTML spec). _onToggle also calls\n // _reflectOpen for user-initiated clicks, but that arrives after a tick.\n if (reflect) {\n this._reflectOpen(value);\n }\n }\n\n private _reflectOpen(value: boolean): void {\n if (value) {\n if (!this.hasAttribute('open')) {\n this.setAttribute('open', '');\n }\n\n return;\n }\n\n if (this.hasAttribute('open')) {\n this.removeAttribute('open');\n }\n }\n\n private _onToggle = (): void => {\n const open = this._$details?.open ?? false;\n\n this._reflectOpen(open);\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open },\n }),\n );\n };\n\n private _onHashChange = (): void => {\n this._openForCurrentHash();\n };\n\n private _openForCurrentHash(): void {\n if (!location.hash) {\n return;\n }\n\n const targetId = decodeURIComponent(location.hash.slice(1));\n if (!targetId) {\n return;\n }\n\n const $target = this.querySelector(`#${CSS.escape(targetId)}`);\n if (!$target) {\n return;\n }\n\n const wasOpen = this.open;\n\n this.open = true;\n\n if (wasOpen) {\n return;\n }\n\n cancelAnimationFrame(this._scrollFrame);\n this._scrollFrame = requestAnimationFrame(() => {\n document.getElementById(targetId)?.scrollIntoView();\n });\n }\n}\n\nexport default RCDisclosure;\n"],"names":["TOGGLE_EVENT","DETAILS_SELECTOR","SUMMARY_SELECTOR","RCDisclosure","open","value","name","oldValue","newValue","$details","nextOpen","reflect","targetId","wasOpen"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.4.
|
|
6
|
+
"version": "0.4.2",
|
|
7
7
|
"description": "Disclosure wrapper for a native <details>/<summary> pair with controlled open state.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -58,4 +58,4 @@
|
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"lit": "^3.0.0"
|
|
60
60
|
}
|
|
61
|
-
}
|
|
61
|
+
}
|