ywana-core8 0.1.55 → 0.1.57

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ywana-core8",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "ywana-core8",
5
5
  "homepage": "https://ywana.github.io/workspace",
6
6
  "author": "Ernesto Roldan Garcia",
@@ -36,6 +36,7 @@
36
36
  "axios": "^1.3.4",
37
37
  "crypto-js": "^4.1.1",
38
38
  "deep-equal": "^2.0.5",
39
+ "framer-motion": "^5.6.0",
39
40
  "material-design-icons-iconfont": "^6.7.0",
40
41
  "moment": "^2.29.1",
41
42
  "moment-range": "^4.0.2",
package/src/site/index.js CHANGED
@@ -2,4 +2,6 @@ export * from './site'
2
2
  export * from './siteContext'
3
3
  export * from './page'
4
4
  export * from './dialog'
5
- export * from './view'
5
+ export * from './view'
6
+ export * from './link'
7
+ export * from './navigation'
@@ -0,0 +1,75 @@
1
+ import { useEffect, useState, useRef } from "react"
2
+ import React, { useContext } from 'react'
3
+ import { SiteContext } from './siteContext'
4
+
5
+ /**
6
+ * Use Hash Page
7
+ */
8
+ export function useHashPage(defaultPage = "home") {
9
+ const getCurrentPageFromURL = () => {
10
+ const hash = window.location.hash.replace("#", "")
11
+ return hash || defaultPage
12
+ }
13
+
14
+ const [page, setPage] = useState(getCurrentPageFromURL())
15
+ const [history, setHistory] = useState([])
16
+ const isFirstLoad = useRef(true)
17
+
18
+ useEffect(() => {
19
+ const handleHashChange = () => {
20
+ const newPage = getCurrentPageFromURL()
21
+ if (!isFirstLoad.current) {
22
+ setHistory(prev => [...prev, page]) // Guarda la página anterior
23
+ } else {
24
+ isFirstLoad.current = false
25
+ }
26
+ setPage(newPage)
27
+ }
28
+
29
+ window.addEventListener("hashchange", handleHashChange)
30
+ return () => window.removeEventListener("hashchange", handleHashChange)
31
+ }, [page])
32
+
33
+ const goto = (id) => {
34
+ if (page) {
35
+ setHistory(prev => [...prev, page])
36
+ }
37
+ setPage(id)
38
+ window.location.hash = id
39
+ }
40
+
41
+ const goBack = () => {
42
+ if (history.length > 0) {
43
+ const lastPage = history[history.length - 1]
44
+ setHistory(prev => prev.slice(0, -1))
45
+ setPage(lastPage)
46
+ window.location.hash = lastPage
47
+ }
48
+ }
49
+
50
+ return { page, goto, goBack, history }
51
+ }
52
+
53
+ /**
54
+ * PageLink - Navegación declarativa usando el sistema de hash
55
+ *
56
+ * Props:
57
+ * - page: string → ID de la página a mostrar
58
+ * - children: ReactNode → contenido visual del enlace
59
+ * - className: string → clases opcionales
60
+ * - style: object → estilos en línea opcionales
61
+ */
62
+ export const PageLink = ({ page, children, className = '', style = {} }) => {
63
+ const { goto } = useContext(SiteContext)
64
+
65
+ const handleClick = (e) => {
66
+ e.preventDefault()
67
+ goto(page)
68
+ }
69
+
70
+ return (
71
+ <a href={`#${page}`} onClick={handleClick} className={className} style={style}>
72
+ {children}
73
+ </a>
74
+ )
75
+ }
@@ -0,0 +1,54 @@
1
+ import { useEffect, useState, useRef } from "react"
2
+ import React, { useContext } from 'react'
3
+ import { SiteContext } from './siteContext'
4
+
5
+ /**
6
+ * Use Hash Page
7
+ */
8
+ export function useHashPage(defaultPage = "home") {
9
+ const getCurrentPageFromURL = () => {
10
+ const hash = window.location.hash.replace("#", "")
11
+ return hash || defaultPage
12
+ }
13
+
14
+ const [page, setPage] = useState(getCurrentPageFromURL())
15
+ const [history, setHistory] = useState([])
16
+ const [direction, setDirection] = useState("left")
17
+ const isFirstLoad = useRef(true)
18
+
19
+ useEffect(() => {
20
+ const handleHashChange = () => {
21
+ const newPage = getCurrentPageFromURL()
22
+ if (!isFirstLoad.current) {
23
+ setHistory(prev => [...prev, page]) // Guarda la página anterior
24
+ } else {
25
+ isFirstLoad.current = false
26
+ }
27
+ setPage(newPage)
28
+ }
29
+
30
+ window.addEventListener("hashchange", handleHashChange)
31
+ return () => window.removeEventListener("hashchange", handleHashChange)
32
+ }, [page])
33
+
34
+ const goto = (id, dir = "left") => {
35
+ if (page) {
36
+ setHistory(prev => [...prev, page])
37
+ }
38
+ setDirection(dir)
39
+ setPage(id)
40
+ window.location.hash = id
41
+ }
42
+
43
+ const goBack = () => {
44
+ if (history.length > 0) {
45
+ const lastPage = history[history.length - 1]
46
+ setHistory(prev => prev.slice(0, -1))
47
+ setDirection("right")
48
+ setPage(lastPage)
49
+ window.location.hash = lastPage
50
+ }
51
+ }
52
+
53
+ return { page, goto, goBack, history }
54
+ }
package/src/site/site.css CHANGED
@@ -118,6 +118,11 @@
118
118
  align-items: center;
119
119
  }
120
120
 
121
+ .site-page-container {
122
+ position:relative;
123
+ overflow: hidden;
124
+ }
125
+
121
126
  .site6>main {
122
127
  grid-area: main;
123
128
  overflow: hidden;
package/src/site/site.js CHANGED
@@ -6,6 +6,8 @@ import { Tooltip } from '../html/tooltip'
6
6
  import { Page } from './page'
7
7
  import { SiteContext } from './siteContext'
8
8
  import { ReactNotifications, Store } from 'react-notifications-component'
9
+ import { useHashPage } from './navigation'
10
+ import { AnimatePresence, motion } from 'framer-motion'
9
11
  import 'react-notifications-component/dist/theme.css'
10
12
  import './site.css'
11
13
 
@@ -25,25 +27,8 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
25
27
  const [promptDialog, setPromptDialog] = useState()
26
28
  const [preview, setPreview] = useState()
27
29
  const [breadcrumb, setBreadcrumb] = useState()
28
- const [history, setHistory] = useState([])
29
30
 
30
- // 📌 Extraer la página actual desde la URL (por defecto "home")
31
- const getCurrentPageFromURL = () => {
32
- const path = window.location.pathname.replace("/", "")
33
- return path || "home"
34
- }
35
- const [page, setPage] = useState(getCurrentPageFromURL())
36
-
37
- useEffect(() => {
38
- // 📌 Detectar cambios en la URL cuando el usuario presiona "Atrás" o "Adelante"
39
- const handlePopState = (event) => {
40
- const previousPage = event.state?.page || "home"
41
- setPage(previousPage)
42
- }
43
-
44
- window.addEventListener("popstate", handlePopState)
45
- return () => window.removeEventListener("popstate", handlePopState)
46
- }, [])
31
+ const { page, goto, goBack } = useHashPage()
47
32
 
48
33
  const value = {
49
34
 
@@ -53,14 +38,6 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
53
38
  dictionary,
54
39
  setDictionary,
55
40
  translate: useCallback((key) => dictionary?.[key]?.[lang] || key, [lang, dictionary]),
56
- /*
57
- translate: (key) => {
58
- if (!key) return key
59
- if (dictionary === undefined) return key
60
- const term = dictionary[key]
61
- return term ? term[lang] : key
62
- },
63
- */
64
41
 
65
42
  sideNav,
66
43
  setSideNav,
@@ -85,21 +62,8 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
85
62
  setBreadcrumb,
86
63
 
87
64
  page,
88
- goto: (id) => {
89
- if (page) {
90
- setHistory(prev => [...prev, page]) // 🔹 Guarda la página actual en el historial antes de cambiar
91
- }
92
- setPage(id)
93
- window.history.pushState({ page: id }, "", `/${id}`) // 🔹 Actualiza la URL
94
- },
95
- goBack: () => {
96
- if (history.length > 0) {
97
- const lastPage = history[history.length - 1]
98
- setHistory(prev => prev.slice(0, -1)) // 🔹 Elimina la última entrada del historial
99
- setPage(lastPage) // 🔹 Vuelve a la página anterior
100
- window.history.back() // 🔹 Regresa en la navegación del navegador
101
- }
102
- },
65
+ goto,
66
+ goBack,
103
67
 
104
68
  dialog,
105
69
  openDialog: (dialog) => { setDialog(dialog) },
@@ -290,7 +254,7 @@ const SiteMenu = ({ iconSrc, title, children, min }) => {
290
254
  */
291
255
  const SitePage = ({ children, init }) => {
292
256
  const context = useContext(SiteContext)
293
- const { page } = context
257
+ const { page, direction } = context
294
258
  useEffect(() => {
295
259
  if (init) {
296
260
  context.goto(init)
@@ -298,9 +262,24 @@ const SitePage = ({ children, init }) => {
298
262
  context.goto("EMPTY")
299
263
  }
300
264
  }, [])
265
+
266
+ const currentPage = React.Children.toArray(children).filter(child => child.props ? child.props.id === page : false)
267
+ const xOffset = direction === "left" ? 40 : -40
301
268
  return (
302
- <main>
303
- {React.Children.toArray(children).filter(child => child.props ? child.props.id === page : false)}
269
+ <main className='site-page-container'>
270
+ <AnimatePresence exitBeforeEnter>
271
+ {currentPage && (
272
+ <motion.div
273
+ key={page}
274
+ initial={{ opacity: 0, x: xOffset }}
275
+ animate={{ opacity: 1, x: 0 }}
276
+ exit={{ opacity: 0, x: -xOffset }}
277
+ transition={{ duration: 0.3 }}
278
+ >
279
+ {currentPage}
280
+ </motion.div>
281
+ )}
282
+ </AnimatePresence>
304
283
  </main>
305
284
  )
306
285
  }