@brillout/docpress 0.16.27 → 0.16.29
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/code-blocks/components/ChoiceGroup.css +122 -12
- package/code-blocks/components/ChoiceGroup.tsx +82 -15
- package/code-blocks/hooks/useSelectedChoice.ts +1 -1
- package/dist/vite.config.js +1 -2
- package/docsearch/DocSearchInstall.tsx +0 -3
- package/package.json +7 -7
- package/vite.config.ts +1 -2
- package/AGENTS.md +0 -30
|
@@ -2,29 +2,139 @@
|
|
|
2
2
|
position: relative;
|
|
3
3
|
|
|
4
4
|
&:hover {
|
|
5
|
-
.select-
|
|
5
|
+
.select-container,
|
|
6
6
|
.copy-button {
|
|
7
7
|
opacity: 1;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/* layout */
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
12
|
+
--top-position: 10px;
|
|
13
|
+
--right-base: 42px;
|
|
14
|
+
--right-offset: 0px;
|
|
15
|
+
--border-color: hsl(0, 0%, 75%) hsl(0, 0%, 72%) hsl(0, 0%, 72%) hsl(0, 0%, 75%);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
.select-choice {
|
|
17
|
+
.select-container {
|
|
19
18
|
position: absolute;
|
|
19
|
+
background: #eee;
|
|
20
20
|
z-index: 3;
|
|
21
|
-
|
|
22
|
-
top: var(--
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
font-size: 13.3333px;
|
|
22
|
+
top: var(--top-position);
|
|
23
|
+
right: calc(var(--right-base) + (var(--right-offset)));
|
|
24
|
+
|
|
25
|
+
-webkit-user-select: none; /* Safari */
|
|
26
|
+
-moz-user-select: none; /* Firefox */
|
|
27
|
+
-ms-user-select: none; /* IE/Edge legacy */
|
|
28
|
+
user-select: none; /* Standard */
|
|
29
|
+
|
|
30
|
+
border-radius: 5px;
|
|
31
|
+
border-style: solid;
|
|
32
|
+
border-color: var(--border-color);
|
|
25
33
|
|
|
26
34
|
opacity: 0;
|
|
27
|
-
transition: opacity 0.5s ease-in-out
|
|
35
|
+
transition: opacity 0.5s ease-in-out;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.sliding-rectangle {
|
|
39
|
+
position: relative;
|
|
40
|
+
border-radius: 5px;
|
|
41
|
+
border-color: var(--border-color);
|
|
42
|
+
width: 100%;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
transition: top 180ms cubic-bezier(0.2, 0.9, 0.2, 1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.select-choice {
|
|
48
|
+
display: flex;
|
|
49
|
+
white-space: nowrap;
|
|
50
|
+
align-items: center;
|
|
51
|
+
flex-wrap: nowrap;
|
|
52
|
+
background: #fff;
|
|
53
|
+
padding: 0 3px 0 5px;
|
|
54
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
transition: background 120ms ease;
|
|
57
|
+
|
|
58
|
+
span {
|
|
59
|
+
flex: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&::after {
|
|
63
|
+
width: 15px;
|
|
64
|
+
text-align: end;
|
|
65
|
+
--animation-width: 2px;
|
|
66
|
+
position: relative;
|
|
67
|
+
padding-right: var(--animation-width);
|
|
68
|
+
padding-left: var(--animation-width);
|
|
69
|
+
font-size: 1.13em;
|
|
70
|
+
color: #666;
|
|
71
|
+
left: 0;
|
|
72
|
+
transition: left 500ms ease, opacity 150ms ease-in-out;
|
|
73
|
+
opacity: 0;
|
|
74
|
+
}
|
|
75
|
+
.sliding-rectangle:hover &:hover::after {
|
|
76
|
+
opacity: 1;
|
|
77
|
+
}
|
|
78
|
+
&[aria-selected='true'] {
|
|
79
|
+
&::after {
|
|
80
|
+
content: '»' !important;
|
|
81
|
+
opacity: 1;
|
|
82
|
+
}
|
|
83
|
+
.sliding-rectangle:hover &:not(:hover)::after {
|
|
84
|
+
opacity: 0;
|
|
85
|
+
}
|
|
86
|
+
&:hover::after {
|
|
87
|
+
left: var(--animation-width);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
&[aria-disabled='true'] {
|
|
91
|
+
&::after {
|
|
92
|
+
content: '⊘';
|
|
93
|
+
font-size: 1em;
|
|
94
|
+
left: 1px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
&:not([aria-selected='true']):not([aria-disabled='true']) {
|
|
98
|
+
&::after {
|
|
99
|
+
content: '«';
|
|
100
|
+
}
|
|
101
|
+
&:hover::after {
|
|
102
|
+
left: calc(-1 * var(--animation-width));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.select-container[aria-expanded='false'] {
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
border-width: 1px 2px 2px 1px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.select-container[aria-expanded='true'] {
|
|
113
|
+
overflow: visible;
|
|
114
|
+
border-width: 0;
|
|
115
|
+
|
|
116
|
+
.sliding-rectangle {
|
|
117
|
+
border-style: solid;
|
|
118
|
+
border-width: 1px 2px 2px 1px;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.select-choice:last-child {
|
|
123
|
+
border-bottom: none;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.select-choice:hover {
|
|
127
|
+
background: #f5f5f5;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.select-choice[aria-selected='true'] {
|
|
131
|
+
background: #eee;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.select-choice[aria-disabled='true'] {
|
|
135
|
+
color: #999;
|
|
136
|
+
cursor: default;
|
|
137
|
+
opacity: 0.8;
|
|
28
138
|
}
|
|
29
139
|
|
|
30
140
|
.hidden {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ChoiceGroup }
|
|
2
2
|
|
|
3
|
-
import React from 'react'
|
|
3
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
4
4
|
import { useSelectedChoice } from '../hooks/useSelectedChoice.js'
|
|
5
5
|
import { useRestoreScroll } from '../hooks/useRestoreScroll.js'
|
|
6
6
|
import { cls } from '../../utils/cls.js'
|
|
@@ -18,32 +18,99 @@ function ChoiceGroup({
|
|
|
18
18
|
choiceGroup,
|
|
19
19
|
lvl,
|
|
20
20
|
hide = false,
|
|
21
|
-
}: { children: React.ReactNode; choiceGroup: TChoiceGroup; lvl:
|
|
22
|
-
const
|
|
21
|
+
}: { children: React.ReactNode; choiceGroup: TChoiceGroup; lvl: string; hide: boolean }) {
|
|
22
|
+
const level = Number(lvl)
|
|
23
|
+
const { name: groupName, choices, default: defaultChoice, disabled: disabledChoices } = choiceGroup
|
|
24
|
+
// TODO/after-PR-merge rename useSelectedChoice useCurrentSelection
|
|
25
|
+
const [selectedChoice, setSelectedChoice] = useSelectedChoice(groupName, defaultChoice)
|
|
23
26
|
const prevPositionRef = useRestoreScroll([selectedChoice])
|
|
27
|
+
const choiceGroupRef = useRef<HTMLDivElement>(null)
|
|
28
|
+
const [rightOffset, setRightOffset] = useState(0)
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (level === 0 || !choiceGroupRef.current) return
|
|
32
|
+
const parentCustomSelect = choiceGroupRef.current.closest(`[data-lvl="${level - 1}"]`)!.lastElementChild!
|
|
33
|
+
const width = parentCustomSelect.getBoundingClientRect().width
|
|
34
|
+
|
|
35
|
+
setRightOffset(level * width + 2)
|
|
36
|
+
}, [])
|
|
37
|
+
|
|
38
|
+
const isDisabled = (choice: string) => disabledChoices.includes(choice)
|
|
39
|
+
const selectedIndex = choices.indexOf(selectedChoice)
|
|
40
|
+
|
|
41
|
+
const height = 25
|
|
42
|
+
const [expanded, setExpanded] = useState(false)
|
|
43
|
+
const rectTop = -selectedIndex * height
|
|
44
|
+
|
|
45
|
+
// Cycle to next option
|
|
46
|
+
const next = () => {
|
|
47
|
+
let nextIndex = selectedIndex
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < choices.length; i++) {
|
|
50
|
+
nextIndex = (nextIndex + 1) % choices.length
|
|
51
|
+
if (!isDisabled(choices[nextIndex]!)) {
|
|
52
|
+
setSelectedChoice(choices[nextIndex]!)
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
24
57
|
|
|
25
58
|
return (
|
|
26
|
-
<div data-choice-group={
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
value={selectedChoice}
|
|
30
|
-
onChange={onChange}
|
|
31
|
-
className={cls(['select-choice', hide && 'hidden'])}
|
|
32
|
-
style={{ '--lvl': lvl }}
|
|
33
|
-
>
|
|
59
|
+
<div ref={choiceGroupRef} data-choice-group={groupName} data-lvl={level} className="choice-group">
|
|
60
|
+
{/* Hidden select used to control choice visibility via CSS */}
|
|
61
|
+
<select name={`choicesFor-${groupName}`} value={selectedChoice} hidden disabled>
|
|
34
62
|
{choiceGroup.choices.map((choice, i) => (
|
|
35
|
-
<option key={i} value={choice}
|
|
63
|
+
<option key={i} value={choice}>
|
|
36
64
|
{choice}
|
|
37
65
|
</option>
|
|
38
66
|
))}
|
|
39
67
|
</select>
|
|
40
68
|
{children}
|
|
69
|
+
<div
|
|
70
|
+
id={`choicesFor-${groupName}`}
|
|
71
|
+
aria-haspopup="listbox"
|
|
72
|
+
aria-expanded={expanded}
|
|
73
|
+
className={cls(['select-container', (hide || isDisabled(selectedChoice)) && 'hidden'])}
|
|
74
|
+
style={{ height, '--right-offset': `${rightOffset}px` }}
|
|
75
|
+
onMouseEnter={() => setExpanded(true)}
|
|
76
|
+
onMouseLeave={() => setExpanded(false)}
|
|
77
|
+
onClick={() => {
|
|
78
|
+
if (!expanded) next()
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<div
|
|
82
|
+
aria-activedescendant={`choice-${selectedChoice}`}
|
|
83
|
+
role="listbox"
|
|
84
|
+
className="sliding-rectangle"
|
|
85
|
+
style={{ top: rectTop, height: choices.length * height }}
|
|
86
|
+
>
|
|
87
|
+
{choices.map((choice, i) => (
|
|
88
|
+
<div
|
|
89
|
+
id={choice}
|
|
90
|
+
key={i}
|
|
91
|
+
aria-selected={i === selectedIndex}
|
|
92
|
+
aria-disabled={isDisabled(choice)}
|
|
93
|
+
role="option"
|
|
94
|
+
className="select-choice"
|
|
95
|
+
style={{ height }}
|
|
96
|
+
onClick={handleOnClick}
|
|
97
|
+
>
|
|
98
|
+
<span>{choice}</span>
|
|
99
|
+
</div>
|
|
100
|
+
))}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
41
103
|
</div>
|
|
42
104
|
)
|
|
43
105
|
|
|
44
|
-
function
|
|
45
|
-
|
|
106
|
+
function handleOnClick(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
|
107
|
+
e.stopPropagation()
|
|
108
|
+
const el = e.currentTarget
|
|
46
109
|
prevPositionRef.current = { top: el.getBoundingClientRect().top, el }
|
|
47
|
-
|
|
110
|
+
if (el.ariaSelected === 'true') {
|
|
111
|
+
next()
|
|
112
|
+
} else if (el.ariaDisabled === 'false') {
|
|
113
|
+
setSelectedChoice(el.id)
|
|
114
|
+
}
|
|
48
115
|
}
|
|
49
116
|
}
|
|
@@ -25,7 +25,7 @@ function initializeChoiceGroup() {
|
|
|
25
25
|
const storageKey = `docpress:choice:${choiceGroupName}`
|
|
26
26
|
const selectedChoice = localStorage.getItem(storageKey)
|
|
27
27
|
if (selectedChoice) {
|
|
28
|
-
const selectEl = groupEl.querySelector<HTMLSelectElement>(
|
|
28
|
+
const selectEl = groupEl.querySelector<HTMLSelectElement>(`select[name="choicesFor-${choiceGroupName}"]`)!
|
|
29
29
|
const selectedIndex = [...selectEl.options].findIndex((option) => option.value === selectedChoice)
|
|
30
30
|
if (selectedIndex === -1) {
|
|
31
31
|
localStorage.removeItem(storageKey)
|
package/dist/vite.config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { config as viteConfig };
|
|
2
2
|
import mdx from '@mdx-js/rollup';
|
|
3
|
-
import react from '@vitejs/plugin-react
|
|
3
|
+
import react from '@vitejs/plugin-react';
|
|
4
4
|
import { parsePageSections } from './parsePageSections.js';
|
|
5
5
|
import rehypePrettyCode from 'rehype-pretty-code';
|
|
6
6
|
import remarkGfm from 'remark-gfm';
|
|
@@ -37,7 +37,6 @@ const config = {
|
|
|
37
37
|
plugins: [
|
|
38
38
|
parsePageSections(),
|
|
39
39
|
mdx({ rehypePlugins, remarkPlugins, providerImportSource: '@brillout/docpress' }),
|
|
40
|
-
// @vitejs/plugin-react-swc needs to be added *after* the mdx plugins
|
|
41
40
|
react(),
|
|
42
41
|
],
|
|
43
42
|
optimizeDeps: {
|
|
@@ -23,9 +23,6 @@ function DocSearchInstall() {
|
|
|
23
23
|
hitsPerPage: 50,
|
|
24
24
|
}}
|
|
25
25
|
transformItems={(hits) => {
|
|
26
|
-
hits.map((hit) => {
|
|
27
|
-
if (hit.type === 'lvl1') hit.url = hit.url.split('#')[0]!
|
|
28
|
-
})
|
|
29
26
|
hits.sort((a, b) => Number(a.url.includes('#')) - Number(b.url.includes('#')))
|
|
30
27
|
return hits
|
|
31
28
|
}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brillout/docpress",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@brillout/picocolors": "^1.0.10",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@mdx-js/react": "3.0.1",
|
|
12
12
|
"@mdx-js/rollup": "3.0.1",
|
|
13
13
|
"@shikijs/transformers": "^4.0.2",
|
|
14
|
-
"@vitejs/plugin-react
|
|
14
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
15
15
|
"detype": "^2.0.2",
|
|
16
16
|
"estree-util-value-to-estree": "^3.5.0",
|
|
17
17
|
"npm-to-yarn": "^3.0.1",
|
|
@@ -19,11 +19,10 @@
|
|
|
19
19
|
"remark-directive": "^4.0.0",
|
|
20
20
|
"remark-gfm": "4.0.0",
|
|
21
21
|
"shiki": "1.2.0",
|
|
22
|
-
"unist-util-visit": "^5.0.0"
|
|
23
|
-
"vite": "^6.3.5"
|
|
22
|
+
"unist-util-visit": "^5.0.0"
|
|
24
23
|
},
|
|
25
24
|
"peerDependencies": {
|
|
26
|
-
"@vitejs/plugin-react
|
|
25
|
+
"@vitejs/plugin-react": ">=6.0.0",
|
|
27
26
|
"react": ">=18.0.0",
|
|
28
27
|
"react-dom": ">=18.0.0",
|
|
29
28
|
"typescript": ">=5.0.0",
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
"vite": ">=5.2.0"
|
|
32
31
|
},
|
|
33
32
|
"peerDependenciesMeta": {
|
|
34
|
-
"@vitejs/plugin-react
|
|
33
|
+
"@vitejs/plugin-react": {
|
|
35
34
|
"optional": true
|
|
36
35
|
},
|
|
37
36
|
"vite": {
|
|
@@ -71,7 +70,8 @@
|
|
|
71
70
|
"@types/react-dom": "^19.2.2",
|
|
72
71
|
"mdast-util-directive": "^3.1.0",
|
|
73
72
|
"mdast-util-mdx-jsx": "^3.2.0",
|
|
74
|
-
"vike": "^0.4.255"
|
|
73
|
+
"vike": "^0.4.255",
|
|
74
|
+
"vite": "^8.0.8"
|
|
75
75
|
},
|
|
76
76
|
"repository": "https://github.com/brillout/docpress",
|
|
77
77
|
"license": "MIT",
|
package/vite.config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { config as viteConfig }
|
|
2
2
|
|
|
3
3
|
import mdx from '@mdx-js/rollup'
|
|
4
|
-
import react from '@vitejs/plugin-react
|
|
4
|
+
import react from '@vitejs/plugin-react'
|
|
5
5
|
import type { PluginOption, UserConfig } from 'vite'
|
|
6
6
|
import { parsePageSections } from './parsePageSections.js'
|
|
7
7
|
import rehypePrettyCode from 'rehype-pretty-code'
|
|
@@ -41,7 +41,6 @@ const config: UserConfig = {
|
|
|
41
41
|
plugins: [
|
|
42
42
|
parsePageSections(),
|
|
43
43
|
mdx({ rehypePlugins, remarkPlugins, providerImportSource: '@brillout/docpress' }) as PluginOption,
|
|
44
|
-
// @vitejs/plugin-react-swc needs to be added *after* the mdx plugins
|
|
45
44
|
react(),
|
|
46
45
|
],
|
|
47
46
|
optimizeDeps: {
|
package/AGENTS.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
🚨 STOP: Before responding to ANY message, you MUST complete STEP 1 below. No exceptions - even for simple questions like "1+1".
|
|
2
|
-
|
|
3
|
-
@AI: Read and always respect all instructions in all AGENTS.md files. Treat this context as always up-to-date — it's never out of scope, no matter how much other context you have.
|
|
4
|
-
|
|
5
|
-
List of `AGENTS.md` files:
|
|
6
|
-
1. This file (project preferences)
|
|
7
|
-
2. `~/.config/AGENTS.md` (user preferences)
|
|
8
|
-
|
|
9
|
-
# CRITICAL AGENT INSTRUCTIONS - MUST FOLLOW
|
|
10
|
-
|
|
11
|
-
## What is "ANY agentic session"?
|
|
12
|
-
- User asks a question (even "1+1" or simple queries)
|
|
13
|
-
- User requests a code change
|
|
14
|
-
- User asks for information
|
|
15
|
-
- Session resumes after idle time
|
|
16
|
-
- First interaction in a conversation
|
|
17
|
-
- EVERYTHING counts - no exceptions
|
|
18
|
-
|
|
19
|
-
## STEP 1: ALWAYS START HERE (BEFORE ANY TASK)
|
|
20
|
-
**MANDATORY:** When starting ANY agentic session, you MUST:
|
|
21
|
-
1. Read both AGENTS.md files (this file + ~/.config/AGENTS.md)
|
|
22
|
-
2. Say "I've successfully read [list-of-AGENTS.md-files]"
|
|
23
|
-
3. List ALL instructions from both files
|
|
24
|
-
4. Confirm: "✅ AGENTS.md check complete, proceeding with: [brief task description]"
|
|
25
|
-
5. Then proceed with the task
|
|
26
|
-
|
|
27
|
-
## STEP 2: AFTER MAKING CHANGES
|
|
28
|
-
**MANDATORY:** After completing a task and if you made changes:
|
|
29
|
-
1. Run `$ pnpm run -w format`
|
|
30
|
-
2. Follow user preferences from ~/.config/AGENTS.md for commits and notifications
|