nextia 6.1.1 → 7.0.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.
Files changed (76) hide show
  1. package/README.md +1 -1
  2. package/biome.json +21 -0
  3. package/package.json +13 -4
  4. package/src/bin.js +240 -0
  5. package/src/lib.js +2 -2
  6. package/template/README.md +29 -0
  7. package/template/_env.dev +4 -0
  8. package/template/_env.prod +1 -0
  9. package/template/_env.test +1 -0
  10. package/template/_gitignore +10 -0
  11. package/template/package.json +35 -0
  12. package/template/public/error.html +14 -0
  13. package/template/public/logo.svg +105 -0
  14. package/template/src/assets/i18n/index.js +26 -0
  15. package/template/src/assets/img/image.jpg +0 -0
  16. package/template/src/components/Counter/index.jsx +34 -0
  17. package/template/src/components/Counter/style.css +5 -0
  18. package/template/src/components/Message/index.jsx +12 -0
  19. package/template/src/components/index.js +10 -0
  20. package/template/src/components/ui/I18n/index.jsx +23 -0
  21. package/template/src/components/ui/Icon/index.jsx +50 -0
  22. package/template/src/components/ui/Link/index.jsx +12 -0
  23. package/template/src/components/ui/Svg/index.jsx +54 -0
  24. package/template/src/components/ui/Translate/index.jsx +18 -0
  25. package/template/src/index.html +18 -0
  26. package/template/src/index.jsx +4 -0
  27. package/template/src/pages/counter/functions.js +6 -0
  28. package/template/src/pages/counter/index.jsx +51 -0
  29. package/template/src/pages/counter/style.css +2 -0
  30. package/template/src/pages/env/functions.js +3 -0
  31. package/template/src/pages/env/index.jsx +27 -0
  32. package/template/src/pages/env/style.css +2 -0
  33. package/template/src/pages/functions.js +37 -0
  34. package/template/src/pages/home/functions.js +43 -0
  35. package/template/src/pages/home/index.jsx +211 -0
  36. package/template/src/pages/home/style.css +51 -0
  37. package/template/src/pages/http/not-found/index.jsx +10 -0
  38. package/template/src/pages/http/not-found/style.css +2 -0
  39. package/template/src/pages/icons/functions.js +3 -0
  40. package/template/src/pages/icons/index.jsx +20 -0
  41. package/template/src/pages/icons/style.css +5 -0
  42. package/template/src/pages/images/functions.js +3 -0
  43. package/template/src/pages/images/index.jsx +20 -0
  44. package/template/src/pages/images/style.css +8 -0
  45. package/template/src/pages/index.jsx +114 -0
  46. package/template/src/pages/mockapi/functions.js +71 -0
  47. package/template/src/pages/mockapi/index.jsx +101 -0
  48. package/template/src/pages/mockapi/style.css +57 -0
  49. package/template/src/pages/my-context/functions.js +7 -0
  50. package/template/src/pages/my-context/index.jsx +32 -0
  51. package/template/src/pages/my-context/style.css +2 -0
  52. package/template/src/pages/resize/functions.js +3 -0
  53. package/template/src/pages/resize/index.jsx +15 -0
  54. package/template/src/pages/resize/style.css +2 -0
  55. package/template/src/pages/search-params/functions.js +3 -0
  56. package/template/src/pages/search-params/index.jsx +36 -0
  57. package/template/src/pages/search-params/style.css +2 -0
  58. package/template/src/pages/subpage/hello/functions.js +3 -0
  59. package/template/src/pages/subpage/hello/index.jsx +11 -0
  60. package/template/src/pages/subpage/hello/style.css +2 -0
  61. package/template/src/pages/translate/functions.js +5 -0
  62. package/template/src/pages/translate/index.jsx +31 -0
  63. package/template/src/pages/translate/style.css +12 -0
  64. package/template/src/services/api.js +9 -0
  65. package/template/src/services/http.js +40 -0
  66. package/template/src/theme/animations.css +72 -0
  67. package/template/src/theme/fonts/Roboto-Regular.ttf +0 -0
  68. package/template/src/theme/fonts/index.css +7 -0
  69. package/template/src/theme/icons/exit.svg +69 -0
  70. package/template/src/theme/icons/icons.svg +126 -0
  71. package/template/src/theme/index.css +39 -0
  72. package/template/src/theme/util.css +27 -0
  73. package/template/src/utils/hooks.js +49 -0
  74. package/template/src/utils/index.js +19 -0
  75. package/template/test/index.test.js +12 -0
  76. package/template/vite.config.js +97 -0
@@ -0,0 +1,50 @@
1
+ import { useEffect, useRef } from 'react'
2
+ import icons from 'theme/icons/icons.svg?raw'
3
+
4
+ export default function UiIcon({
5
+ id,
6
+ className,
7
+ style,
8
+ width = '48',
9
+ height,
10
+ viewBox = '0 0 48 48',
11
+ fill = 'none',
12
+ color = 'currentColor',
13
+ stroke = 'currentColor',
14
+ strokeWidth = '2',
15
+ strokeLinecap = 'round',
16
+ strokeLinejoin = 'round',
17
+ ...props
18
+ }) {
19
+ const ref = useRef()
20
+
21
+ useEffect(() => {
22
+ const svg = new DOMParser()
23
+ .parseFromString(icons, 'image/svg+xml')
24
+ .documentElement.getElementById(id)
25
+
26
+ if (svg) {
27
+ ref.current.innerHTML = svg.innerHTML
28
+ }
29
+ }, [id])
30
+
31
+ return (
32
+ <svg
33
+ xmlns="http://www.w3.org/2000/svg"
34
+ ref={ref}
35
+ id={id}
36
+ className={className}
37
+ style={style}
38
+ width={width}
39
+ height={height}
40
+ viewBox={viewBox}
41
+ fill={fill}
42
+ color={color}
43
+ stroke={stroke}
44
+ strokeWidth={strokeWidth}
45
+ strokeLinecap={strokeLinecap}
46
+ strokeLinejoin={strokeLinejoin}
47
+ {...props}
48
+ />
49
+ )
50
+ }
@@ -0,0 +1,12 @@
1
+ export default function UiLink({ children, href, value = {}, ...props }) {
2
+ href ??= window.location.hash.split('?')[0]
3
+ value = Object.keys(value).length
4
+ ? `?${new URLSearchParams(value).toString()}`
5
+ : ''
6
+
7
+ return (
8
+ <a href={href + value} {...props}>
9
+ {children}
10
+ </a>
11
+ )
12
+ }
@@ -0,0 +1,54 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ export default function UiSvg({
4
+ src,
5
+ width = '48',
6
+ height,
7
+ viewBox = '0 0 48 48',
8
+ fill = 'none',
9
+ color = 'currentColor',
10
+ stroke = 'currentColor',
11
+ strokeWidth = '2',
12
+ strokeLinecap = 'round',
13
+ strokeLinejoin = 'round'
14
+ }) {
15
+ const ref = useRef()
16
+
17
+ useEffect(() => {
18
+ if (!ref.current) return
19
+
20
+ const svg = new DOMParser()
21
+ .parseFromString(src, 'image/svg+xml')
22
+ .querySelector('svg')
23
+
24
+ svg.setAttribute('width', width)
25
+ svg.setAttribute('height', height ?? width)
26
+ svg.setAttribute('viewBox', viewBox)
27
+ svg.setAttribute('fill', fill)
28
+ svg.setAttribute('color', color)
29
+ svg.setAttribute('stroke', stroke)
30
+ svg.setAttribute('stroke-width', strokeWidth)
31
+ svg.setAttribute('stroke-linecap', strokeLinecap)
32
+ svg.setAttribute('stroke-linejoin', strokeLinejoin)
33
+
34
+ const shadow =
35
+ ref.current.shadowRoot ?? ref.current.attachShadow({ mode: 'open' })
36
+ shadow.innerHTML = svg.outerHTML
37
+
38
+ ref.current.style.width = `${width}px`
39
+ ref.current.style.height = `${height ?? width}px`
40
+ }, [
41
+ src,
42
+ width,
43
+ height,
44
+ viewBox,
45
+ fill,
46
+ color,
47
+ stroke,
48
+ strokeWidth,
49
+ strokeLinecap,
50
+ strokeLinejoin
51
+ ])
52
+
53
+ return <div ref={ref} />
54
+ }
@@ -0,0 +1,18 @@
1
+ export default function UiTranslate({
2
+ value,
3
+ onChange = () => {},
4
+ className,
5
+ style
6
+ }) {
7
+ return (
8
+ <article className={className} style={style}>
9
+ <select value={value.currentLocale} onChange={onChange}>
10
+ {value.locales.map((e) => (
11
+ <option key={e} value={e} className="m-2">
12
+ {e}
13
+ </option>
14
+ ))}
15
+ </select>
16
+ </article>
17
+ )
18
+ }
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <title>%PUBLIC_TITLE%</title>
7
+ <link rel="shortcut icon" href="logo.svg" />
8
+ <meta name="version" content="%VERSION%" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
10
+ <link rel="stylesheet" href="theme/index.css" />
11
+ <script type="module" src="index.jsx"></script>
12
+ </head>
13
+
14
+ <body>
15
+ <div id="root"></div>
16
+ </body>
17
+
18
+ </html>
@@ -0,0 +1,4 @@
1
+ import { createRoot } from 'react-dom/client'
2
+ import Pages from './pages'
3
+
4
+ createRoot(document.getElementById('root')).render(<Pages />)
@@ -0,0 +1,6 @@
1
+ const initialState = {
2
+ count: 1,
3
+ count2: 1
4
+ }
5
+
6
+ export default { initialState }
@@ -0,0 +1,51 @@
1
+ import { Counter } from 'components'
2
+ import { css, useFx } from 'nextia'
3
+ import functions from './functions'
4
+ import './style.css'
5
+
6
+ export default function CounterPage() {
7
+ const { state, fx } = useFx(functions)
8
+
9
+ return (
10
+ <section
11
+ className={css(
12
+ 'CounterPage',
13
+ '',
14
+ 'class-test',
15
+ 'class-test',
16
+ {},
17
+ null,
18
+ true,
19
+ false,
20
+ [],
21
+ { 'css-false': false },
22
+ undefined,
23
+ { 'css-true': true },
24
+ { 'css-true': true }
25
+ )}
26
+ >
27
+ Counters
28
+ <div className={css(null)} />
29
+ <div className={css(undefined)} />
30
+ <div className={css([])} />
31
+ <div className={css({})} />
32
+ <div className={css()} />
33
+ <Counter
34
+ value={state.count}
35
+ animation="count"
36
+ onChange={() => {
37
+ fx.set({ count: state.count + 1 })
38
+ }}
39
+ />
40
+ <br />
41
+ <br />
42
+ <Counter
43
+ value={state.count2}
44
+ animation="count2"
45
+ onChange={() => {
46
+ fx.set({ count2: state.count2 + 10 })
47
+ }}
48
+ />
49
+ </section>
50
+ )
51
+ }
@@ -0,0 +1,2 @@
1
+ .CounterPage {
2
+ }
@@ -0,0 +1,3 @@
1
+ const initialState = {}
2
+
3
+ export default { initialState }
@@ -0,0 +1,27 @@
1
+ import { css, useFx } from 'nextia'
2
+ import { useEffect } from 'react'
3
+ import { env } from 'utils'
4
+ import functions from './functions'
5
+ import './style.css'
6
+
7
+ export default function EnvPage() {
8
+ const { state, fx } = useFx(functions)
9
+
10
+ // env
11
+ useEffect(() => {
12
+ console.log('env:', env)
13
+ }, [])
14
+
15
+ return (
16
+ <section className={css('EnvPage', '')}>
17
+ <br />
18
+ <br />
19
+
20
+ <div style={{ display: 'flex' }}>
21
+ <pre style={{ margin: '0 50px 0 50px' }}>
22
+ env = {JSON.stringify(env, undefined, 2)}
23
+ </pre>
24
+ </div>
25
+ </section>
26
+ )
27
+ }
@@ -0,0 +1,2 @@
1
+ .EnvPage {
2
+ }
@@ -0,0 +1,37 @@
1
+ import i18nFile from 'assets/i18n'
2
+
3
+ const initialState = {
4
+ i18n: {
5
+ currentLocale:
6
+ window.localStorage.getItem('i18n') || i18nFile.defaultLocale,
7
+ locales: i18nFile.locales
8
+ },
9
+ loading: false,
10
+ num: 0
11
+ }
12
+
13
+ function changeI18n({ payload, set }) {
14
+ const { value } = payload.target
15
+ set({ i18n: { currentLocale: value } })
16
+ window.localStorage.setItem('i18n', value)
17
+ }
18
+
19
+ function increment({ state, set }) {
20
+ set({ num: state.num + 1 })
21
+ }
22
+
23
+ function decrement({ state, set }) {
24
+ set({ num: state.num - 1 })
25
+ }
26
+
27
+ function zero({ payload, set }) {
28
+ set({ num: payload.value })
29
+ }
30
+
31
+ export default {
32
+ initialState,
33
+ changeI18n,
34
+ increment,
35
+ decrement,
36
+ zero
37
+ }
@@ -0,0 +1,43 @@
1
+ const initialState = {
2
+ channel: 7,
3
+ msg: 'https://sinuhe.dev',
4
+ data: { user: 'Sinuhe MB' },
5
+ myArray: ['A', 'B', 'C'],
6
+ setNameValue: 'name value',
7
+ form: {
8
+ funny: false,
9
+ gender: 'M',
10
+ name: {
11
+ firstName: 'Sinuhe',
12
+ lastName: 'Maceda'
13
+ },
14
+ year: 33,
15
+ moreArray: [[[50, 40, 10]]]
16
+ },
17
+ ls: {
18
+ users: [
19
+ {
20
+ name: 'sinuhe',
21
+ year: 33
22
+ },
23
+ {
24
+ name: 'alberto',
25
+ year: 20
26
+ }
27
+ ]
28
+ }
29
+ }
30
+
31
+ function increment({ state, set }) {
32
+ set({ channel: state.channel + 1 })
33
+ }
34
+
35
+ function decrement({ state, set }) {
36
+ set({ channel: state.channel - 1 })
37
+ }
38
+
39
+ export default {
40
+ initialState,
41
+ increment,
42
+ decrement
43
+ }
@@ -0,0 +1,211 @@
1
+ import { useEffect } from 'react'
2
+ import './style.css'
3
+ import { css, useFx } from 'nextia'
4
+ import { sum } from 'utils'
5
+ import functions from './functions'
6
+
7
+ export default function HomePage() {
8
+ const { state, initialState, fx, context } = useFx(functions)
9
+
10
+ useEffect(() => {
11
+ console.info(sum(10, 10))
12
+ }, [])
13
+
14
+ return (
15
+ <section className={css('HomePage', 'container')}>
16
+ <div>
17
+ <div>
18
+ <p>set</p>
19
+ <button
20
+ type="button"
21
+ className=""
22
+ onClick={() => fx.set({ setNameValue: 'set 1 level' })}
23
+ >
24
+ set Value
25
+ </button>
26
+ <button
27
+ type="button"
28
+ onClick={() =>
29
+ fx.set({
30
+ form: {
31
+ name: {
32
+ firstName: 'ppppppppppp',
33
+ lastName: '***********'
34
+ }
35
+ }
36
+ })
37
+ }
38
+ >
39
+ set Json
40
+ </button>
41
+ </div>
42
+
43
+ <div>
44
+ <button
45
+ type="button"
46
+ onClick={() => fx.set({ 'form.name.lastName': 'BOUCHAN' })}
47
+ >
48
+ set mulit level (Value)
49
+ </button>
50
+
51
+ <button
52
+ type="button"
53
+ onClick={() =>
54
+ fx.set({
55
+ 'form.name': { firstName: 'SINUHE', lastName: 'MACEDA' }
56
+ })
57
+ }
58
+ >
59
+ set mulit level (Json)
60
+ </button>
61
+ </div>
62
+
63
+ <div>
64
+ <p>Show and Hide :</p>
65
+ <button type="button" onClick={() => fx.show('form.funny')}>
66
+ show
67
+ </button>
68
+ <button type="button" onClick={() => fx.hide('form.funny')}>
69
+ hide
70
+ </button>
71
+ </div>
72
+
73
+ <div>
74
+ <p>Reset :</p>
75
+ <button type="button" onClick={() => fx.reset('ls')}>
76
+ Reset (ls)
77
+ </button>
78
+ <button type="button" onClick={() => fx.reset('form.name')}>
79
+ Reset (form.name)
80
+ </button>
81
+ <button
82
+ type="button"
83
+ onClick={() => fx.reset(['channel', 'msg', 'form.name'])}
84
+ >
85
+ Reset ([channel,msg,form.name])
86
+ </button>
87
+ </div>
88
+
89
+ <div>
90
+ <p>Simple actions/Reducer:</p>
91
+ <button type="button" onClick={(e) => fx.increment(e)}>
92
+ +
93
+ </button>
94
+ <button type="button" onClick={(e) => fx.decrement(e)}>
95
+ -
96
+ </button>
97
+
98
+ <button
99
+ type="button"
100
+ onClick={() =>
101
+ fx.set({
102
+ channel: 256,
103
+ msg: 256,
104
+ data: { user: 256 },
105
+ myArray: ['256', '256', '256'],
106
+ setNameValue: '256',
107
+ form: {
108
+ // funny: 256,
109
+ // gender: '256',
110
+ name: {
111
+ firstName: '256',
112
+ lastName: '256'
113
+ },
114
+ year: 256,
115
+ moreArray: [[[256, 256, 256]]]
116
+ },
117
+ ls: {
118
+ users: [
119
+ {
120
+ name: '256',
121
+ year: 256
122
+ },
123
+ {
124
+ name: '256',
125
+ year: 256
126
+ }
127
+ ]
128
+ }
129
+ })
130
+ }
131
+ >
132
+ 256
133
+ </button>
134
+ </div>
135
+
136
+ <div>
137
+ <p>onChange:</p>
138
+
139
+ {/* input text */}
140
+ <input
141
+ type="text"
142
+ name="form.name.firstName"
143
+ value={state.form.name.firstName}
144
+ onChange={(evt) => fx.change(evt)}
145
+ />
146
+
147
+ {/* checkbox */}
148
+ <input
149
+ type="checkbox"
150
+ name="form.funny"
151
+ checked={state.form.funny}
152
+ onChange={(evt) => fx.change(evt)}
153
+ />
154
+ <label htmlFor="form.funny">Funny</label>
155
+
156
+ {/* radio */}
157
+ <input
158
+ type="radio"
159
+ name="form.gender"
160
+ value="M"
161
+ checked={state.form.gender === 'M'}
162
+ onChange={(evt) => fx.change(evt)}
163
+ />
164
+ <label htmlFor="M">M</label>
165
+ <input
166
+ type="radio"
167
+ name="form.gender"
168
+ value="F"
169
+ checked={state.form.gender === 'F'}
170
+ onChange={(evt) => fx.change(evt)}
171
+ />
172
+ <label htmlFor="F">F</label>
173
+
174
+ {/* select */}
175
+ <select name="form.year" onChange={(evt) => fx.change(evt)}>
176
+ <option value="20">20</option>
177
+ <option value="21">21</option>
178
+ <option value="22">22</option>
179
+ <option value="33">33</option>
180
+ </select>
181
+ </div>
182
+ </div>
183
+
184
+ <div>
185
+ <div style={{ textAlign: 'center' }}>
186
+ <button type="button" onClick={() => fx.reset()}>
187
+ RESET
188
+ </button>
189
+ <button
190
+ type="button"
191
+ onClick={() => {
192
+ if (context.state.loading) context.fx.hide('loading')
193
+ else context.fx.show('loading')
194
+ }}
195
+ >
196
+ loading
197
+ </button>
198
+ </div>
199
+
200
+ <div style={{ display: 'flex' }}>
201
+ <pre style={{ margin: '0 50px 0 50px' }}>
202
+ state = {JSON.stringify(state, undefined, 2)}
203
+ </pre>
204
+ <pre style={{ margin: '0 50px 0 50px' }}>
205
+ initialState = {JSON.stringify(initialState, undefined, 2)}
206
+ </pre>
207
+ </div>
208
+ </div>
209
+ </section>
210
+ )
211
+ }
@@ -0,0 +1,51 @@
1
+ .HomePage {
2
+ background-color: #21252b;
3
+
4
+ &.container {
5
+ display: flex;
6
+ }
7
+
8
+ p {
9
+ padding-left: 25px;
10
+ margin: 0px;
11
+ }
12
+
13
+ pre {
14
+ color: gray;
15
+ font-size: 12px;
16
+ max-height: 700px;
17
+ overflow: auto;
18
+ }
19
+
20
+ button {
21
+ margin: 12px;
22
+ height: 50px;
23
+ width: 200px;
24
+ }
25
+
26
+ input[type="text"] {
27
+ margin: 20px;
28
+ height: 30px;
29
+ width: 180px;
30
+ }
31
+
32
+ input[type="checkbox"] {
33
+ height: 30px;
34
+ width: 30px;
35
+ }
36
+
37
+ input[type="radio"] {
38
+ height: 30px;
39
+ width: 30px;
40
+ }
41
+
42
+ select {
43
+ margin-left: 40px;
44
+ height: 30px;
45
+ width: 180px;
46
+ }
47
+
48
+ .my-css {
49
+ font-size: 20px;
50
+ }
51
+ }
@@ -0,0 +1,10 @@
1
+ import { css } from 'nextia'
2
+ import './style.css'
3
+
4
+ export default function HttpNotFoundPage() {
5
+ return (
6
+ <section className={css('HttpNotFoundPage')}>
7
+ <h5>Not Found</h5>
8
+ </section>
9
+ )
10
+ }
@@ -0,0 +1,2 @@
1
+ .HttpNotFoundPage {
2
+ }
@@ -0,0 +1,3 @@
1
+ const initialState = {}
2
+
3
+ export default { initialState }
@@ -0,0 +1,20 @@
1
+ import { Icon, Svg } from 'components'
2
+ import { css, useFx } from 'nextia'
3
+ import functions from './functions'
4
+ import './style.css'
5
+ import exitSvg from 'theme/icons/exit.svg?raw'
6
+
7
+ export default function IconsPage() {
8
+ const { state, fx } = useFx(functions)
9
+
10
+ return (
11
+ <section className={css('IconsPage', '')}>
12
+ <Icon id="globe" width="32" />
13
+ <Icon id="camera" width="32" />
14
+ <Icon id="video" width="32" />
15
+ <br />
16
+ <br />
17
+ <Svg src={exitSvg} width="32" />
18
+ </section>
19
+ )
20
+ }
@@ -0,0 +1,5 @@
1
+ .IconsPage {
2
+ svg {
3
+ margin-right: 10px;
4
+ }
5
+ }
@@ -0,0 +1,3 @@
1
+ const initialState = {}
2
+
3
+ export default { initialState }
@@ -0,0 +1,20 @@
1
+ import image from 'assets/img/image.jpg'
2
+ import { css, useFx } from 'nextia'
3
+ import functions from './functions'
4
+ import './style.css'
5
+
6
+ export default function ImagesPage() {
7
+ const { state, fx } = useFx(functions)
8
+
9
+ return (
10
+ <section className={css('ImagesPage', '')}>
11
+ <br />
12
+ <p>css-img</p>
13
+ <div className="css-img" />
14
+
15
+ <br />
16
+ <p>img</p>
17
+ <img src={image} alt="img" height={200} />
18
+ </section>
19
+ )
20
+ }
@@ -0,0 +1,8 @@
1
+ .ImagesPage {
2
+ .css-img {
3
+ background: url("assets/img/image.jpg") no-repeat;
4
+ height: 200px;
5
+ background-repeat: no-repeat;
6
+ background-size: contain;
7
+ }
8
+ }