@rcarls/rc-disclosure 0.6.0 → 0.7.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.
- package/CHANGELOG.md +99 -0
- package/dist/custom-elements.json +167 -0
- package/dist/rc-disclosure-MoC5d7zW.js +101 -0
- package/dist/rc-disclosure-MoC5d7zW.js.map +1 -0
- package/dist/rc-disclosure-define.js +5 -2
- package/dist/rc-disclosure-define.js.map +1 -1
- package/dist/rc-disclosure.js +4 -87
- package/dist/rc-disclosure.js.map +1 -1
- package/dist/types/packages/rc-disclosure/src/disclosureBaseStyles.d.ts +22 -0
- package/dist/types/packages/rc-disclosure/src/index.d.ts +1 -0
- package/dist/types/packages/rc-disclosure/src/rc-disclosure.d.ts +30 -0
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
1
|
# @rcarls/rc-disclosure
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4b9bfe6: Give `rc-disclosure` and `rc-accordion` a public styling contract.
|
|
8
|
+
|
|
9
|
+
Both were styled by targeting the native `<details>` element directly, so neither exposed a
|
|
10
|
+
single `--rc-*` property and no theme could change them without rewriting theme CSS. They now
|
|
11
|
+
follow the light-DOM base pattern `rc-button` and `rc-listbox` already use: `rc-disclosure`
|
|
12
|
+
installs one structural stylesheet per containing `Document` or `ShadowRoot`, in `@layer rc-base`
|
|
13
|
+
behind a `data-rc-light-dom-base` sentinel, reading documented properties with UA-like defaults.
|
|
14
|
+
|
|
15
|
+
One recipe covers both supported child forms, a bare `<details>` inside `rc-accordion` and one
|
|
16
|
+
wrapped in `rc-disclosure`, so neither theme repeats the panel rules. `rc-accordion` owns only
|
|
17
|
+
`--rc-accordion-gap`.
|
|
18
|
+
|
|
19
|
+
Motion is opt-in. `--rc-disclosure-duration` defaults to `0ms`, so a disclosure with no theme keeps
|
|
20
|
+
the platform's snap-open behavior, and the height animation runs on `::details-content` behind a
|
|
21
|
+
`@supports selector()` check. This replaces Material's `60rem` `max-block-size` ceiling, which
|
|
22
|
+
clipped content taller than the guess and made every non-summary child its own animation unit.
|
|
23
|
+
|
|
24
|
+
**Fixes a missing expand affordance in the Material theme.** It set `display: grid` on the
|
|
25
|
+
`<summary>` and then styled `summary::marker`. Any `display` other than `list-item` drops the
|
|
26
|
+
marker box, so that rule styled nothing and the theme drew no replacement: a Material disclosure
|
|
27
|
+
had no disclosure triangle at all. The base layer never sets `display` on a summary, so the
|
|
28
|
+
marker survives. A theme may still change it, as Substrate does, but only alongside a
|
|
29
|
+
replacement affordance.
|
|
30
|
+
|
|
31
|
+
- 6e548d9: Several components handle `prefers-reduced-motion: reduce` in their own
|
|
32
|
+
shadow styles, outside a theme's reach, and refine it the same way the theme
|
|
33
|
+
layer already does: spatial motion (`translate`, `scale`, `transform`,
|
|
34
|
+
`inline-size`, `block-size`) goes fully to zero, while effects motion (color,
|
|
35
|
+
opacity) shortens instead of disappearing.
|
|
36
|
+
|
|
37
|
+
`rc-app-bar` zeros its host's hide/show `translate` but shortens the
|
|
38
|
+
expanded title's fade-in. `rc-disclosure` keeps its panel's expand/collapse
|
|
39
|
+
zeroed, but its summary/content backstop for a theme-added transition now
|
|
40
|
+
shortens instead of zeroing it outright. `rc-list-item`'s row and
|
|
41
|
+
state-layer transition only color and opacity, so the whole sweep shortens.
|
|
42
|
+
`rc-fab-menu`'s popup mixes `scale` with opacity/overlay/display under one
|
|
43
|
+
shared duration; reduced motion now zeros the scale and shortens the rest.
|
|
44
|
+
`rc-switch`'s thumb mixes background-color with inline-size/block-size/
|
|
45
|
+
transform the same way; the icons and track, which each transition only one
|
|
46
|
+
kind of property, needed only the zero-or-shorten call. `rc-fab`'s
|
|
47
|
+
scroll-reveal is opacity/visibility only with no time-based duration to
|
|
48
|
+
shorten in its scroll-linked path, so reduced motion narrows the scroll
|
|
49
|
+
window instead of collapsing it to zero; its JS-transition fallback path
|
|
50
|
+
shortens the same fade rather than removing it. `rc-progress`'s determinate
|
|
51
|
+
fill transition, previously unguarded under reduced motion, is now zeroed;
|
|
52
|
+
its indeterminate loop, a continuous sweep with no meaningful shortened
|
|
53
|
+
form, stays fully stopped rather than shortened.
|
|
54
|
+
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
|
|
58
|
+
and light-DOM structural styles through Lightning CSS, removing comments and
|
|
59
|
+
whitespace while keeping source maps that resolve to each template. Rendered
|
|
60
|
+
styles are unchanged.
|
|
61
|
+
|
|
62
|
+
`@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
|
|
63
|
+
string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
|
|
64
|
+
depend on `@rcarls/rc-common` for it.
|
|
65
|
+
|
|
66
|
+
- 3f19f57: Disclosure summaries draw their hover layer only for a pointer that can hover, so a tapped
|
|
67
|
+
summary no longer stays highlighted on touch screens. The Material theme also spaces disclosure
|
|
68
|
+
content from its summary.
|
|
69
|
+
- Updated dependencies [e3dfa59]
|
|
70
|
+
- Updated dependencies [50d5610]
|
|
71
|
+
- Updated dependencies [9ee769c]
|
|
72
|
+
- Updated dependencies [1179f24]
|
|
73
|
+
- Updated dependencies [595fe37]
|
|
74
|
+
- Updated dependencies [38cd00c]
|
|
75
|
+
- Updated dependencies [5c006de]
|
|
76
|
+
- Updated dependencies [a6553ff]
|
|
77
|
+
- Updated dependencies [2205478]
|
|
78
|
+
- Updated dependencies [4341311]
|
|
79
|
+
- Updated dependencies [899bb5e]
|
|
80
|
+
- Updated dependencies [25fcfe0]
|
|
81
|
+
- Updated dependencies [51f6403]
|
|
82
|
+
- Updated dependencies [9caca6b]
|
|
83
|
+
- Updated dependencies [b764a3c]
|
|
84
|
+
- Updated dependencies [54d9ead]
|
|
85
|
+
- Updated dependencies [b9175e9]
|
|
86
|
+
- Updated dependencies [c8b762b]
|
|
87
|
+
- Updated dependencies [55e1e7f]
|
|
88
|
+
- Updated dependencies [f1ca82d]
|
|
89
|
+
- Updated dependencies [b87f27b]
|
|
90
|
+
- Updated dependencies [32ebead]
|
|
91
|
+
- Updated dependencies [bfefedd]
|
|
92
|
+
- Updated dependencies [c130173]
|
|
93
|
+
- Updated dependencies [11680b6]
|
|
94
|
+
- Updated dependencies [223d36c]
|
|
95
|
+
- Updated dependencies [7b91a44]
|
|
96
|
+
- Updated dependencies [aa04ead]
|
|
97
|
+
- Updated dependencies [ac65b5b]
|
|
98
|
+
- Updated dependencies [afcfef8]
|
|
99
|
+
- Updated dependencies [11ef1ad]
|
|
100
|
+
- @rcarls/rc-common@0.7.0
|
|
101
|
+
|
|
3
102
|
## 0.6.0
|
|
4
103
|
|
|
5
104
|
### Minor Changes
|
|
@@ -25,6 +25,54 @@
|
|
|
25
25
|
}
|
|
26
26
|
]
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
"kind": "javascript-module",
|
|
30
|
+
"path": "src/disclosureBaseStyles.ts",
|
|
31
|
+
"declarations": [
|
|
32
|
+
{
|
|
33
|
+
"kind": "variable",
|
|
34
|
+
"name": "DISCLOSURE_BASE_CSS",
|
|
35
|
+
"default": "cssText` @layer rc-base { rc-disclosure { display: block; } :is(rc-disclosure, rc-accordion) > details { box-sizing: border-box; border: var(--rc-disclosure-border, 0); border-radius: var(--rc-disclosure-radius, 0); background: var(--rc-disclosure-background, transparent); color: var(--rc-disclosure-color, inherit); } :is(rc-disclosure, rc-accordion) > details[open] { background: var(--rc-disclosure-open-background, var(--rc-disclosure-background, transparent)); box-shadow: var(--rc-disclosure-open-shadow, none); } /* * Deliberately no \\`display\\` here. Setting \\`display: grid\\` on a summary drops * its \\`list-item\\` box, which silently removes the native disclosure marker, * so that choice belongs to whichever theme also supplies a replacement. */ :is(rc-disclosure, rc-accordion) > details > summary { box-sizing: border-box; min-block-size: var(--rc-disclosure-summary-min-block-size, 0); padding-block: var(--rc-disclosure-summary-padding-block, 0); padding-inline: var(--rc-disclosure-summary-padding-inline, 0); gap: var(--rc-disclosure-summary-gap, 0); color: var(--rc-disclosure-summary-color, inherit); font: var(--rc-disclosure-summary-font, inherit); cursor: pointer; } :is(rc-disclosure, rc-accordion) > details > summary::marker { color: var(--rc-disclosure-summary-marker-color, currentColor); } /* * Touch browsers keep :hover on the last tapped element, which would leave * a just-toggled summary looking highlighted, so only a hovering pointer * gets the layer. */ @media (hover: hover) { :is(rc-disclosure, rc-accordion) > details > summary:hover { background: var(--rc-disclosure-summary-hover-background, transparent); } } :is(rc-disclosure, rc-accordion) > details > summary:focus-visible { outline: var(--rc-disclosure-focus-ring, var(--rc-focus-ring, 2px solid Highlight)); outline-offset: var(--rc-disclosure-focus-ring-offset, 0); } :is(rc-disclosure, rc-accordion) > details > :not(summary) { box-sizing: border-box; padding-block: var(--rc-disclosure-content-padding-block, 0); padding-inline: var(--rc-disclosure-content-padding-inline, 0); color: var(--rc-disclosure-content-color, inherit); font: var(--rc-disclosure-content-font, inherit); } /* * Height animation is a feature-detected enhancement on the single * \\`::details-content\\` box, never a max-height ceiling on each child: a ceiling * clips content taller than the guess, and animating every non-summary child * makes each one its own animation unit. Without \\`::details-content\\` the * panel keeps the platform's snap-open behavior. */ @supports selector(::details-content) { :is(rc-disclosure, rc-accordion) > details { interpolate-size: allow-keywords; } :is(rc-disclosure, rc-accordion) > details::details-content { block-size: 0; overflow: clip; content-visibility: hidden; transition: block-size var(--rc-disclosure-duration, 0ms) var(--rc-disclosure-easing, ease), content-visibility var(--rc-disclosure-duration, 0ms) var(--rc-disclosure-easing, ease) allow-discrete; transition-behavior: allow-discrete; } :is(rc-disclosure, rc-accordion) > details[open]::details-content { block-size: auto; content-visibility: visible; } } /* * Split by what actually moves: \\`::details-content\\`'s own transition is the * block-size expand/collapse, which is spatial and goes fully to zero. The * base component sets no transition of its own on the \\`<details>\\`, summary, * or content boxes, but this stays as a backstop for a theme that adds one * there (Material adds background-color/border-color/box-shadow, all * effects motion), shortened rather than zeroed so it does not silently * cancel a theme's own reduced-motion handling. */ @media (prefers-reduced-motion: reduce) { :is(rc-disclosure, rc-accordion) > details, :is(rc-disclosure, rc-accordion) > details > summary, :is(rc-disclosure, rc-accordion) > details > :not(summary) { transition-duration: 50ms; } @supports selector(::details-content) { :is(rc-disclosure, rc-accordion) > details::details-content { transition-duration: 0ms; } } } } `",
|
|
36
|
+
"description": "Light-DOM base styles for the disclosure panel recipe.\n\n`rc-disclosure` and `rc-accordion` coordinate consumer-authored native\n`<details>` elements that stay in light DOM, so `::slotted()` cannot reach the\n`<summary>`, the marker, the content children, or `::details-content`. This\ninstalls one structural stylesheet per containing `Document` or `ShadowRoot`,\nfollowing the same pattern as `rc-button` and `rc-listbox`.\n\nOne recipe serves both supported child forms: a `<details>` directly inside\n`rc-accordion`, and one wrapped in `rc-disclosure`. Themes map their tokens to\nthese properties rather than re-selecting the native elements.\n\nDefaults stay close to what a user agent would render on its own, so an\nunthemed disclosure keeps native behavior and no theme is required for the\ncomponent to work. In particular `--rc-disclosure-duration` defaults to `0ms`:\na disclosure snaps open the way the platform does until a theme opts into\nmotion."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"kind": "function",
|
|
40
|
+
"name": "ensureDisclosureBaseStyles",
|
|
41
|
+
"return": {
|
|
42
|
+
"type": {
|
|
43
|
+
"text": "void"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"parameters": [
|
|
47
|
+
{
|
|
48
|
+
"name": "root",
|
|
49
|
+
"type": {
|
|
50
|
+
"text": "Document | ShadowRoot"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"description": "Installs the shared disclosure panel styles once per containing root."
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"exports": [
|
|
58
|
+
{
|
|
59
|
+
"kind": "js",
|
|
60
|
+
"name": "DISCLOSURE_BASE_CSS",
|
|
61
|
+
"declaration": {
|
|
62
|
+
"name": "DISCLOSURE_BASE_CSS",
|
|
63
|
+
"module": "src/disclosureBaseStyles.ts"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"kind": "js",
|
|
68
|
+
"name": "ensureDisclosureBaseStyles",
|
|
69
|
+
"declaration": {
|
|
70
|
+
"name": "ensureDisclosureBaseStyles",
|
|
71
|
+
"module": "src/disclosureBaseStyles.ts"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
28
76
|
{
|
|
29
77
|
"kind": "javascript-module",
|
|
30
78
|
"path": "src/index.ts",
|
|
@@ -37,6 +85,14 @@
|
|
|
37
85
|
"name": "*",
|
|
38
86
|
"module": "src/rc-disclosure.js"
|
|
39
87
|
}
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"kind": "js",
|
|
91
|
+
"name": "*",
|
|
92
|
+
"declaration": {
|
|
93
|
+
"name": "*",
|
|
94
|
+
"module": "src/disclosureBaseStyles.js"
|
|
95
|
+
}
|
|
40
96
|
}
|
|
41
97
|
]
|
|
42
98
|
},
|
|
@@ -48,6 +104,117 @@
|
|
|
48
104
|
"kind": "class",
|
|
49
105
|
"description": "Disclosure wrapper for a native <details>/<summary> pair with controlled and uncontrolled\nopen state,\nfollowing the WAI-ARIA Disclosure pattern.\n\nThe browser keeps ownership of open/close behavior, keyboard support, and\naccessibility. This element mirrors state, emits a consistent custom event,\nand automatically opens when the URL hash matches any id within its subtree.",
|
|
50
106
|
"name": "RCDisclosure",
|
|
107
|
+
"cssProperties": [
|
|
108
|
+
{
|
|
109
|
+
"description": "Panel border.",
|
|
110
|
+
"name": "--rc-disclosure-border",
|
|
111
|
+
"default": "0"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"description": "Panel corner radius.",
|
|
115
|
+
"name": "--rc-disclosure-radius",
|
|
116
|
+
"default": "0"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"description": "Panel background while closed.",
|
|
120
|
+
"name": "--rc-disclosure-background",
|
|
121
|
+
"default": "transparent"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"description": "Panel foreground.",
|
|
125
|
+
"name": "--rc-disclosure-color",
|
|
126
|
+
"default": "inherit"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"description": "Panel background while open. Defers to `--rc-disclosure-background` when unset.",
|
|
130
|
+
"name": "--rc-disclosure-open-background"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"description": "Panel shadow while open.",
|
|
134
|
+
"name": "--rc-disclosure-open-shadow",
|
|
135
|
+
"default": "none"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"description": "Summary minimum block size. Set this to at least `3rem` for a comfortable touch target.",
|
|
139
|
+
"name": "--rc-disclosure-summary-min-block-size",
|
|
140
|
+
"default": "0"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"description": "Summary block padding.",
|
|
144
|
+
"name": "--rc-disclosure-summary-padding-block",
|
|
145
|
+
"default": "0"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"description": "Summary inline padding.",
|
|
149
|
+
"name": "--rc-disclosure-summary-padding-inline",
|
|
150
|
+
"default": "0"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"description": "Summary gap, for a theme that lays the summary out as a grid or flex container.",
|
|
154
|
+
"name": "--rc-disclosure-summary-gap",
|
|
155
|
+
"default": "0"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"description": "Summary foreground.",
|
|
159
|
+
"name": "--rc-disclosure-summary-color",
|
|
160
|
+
"default": "inherit"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"description": "Summary font shorthand.",
|
|
164
|
+
"name": "--rc-disclosure-summary-font",
|
|
165
|
+
"default": "inherit"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"description": "Native disclosure marker color. A theme that replaces the marker with its own affordance should hide `::marker` itself.",
|
|
169
|
+
"name": "--rc-disclosure-summary-marker-color",
|
|
170
|
+
"default": "currentColor"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"description": "Summary hover background.",
|
|
174
|
+
"name": "--rc-disclosure-summary-hover-background",
|
|
175
|
+
"default": "transparent"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"description": "Summary focus-visible outline.",
|
|
179
|
+
"name": "--rc-disclosure-focus-ring",
|
|
180
|
+
"default": "var(--rc-focus-ring, 2px solid Highlight)"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"description": "Summary focus-visible outline offset.",
|
|
184
|
+
"name": "--rc-disclosure-focus-ring-offset",
|
|
185
|
+
"default": "0"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"description": "Content block padding.",
|
|
189
|
+
"name": "--rc-disclosure-content-padding-block",
|
|
190
|
+
"default": "0"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"description": "Content inline padding.",
|
|
194
|
+
"name": "--rc-disclosure-content-padding-inline",
|
|
195
|
+
"default": "0"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"description": "Content foreground.",
|
|
199
|
+
"name": "--rc-disclosure-content-color",
|
|
200
|
+
"default": "inherit"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"description": "Content font shorthand.",
|
|
204
|
+
"name": "--rc-disclosure-content-font",
|
|
205
|
+
"default": "inherit"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"description": "Open and close transition duration. Zero by default, so the panel snaps the way the platform does until a theme opts into motion. The animation runs on `::details-content` where that is supported and is skipped entirely where it is not.",
|
|
209
|
+
"name": "--rc-disclosure-duration",
|
|
210
|
+
"default": "0ms"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"description": "Open and close transition easing.",
|
|
214
|
+
"name": "--rc-disclosure-easing",
|
|
215
|
+
"default": "ease"
|
|
216
|
+
}
|
|
217
|
+
],
|
|
51
218
|
"members": [
|
|
52
219
|
{
|
|
53
220
|
"kind": "field",
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { cssText as c } from "@rcarls/rc-common";
|
|
2
|
+
const l = c`@layer rc-base{rc-disclosure{display:block}:is(rc-disclosure,rc-accordion)>details{box-sizing:border-box;border:var(--rc-disclosure-border,0);border-radius:var(--rc-disclosure-radius,0);background:var(--rc-disclosure-background,transparent);color:var(--rc-disclosure-color,inherit)}:is(rc-disclosure,rc-accordion)>details[open]{background:var(--rc-disclosure-open-background,var(--rc-disclosure-background,transparent));box-shadow:var(--rc-disclosure-open-shadow,none)}:is(rc-disclosure,rc-accordion)>details>summary{box-sizing:border-box;min-block-size:var(--rc-disclosure-summary-min-block-size,0);padding-block:var(--rc-disclosure-summary-padding-block,0);padding-inline:var(--rc-disclosure-summary-padding-inline,0);gap:var(--rc-disclosure-summary-gap,0);color:var(--rc-disclosure-summary-color,inherit);font:var(--rc-disclosure-summary-font,inherit);cursor:pointer}:is(rc-disclosure,rc-accordion)>details>summary::marker{color:var(--rc-disclosure-summary-marker-color,currentColor)}@media (hover:hover){:is(rc-disclosure,rc-accordion)>details>summary:hover{background:var(--rc-disclosure-summary-hover-background,transparent)}}:is(rc-disclosure,rc-accordion)>details>summary:focus-visible{outline:var(--rc-disclosure-focus-ring,var(--rc-focus-ring,2px solid Highlight));outline-offset:var(--rc-disclosure-focus-ring-offset,0)}:is(rc-disclosure,rc-accordion)>details>:not(summary){box-sizing:border-box;padding-block:var(--rc-disclosure-content-padding-block,0);padding-inline:var(--rc-disclosure-content-padding-inline,0);color:var(--rc-disclosure-content-color,inherit);font:var(--rc-disclosure-content-font,inherit)}@supports selector(::details-content){:is(rc-disclosure,rc-accordion)>details{interpolate-size:allow-keywords}:is(rc-disclosure,rc-accordion)>details::details-content{content-visibility:hidden;block-size:0;transition:block-size var(--rc-disclosure-duration,0s) var(--rc-disclosure-easing,ease), content-visibility var(--rc-disclosure-duration,0s) var(--rc-disclosure-easing,ease) allow-discrete;transition-behavior:allow-discrete;overflow:clip}:is(rc-disclosure,rc-accordion)>details[open]::details-content{content-visibility:visible;block-size:auto}}@media (prefers-reduced-motion:reduce){:is(rc-disclosure,rc-accordion)>details,:is(rc-disclosure,rc-accordion)>details>summary,:is(rc-disclosure,rc-accordion)>details>:not(summary){transition-duration:50ms}@supports selector(::details-content){:is(rc-disclosure,rc-accordion)>details::details-content{transition-duration:0s}}}}`, i = /* @__PURE__ */ new WeakSet();
|
|
3
|
+
function a(s) {
|
|
4
|
+
if (i.has(s))
|
|
5
|
+
return;
|
|
6
|
+
i.add(s);
|
|
7
|
+
const e = (s instanceof Document ? s : s.ownerDocument).createElement("style");
|
|
8
|
+
e.setAttribute("data-rc-light-dom-base", "rc-disclosure"), e.textContent = l, s instanceof Document ? s.head.append(e) : s.append(e);
|
|
9
|
+
}
|
|
10
|
+
const o = "rc-disclosure-toggle", d = ":scope > details", n = ":scope > summary";
|
|
11
|
+
class p extends HTMLElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments), this._observer = new MutationObserver(() => this._setupDetails()), this._$details = null, this._scrollFrame = 0, this._defaultOpen = !1, this._defaultOpenInitialized = !1, this._openInitialized = !1, this._reflectingOpen = !1, this._suppressNextToggle = !1, this._onToggle = () => {
|
|
14
|
+
if (this._suppressNextToggle) {
|
|
15
|
+
this._suppressNextToggle = !1;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const e = this._$details?.open ?? !1;
|
|
19
|
+
this._controlledOpen === void 0 ? (this._uncontrolledOpen = e, this._reflectOpen(e)) : (this._applyOpen(this._controlledOpen, !0), this._reflectOpen(this._controlledOpen)), this.dispatchEvent(
|
|
20
|
+
new CustomEvent(o, {
|
|
21
|
+
bubbles: !0,
|
|
22
|
+
composed: !0,
|
|
23
|
+
detail: { open: e }
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
}, this._onHashChange = () => {
|
|
27
|
+
this._openForCurrentHash();
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
static get observedAttributes() {
|
|
31
|
+
return ["open", "default-open"];
|
|
32
|
+
}
|
|
33
|
+
/** Current open state. Host writes are silent; assign `undefined` to release control. */
|
|
34
|
+
get open() {
|
|
35
|
+
return this._controlledOpen ?? this._uncontrolledOpen ?? this._defaultOpen;
|
|
36
|
+
}
|
|
37
|
+
set open(e) {
|
|
38
|
+
this._controlledOpen = e, this._openInitialized = !0, this._applyOpen(this.open), this._reflectOpen(this.open);
|
|
39
|
+
}
|
|
40
|
+
/** Initial open state for uncontrolled usage. */
|
|
41
|
+
get defaultOpen() {
|
|
42
|
+
return this._defaultOpen;
|
|
43
|
+
}
|
|
44
|
+
set defaultOpen(e) {
|
|
45
|
+
this._defaultOpen = e, this._defaultOpenInitialized = !0, !this._openInitialized && this._controlledOpen === void 0 && this._uncontrolledOpen === void 0 && (this._applyOpen(e), this._reflectOpen(e));
|
|
46
|
+
}
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
a(this.getRootNode()), this._observer.observe(this, { childList: !0 }), window.addEventListener("hashchange", this._onHashChange), this._setupDetails();
|
|
49
|
+
}
|
|
50
|
+
disconnectedCallback() {
|
|
51
|
+
this._observer.disconnect(), window.removeEventListener("hashchange", this._onHashChange), cancelAnimationFrame(this._scrollFrame), this._teardownDetails();
|
|
52
|
+
}
|
|
53
|
+
attributeChangedCallback(e, r, t) {
|
|
54
|
+
if (r !== t) {
|
|
55
|
+
if (e === "default-open") {
|
|
56
|
+
this.defaultOpen = t !== null;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this._reflectingOpen || (this.open = t !== null);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
_setupDetails() {
|
|
63
|
+
const e = this.querySelector(d);
|
|
64
|
+
if (e === this._$details || (this._teardownDetails(), this._$details = e, !e))
|
|
65
|
+
return;
|
|
66
|
+
e.id || (e.id = crypto.randomUUID()), e.querySelector(n)?.setAttribute("aria-controls", e.id), e.addEventListener("toggle", this._onToggle), this._controlledOpen === void 0 && this._uncontrolledOpen === void 0 && (this._uncontrolledOpen = this._defaultOpenInitialized ? this._defaultOpen : e.open), this._applyOpen(this.open, !0), this._reflectOpen(this.open), this._openForCurrentHash();
|
|
67
|
+
}
|
|
68
|
+
_teardownDetails() {
|
|
69
|
+
this._$details?.querySelector(n)?.removeAttribute("aria-controls"), this._$details?.removeEventListener("toggle", this._onToggle), this._$details = null;
|
|
70
|
+
}
|
|
71
|
+
_applyOpen(e, r = !0) {
|
|
72
|
+
const t = this._$details;
|
|
73
|
+
t && t.open !== e && (this._suppressNextToggle = r, t.open = e);
|
|
74
|
+
}
|
|
75
|
+
_reflectOpen(e) {
|
|
76
|
+
this.hasAttribute("open") !== e && (this._reflectingOpen = !0, this.toggleAttribute("open", e), this._reflectingOpen = !1);
|
|
77
|
+
}
|
|
78
|
+
_openForCurrentHash() {
|
|
79
|
+
if (!location.hash)
|
|
80
|
+
return;
|
|
81
|
+
const e = decodeURIComponent(location.hash.slice(1));
|
|
82
|
+
if (!e || !this.querySelector(`#${CSS.escape(e)}`))
|
|
83
|
+
return;
|
|
84
|
+
const t = this.open;
|
|
85
|
+
this._controlledOpen === void 0 ? (this._uncontrolledOpen = !0, this._applyOpen(!0), this._reflectOpen(!0)) : this.dispatchEvent(
|
|
86
|
+
new CustomEvent(o, {
|
|
87
|
+
bubbles: !0,
|
|
88
|
+
composed: !0,
|
|
89
|
+
detail: { open: !0 }
|
|
90
|
+
})
|
|
91
|
+
), this.open && (t || (cancelAnimationFrame(this._scrollFrame), this._scrollFrame = requestAnimationFrame(() => {
|
|
92
|
+
document.getElementById(e)?.scrollIntoView();
|
|
93
|
+
})));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
l as D,
|
|
98
|
+
p as R,
|
|
99
|
+
a as e
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=rc-disclosure-MoC5d7zW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-disclosure-MoC5d7zW.js","sources":["../src/disclosureBaseStyles.ts","../src/rc-disclosure.ts"],"sourcesContent":["import { cssText } from '@rcarls/rc-common';\n\n/**\n * Light-DOM base styles for the disclosure panel recipe.\n *\n * `rc-disclosure` and `rc-accordion` coordinate consumer-authored native\n * `<details>` elements that stay in light DOM, so `::slotted()` cannot reach the\n * `<summary>`, the marker, the content children, or `::details-content`. This\n * installs one structural stylesheet per containing `Document` or `ShadowRoot`,\n * following the same pattern as `rc-button` and `rc-listbox`.\n *\n * One recipe serves both supported child forms: a `<details>` directly inside\n * `rc-accordion`, and one wrapped in `rc-disclosure`. Themes map their tokens to\n * these properties rather than re-selecting the native elements.\n *\n * Defaults stay close to what a user agent would render on its own, so an\n * unthemed disclosure keeps native behavior and no theme is required for the\n * component to work. In particular `--rc-disclosure-duration` defaults to `0ms`:\n * a disclosure snaps open the way the platform does until a theme opts into\n * motion.\n */\nexport const DISCLOSURE_BASE_CSS = cssText`\n@layer rc-base {\n rc-disclosure {\n display: block;\n }\n\n :is(rc-disclosure, rc-accordion) > details {\n box-sizing: border-box;\n border: var(--rc-disclosure-border, 0);\n border-radius: var(--rc-disclosure-radius, 0);\n background: var(--rc-disclosure-background, transparent);\n color: var(--rc-disclosure-color, inherit);\n }\n\n :is(rc-disclosure, rc-accordion) > details[open] {\n background: var(--rc-disclosure-open-background, var(--rc-disclosure-background, transparent));\n box-shadow: var(--rc-disclosure-open-shadow, none);\n }\n\n /*\n * Deliberately no \\`display\\` here. Setting \\`display: grid\\` on a summary drops\n * its \\`list-item\\` box, which silently removes the native disclosure marker,\n * so that choice belongs to whichever theme also supplies a replacement.\n */\n :is(rc-disclosure, rc-accordion) > details > summary {\n box-sizing: border-box;\n min-block-size: var(--rc-disclosure-summary-min-block-size, 0);\n padding-block: var(--rc-disclosure-summary-padding-block, 0);\n padding-inline: var(--rc-disclosure-summary-padding-inline, 0);\n gap: var(--rc-disclosure-summary-gap, 0);\n color: var(--rc-disclosure-summary-color, inherit);\n font: var(--rc-disclosure-summary-font, inherit);\n cursor: pointer;\n }\n\n :is(rc-disclosure, rc-accordion) > details > summary::marker {\n color: var(--rc-disclosure-summary-marker-color, currentColor);\n }\n\n /*\n * Touch browsers keep :hover on the last tapped element, which would leave\n * a just-toggled summary looking highlighted, so only a hovering pointer\n * gets the layer.\n */\n @media (hover: hover) {\n :is(rc-disclosure, rc-accordion) > details > summary:hover {\n background: var(--rc-disclosure-summary-hover-background, transparent);\n }\n }\n\n :is(rc-disclosure, rc-accordion) > details > summary:focus-visible {\n outline: var(--rc-disclosure-focus-ring, var(--rc-focus-ring, 2px solid Highlight));\n outline-offset: var(--rc-disclosure-focus-ring-offset, 0);\n }\n\n :is(rc-disclosure, rc-accordion) > details > :not(summary) {\n box-sizing: border-box;\n padding-block: var(--rc-disclosure-content-padding-block, 0);\n padding-inline: var(--rc-disclosure-content-padding-inline, 0);\n color: var(--rc-disclosure-content-color, inherit);\n font: var(--rc-disclosure-content-font, inherit);\n }\n\n /*\n * Height animation is a feature-detected enhancement on the single\n * \\`::details-content\\` box, never a max-height ceiling on each child: a ceiling\n * clips content taller than the guess, and animating every non-summary child\n * makes each one its own animation unit. Without \\`::details-content\\` the\n * panel keeps the platform's snap-open behavior.\n */\n @supports selector(::details-content) {\n :is(rc-disclosure, rc-accordion) > details {\n interpolate-size: allow-keywords;\n }\n\n :is(rc-disclosure, rc-accordion) > details::details-content {\n block-size: 0;\n overflow: clip;\n content-visibility: hidden;\n transition:\n block-size var(--rc-disclosure-duration, 0ms) var(--rc-disclosure-easing, ease),\n content-visibility var(--rc-disclosure-duration, 0ms) var(--rc-disclosure-easing, ease)\n allow-discrete;\n transition-behavior: allow-discrete;\n }\n\n :is(rc-disclosure, rc-accordion) > details[open]::details-content {\n block-size: auto;\n content-visibility: visible;\n }\n }\n\n /*\n * Split by what actually moves: \\`::details-content\\`'s own transition is the\n * block-size expand/collapse, which is spatial and goes fully to zero. The\n * base component sets no transition of its own on the \\`<details>\\`, summary,\n * or content boxes, but this stays as a backstop for a theme that adds one\n * there (Material adds background-color/border-color/box-shadow, all\n * effects motion), shortened rather than zeroed so it does not silently\n * cancel a theme's own reduced-motion handling.\n */\n @media (prefers-reduced-motion: reduce) {\n :is(rc-disclosure, rc-accordion) > details,\n :is(rc-disclosure, rc-accordion) > details > summary,\n :is(rc-disclosure, rc-accordion) > details > :not(summary) {\n transition-duration: 50ms;\n }\n\n @supports selector(::details-content) {\n :is(rc-disclosure, rc-accordion) > details::details-content {\n transition-duration: 0ms;\n }\n }\n }\n}\n`;\n\nconst styledRoots = new WeakSet<Document | ShadowRoot>();\n\n/** Installs the shared disclosure panel styles once per containing root. */\nexport function ensureDisclosureBaseStyles(root: Document | ShadowRoot): void {\n if (styledRoots.has(root)) {\n return;\n }\n\n styledRoots.add(root);\n\n const $style = (root instanceof Document ? root : root.ownerDocument).createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-disclosure');\n $style.textContent = DISCLOSURE_BASE_CSS;\n\n if (root instanceof Document) {\n root.head.append($style);\n } else {\n root.append($style);\n }\n}\n","import { ensureDisclosureBaseStyles } from './disclosureBaseStyles.js';\n\nexport 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 and uncontrolled\n * 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 - Controlled open state mirrored to the child `<details>`.\n * @attr default-open - Initial open state for uncontrolled usage.\n *\n * @cssprop [--rc-disclosure-border=0] - Panel border.\n * @cssprop [--rc-disclosure-radius=0] - Panel corner radius.\n * @cssprop [--rc-disclosure-background=transparent] - Panel background while closed.\n * @cssprop [--rc-disclosure-color=inherit] - Panel foreground.\n * @cssprop [--rc-disclosure-open-background] - Panel background while open. Defers to\n * `--rc-disclosure-background` when unset.\n * @cssprop [--rc-disclosure-open-shadow=none] - Panel shadow while open.\n * @cssprop [--rc-disclosure-summary-min-block-size=0] - Summary minimum block size. Set this to\n * at least `3rem` for a comfortable touch target.\n * @cssprop [--rc-disclosure-summary-padding-block=0] - Summary block padding.\n * @cssprop [--rc-disclosure-summary-padding-inline=0] - Summary inline padding.\n * @cssprop [--rc-disclosure-summary-gap=0] - Summary gap, for a theme that lays the summary out\n * as a grid or flex container.\n * @cssprop [--rc-disclosure-summary-color=inherit] - Summary foreground.\n * @cssprop [--rc-disclosure-summary-font=inherit] - Summary font shorthand.\n * @cssprop [--rc-disclosure-summary-marker-color=currentColor] - Native disclosure marker color.\n * A theme that replaces the marker with its own affordance should hide `::marker` itself.\n * @cssprop [--rc-disclosure-summary-hover-background=transparent] - Summary hover background.\n * @cssprop [--rc-disclosure-focus-ring=var(--rc-focus-ring, 2px solid Highlight)] - Summary\n * focus-visible outline.\n * @cssprop [--rc-disclosure-focus-ring-offset=0] - Summary focus-visible outline offset.\n * @cssprop [--rc-disclosure-content-padding-block=0] - Content block padding.\n * @cssprop [--rc-disclosure-content-padding-inline=0] - Content inline padding.\n * @cssprop [--rc-disclosure-content-color=inherit] - Content foreground.\n * @cssprop [--rc-disclosure-content-font=inherit] - Content font shorthand.\n * @cssprop [--rc-disclosure-duration=0ms] - Open and close transition duration. Zero by default,\n * so the panel snaps the way the platform does until a theme opts into motion. The animation\n * runs on `::details-content` where that is supported and is skipped entirely where it is not.\n * @cssprop [--rc-disclosure-easing=ease] - Open and close transition easing.\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 private _controlledOpen: boolean | undefined;\n private _defaultOpen = false;\n private _defaultOpenInitialized = false;\n private _uncontrolledOpen: boolean | undefined;\n private _openInitialized = false;\n private _reflectingOpen = false;\n private _suppressNextToggle = false;\n\n static get observedAttributes(): string[] {\n return ['open', 'default-open'];\n }\n\n /** Current open state. Host writes are silent; assign `undefined` to release control. */\n get open(): boolean {\n return this._controlledOpen ?? this._uncontrolledOpen ?? this._defaultOpen;\n }\n\n set open(value: boolean | undefined) {\n this._controlledOpen = value;\n this._openInitialized = true;\n this._applyOpen(this.open);\n this._reflectOpen(this.open);\n }\n\n /** Initial open state for uncontrolled usage. */\n get defaultOpen(): boolean {\n return this._defaultOpen;\n }\n\n set defaultOpen(value: boolean) {\n this._defaultOpen = value;\n this._defaultOpenInitialized = true;\n\n if (\n !this._openInitialized &&\n this._controlledOpen === undefined &&\n this._uncontrolledOpen === undefined\n ) {\n this._applyOpen(value);\n this._reflectOpen(value);\n }\n }\n\n connectedCallback(): void {\n ensureDisclosureBaseStyles(this.getRootNode() as Document | ShadowRoot);\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 === 'default-open') {\n this.defaultOpen = newValue !== null;\n\n return;\n }\n\n if (this._reflectingOpen) {\n return;\n }\n\n this.open = newValue === null ? false : true;\n }\n\n private _setupDetails(): void {\n const $details = this.querySelector<HTMLDetailsElement>(DETAILS_SELECTOR);\n\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\n $summary?.setAttribute('aria-controls', $details.id);\n\n $details.addEventListener('toggle', this._onToggle);\n\n if (this._controlledOpen === undefined && this._uncontrolledOpen === undefined) {\n this._uncontrolledOpen = this._defaultOpenInitialized ? this._defaultOpen : $details.open;\n }\n\n this._applyOpen(this.open, true);\n this._reflectOpen(this.open);\n this._openForCurrentHash();\n }\n\n private _teardownDetails(): void {\n const $summary = this._$details?.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n\n $summary?.removeAttribute('aria-controls');\n\n this._$details?.removeEventListener('toggle', this._onToggle);\n this._$details = null;\n }\n\n private _applyOpen(open: boolean, suppressToggle = true): void {\n const $details = this._$details;\n\n if (!$details) {\n return;\n }\n\n if ($details.open !== open) {\n this._suppressNextToggle = suppressToggle;\n $details.open = open;\n }\n }\n\n private _reflectOpen(value: boolean): void {\n if (this.hasAttribute('open') === value) {\n return;\n }\n\n this._reflectingOpen = true;\n this.toggleAttribute('open', value);\n this._reflectingOpen = false;\n }\n\n private _onToggle = (): void => {\n if (this._suppressNextToggle) {\n this._suppressNextToggle = false;\n\n return;\n }\n\n const requestedOpen = this._$details?.open ?? false;\n\n if (this._controlledOpen === undefined) {\n this._uncontrolledOpen = requestedOpen;\n this._reflectOpen(requestedOpen);\n } else {\n this._applyOpen(this._controlledOpen, true);\n this._reflectOpen(this._controlledOpen);\n }\n\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open: requestedOpen },\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\n if (!targetId) {\n return;\n }\n\n const $target = this.querySelector(`#${CSS.escape(targetId)}`);\n\n if (!$target) {\n return;\n }\n\n const wasOpen = this.open;\n\n if (this._controlledOpen === undefined) {\n this._uncontrolledOpen = true;\n this._applyOpen(true);\n this._reflectOpen(true);\n } else {\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open: true },\n }),\n );\n }\n\n if (!this.open) {\n return;\n }\n\n if (wasOpen) {\n return;\n }\n\n cancelAnimationFrame(this._scrollFrame);\n\n this._scrollFrame = requestAnimationFrame(() => {\n document.getElementById(targetId)?.scrollIntoView();\n });\n }\n}\n\nexport default RCDisclosure;\n"],"names":["DISCLOSURE_BASE_CSS","cssText","styledRoots","ensureDisclosureBaseStyles","root","$style","TOGGLE_EVENT","DETAILS_SELECTOR","SUMMARY_SELECTOR","RCDisclosure","requestedOpen","value","name","oldValue","newValue","$details","open","suppressToggle","targetId","wasOpen"],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as e } from "./rc-disclosure-MoC5d7zW.js";
|
|
2
|
+
import { D as t, e as c } from "./rc-disclosure-MoC5d7zW.js";
|
|
2
3
|
customElements.get("rc-disclosure") || customElements.define("rc-disclosure", e);
|
|
3
4
|
export {
|
|
4
|
-
|
|
5
|
+
t as DISCLOSURE_BASE_CSS,
|
|
6
|
+
e as RCDisclosure,
|
|
7
|
+
c as ensureDisclosureBaseStyles
|
|
5
8
|
};
|
|
6
9
|
//# sourceMappingURL=rc-disclosure-define.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rc-disclosure-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCDisclosure } from './index.js';\n\nif (!customElements.get('rc-disclosure')) {\n customElements.define('rc-disclosure', RCDisclosure);\n}\n\nexport * from './index.js';\n"],"names":["RCDisclosure"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rc-disclosure-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCDisclosure } from './index.js';\n\nif (!customElements.get('rc-disclosure')) {\n customElements.define('rc-disclosure', RCDisclosure);\n}\n\nexport * from './index.js';\n"],"names":["RCDisclosure"],"mappings":";;AAEK,eAAe,IAAI,eAAe,KACrC,eAAe,OAAO,iBAAiBA,CAAY;"}
|
package/dist/rc-disclosure.js
CHANGED
|
@@ -1,90 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
class l extends HTMLElement {
|
|
3
|
-
constructor() {
|
|
4
|
-
super(...arguments), this._observer = new MutationObserver(() => this._setupDetails()), this._$details = null, this._scrollFrame = 0, this._defaultOpen = !1, this._defaultOpenInitialized = !1, this._openInitialized = !1, this._reflectingOpen = !1, this._suppressNextToggle = !1, this._onToggle = () => {
|
|
5
|
-
if (this._suppressNextToggle) {
|
|
6
|
-
this._suppressNextToggle = !1;
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
const e = this._$details?.open ?? !1;
|
|
10
|
-
this._controlledOpen === void 0 ? (this._uncontrolledOpen = e, this._reflectOpen(e)) : (this._applyOpen(this._controlledOpen, !0), this._reflectOpen(this._controlledOpen)), this.dispatchEvent(
|
|
11
|
-
new CustomEvent(n, {
|
|
12
|
-
bubbles: !0,
|
|
13
|
-
composed: !0,
|
|
14
|
-
detail: { open: e }
|
|
15
|
-
})
|
|
16
|
-
);
|
|
17
|
-
}, this._onHashChange = () => {
|
|
18
|
-
this._openForCurrentHash();
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
static get observedAttributes() {
|
|
22
|
-
return ["open", "default-open"];
|
|
23
|
-
}
|
|
24
|
-
/** Current open state. Host writes are silent; assign `undefined` to release control. */
|
|
25
|
-
get open() {
|
|
26
|
-
return this._controlledOpen ?? this._uncontrolledOpen ?? this._defaultOpen;
|
|
27
|
-
}
|
|
28
|
-
set open(e) {
|
|
29
|
-
this._controlledOpen = e, this._openInitialized = !0, this._applyOpen(this.open), this._reflectOpen(this.open);
|
|
30
|
-
}
|
|
31
|
-
/** Initial open state for uncontrolled usage. */
|
|
32
|
-
get defaultOpen() {
|
|
33
|
-
return this._defaultOpen;
|
|
34
|
-
}
|
|
35
|
-
set defaultOpen(e) {
|
|
36
|
-
this._defaultOpen = e, this._defaultOpenInitialized = !0, !this._openInitialized && this._controlledOpen === void 0 && this._uncontrolledOpen === void 0 && (this._applyOpen(e), this._reflectOpen(e));
|
|
37
|
-
}
|
|
38
|
-
connectedCallback() {
|
|
39
|
-
this._observer.observe(this, { childList: !0 }), window.addEventListener("hashchange", this._onHashChange), this._setupDetails();
|
|
40
|
-
}
|
|
41
|
-
disconnectedCallback() {
|
|
42
|
-
this._observer.disconnect(), window.removeEventListener("hashchange", this._onHashChange), cancelAnimationFrame(this._scrollFrame), this._teardownDetails();
|
|
43
|
-
}
|
|
44
|
-
attributeChangedCallback(e, s, t) {
|
|
45
|
-
if (s !== t) {
|
|
46
|
-
if (e === "default-open") {
|
|
47
|
-
this.defaultOpen = t !== null;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this._reflectingOpen || (this.open = t !== null);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
_setupDetails() {
|
|
54
|
-
const e = this.querySelector(r);
|
|
55
|
-
if (e === this._$details || (this._teardownDetails(), this._$details = e, !e))
|
|
56
|
-
return;
|
|
57
|
-
e.id || (e.id = crypto.randomUUID()), e.querySelector(i)?.setAttribute("aria-controls", e.id), e.addEventListener("toggle", this._onToggle), this._controlledOpen === void 0 && this._uncontrolledOpen === void 0 && (this._uncontrolledOpen = this._defaultOpenInitialized ? this._defaultOpen : e.open), this._applyOpen(this.open, !0), this._reflectOpen(this.open), this._openForCurrentHash();
|
|
58
|
-
}
|
|
59
|
-
_teardownDetails() {
|
|
60
|
-
this._$details?.querySelector(i)?.removeAttribute("aria-controls"), this._$details?.removeEventListener("toggle", this._onToggle), this._$details = null;
|
|
61
|
-
}
|
|
62
|
-
_applyOpen(e, s = !0) {
|
|
63
|
-
const t = this._$details;
|
|
64
|
-
t && t.open !== e && (this._suppressNextToggle = s, t.open = e);
|
|
65
|
-
}
|
|
66
|
-
_reflectOpen(e) {
|
|
67
|
-
this.hasAttribute("open") !== e && (this._reflectingOpen = !0, this.toggleAttribute("open", e), this._reflectingOpen = !1);
|
|
68
|
-
}
|
|
69
|
-
_openForCurrentHash() {
|
|
70
|
-
if (!location.hash)
|
|
71
|
-
return;
|
|
72
|
-
const e = decodeURIComponent(location.hash.slice(1));
|
|
73
|
-
if (!e || !this.querySelector(`#${CSS.escape(e)}`))
|
|
74
|
-
return;
|
|
75
|
-
const t = this.open;
|
|
76
|
-
this._controlledOpen === void 0 ? (this._uncontrolledOpen = !0, this._applyOpen(!0), this._reflectOpen(!0)) : this.dispatchEvent(
|
|
77
|
-
new CustomEvent(n, {
|
|
78
|
-
bubbles: !0,
|
|
79
|
-
composed: !0,
|
|
80
|
-
detail: { open: !0 }
|
|
81
|
-
})
|
|
82
|
-
), this.open && (t || (cancelAnimationFrame(this._scrollFrame), this._scrollFrame = requestAnimationFrame(() => {
|
|
83
|
-
document.getElementById(e)?.scrollIntoView();
|
|
84
|
-
})));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
1
|
+
import { D as S, R as r, e as a } from "./rc-disclosure-MoC5d7zW.js";
|
|
87
2
|
export {
|
|
88
|
-
|
|
3
|
+
S as DISCLOSURE_BASE_CSS,
|
|
4
|
+
r as RCDisclosure,
|
|
5
|
+
a as ensureDisclosureBaseStyles
|
|
89
6
|
};
|
|
90
7
|
//# sourceMappingURL=rc-disclosure.js.map
|
|
@@ -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 and uncontrolled\n * 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 - Controlled open state mirrored to the child `<details>`.\n * @attr default-open - Initial open state for uncontrolled usage.\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 private _controlledOpen: boolean | undefined;\n private _defaultOpen = false;\n private _defaultOpenInitialized = false;\n private _uncontrolledOpen: boolean | undefined;\n private _openInitialized = false;\n private _reflectingOpen = false;\n private _suppressNextToggle = false;\n\n static get observedAttributes(): string[] {\n return ['open', 'default-open'];\n }\n\n /** Current open state. Host writes are silent; assign `undefined` to release control. */\n get open(): boolean {\n return this._controlledOpen ?? this._uncontrolledOpen ?? this._defaultOpen;\n }\n\n set open(value: boolean | undefined) {\n this._controlledOpen = value;\n this._openInitialized = true;\n this._applyOpen(this.open);\n this._reflectOpen(this.open);\n }\n\n /** Initial open state for uncontrolled usage. */\n get defaultOpen(): boolean {\n return this._defaultOpen;\n }\n\n set defaultOpen(value: boolean) {\n this._defaultOpen = value;\n this._defaultOpenInitialized = true;\n\n if (\n !this._openInitialized &&\n this._controlledOpen === undefined &&\n this._uncontrolledOpen === undefined\n ) {\n this._applyOpen(value);\n this._reflectOpen(value);\n }\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 === 'default-open') {\n this.defaultOpen = newValue !== null;\n\n return;\n }\n\n if (this._reflectingOpen) {\n return;\n }\n\n this.open = newValue === null ? false : true;\n }\n\n private _setupDetails(): void {\n const $details = this.querySelector<HTMLDetailsElement>(DETAILS_SELECTOR);\n\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\n $summary?.setAttribute('aria-controls', $details.id);\n\n $details.addEventListener('toggle', this._onToggle);\n\n if (this._controlledOpen === undefined && this._uncontrolledOpen === undefined) {\n this._uncontrolledOpen = this._defaultOpenInitialized ? this._defaultOpen : $details.open;\n }\n\n this._applyOpen(this.open, true);\n this._reflectOpen(this.open);\n this._openForCurrentHash();\n }\n\n private _teardownDetails(): void {\n const $summary = this._$details?.querySelector<HTMLElement>(SUMMARY_SELECTOR);\n\n $summary?.removeAttribute('aria-controls');\n\n this._$details?.removeEventListener('toggle', this._onToggle);\n this._$details = null;\n }\n\n private _applyOpen(open: boolean, suppressToggle = true): void {\n const $details = this._$details;\n\n if (!$details) {\n return;\n }\n\n if ($details.open !== open) {\n this._suppressNextToggle = suppressToggle;\n $details.open = open;\n }\n }\n\n private _reflectOpen(value: boolean): void {\n if (this.hasAttribute('open') === value) {\n return;\n }\n\n this._reflectingOpen = true;\n this.toggleAttribute('open', value);\n this._reflectingOpen = false;\n }\n\n private _onToggle = (): void => {\n if (this._suppressNextToggle) {\n this._suppressNextToggle = false;\n\n return;\n }\n\n const requestedOpen = this._$details?.open ?? false;\n\n if (this._controlledOpen === undefined) {\n this._uncontrolledOpen = requestedOpen;\n this._reflectOpen(requestedOpen);\n } else {\n this._applyOpen(this._controlledOpen, true);\n this._reflectOpen(this._controlledOpen);\n }\n\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open: requestedOpen },\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\n if (!targetId) {\n return;\n }\n\n const $target = this.querySelector(`#${CSS.escape(targetId)}`);\n\n if (!$target) {\n return;\n }\n\n const wasOpen = this.open;\n\n if (this._controlledOpen === undefined) {\n this._uncontrolledOpen = true;\n this._applyOpen(true);\n this._reflectOpen(true);\n } else {\n this.dispatchEvent(\n new CustomEvent<RCDisclosureToggleEvent>(TOGGLE_EVENT, {\n bubbles: true,\n composed: true,\n detail: { open: true },\n }),\n );\n }\n\n if (!this.open) {\n return;\n }\n\n if (wasOpen) {\n return;\n }\n\n cancelAnimationFrame(this._scrollFrame);\n\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","requestedOpen","value","name","oldValue","newValue","$details","open","suppressToggle","targetId","wasOpen"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rc-disclosure.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Light-DOM base styles for the disclosure panel recipe.
|
|
3
|
+
*
|
|
4
|
+
* `rc-disclosure` and `rc-accordion` coordinate consumer-authored native
|
|
5
|
+
* `<details>` elements that stay in light DOM, so `::slotted()` cannot reach the
|
|
6
|
+
* `<summary>`, the marker, the content children, or `::details-content`. This
|
|
7
|
+
* installs one structural stylesheet per containing `Document` or `ShadowRoot`,
|
|
8
|
+
* following the same pattern as `rc-button` and `rc-listbox`.
|
|
9
|
+
*
|
|
10
|
+
* One recipe serves both supported child forms: a `<details>` directly inside
|
|
11
|
+
* `rc-accordion`, and one wrapped in `rc-disclosure`. Themes map their tokens to
|
|
12
|
+
* these properties rather than re-selecting the native elements.
|
|
13
|
+
*
|
|
14
|
+
* Defaults stay close to what a user agent would render on its own, so an
|
|
15
|
+
* unthemed disclosure keeps native behavior and no theme is required for the
|
|
16
|
+
* component to work. In particular `--rc-disclosure-duration` defaults to `0ms`:
|
|
17
|
+
* a disclosure snaps open the way the platform does until a theme opts into
|
|
18
|
+
* motion.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DISCLOSURE_BASE_CSS: string;
|
|
21
|
+
/** Installs the shared disclosure panel styles once per containing root. */
|
|
22
|
+
export declare function ensureDisclosureBaseStyles(root: Document | ShadowRoot): void;
|
|
@@ -23,6 +23,36 @@ declare global {
|
|
|
23
23
|
*
|
|
24
24
|
* @attr open - Controlled open state mirrored to the child `<details>`.
|
|
25
25
|
* @attr default-open - Initial open state for uncontrolled usage.
|
|
26
|
+
*
|
|
27
|
+
* @cssprop [--rc-disclosure-border=0] - Panel border.
|
|
28
|
+
* @cssprop [--rc-disclosure-radius=0] - Panel corner radius.
|
|
29
|
+
* @cssprop [--rc-disclosure-background=transparent] - Panel background while closed.
|
|
30
|
+
* @cssprop [--rc-disclosure-color=inherit] - Panel foreground.
|
|
31
|
+
* @cssprop [--rc-disclosure-open-background] - Panel background while open. Defers to
|
|
32
|
+
* `--rc-disclosure-background` when unset.
|
|
33
|
+
* @cssprop [--rc-disclosure-open-shadow=none] - Panel shadow while open.
|
|
34
|
+
* @cssprop [--rc-disclosure-summary-min-block-size=0] - Summary minimum block size. Set this to
|
|
35
|
+
* at least `3rem` for a comfortable touch target.
|
|
36
|
+
* @cssprop [--rc-disclosure-summary-padding-block=0] - Summary block padding.
|
|
37
|
+
* @cssprop [--rc-disclosure-summary-padding-inline=0] - Summary inline padding.
|
|
38
|
+
* @cssprop [--rc-disclosure-summary-gap=0] - Summary gap, for a theme that lays the summary out
|
|
39
|
+
* as a grid or flex container.
|
|
40
|
+
* @cssprop [--rc-disclosure-summary-color=inherit] - Summary foreground.
|
|
41
|
+
* @cssprop [--rc-disclosure-summary-font=inherit] - Summary font shorthand.
|
|
42
|
+
* @cssprop [--rc-disclosure-summary-marker-color=currentColor] - Native disclosure marker color.
|
|
43
|
+
* A theme that replaces the marker with its own affordance should hide `::marker` itself.
|
|
44
|
+
* @cssprop [--rc-disclosure-summary-hover-background=transparent] - Summary hover background.
|
|
45
|
+
* @cssprop [--rc-disclosure-focus-ring=var(--rc-focus-ring, 2px solid Highlight)] - Summary
|
|
46
|
+
* focus-visible outline.
|
|
47
|
+
* @cssprop [--rc-disclosure-focus-ring-offset=0] - Summary focus-visible outline offset.
|
|
48
|
+
* @cssprop [--rc-disclosure-content-padding-block=0] - Content block padding.
|
|
49
|
+
* @cssprop [--rc-disclosure-content-padding-inline=0] - Content inline padding.
|
|
50
|
+
* @cssprop [--rc-disclosure-content-color=inherit] - Content foreground.
|
|
51
|
+
* @cssprop [--rc-disclosure-content-font=inherit] - Content font shorthand.
|
|
52
|
+
* @cssprop [--rc-disclosure-duration=0ms] - Open and close transition duration. Zero by default,
|
|
53
|
+
* so the panel snaps the way the platform does until a theme opts into motion. The animation
|
|
54
|
+
* runs on `::details-content` where that is supported and is skipped entirely where it is not.
|
|
55
|
+
* @cssprop [--rc-disclosure-easing=ease] - Open and close transition easing.
|
|
26
56
|
*/
|
|
27
57
|
export declare class RCDisclosure extends HTMLElement {
|
|
28
58
|
private _observer;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.7.0",
|
|
7
7
|
"description": "Disclosure wrapper for a native <details>/<summary> pair with controlled open state.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
"test:browser:chrome": "vitest --run --project=chromium",
|
|
44
44
|
"test:browser:firefox": "vitest --run --project=firefox"
|
|
45
45
|
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@rcarls/rc-common": "0.7.0"
|
|
48
|
+
},
|
|
46
49
|
"devDependencies": {
|
|
47
50
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
48
51
|
"@vitest/browser-playwright": "4.1.5",
|