@brillout/docpress 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/cli.mjs +2 -0
  2. package/dist/cli/chunk-KZROB63P.js +8 -0
  3. package/dist/cli/configFile.js +6 -0
  4. package/dist/cli/devServer.js +31 -0
  5. package/dist/cli/index.js +37 -0
  6. package/index.ts +2 -0
  7. package/mdx.d.ts +6 -0
  8. package/package.json +73 -0
  9. package/readme.md +3 -0
  10. package/src/MobileHeader.tsx +68 -0
  11. package/src/PageLayout.css +32 -0
  12. package/src/PageLayout.tsx +43 -0
  13. package/src/algolia/DocSearch.css +29 -0
  14. package/src/algolia/DocSearch.ts +37 -0
  15. package/src/autoScrollNav.ts +22 -0
  16. package/src/components/ContactUs.tsx +19 -0
  17. package/src/components/DocLink.tsx +108 -0
  18. package/src/components/EditPageNote.tsx +18 -0
  19. package/src/components/HorizontalLine.tsx +20 -0
  20. package/src/components/ImportMeta.tsx +11 -0
  21. package/src/components/Info.tsx +12 -0
  22. package/src/components/Link.tsx +18 -0
  23. package/src/components/Note.tsx +31 -0
  24. package/src/components/P.css +8 -0
  25. package/src/components/P.tsx +8 -0
  26. package/src/components/ReadingRecommendation.tsx +53 -0
  27. package/src/components/RepoLink.tsx +24 -0
  28. package/src/components/Sponsors/companyLogos/ccoli-logo.svg +1 -0
  29. package/src/components/Sponsors/companyLogos/ccoli-text.svg +1 -0
  30. package/src/components/Sponsors/companyLogos/ccoli.svg +9 -0
  31. package/src/components/Sponsors/companyLogos/contra.svg +1 -0
  32. package/src/components/Sponsors/companyLogos/mfqs.svg +1 -0
  33. package/src/components/Sponsors/label.draft.svg +108 -0
  34. package/src/components/Sponsors/label.svg +5 -0
  35. package/src/components/Sponsors/medalBronze.svg +65 -0
  36. package/src/components/Sponsors/medalGold.svg +65 -0
  37. package/src/components/Sponsors/medalSilver.svg +65 -0
  38. package/src/components/Sponsors.tsx +240 -0
  39. package/src/components/TextContactUs.tsx +15 -0
  40. package/src/components/features/FeatureList.css +117 -0
  41. package/src/components/features/FeatureList.tsx +114 -0
  42. package/src/components/features/chevron.svg +7 -0
  43. package/src/components/features/initFeatureList.ts +61 -0
  44. package/src/components/index.ts +14 -0
  45. package/src/config/Config.ts +30 -0
  46. package/src/config/getConfig.ts +18 -0
  47. package/src/config/resolveConfig/resolveHeading.ts +0 -0
  48. package/src/config/resolvePageContext.ts +156 -0
  49. package/src/css/Inter-Var.ttf +0 -0
  50. package/src/css/button.css +7 -0
  51. package/src/css/code/block.css +36 -0
  52. package/src/css/code/inline.css +27 -0
  53. package/src/css/code.css +20 -0
  54. package/src/css/colorize-on-hover.css +29 -0
  55. package/src/css/font.css +19 -0
  56. package/src/css/heading.css +25 -0
  57. package/src/css/index.css +10 -0
  58. package/src/css/link.css +17 -0
  59. package/src/css/note.css +26 -0
  60. package/src/css/reset.css +12 -0
  61. package/src/css/table.css +14 -0
  62. package/src/css/tooltip.css +11 -0
  63. package/src/headings.ts +206 -0
  64. package/src/icons/changelog.svg +2 -0
  65. package/src/icons/discord.svg +10 -0
  66. package/src/icons/github.svg +74 -0
  67. package/src/icons/heart.svg +1 -0
  68. package/src/icons/twitter.svg +16 -0
  69. package/src/index.ts +3 -0
  70. package/src/installSectionUrlHashs.ts +50 -0
  71. package/src/navigation/Navigation-highlight.css +41 -0
  72. package/src/navigation/Navigation-items.css +122 -0
  73. package/src/navigation/Navigation-layout.css +119 -0
  74. package/src/navigation/Navigation.client.old.ts +303 -0
  75. package/src/navigation/Navigation.client.ts +19 -0
  76. package/src/navigation/Navigation.css +8 -0
  77. package/src/navigation/Navigation.tsx +228 -0
  78. package/src/navigation/NavigationHeader.tsx +97 -0
  79. package/src/navigation/navigation-fullscreen/NavigationFullscreenButton.css +32 -0
  80. package/src/navigation/navigation-fullscreen/NavigationFullscreenButton.tsx +44 -0
  81. package/src/navigation/navigation-fullscreen/chevron.svg +1 -0
  82. package/src/navigation/navigation-fullscreen/close.svg +4 -0
  83. package/src/navigation/navigation-fullscreen/initNavigationFullscreen.ts +115 -0
  84. package/src/parseEmojis.ts +33 -0
  85. package/src/renderer/_default.page.client.ts +7 -0
  86. package/src/renderer/_default.page.server.tsx +69 -0
  87. package/src/renderer/usePageContext.tsx +25 -0
  88. package/src/types.ts +2 -0
  89. package/src/utils/Emoji/Emoji.ts +216 -0
  90. package/src/utils/Emoji/assets.ts +9 -0
  91. package/src/utils/Emoji/compass.svg +1 -0
  92. package/src/utils/Emoji/engine.png +0 -0
  93. package/src/utils/Emoji/index.ts +1 -0
  94. package/src/utils/Emoji/mechanical-arm.svg +1 -0
  95. package/src/utils/Emoji/mountain.svg +1 -0
  96. package/src/utils/Emoji/road-fork.svg +17 -0
  97. package/src/utils/Emoji/shield.svg +1 -0
  98. package/src/utils/Emoji/typescript.svg +1 -0
  99. package/src/utils/assert.ts +39 -0
  100. package/src/utils/determineSectionUrlHash.ts +35 -0
  101. package/src/utils/filter.ts +12 -0
  102. package/src/utils/index.ts +6 -0
  103. package/src/utils/isBrowser.ts +5 -0
  104. package/src/utils/jsxToTextContent.ts +11 -0
  105. package/src/utils/objectAssign.ts +6 -0
  106. package/vite.config/markdownHeadings.ts +128 -0
  107. package/vite.config.ts +42 -0
@@ -0,0 +1,240 @@
1
+ import React from 'react'
2
+ import iconHeart from '../icons/heart.svg'
3
+ import { usePageContext } from '../renderer/usePageContext'
4
+ import { assert } from '../utils'
5
+ import ccoliLogo from './Sponsors/companyLogos/ccoli.svg'
6
+ import contraLogo from './Sponsors/companyLogos/contra.svg'
7
+ import mfqsLogo from './Sponsors/companyLogos/mfqs.svg'
8
+ import medalGold from './Sponsors/medalGold.svg'
9
+ import medalSilver from './Sponsors/medalSilver.svg'
10
+ import medalBronze from './Sponsors/medalBronze.svg'
11
+ import labelBgImg from './Sponsors/label.svg'
12
+ import { Emoji } from '../utils/Emoji'
13
+
14
+ export { Sponsors }
15
+
16
+ type Plan = 'bronze' | 'silver' | 'gold' | 'platinum'
17
+
18
+ type SponsorCompany = {
19
+ companyName: string
20
+ companyLogo: string
21
+ website: string
22
+ plan: Plan
23
+ }
24
+ type SponsorIndividual = {
25
+ username: string
26
+ }
27
+ type Sponsor = SponsorCompany | SponsorIndividual
28
+
29
+ const sponsors: Sponsor[] = [
30
+ {
31
+ companyName: 'Contra',
32
+ companyLogo: contraLogo,
33
+ plan: 'platinum',
34
+ website: 'https://contra.com'
35
+ },
36
+ {
37
+ companyName: 'ccoli',
38
+ companyLogo: ccoliLogo,
39
+ plan: 'gold',
40
+ website: 'https://ccoli.co'
41
+ },
42
+ {
43
+ companyName: 'My Favorite Quilt Store',
44
+ companyLogo: mfqsLogo,
45
+ plan: 'silver',
46
+ website: 'https://myfavoritequiltstore.com'
47
+ },
48
+ {
49
+ username: 'spacedawwwg'
50
+ },
51
+ {
52
+ username: 'codthing'
53
+ },
54
+ {
55
+ username: 'Junaidhkn'
56
+ },
57
+ {
58
+ username: 'zgfdev'
59
+ }
60
+ ]
61
+
62
+ function Sponsors() {
63
+ const pageContext = usePageContext()
64
+ const { projectInfo } = pageContext.config
65
+ return (
66
+ <div style={{ textAlign: 'center', marginTop: 19 }}>
67
+ <a
68
+ className="button"
69
+ href="https://github.com/sponsors/brillout"
70
+ style={{
71
+ color: 'inherit',
72
+ display: 'inline-flex',
73
+ alignItems: 'center',
74
+ padding: '5px 10px',
75
+ marginBottom: 10
76
+ }}
77
+ >
78
+ <img src={iconHeart} height={22} /> <span style={{ marginLeft: 7, fontSize: '1.07em' }}>Sponsor</span>
79
+ </a>
80
+ <div></div>
81
+ <div style={{ maxWidth: 400, display: 'inline-block', marginTop: 12, marginBottom: 12 }}>
82
+ {projectInfo.projectNameJsx || projectInfo.projectName} is free and open source, made possible by wonderful
83
+ sponsors.
84
+ </div>
85
+ <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'end' }}>
86
+ {sponsors.map((sponsor, i) => (
87
+ <SponsorDiv sponsor={sponsor} key={i} />
88
+ ))}
89
+ </div>
90
+ </div>
91
+ )
92
+ }
93
+
94
+ function SponsorDiv({ sponsor }: { sponsor: Sponsor }) {
95
+ let imgSrc: string
96
+ let imgAlt: string | undefined
97
+ let width: number
98
+ let height: number
99
+ let website: string
100
+ let padding: number
101
+ let backgroundColor = '#f0f0f0'
102
+ let label: null | JSX.Element = null
103
+ if ('username' in sponsor) {
104
+ website = `https://github.com/${sponsor.username}`
105
+ imgSrc = `https://github.com/${sponsor.username}.png?size=30`
106
+ width = 30
107
+ height = 30
108
+ padding = 0
109
+ backgroundColor = 'none'
110
+ } else {
111
+ imgSrc = sponsor.companyLogo
112
+ website = sponsor.website
113
+ const size = getSize(sponsor.plan)
114
+ width = size.width
115
+ height = size.height
116
+ padding = size.padding
117
+ imgAlt = sponsor.companyName
118
+ label = <Label sponsor={sponsor} />
119
+ }
120
+ const marginWidth = 5
121
+ return (
122
+ <a
123
+ href={website}
124
+ style={{
125
+ margin: `10px ${marginWidth}px`
126
+ }}
127
+ >
128
+ {label}
129
+ <div
130
+ style={{
131
+ backgroundColor,
132
+ borderRadius: 7,
133
+ overflow: 'hidden',
134
+ width,
135
+ maxWidth: `calc(100vw - 2 * var(--main-view-padding) - 2 * ${marginWidth}px)`,
136
+ height,
137
+ display: 'flex',
138
+ alignItems: 'center',
139
+ flexDirection: 'column',
140
+ justifyContent: 'center'
141
+ }}
142
+ >
143
+ <img
144
+ style={{ width: `calc(100% - ${padding}px)`, height: height - padding, zIndex: 2 }}
145
+ src={imgSrc}
146
+ alt={imgAlt}
147
+ />
148
+ </div>
149
+ </a>
150
+ )
151
+ }
152
+
153
+ function Label({ sponsor }: { sponsor: Sponsor }) {
154
+ assert(!('username' in sponsor))
155
+ const labelBg = getLabelBg(sponsor)
156
+ const labelIcon = getLabelIcon(sponsor)
157
+ const labelText = getLabelText(sponsor)
158
+ return (
159
+ <div
160
+ style={{
161
+ top: 0,
162
+ display: 'flex',
163
+ justifyContent: 'center',
164
+ alignItems: 'center',
165
+ position: 'relative',
166
+ paddingBottom: 1
167
+ }}
168
+ >
169
+ {labelBg}
170
+ {labelIcon}
171
+ {labelText}
172
+ </div>
173
+ )
174
+ }
175
+
176
+ function getLabelBg(sponsor: SponsorCompany) {
177
+ const height = sponsor.plan === 'platinum' ? 32 : 24
178
+ return <img src={labelBgImg} style={{ height, position: 'absolute', bottom: 0, zIndex: -1 }} />
179
+ }
180
+
181
+ function getLabelText(sponsor: SponsorCompany) {
182
+ if (sponsor.plan === 'platinum') {
183
+ return <></>
184
+ }
185
+ const letterSpacing = ['silver', 'gold'].includes(sponsor.plan) ? 1 : undefined
186
+ return (
187
+ <>
188
+ {' '}
189
+ <span
190
+ style={{
191
+ zIndex: 1,
192
+ fontSize: '0.82em',
193
+ position: 'relative',
194
+ top: 0,
195
+ fontWeight: 500,
196
+ color: '#666',
197
+ letterSpacing
198
+ }}
199
+ >
200
+ {capitalizeFirstLetter(sponsor.plan)}
201
+ </span>
202
+ </>
203
+ )
204
+ }
205
+
206
+ function getLabelIcon(sponsor: SponsorCompany) {
207
+ let medalSrc: string
208
+ if (sponsor.plan === 'platinum') {
209
+ return <Emoji name="trophy" style={{ fontSize: '1.3em' }} />
210
+ } else if (sponsor.plan === 'gold') {
211
+ medalSrc = medalGold
212
+ } else if (sponsor.plan === 'silver') {
213
+ medalSrc = medalSilver
214
+ } else if (sponsor.plan === 'bronze') {
215
+ medalSrc = medalBronze
216
+ } else {
217
+ assert(false)
218
+ }
219
+ return <img src={medalSrc} style={{ height: 15, zIndex: 1, marginRight: 5 }} />
220
+ }
221
+
222
+ function getSize(plan: Plan) {
223
+ if (plan === 'platinum') {
224
+ return { width: 400, height: 150, padding: 95 }
225
+ }
226
+ if (plan === 'gold') {
227
+ return { width: 300, height: 100, padding: 45 }
228
+ }
229
+ if (plan === 'silver') {
230
+ return { width: 200, height: 70, padding: 30 }
231
+ }
232
+ if (plan === 'bronze') {
233
+ return { width: 150, height: 40, padding: 15 }
234
+ }
235
+ assert(false)
236
+ }
237
+
238
+ function capitalizeFirstLetter(word: string): string {
239
+ return word[0].toUpperCase() + word.slice(1)
240
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+ import { usePageContext } from '../renderer/usePageContext'
3
+
4
+ export { TextContactUs }
5
+
6
+ function TextContactUs() {
7
+ const pageContext = usePageContext()
8
+ const { projectInfo } = pageContext.config
9
+ return (
10
+ <>
11
+ <a href={projectInfo.discordInvite}>Join our Discord</a> or{' '}
12
+ <a href={projectInfo.githubIssues}>open a GitHub ticket</a>.
13
+ </>
14
+ )
15
+ }
@@ -0,0 +1,117 @@
1
+ @media screen and (min-width: 840px) {
2
+ .features-row {
3
+ display: grid;
4
+ grid-template-columns: repeat(2, 1fr);
5
+ }
6
+ .features-row summary:nth-of-type(1) {
7
+ grid-row: 1;
8
+ grid-column: 1 / 2;
9
+ }
10
+ .features-row summary:nth-of-type(2) {
11
+ grid-row: 1;
12
+ grid-column: 2 / 3;
13
+ }
14
+ .features-row aside {
15
+ grid-row: 2;
16
+ grid-column: 1 / 3;
17
+ }
18
+ }
19
+
20
+ @media screen and (min-width: 840px) {
21
+ .features-row.single-column .feature {
22
+ grid-column: 1 / span 2 !important;
23
+ width: 100% !important;
24
+ max-width: calc(1010px / 2) !important;
25
+ margin: auto !important;
26
+ }
27
+ }
28
+
29
+ #features {
30
+ margin: auto;
31
+ margin-top: 0;
32
+ max-width: 1080px;
33
+ }
34
+
35
+ #features summary p {
36
+ margin: 10px 0;
37
+ }
38
+ #features h2 {
39
+ margin-bottom: 0.7em;
40
+ margin-top: 0.5em;
41
+ }
42
+ #features .secondary-feature h2 {
43
+ font-size: 1.1em;
44
+ margin-bottom: 0.7em;
45
+ }
46
+ .learn-more h3:first-of-type {
47
+ margin-top: 15px;
48
+ }
49
+
50
+ .learn-more {
51
+ border: var(--border-width) solid var(--border-color);
52
+ padding: 10px 8px;
53
+ }
54
+ @media screen and (min-width: 840px) {
55
+ .learn-more {
56
+ max-width: 886px;
57
+ border-radius: var(--border-radius);
58
+ }
59
+ }
60
+ aside.learn-more:not(.right-side) {
61
+ border-top-left-radius: 0;
62
+ }
63
+ aside.learn-more.right-side {
64
+ border-top-right-radius: 0;
65
+ justify-self: end;
66
+ width: 100%;
67
+ }
68
+ @media screen and (max-width: 340px) {
69
+ .learn-more {
70
+ padding-right: 5px;
71
+ padding-left: 5px;
72
+ }
73
+ }
74
+ .learn-more {
75
+ display: none;
76
+ }
77
+ .learn-more.selected {
78
+ display: block;
79
+ }
80
+ #features {
81
+ --border-radius: 20px;
82
+ --border-width: 10px;
83
+ --border-color: #f6f6f6;
84
+ }
85
+ .feature {
86
+ padding: 8px;
87
+ border-width: var(--border-width);
88
+ border-style: solid;
89
+ border-color: transparent;
90
+ border-top-left-radius: var(--border-radius);
91
+ border-top-right-radius: var(--border-radius);
92
+ }
93
+ .selected {
94
+ border-color: var(--border-color);
95
+ background-color: #fcfcfc;
96
+ }
97
+ .feature.selected {
98
+ border-bottom: 0 !important;
99
+ z-index: 1;
100
+ }
101
+
102
+ /* Hide top border of .learn-more */
103
+ .learn-more {
104
+ position: relative;
105
+ top: calc(-1 * var(--border-width));
106
+ }
107
+ .feature {
108
+ position: relative;
109
+ z-index: 1;
110
+ }
111
+
112
+ .feature .chevron {
113
+ transition: filter 0.3s ease-in-out, transform 0.3s ease-in-out !important;
114
+ }
115
+ .feature.selected .chevron {
116
+ transform: rotate(180deg);
117
+ }
@@ -0,0 +1,114 @@
1
+ import React from 'react'
2
+ import './FeatureList.css'
3
+ import iconChevron from './chevron.svg'
4
+
5
+ export { FeatureList }
6
+
7
+ type FeatureProps = {
8
+ title: React.ReactNode
9
+ desc: React.ReactNode
10
+ learnMore?: React.ReactNode
11
+ isSecondaryFeature?: true
12
+ }
13
+
14
+ function FeatureList({ features }: { features: FeatureProps[] }) {
15
+ const numberOfFeatures = features.length
16
+ const numberOfRows = Math.ceil(numberOfFeatures / 2)
17
+ return (
18
+ <div id="features">
19
+ {Array.from({ length: numberOfRows }, (_, i) => {
20
+ const feature1Id = 2 * i + 0
21
+ const feature2Id = 2 * i + 1
22
+ const feature1 = features[feature1Id]
23
+ const feature2 = features[feature2Id]
24
+ const className = ['features-row', feature2 ? '' : 'single-column'].filter(Boolean).join(' ')
25
+ return (
26
+ <div className={className} key={i}>
27
+ <Feature {...{ ...feature1, featureId: feature1Id }} />
28
+ {feature2 && <Feature {...{ ...feature2, featureId: feature2Id }} />}
29
+ </div>
30
+ )
31
+ })}
32
+ </div>
33
+ )
34
+ }
35
+
36
+ function Feature({ title, desc, learnMore, isSecondaryFeature, featureId }: FeatureProps & { featureId: number }) {
37
+ const name = `feature-${featureId}`
38
+ const rightSide = featureId % 2 === 1
39
+ return (
40
+ <>
41
+ <FeatureHead name={name} hasLearnMore={!!learnMore} isSecondaryFeature={isSecondaryFeature}>
42
+ {' '}
43
+ <h2>{title}</h2>
44
+ {desc}
45
+ </FeatureHead>
46
+ {!!learnMore && (
47
+ <LearnMore name={name} rightSide={rightSide}>
48
+ {learnMore}
49
+ </LearnMore>
50
+ )}
51
+ </>
52
+ )
53
+ }
54
+
55
+ function FeatureHead({
56
+ children,
57
+ name,
58
+ hasLearnMore,
59
+ isSecondaryFeature,
60
+ className = ''
61
+ }: {
62
+ className?: string
63
+ name?: string
64
+ hasLearnMore?: boolean
65
+ isSecondaryFeature?: true
66
+ children: any
67
+ }) {
68
+ return (
69
+ <summary
70
+ className={[
71
+ className,
72
+ 'feature',
73
+ 'colorize-on-hover',
74
+ hasLearnMore && 'has-learn-more',
75
+ isSecondaryFeature && 'secondary-feature'
76
+ ]
77
+ .filter(Boolean)
78
+ .join(' ')}
79
+ id={name && `feature-${name}`}
80
+ style={{ cursor: (hasLearnMore && 'pointer') || undefined }}
81
+ >
82
+ {children}
83
+ {hasLearnMore && (
84
+ <div style={{ textAlign: 'center', marginTop: '1em' }}>
85
+ <button
86
+ type="button"
87
+ style={{
88
+ textAlign: 'center',
89
+ padding: '0 7px',
90
+ paddingTop: 3,
91
+ paddingBottom: 1,
92
+ display: 'inline-block',
93
+ fontSize: '10px',
94
+ textTransform: 'uppercase',
95
+ letterSpacing: '1px',
96
+ fontWeight: 600
97
+ }}
98
+ >
99
+ <span className="decolorize-5">Learn more</span>
100
+ <br />
101
+ <img className="decolorize-4 chevron" src={iconChevron} height="7" style={{ marginTop: 2 }} />
102
+ </button>
103
+ </div>
104
+ )}
105
+ </summary>
106
+ )
107
+ }
108
+ function LearnMore({ children, name, rightSide }: { name: string; children: any; rightSide: boolean }) {
109
+ return (
110
+ <aside className={'learn-more ' + (rightSide ? 'right-side' : '')} id={`learn-more-${name}`}>
111
+ {children}
112
+ </aside>
113
+ )
114
+ }
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg width="512.05" height="292.52" version="1.1" viewBox="0 0 512.05 292.52" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
4
+ <g transform="translate(.025 -109.68)">
5
+ <path fill="#323d48" d="m10.7 172.1 219.4 219.4c6.8 6.8 16.2 10.7 25.9 10.7s19.1-3.9 25.9-10.7l219.4-219.4c14.3-14.3 14.3-37.4 0-51.7s-37.4-14.3-51.7 0l-193.6 193.6-193.6-193.6c-14.3-14.3-37.4-14.3-51.7 0s-14.3 37.5 0 51.7z"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,61 @@
1
+ import { assert } from '../../utils'
2
+
3
+ addTwitterWidgets()
4
+ addFeatureClickHandlers()
5
+
6
+ function addTwitterWidgets() {
7
+ loadScript('https://platform.twitter.com/widgets.js')
8
+ }
9
+
10
+ function addFeatureClickHandlers() {
11
+ const featureEls: HTMLElement[] = Array.from(
12
+ document.getElementById('features')!.querySelectorAll('.feature.has-learn-more')
13
+ )
14
+ featureEls.forEach((featureEl) => {
15
+ featureEl.onclick = () => {
16
+ expandLearnMore(featureEl)
17
+ }
18
+ })
19
+ }
20
+
21
+ function expandLearnMore(featureEl: HTMLElement) {
22
+ const featureId = featureEl.id
23
+ assert(featureId.startsWith('feature-'), { featureId })
24
+ const featureName = featureId.slice('feature-'.length)
25
+
26
+ const selectedClass = 'selected'
27
+ const learnId = 'learn-more-' + featureName
28
+ const learnEl = document.getElementById(learnId)
29
+ assert(learnEl, { learnId })
30
+
31
+ const isExpanded = featureEl.classList.contains(selectedClass)
32
+
33
+ if (!isExpanded) {
34
+ const rowEl = featureEl.parentNode as HTMLElement
35
+ if (getComputedStyle(rowEl, 'display') === 'grid') {
36
+ ;[
37
+ ...(rowEl.querySelectorAll('.learn-more') as any as HTMLElement[]),
38
+ ...(rowEl.querySelectorAll('.feature') as any as HTMLElement[])
39
+ ].forEach((el) => {
40
+ el.classList.remove(selectedClass)
41
+ })
42
+ }
43
+ }
44
+
45
+ ;[featureEl, learnEl].forEach((el) => {
46
+ el.classList.toggle(selectedClass)
47
+ })
48
+ }
49
+
50
+ function loadScript(scriptUrl: string): void {
51
+ assert(scriptUrl.startsWith('https://'))
52
+ const scriptEl = document.createElement('script')
53
+ scriptEl.src = scriptUrl
54
+ scriptEl.async = true
55
+ scriptEl.setAttribute('charset', 'utf-8')
56
+ document.getElementsByTagName('head')[0].appendChild(scriptEl)
57
+ }
58
+
59
+ function getComputedStyle(el: HTMLElement, styleProp: string) {
60
+ return window.document.defaultView!.getComputedStyle(el).getPropertyValue(styleProp)
61
+ }
@@ -0,0 +1,14 @@
1
+ export * from '../utils/Emoji'
2
+ export * from './Link'
3
+ export * from './DocLink'
4
+ export * from './RepoLink'
5
+ export * from './P'
6
+ export * from './Info'
7
+ export * from './ReadingRecommendation'
8
+ export * from './Note'
9
+ export * from './ImportMeta'
10
+ export * from './features/FeatureList'
11
+ export * from './HorizontalLine'
12
+ export * from './ContactUs'
13
+ export * from './TextContactUs'
14
+ export * from './Sponsors'
@@ -0,0 +1,30 @@
1
+ export type { Config }
2
+
3
+ import type { HeadingDefinition, HeadingWithoutLink } from '../headings'
4
+
5
+ type Config = {
6
+ projectInfo: {
7
+ githubRepository: string
8
+ githubIssues: string
9
+ projectName: string
10
+ projectNameJsx?: JSX.Element
11
+ projectVersion: string
12
+ discordInvite: string
13
+ twitterProfile: string
14
+ }
15
+ faviconUrl: string
16
+ algolia: null | {
17
+ appId: string
18
+ apiKey: string
19
+ indexName: string
20
+ }
21
+ headings: HeadingDefinition[]
22
+ headingsWithoutLink: HeadingWithoutLink[]
23
+ navHeaderMobile: React.ReactNode
24
+ navHeader: React.ReactNode
25
+ titleNormalCase: boolean
26
+ tagline: string
27
+ websiteUrl: string
28
+ bannerUrl?: string
29
+ twitterHandle: string
30
+ }
@@ -0,0 +1,18 @@
1
+ export { getConfig }
2
+ import { assert, assertUsage } from '../utils'
3
+ import { Config } from './Config'
4
+
5
+ function getConfig(): Config {
6
+ // We use `@ts-ignore` because the DocPress user most likely didn't add `vite/client` in his `tsconfig.json`.
7
+ // @ts-ignore
8
+ const globResult = import.meta.glob('/**/docpress.config.*([a-zA-Z0-9])', { eager: true })
9
+ const files = Object.keys(globResult)
10
+ assertUsage(files.length >= 1, 'No DocPress config file found `docpress.config.(js|ts|tsx|...)`')
11
+ assertUsage(
12
+ files.length === 1,
13
+ `Found multiple \`docpress.config.js\` files: ${files.map((f) => `\`${f}\``).join(', ')}. Define only one instead.`
14
+ )
15
+ const config = (Object.values(globResult)[0] as any).default as Config
16
+ assert(config)
17
+ return config
18
+ }
File without changes