Skip to content

Commit f90bc84

Browse files
committed
fix: gitignore
1 parent 38f5da8 commit f90bc84

17 files changed

Lines changed: 787 additions & 5 deletions

.gitignore

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ dist-ssr
2626
*.orig
2727

2828
# VitePress
29-
docs/*
29+
docs/**/*
3030
!docs/
31-
!docs/.vitepress/theme/*
31+
!docs/.vitepress/
32+
!docs/.vitepress/theme/
33+
!docs/public/
34+
!docs/guide/
3235
!docs/.vitepress/config.ts
3336
!docs/.vitepress/tsconfig.json
3437
!docs/.vitepress/vue-shim.d.ts
35-
!docs/public/*
38+
!docs/.vitepress/theme/**
39+
!docs/public/**
40+
!docs/guide/**
3641
!docs/index.md
37-
!docs/vitepress-env.d.ts
38-
!docs/guide/*
42+
!docs/vitepress-env.d.ts

docs/.vitepress/config.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { defineConfig } from 'vitepress'
2+
import { fileURLToPath } from 'url'
3+
import { resolve, dirname } from 'path'
4+
import react from '@vitejs/plugin-react'
5+
import { docsPlugin, buildSidebarFromDocs, ROOT } from '../../scripts/docs-plugin.js'
6+
7+
const __filename = fileURLToPath(import.meta.url)
8+
const __dirname = dirname(__filename)
9+
10+
// Sidebar is built dynamically from the .md files generated by docsPlugin()
11+
// At first run docs/ may be empty — the plugin fills it during buildStart
12+
const sidebar = buildSidebarFromDocs()
13+
14+
export default defineConfig({
15+
title: 'React Tools',
16+
description: 'A collection of Hooks, Components, Utilities and Types for React',
17+
lang: 'en-US',
18+
19+
head: [
20+
['link', { rel: 'icon', href: '/react-red.webp' }],
21+
['meta', { name: 'theme-color', content: '#f53340' }],
22+
['meta', { property: 'og:type', content: 'website' }],
23+
['meta', { property: 'og:title', content: 'React Tools' }],
24+
['meta', { property: 'og:description', content: 'Hooks, Components, Utilities and Types for React' }],
25+
['meta', { property: 'og:image', content: '/react-red.webp' }],
26+
['link', { rel: 'sitemap', type: 'application/xml', href: '/sitemap.xml' }],
27+
],
28+
29+
base: '/',
30+
cleanUrls: true,
31+
32+
// VitePress built-in sitemap (generates /sitemap.xml during build)
33+
// We also generate one manually with our plugin for full control, but
34+
// enabling this adds <lastmod> and <changefreq> awareness from VitePress itself.
35+
// Disable to avoid duplicate – our plugin handles it with richer data.
36+
// sitemap: { hostname: 'https://react-tools.ndria.dev' },
37+
38+
themeConfig: {
39+
logo: '/react-red.webp',
40+
41+
nav: [
42+
{ text: 'Home', link: '/' },
43+
{ text: 'Hooks', link: '/hooks/state/createPubSubStore' },
44+
{ text: 'Components', link: '/components/ErrorBoundary' },
45+
{ text: 'Utils', link: '/utils/alphanumericCompare' },
46+
{ text: 'Types', link: '/types/' },
47+
{ text: 'npm', link: 'https://www.npmjs.com/package/@ndriadev/react-tools' },
48+
],
49+
50+
sidebar,
51+
52+
socialLinks: [
53+
{ icon: 'github', link: 'https://github.com/nDriaDev/react-tools' },
54+
],
55+
56+
footer: {
57+
message: 'Released under the MIT License.',
58+
copyright: 'Copyright © 2024-present nDriaDev',
59+
},
60+
61+
search: { provider: 'local' }
62+
},
63+
64+
vite: {
65+
plugins: [
66+
react(),
67+
docsPlugin() as any,
68+
],
69+
resolve: {
70+
alias: [
71+
// Library root alias (demo files import from '../../...' which resolves to src/)
72+
{
73+
find: '@ndriadev/react-tools',
74+
replacement: resolve(ROOT, 'src/index.ts'),
75+
},
76+
// assets/ is now inside src/assets – relative '../../../../assets/...' from
77+
// src/demo/hooks/category/tool/ resolves correctly to src/assets/
78+
// No alias needed; the path arithmetic already points to src/assets/
79+
],
80+
},
81+
optimizeDeps: {
82+
include: ['react', 'react-dom', 'react-dom/client'],
83+
},
84+
assetsInclude: ['**/*.mp3', '**/*.mp4'],
85+
build: {
86+
minify: true
87+
}
88+
},
89+
90+
markdown: {
91+
lineNumbers: true,
92+
theme: { light: 'github-light', dark: 'github-dark' },
93+
}
94+
})
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<template>
2+
<div ref="containerRef" class="react-demo-wrapper">
3+
<div v-if="error" class="react-demo-error">
4+
<p>⚠️ Demo non available: {{ error }}</p>
5+
</div>
6+
<div v-else-if="!ready" class="react-demo-loading">
7+
<span>Loading demo…</span>
8+
</div>
9+
</div>
10+
</template>
11+
12+
<script setup lang="ts">
13+
import { ref, watch, onUnmounted } from 'vue'
14+
15+
const props = defineProps<{
16+
component: any
17+
}>()
18+
19+
const containerRef = ref<HTMLDivElement | null>(null)
20+
const error = ref<string | null>(null)
21+
const ready = ref(false)
22+
23+
let reactRoot: any = null
24+
25+
async function mount(Comp: any) {
26+
// Only browser
27+
if (typeof window === 'undefined' || !containerRef.value) return
28+
29+
// Unmount previous root
30+
if (reactRoot) {
31+
try { reactRoot.unmount() } catch (_) {}
32+
reactRoot = null
33+
}
34+
35+
if (!Comp) return
36+
37+
try {
38+
const [{ createRoot }, React] = await Promise.all([
39+
import('react-dom/client'),
40+
import('react'),
41+
])
42+
43+
const element = React.createElement(Comp)
44+
45+
reactRoot = createRoot(containerRef.value)
46+
reactRoot.render(element)
47+
ready.value = true
48+
} catch (err: any) {
49+
error.value = err?.message ?? String(err)
50+
console.error('[ReactWrapper] errore mount:', err)
51+
}
52+
}
53+
54+
watch(
55+
() => props.component,
56+
(newComp) => {
57+
error.value = null
58+
ready.value = false
59+
mount(newComp)
60+
},
61+
{ immediate: true },
62+
)
63+
64+
onUnmounted(() => {
65+
if (reactRoot) {
66+
try { reactRoot.unmount() } catch (_) {}
67+
reactRoot = null
68+
}
69+
})
70+
</script>
71+
72+
<style scoped>
73+
.react-demo-wrapper {
74+
border: 1px solid var(--vp-c-divider);
75+
border-radius: 8px;
76+
padding: 24px;
77+
margin: 16px 0;
78+
min-height: 60px;
79+
background-image: radial-gradient(#444242 1px, #2a2b33 0);
80+
background-position-y: 50%;
81+
background-size: 8px 8px;
82+
}
83+
84+
.react-demo-loading {
85+
color: var(--vp-c-text-2);
86+
font-size: 0.9em;
87+
text-align: center;
88+
padding: 12px 0;
89+
}
90+
91+
.react-demo-error {
92+
color: var(--vp-c-danger-1, #e53e3e);
93+
font-size: 0.875em;
94+
padding: 8px 0;
95+
}
96+
</style>

docs/.vitepress/theme/custom.css

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* ── Brand colours ─────────────────────────────────────── */
2+
:root {
3+
--vp-c-brand-1: #f53340;
4+
--vp-c-brand-2: #d62a36;
5+
--vp-c-brand-3: #b8222c;
6+
--vp-c-brand-soft: rgba(245, 51, 64, 0.12);
7+
}
8+
9+
/* ── Home hero image ────────────────────────────────────── */
10+
.VPImage.image-src {
11+
border-radius: 12px;
12+
}
13+
14+
/* ── API page layout helpers ────────────────────────────── */
15+
.react-demo-wrapper button {
16+
cursor: pointer;
17+
border: 1px solid var(--vp-c-divider);
18+
border-radius: 4px;
19+
padding: 4px 12px;
20+
background: var(--vp-c-bg);
21+
color: var(--vp-c-text-1);
22+
font-size: 0.875rem;
23+
transition: background 0.2s;
24+
margin: 2px;
25+
}
26+
27+
.react-demo-wrapper button:hover:not(:disabled) {
28+
background: var(--vp-c-brand-soft);
29+
border-color: var(--vp-c-brand-1);
30+
}
31+
32+
.react-demo-wrapper button:disabled {
33+
opacity: 0.45;
34+
cursor: not-allowed;
35+
}
36+
37+
.react-demo-wrapper input[type="text"],
38+
.react-demo-wrapper input[type="number"],
39+
.react-demo-wrapper input[type="range"] {
40+
border: 1px solid var(--vp-c-divider);
41+
border-radius: 4px;
42+
padding: 4px 8px;
43+
background: var(--vp-c-bg);
44+
color: var(--vp-c-text-1);
45+
font-size: 0.875rem;
46+
outline: none;
47+
}
48+
49+
.react-demo-wrapper input:focus {
50+
border-color: var(--vp-c-brand-1);
51+
}
52+
53+
.react-demo-wrapper pre {
54+
font-size: 0.78rem;
55+
max-height: 260px;
56+
overflow-y: auto;
57+
}

docs/.vitepress/theme/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import DefaultTheme from 'vitepress/theme'
2+
import type { Theme } from 'vitepress'
3+
import ReactWrapper from './ReactWrapper.vue'
4+
import './custom.css'
5+
6+
export default {
7+
extends: DefaultTheme,
8+
enhanceApp({ app }) {
9+
app.component('ReactWrapper', ReactWrapper)
10+
},
11+
} satisfies Theme

docs/.vitepress/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"module": "ESNext",
5+
"moduleResolution": "bundler",
6+
"noEmit": true
7+
},
8+
"include": [
9+
"./**/*.ts",
10+
"./**/*.vue",
11+
"../**/*.md"
12+
]
13+
}

docs/.vitepress/vue-shim.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare module '*.vue' {
2+
import type { DefineComponent } from 'vue'
3+
const component: DefineComponent<{}, {}, any>
4+
export default component
5+
}

0 commit comments

Comments
 (0)