astro-better-release-notes 0.1.0 → 0.2.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/README.md +79 -11
- package/ReleaseNotes.astro +52 -16
- package/ReleaseNotesItem.astro +6 -6
- package/package.json +1 -1
- package/style.css +205 -75
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ import 'astro-better-release-notes/style.css';
|
|
|
18
18
|
|
|
19
19
|
## Components
|
|
20
20
|
|
|
21
|
-
- `ReleaseNotes` - renders
|
|
21
|
+
- `ReleaseNotes` - renders a unified sticky header (version selector + category filter chips) and the full version list
|
|
22
22
|
- `ReleaseNotesItem` - a single categorized release note row (used inside MDX content)
|
|
23
|
-
- `ReleaseNotesSelector` - a
|
|
23
|
+
- `ReleaseNotesSelector` - a standalone version jump dropdown (for custom layouts that need it separately)
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
@@ -54,14 +54,12 @@ import { ReleaseNotesItem } from 'astro-better-release-notes';
|
|
|
54
54
|
|
|
55
55
|
### Page component
|
|
56
56
|
|
|
57
|
+
`ReleaseNotes` renders everything in one call: a sticky header containing the version selector and filter chips, then the full version list below.
|
|
58
|
+
|
|
57
59
|
```astro
|
|
58
60
|
---
|
|
59
61
|
import { getCollection, render } from 'astro:content';
|
|
60
|
-
import {
|
|
61
|
-
ReleaseNotes,
|
|
62
|
-
ReleaseNotesSelector,
|
|
63
|
-
DEFAULT_CATEGORIES,
|
|
64
|
-
} from 'astro-better-release-notes';
|
|
62
|
+
import { ReleaseNotes, DEFAULT_CATEGORIES } from 'astro-better-release-notes';
|
|
65
63
|
|
|
66
64
|
const allUpdates = await getCollection('releases');
|
|
67
65
|
const updates = allUpdates
|
|
@@ -78,10 +76,60 @@ const rendered = await Promise.all(
|
|
|
78
76
|
);
|
|
79
77
|
---
|
|
80
78
|
|
|
81
|
-
<ReleaseNotesSelector updates={rendered} />
|
|
82
79
|
<ReleaseNotes updates={rendered} categories={DEFAULT_CATEGORIES} />
|
|
83
80
|
```
|
|
84
81
|
|
|
82
|
+
### ReleaseNotes props
|
|
83
|
+
|
|
84
|
+
| Prop | Type | Default | Description |
|
|
85
|
+
|------|------|---------|-------------|
|
|
86
|
+
| `updates` | `ReleaseEntry[]` | required | Pre-rendered version entries |
|
|
87
|
+
| `categories` | `Category[]` | `DEFAULT_CATEGORIES` | Category definitions |
|
|
88
|
+
| `components` | `Record<string, any>` | `{}` | Component overrides (e.g. custom `ReleaseNotesItem`) |
|
|
89
|
+
| `showSelector` | `boolean` | `true` | Set `false` to hide the version jump dropdown |
|
|
90
|
+
|
|
91
|
+
### Sticky offset and scroll margins
|
|
92
|
+
|
|
93
|
+
Two CSS custom properties control the positioning:
|
|
94
|
+
|
|
95
|
+
`--release-notes-top` — how far the sticky header sits from the viewport top (should match your site's fixed nav height). Default: `3.5rem`.
|
|
96
|
+
|
|
97
|
+
`--release-notes-scroll-margin` — the `scroll-margin-top` applied to both version articles and individual release note rows when navigating via anchor links. Should be at least as large as your total sticky height (nav + release-notes sticky header). Default: `5rem`.
|
|
98
|
+
|
|
99
|
+
```css
|
|
100
|
+
/* in your root layout or global CSS */
|
|
101
|
+
html {
|
|
102
|
+
--release-notes-top: 56px;
|
|
103
|
+
--release-notes-scroll-margin: 6rem; /* nav + sticky header height */
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@media (min-width: 1024px) {
|
|
107
|
+
html {
|
|
108
|
+
--release-notes-top: 80px;
|
|
109
|
+
--release-notes-scroll-margin: 11rem;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Set both variables on `html` or any ancestor of `.release-container`.
|
|
115
|
+
|
|
116
|
+
### Link colors
|
|
117
|
+
|
|
118
|
+
The github issue links and category badge hover colors are configurable:
|
|
119
|
+
|
|
120
|
+
| Variable | Default | Description |
|
|
121
|
+
|----------|---------|-------------|
|
|
122
|
+
| `--release-notes-link-color` | `#4338ca` (indigo-700) | Issue link color |
|
|
123
|
+
| `--release-notes-link-hover-color` | `#9a3412` (orange-800) | Hover color for links and badge |
|
|
124
|
+
| `--release-notes-link-color-dark` | `#818cf8` (indigo-400) | Dark mode link color |
|
|
125
|
+
| `--release-notes-link-hover-color-dark` | `#fed7aa` (orange-200) | Dark mode hover color |
|
|
126
|
+
|
|
127
|
+
### Mobile filter behavior
|
|
128
|
+
|
|
129
|
+
On narrow screens the category filter chips are hidden behind a "Filter" toggle button that sits next to the version selector. Tapping it expands the chips below the selector row. When any filter is active, the button changes color as a visual indicator.
|
|
130
|
+
|
|
131
|
+
On screens 768px and wider, the chips are always visible.
|
|
132
|
+
|
|
85
133
|
## Custom categories
|
|
86
134
|
|
|
87
135
|
Pass a `categories` array to `ReleaseNotes` to define your own set:
|
|
@@ -131,8 +179,6 @@ Note: for the `components` injection to work with categories, you also need to p
|
|
|
131
179
|
import { getCategoryColor, getCategoryLabel, DEFAULT_CATEGORIES } from 'astro-better-release-notes';
|
|
132
180
|
```
|
|
133
181
|
|
|
134
|
-
Or provide these values in your own wrapper by computing them from your category list.
|
|
135
|
-
|
|
136
182
|
## ReleaseNotesItem props
|
|
137
183
|
|
|
138
184
|
| Prop | Type | Description |
|
|
@@ -153,6 +199,28 @@ Or provide these values in your own wrapper by computing them from your category
|
|
|
153
199
|
|
|
154
200
|
`ReleaseNotes.astro` does not automatically inject `categoryColor`/`categoryLabel` into the MDX-rendered items -- those props come from the MDX markup. To automate this, create a wrapper that looks up the category in your list and injects the values, then pass it via `components`.
|
|
155
201
|
|
|
202
|
+
## Standalone ReleaseNotesSelector
|
|
203
|
+
|
|
204
|
+
`ReleaseNotesSelector` is available as a standalone component for custom layouts that need the version dropdown without the rest of the notes. It is not sticky by default; wrap it in your own sticky container if needed.
|
|
205
|
+
|
|
206
|
+
```astro
|
|
207
|
+
import { ReleaseNotesSelector } from 'astro-better-release-notes';
|
|
208
|
+
---
|
|
209
|
+
<div style="position: sticky; top: 56px;">
|
|
210
|
+
<ReleaseNotesSelector {updates} />
|
|
211
|
+
</div>
|
|
212
|
+
```
|
|
213
|
+
|
|
156
214
|
## Dark mode
|
|
157
215
|
|
|
158
|
-
The stylesheet
|
|
216
|
+
The stylesheet uses a `.dark` ancestor class (compatible with Tailwind's `darkMode: 'class'`). To also enable automatic OS-based dark mode, add to your project CSS:
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
@media (prefers-color-scheme: dark) {
|
|
220
|
+
html:not([data-theme="light"]) {
|
|
221
|
+
/* copy the .dark rules you need, or add the .dark class via JS */
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Most Tailwind setups initialize the `.dark` class from OS preference on first load, so no extra CSS is needed.
|
package/ReleaseNotes.astro
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import ReleaseNotesItem from './ReleaseNotesItem.astro';
|
|
3
|
+
import ReleaseNotesSelector from './ReleaseNotesSelector.astro';
|
|
3
4
|
|
|
4
5
|
export interface Category {
|
|
5
6
|
id: string;
|
|
@@ -8,14 +9,14 @@ export interface Category {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export const DEFAULT_CATEGORIES: Category[] = [
|
|
11
|
-
{ id: 'new-feature', label: 'New Feature', color: '#16a34a' },
|
|
12
|
-
{ id: 'enhancement', label: 'Enhancement', color: '#2563eb' },
|
|
13
|
-
{ id: 'fix', label: 'Fix', color: '#d97706' },
|
|
14
|
-
{ id: 'security', label: 'Security', color: '#566f98' },
|
|
15
|
-
{ id: 'deprecated', label: 'Deprecated', color: '#ffcc48' },
|
|
16
|
-
{ id: 'breaking-change', label: 'Breaking Change', color: '#aaaa33' },
|
|
17
|
-
{ id: 'known-issue', label: 'Known Issue', color: '#bb4448' },
|
|
18
|
-
{ id: 'internal', label: 'Internal', color: '#71717a' },
|
|
12
|
+
{ id: 'new-feature', label: 'New Feature', color: 'var(--rn-color-new-feature, #16a34a)' },
|
|
13
|
+
{ id: 'enhancement', label: 'Enhancement', color: 'var(--rn-color-enhancement, #2563eb)' },
|
|
14
|
+
{ id: 'fix', label: 'Fix', color: 'var(--rn-color-fix, #d97706)' },
|
|
15
|
+
{ id: 'security', label: 'Security', color: 'var(--rn-color-security, #566f98)' },
|
|
16
|
+
{ id: 'deprecated', label: 'Deprecated', color: 'var(--rn-color-deprecated, #ffcc48)' },
|
|
17
|
+
{ id: 'breaking-change', label: 'Breaking Change', color: 'var(--rn-color-breaking-change, #aaaa33)' },
|
|
18
|
+
{ id: 'known-issue', label: 'Known Issue', color: 'var(--rn-color-known-issue, #bb4448)' },
|
|
19
|
+
{ id: 'internal', label: 'Internal', color: 'var(--rn-color-internal, #71717a)' },
|
|
19
20
|
];
|
|
20
21
|
|
|
21
22
|
export const getCategoryColor = (id: string, categories: Category[]) =>
|
|
@@ -41,12 +42,15 @@ export interface Props {
|
|
|
41
42
|
categories?: Category[];
|
|
42
43
|
// pass { ReleaseNotesItem: YourWrapper } to inject a custom item component
|
|
43
44
|
components?: Record<string, any>;
|
|
45
|
+
// set false to hide the version jump dropdown
|
|
46
|
+
showSelector?: boolean;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
const {
|
|
47
50
|
updates,
|
|
48
51
|
categories = DEFAULT_CATEGORIES,
|
|
49
52
|
components: extraComponents = {},
|
|
53
|
+
showSelector = true,
|
|
50
54
|
} = Astro.props as Props;
|
|
51
55
|
|
|
52
56
|
const mergedComponents = { ReleaseNotesItem, ...extraComponents };
|
|
@@ -63,14 +67,31 @@ const filterCSS = [
|
|
|
63
67
|
<Fragment set:html={`<style>${filterCSS}</style>`} />
|
|
64
68
|
|
|
65
69
|
<div class="release-container">
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
<div class="release-sticky-header">
|
|
71
|
+
{showSelector && <ReleaseNotesSelector {updates} />}
|
|
72
|
+
|
|
73
|
+
<button
|
|
74
|
+
class="filter-toggle-btn"
|
|
75
|
+
aria-expanded="false"
|
|
76
|
+
aria-controls="release-notes-filters"
|
|
77
|
+
>
|
|
78
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 16 16" aria-hidden="true" fill="currentColor">
|
|
79
|
+
<path d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
|
|
80
|
+
</svg>
|
|
81
|
+
Filter
|
|
82
|
+
</button>
|
|
83
|
+
|
|
84
|
+
<nav id="release-notes-filters" class="filter-controls" aria-label="Filter release notes by category">
|
|
85
|
+
{categories.map(cat => (
|
|
86
|
+
<label class="filter-chip" style={`--cat-color: ${cat.color}`}>
|
|
87
|
+
<input type="checkbox" id={`toggle-${cat.id}`} class="filter-input" aria-label={`Show ${cat.label}`} />
|
|
88
|
+
<span aria-hidden="true">{cat.label}</span>
|
|
89
|
+
</label>
|
|
90
|
+
))}
|
|
91
|
+
</nav>
|
|
92
|
+
|
|
93
|
+
<noscript><style>@media (max-width: 1023px) { #release-notes-filters { display: flex !important; flex-wrap: wrap; } .filter-toggle-btn { display: none !important; } }</style></noscript>
|
|
94
|
+
</div>
|
|
74
95
|
|
|
75
96
|
<div class="version-list">
|
|
76
97
|
{updates.map((item) => {
|
|
@@ -96,3 +117,18 @@ const filterCSS = [
|
|
|
96
117
|
})}
|
|
97
118
|
</div>
|
|
98
119
|
</div>
|
|
120
|
+
|
|
121
|
+
<script is:inline>
|
|
122
|
+
const initFilterToggle = () => {
|
|
123
|
+
const btn = document.querySelector('.filter-toggle-btn');
|
|
124
|
+
const nav = document.getElementById('release-notes-filters');
|
|
125
|
+
if (!btn || !nav) return;
|
|
126
|
+
btn.addEventListener('click', () => {
|
|
127
|
+
const expanded = btn.getAttribute('aria-expanded') === 'true';
|
|
128
|
+
btn.setAttribute('aria-expanded', String(!expanded));
|
|
129
|
+
nav.classList.toggle('is-open', !expanded);
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
document.addEventListener('DOMContentLoaded', initFilterToggle);
|
|
133
|
+
document.addEventListener('astro:page-load', initFilterToggle);
|
|
134
|
+
</script>
|
package/ReleaseNotesItem.astro
CHANGED
|
@@ -11,7 +11,7 @@ export interface Props {
|
|
|
11
11
|
// base URL for issue links, e.g. "https://github.com/org/repo/issues/"
|
|
12
12
|
// if omitted, issue numbers are shown as plain text
|
|
13
13
|
issueBaseUrl?: string;
|
|
14
|
-
// color for this item's badge; if omitted,
|
|
14
|
+
// color for this item's badge; if omitted, CSS handles it via --rn-color-{category}
|
|
15
15
|
categoryColor?: string;
|
|
16
16
|
// human-readable category label; if omitted, generated from id
|
|
17
17
|
categoryLabel?: string;
|
|
@@ -27,7 +27,7 @@ const {
|
|
|
27
27
|
resolvedIn,
|
|
28
28
|
viaIssue,
|
|
29
29
|
issueBaseUrl = '',
|
|
30
|
-
categoryColor
|
|
30
|
+
categoryColor,
|
|
31
31
|
categoryLabel,
|
|
32
32
|
} = Astro.props as Props;
|
|
33
33
|
|
|
@@ -63,11 +63,11 @@ const rowId = baseId ? `${baseId}--${contentSlug}` : contentSlug;
|
|
|
63
63
|
id={rowId}
|
|
64
64
|
class="issue-row"
|
|
65
65
|
data-category={category}
|
|
66
|
-
style={`--cat-color: ${categoryColor}`}
|
|
66
|
+
style={categoryColor ? `--cat-color: ${categoryColor}` : undefined}
|
|
67
67
|
>
|
|
68
68
|
<a
|
|
69
69
|
href={`#${rowId}`}
|
|
70
|
-
class="issue-badge"
|
|
70
|
+
class="issue-badge not-prose"
|
|
71
71
|
aria-label={`${label} - permalink to this release note`}
|
|
72
72
|
>
|
|
73
73
|
{label}
|
|
@@ -106,12 +106,12 @@ const rowId = baseId ? `${baseId}--${contentSlug}` : contentSlug;
|
|
|
106
106
|
|
|
107
107
|
{issue && (
|
|
108
108
|
issueBaseUrl
|
|
109
|
-
? <a class="github-link" target="_blank" rel="noopener noreferrer" href={`${issueBaseUrl}${issue}`}>#{issue}</a>
|
|
109
|
+
? <a class="github-link not-prose" target="_blank" rel="noopener noreferrer" href={`${issueBaseUrl}${issue}`}>#{issue}</a>
|
|
110
110
|
: <span class="github-link">#{issue}</span>
|
|
111
111
|
)}
|
|
112
112
|
{bonusIssue && (
|
|
113
113
|
issueBaseUrl
|
|
114
|
-
? <a class="github-link" target="_blank" rel="noopener noreferrer" href={`${issueBaseUrl}${bonusIssue}`}>#{bonusIssue}</a>
|
|
114
|
+
? <a class="github-link not-prose" target="_blank" rel="noopener noreferrer" href={`${issueBaseUrl}${bonusIssue}`}>#{bonusIssue}</a>
|
|
115
115
|
: <span class="github-link">#{bonusIssue}</span>
|
|
116
116
|
)}
|
|
117
117
|
</div>
|
package/package.json
CHANGED
package/style.css
CHANGED
|
@@ -4,20 +4,164 @@
|
|
|
4
4
|
Import this in your project root layout to enable release notes styles.
|
|
5
5
|
No external dependencies -- no Tailwind, no framework.
|
|
6
6
|
|
|
7
|
-
Dark mode:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Category colors
|
|
7
|
+
Dark mode: uses a .dark ancestor class (e.g. Tailwind's darkMode: 'class').
|
|
8
|
+
See README for enabling OS-based dark mode without a class toggle.
|
|
9
|
+
|
|
10
|
+
Category colors: set --rn-color-{id} on :root / .dark to override per-category
|
|
11
|
+
badge and chip colors without touching component code. E.g.:
|
|
12
|
+
:root { --rn-color-enhancement: #7c3aed; }
|
|
13
|
+
.dark { --rn-color-enhancement: #fb923c; }
|
|
14
|
+
|
|
15
|
+
Built-in category defaults (CSS fallback, also used by DEFAULT_CATEGORIES):
|
|
16
|
+
--rn-color-new-feature: #16a34a
|
|
17
|
+
--rn-color-enhancement: #2563eb
|
|
18
|
+
--rn-color-fix: #d97706
|
|
19
|
+
--rn-color-security: #566f98
|
|
20
|
+
--rn-color-deprecated: #ffcc48
|
|
21
|
+
--rn-color-breaking-change: #aaaa33
|
|
22
|
+
--rn-color-known-issue: #bb4448
|
|
23
|
+
--rn-color-internal: #71717a
|
|
24
|
+
|
|
25
|
+
Sticky offset configuration:
|
|
26
|
+
Set --release-notes-top on :root (or any ancestor of .release-sticky-header)
|
|
27
|
+
to match your site's fixed navigation height. Defaults to 3.5rem (56px).
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
:root { --release-notes-top: 57px; }
|
|
31
|
+
@media (min-width: 1024px) { :root { --release-notes-top: 80px; } }
|
|
11
32
|
*/
|
|
12
33
|
|
|
34
|
+
/* ---------------------------------------------------------------
|
|
35
|
+
Sticky header (selector + filter toggle + chips)
|
|
36
|
+
--------------------------------------------------------------- */
|
|
37
|
+
|
|
38
|
+
.release-sticky-header {
|
|
39
|
+
position: sticky;
|
|
40
|
+
top: var(--release-notes-top, 3.5rem);
|
|
41
|
+
z-index: 11;
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
align-items: center;
|
|
45
|
+
gap: 0.5rem;
|
|
46
|
+
padding: 0.5rem 0;
|
|
47
|
+
background-color: var(--rn-bg, white);
|
|
48
|
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
|
49
|
+
margin-bottom: 0.5rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.dark .release-sticky-header {
|
|
53
|
+
background-color: var(--rn-bg, #0f172a);
|
|
54
|
+
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* ---------------------------------------------------------------
|
|
58
|
+
Version selector (jump dropdown)
|
|
59
|
+
--------------------------------------------------------------- */
|
|
60
|
+
|
|
61
|
+
.release-selector {
|
|
62
|
+
flex: 1;
|
|
63
|
+
min-width: 200px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.release-selector-select {
|
|
67
|
+
width: 100%;
|
|
68
|
+
height: 2.5rem;
|
|
69
|
+
padding: 0 0.5rem;
|
|
70
|
+
border-radius: 6px;
|
|
71
|
+
border: 2px solid var(--rn-border, #d1d5db);
|
|
72
|
+
background-color: var(--rn-input-bg, #f3f4f6);
|
|
73
|
+
color: var(--rn-text, #111827);
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.release-selector-select:focus {
|
|
78
|
+
outline: 2px solid var(--rn-focus, #6366f1);
|
|
79
|
+
outline-offset: 1px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.dark .release-selector-select {
|
|
83
|
+
border-color: var(--rn-border, #4b5563);
|
|
84
|
+
background-color: var(--rn-input-bg, #1e293b);
|
|
85
|
+
color: var(--rn-text, #cbd5e1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* ---------------------------------------------------------------
|
|
89
|
+
Filter toggle button (mobile only)
|
|
90
|
+
--------------------------------------------------------------- */
|
|
91
|
+
|
|
92
|
+
.filter-toggle-btn {
|
|
93
|
+
flex: 0 0 auto;
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
gap: 0.375rem;
|
|
97
|
+
padding: 0.4375rem 0.75rem;
|
|
98
|
+
height: 2.5rem;
|
|
99
|
+
font-size: 0.875rem;
|
|
100
|
+
font-weight: 500;
|
|
101
|
+
border-radius: 6px;
|
|
102
|
+
border: 2px solid var(--rn-border, #d1d5db);
|
|
103
|
+
background-color: var(--rn-input-bg, #f3f4f6);
|
|
104
|
+
color: var(--rn-text-muted, #374151);
|
|
105
|
+
cursor: pointer;
|
|
106
|
+
white-space: nowrap;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.filter-toggle-btn:focus {
|
|
110
|
+
outline: 2px solid var(--rn-focus, #6366f1);
|
|
111
|
+
outline-offset: 1px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.dark .filter-toggle-btn {
|
|
115
|
+
border-color: var(--rn-border, #4b5563);
|
|
116
|
+
background-color: var(--rn-input-bg, #1e293b);
|
|
117
|
+
color: var(--rn-text, #cbd5e1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* indicate active filters */
|
|
121
|
+
.release-container:has(.filter-input:checked) .filter-toggle-btn {
|
|
122
|
+
border-color: var(--rn-focus, #6366f1);
|
|
123
|
+
background-color: color-mix(in srgb, var(--rn-focus, #6366f1) 12%, transparent);
|
|
124
|
+
color: var(--rn-focus, #6366f1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.dark .release-container:has(.filter-input:checked) .filter-toggle-btn {
|
|
128
|
+
border-color: var(--rn-focus, #818cf8);
|
|
129
|
+
color: var(--rn-focus, #818cf8);
|
|
130
|
+
background-color: color-mix(in srgb, var(--rn-focus, #818cf8) 15%, transparent);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@media (min-width: 1024px) {
|
|
134
|
+
.filter-toggle-btn {
|
|
135
|
+
display: none;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
13
139
|
/* ---------------------------------------------------------------
|
|
14
140
|
Filter controls (category chips)
|
|
15
141
|
--------------------------------------------------------------- */
|
|
16
142
|
|
|
143
|
+
/* hidden on mobile by default; shown via .is-open (JS) or desktop breakpoint */
|
|
144
|
+
@media (max-width: 1023px) {
|
|
145
|
+
.filter-controls {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.filter-controls.is-open {
|
|
150
|
+
display: flex;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@media (min-width: 1024px) {
|
|
155
|
+
.filter-controls {
|
|
156
|
+
display: flex;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
17
160
|
.filter-controls {
|
|
18
|
-
|
|
161
|
+
flex: 0 0 100%;
|
|
19
162
|
flex-wrap: wrap;
|
|
20
163
|
gap: 0.75rem;
|
|
164
|
+
padding: 0.25rem 0;
|
|
21
165
|
}
|
|
22
166
|
|
|
23
167
|
.filter-input {
|
|
@@ -33,35 +177,21 @@
|
|
|
33
177
|
transition: filter 0.15s ease-in-out;
|
|
34
178
|
opacity: 0.7;
|
|
35
179
|
filter: grayscale(100%);
|
|
36
|
-
color: #334155;
|
|
37
|
-
background-color: #f1f5f9;
|
|
38
|
-
border: 1px solid #cbd5e1;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@media (prefers-color-scheme: dark) {
|
|
42
|
-
.filter-chip {
|
|
43
|
-
color: #cbd5e1;
|
|
44
|
-
background-color: #1e293b;
|
|
45
|
-
border-color: #475569;
|
|
46
|
-
}
|
|
180
|
+
color: var(--rn-chip-color, #334155);
|
|
181
|
+
background-color: var(--rn-chip-bg, #f1f5f9);
|
|
182
|
+
border: 1px solid var(--rn-chip-border, #cbd5e1);
|
|
47
183
|
}
|
|
48
184
|
|
|
49
185
|
.dark .filter-chip {
|
|
50
|
-
color: #cbd5e1;
|
|
51
|
-
background-color: #1e293b;
|
|
52
|
-
border-color: #475569;
|
|
186
|
+
color: var(--rn-chip-color, #cbd5e1);
|
|
187
|
+
background-color: var(--rn-chip-bg, #1e293b);
|
|
188
|
+
border-color: var(--rn-chip-border, #475569);
|
|
53
189
|
}
|
|
54
190
|
|
|
55
191
|
.filter-chip:hover {
|
|
56
192
|
filter: grayscale(100%) brightness(0.95);
|
|
57
193
|
}
|
|
58
194
|
|
|
59
|
-
@media (prefers-color-scheme: dark) {
|
|
60
|
-
.filter-chip:hover {
|
|
61
|
-
filter: grayscale(100%) brightness(1.1);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
195
|
.dark .filter-chip:hover {
|
|
66
196
|
filter: grayscale(100%) brightness(1.1);
|
|
67
197
|
}
|
|
@@ -74,6 +204,20 @@
|
|
|
74
204
|
color: #fff !important;
|
|
75
205
|
}
|
|
76
206
|
|
|
207
|
+
/* ---------------------------------------------------------------
|
|
208
|
+
Release note rows: per-category --cat-color defaults
|
|
209
|
+
These are overridden when the caller sets --cat-color inline.
|
|
210
|
+
--------------------------------------------------------------- */
|
|
211
|
+
|
|
212
|
+
.issue-row[data-category="new-feature"] { --cat-color: var(--rn-color-new-feature, #16a34a); }
|
|
213
|
+
.issue-row[data-category="enhancement"] { --cat-color: var(--rn-color-enhancement, #2563eb); }
|
|
214
|
+
.issue-row[data-category="fix"] { --cat-color: var(--rn-color-fix, #d97706); }
|
|
215
|
+
.issue-row[data-category="security"] { --cat-color: var(--rn-color-security, #566f98); }
|
|
216
|
+
.issue-row[data-category="deprecated"] { --cat-color: var(--rn-color-deprecated, #ffcc48); }
|
|
217
|
+
.issue-row[data-category="breaking-change"] { --cat-color: var(--rn-color-breaking-change, #aaaa33); }
|
|
218
|
+
.issue-row[data-category="known-issue"] { --cat-color: var(--rn-color-known-issue, #bb4448); }
|
|
219
|
+
.issue-row[data-category="internal"] { --cat-color: var(--rn-color-internal, #71717a); }
|
|
220
|
+
|
|
77
221
|
/* ---------------------------------------------------------------
|
|
78
222
|
Release note rows
|
|
79
223
|
Note: per-category show/hide rules are generated dynamically
|
|
@@ -89,7 +233,7 @@
|
|
|
89
233
|
transition: border-color 0.2s;
|
|
90
234
|
padding: 6px 8px;
|
|
91
235
|
border: 2px solid transparent;
|
|
92
|
-
scroll-margin-top: 5rem;
|
|
236
|
+
scroll-margin-top: var(--release-notes-scroll-margin, 5rem);
|
|
93
237
|
}
|
|
94
238
|
|
|
95
239
|
@media (min-width: 768px) {
|
|
@@ -114,15 +258,22 @@
|
|
|
114
258
|
text-decoration: none;
|
|
115
259
|
cursor: pointer;
|
|
116
260
|
user-select: none;
|
|
117
|
-
transition: transform 0.15s ease-out;
|
|
261
|
+
transition: transform 0.15s ease-out, color 0.15s ease-out;
|
|
118
262
|
transform-origin: left center;
|
|
119
263
|
background-color: color-mix(in srgb, var(--cat-color) 13%, transparent);
|
|
120
264
|
color: var(--cat-color);
|
|
121
265
|
border: 1px solid color-mix(in srgb, var(--cat-color) 27%, transparent);
|
|
122
266
|
}
|
|
123
267
|
|
|
124
|
-
.issue-badge:hover {
|
|
268
|
+
.issue-badge:hover {
|
|
269
|
+
transform: scale(1.05);
|
|
270
|
+
color: var(--release-notes-link-hover-color, #9a3412);
|
|
271
|
+
text-decoration: none;
|
|
272
|
+
}
|
|
125
273
|
.issue-badge:active { transform: scale(0.95); }
|
|
274
|
+
.dark .issue-badge:hover {
|
|
275
|
+
color: var(--release-notes-link-hover-color-dark, #fed7aa);
|
|
276
|
+
}
|
|
126
277
|
|
|
127
278
|
.issue-content {
|
|
128
279
|
flex: 1;
|
|
@@ -145,29 +296,35 @@
|
|
|
145
296
|
color: #475569;
|
|
146
297
|
}
|
|
147
298
|
|
|
148
|
-
@media (prefers-color-scheme: dark) {
|
|
149
|
-
.rni-thanks { color: #94a3b8; }
|
|
150
|
-
}
|
|
151
|
-
|
|
152
299
|
.dark .rni-thanks { color: #94a3b8; }
|
|
153
300
|
|
|
154
301
|
.github-link {
|
|
155
302
|
flex-shrink: 0;
|
|
156
303
|
font-size: 0.875rem;
|
|
157
304
|
text-decoration: none;
|
|
158
|
-
|
|
159
|
-
|
|
305
|
+
color: var(--release-notes-link-color, #4338ca);
|
|
306
|
+
transition: color 0.15s;
|
|
160
307
|
}
|
|
161
308
|
|
|
162
|
-
.github-link:hover {
|
|
309
|
+
.github-link:hover {
|
|
310
|
+
color: var(--release-notes-link-hover-color, #9a3412);
|
|
311
|
+
text-decoration: none;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.dark .github-link {
|
|
315
|
+
color: var(--release-notes-link-color-dark, #818cf8);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.dark .github-link:hover {
|
|
319
|
+
color: var(--release-notes-link-hover-color-dark, #fed7aa);
|
|
320
|
+
}
|
|
163
321
|
|
|
164
322
|
/* ---------------------------------------------------------------
|
|
165
323
|
Version articles
|
|
166
324
|
--------------------------------------------------------------- */
|
|
167
325
|
|
|
168
326
|
.version {
|
|
169
|
-
|
|
170
|
-
contain-intrinsic-size: 0 800px;
|
|
327
|
+
scroll-margin-top: var(--release-notes-scroll-margin, 5rem);
|
|
171
328
|
}
|
|
172
329
|
|
|
173
330
|
.version-header {
|
|
@@ -181,10 +338,6 @@
|
|
|
181
338
|
border-bottom: 1px solid #e2e8f0;
|
|
182
339
|
}
|
|
183
340
|
|
|
184
|
-
@media (prefers-color-scheme: dark) {
|
|
185
|
-
.version-header { border-bottom-color: #1e293b; }
|
|
186
|
-
}
|
|
187
|
-
|
|
188
341
|
.dark .version-header { border-bottom-color: #1e293b; }
|
|
189
342
|
|
|
190
343
|
.version-date {
|
|
@@ -193,42 +346,19 @@
|
|
|
193
346
|
}
|
|
194
347
|
|
|
195
348
|
/* ---------------------------------------------------------------
|
|
196
|
-
Version
|
|
349
|
+
Version anchor links (# permalink)
|
|
197
350
|
--------------------------------------------------------------- */
|
|
198
351
|
|
|
199
|
-
.release-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
.release-selector-select {
|
|
207
|
-
width: 100%;
|
|
208
|
-
height: 2.5rem;
|
|
209
|
-
padding: 0 0.5rem;
|
|
210
|
-
border-radius: 6px;
|
|
211
|
-
border: 2px solid #d1d5db;
|
|
212
|
-
background-color: #f3f4f6;
|
|
213
|
-
color: #111827;
|
|
214
|
-
cursor: pointer;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.release-selector-select:focus {
|
|
218
|
-
outline: 2px solid #6366f1;
|
|
219
|
-
outline-offset: 1px;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
@media (prefers-color-scheme: dark) {
|
|
223
|
-
.release-selector-select {
|
|
224
|
-
border-color: #4b5563;
|
|
225
|
-
background-color: #1e293b;
|
|
226
|
-
color: #cbd5e1;
|
|
227
|
-
}
|
|
352
|
+
.release-note .anchor-link {
|
|
353
|
+
opacity: 0;
|
|
354
|
+
text-decoration: none;
|
|
355
|
+
border: none;
|
|
356
|
+
margin-left: 0.5rem;
|
|
357
|
+
color: inherit;
|
|
358
|
+
transition: opacity 0.15s ease;
|
|
228
359
|
}
|
|
229
360
|
|
|
230
|
-
.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
color: #cbd5e1;
|
|
361
|
+
.release-note:hover .anchor-link,
|
|
362
|
+
.release-note .anchor-link:focus-visible {
|
|
363
|
+
opacity: 1;
|
|
234
364
|
}
|