jtsx-loader 0.1.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.
@@ -0,0 +1,231 @@
1
+ body {
2
+ font-family: Raleway, Arial, Helvetica, sans-serif;
3
+ font-weight: 400;
4
+ font-style: normal;
5
+ line-height: 1.5;
6
+ font-size: 16px;
7
+ color: #fff;
8
+ background-color: #151515;
9
+ padding: 40px 80px;
10
+ }
11
+
12
+ h1, h2, h3, h4 {
13
+ font-weight: 600;
14
+ font-style: normal;
15
+ margin: 10px 0;
16
+ }
17
+
18
+ h1 {
19
+ font-size: 42px;
20
+ }
21
+
22
+ h1 small {
23
+ font-size: 14px;
24
+ display: inline-block;
25
+ vertical-align: top;
26
+ font-weight: normal;
27
+ }
28
+
29
+ h2 {
30
+ font-size: 36px;
31
+ margin-top: 40px;
32
+ }
33
+
34
+ h2:nth-of-type(n + 2) {
35
+ margin-top: 30px;
36
+ margin-bottom: 20px;
37
+ }
38
+
39
+ h3 {
40
+ padding: 10px 20px;
41
+ border-radius: 8px;
42
+ background-color: #000;
43
+ margin-left: -20px;
44
+
45
+ font-size: 28px;
46
+ }
47
+
48
+ h4 {
49
+ padding: 8px 20px;
50
+ border-radius: 8px;
51
+ background-color: #000;
52
+ margin-left: -20px;
53
+
54
+ font-size: 20px;
55
+ /* letter-spacing: 0.5px; */
56
+ /* text-transform: uppercase; */
57
+ margin-top: 50px;
58
+ }
59
+
60
+ h3:nth-of-type(n + 2) {
61
+ margin-top: 30px;
62
+ margin-bottom: 20px;
63
+ }
64
+
65
+ code {
66
+ font-size: 16px;
67
+ padding: 3px 5px;
68
+ border-radius: 4px;
69
+ background-color: #02c;
70
+ }
71
+
72
+ pre {
73
+ margin: 5px 0;
74
+ padding: 7px 10px;
75
+ border-radius: 8px;
76
+ background-color: #1e213a;
77
+ }
78
+
79
+ p {
80
+ margin: 14px 0;
81
+ }
82
+
83
+ section {
84
+ }
85
+
86
+ a {
87
+ color: #fff;
88
+ }
89
+
90
+ main {
91
+ display: flex;
92
+ justify-content: center;
93
+ }
94
+
95
+ .container {
96
+ max-width: 800px;
97
+ }
98
+
99
+ .lang a {
100
+ color: #fff;
101
+ display: inline-block;
102
+ text-decoration: none;
103
+ padding: 4px 10px;
104
+ border-radius: 6px;
105
+ background-color: #00000000;
106
+ }
107
+
108
+ .lang a.is-active {
109
+ pointer-events: none;
110
+ background-color: #0026e6;
111
+ }
112
+
113
+ .item {
114
+ padding: 20px 0;
115
+ border-radius: 16px;
116
+ /* background-color: #000; */
117
+ }
118
+
119
+ .examples {
120
+ display: inline-flex;
121
+ flex-direction: column;
122
+ gap: 20px;
123
+ }
124
+
125
+ .svg-icon {
126
+ width: 100%;
127
+ height: auto;
128
+ }
129
+
130
+ @keyframes scaleX {
131
+ from {
132
+ transform: scaleX(0);
133
+ }
134
+
135
+ to {
136
+ transform: scaleX(1);
137
+ }
138
+ }
139
+
140
+ @keyframes scaleY {
141
+ from {
142
+ transform: scaleY(0);
143
+ }
144
+
145
+ to {
146
+ transform: scaleY(1);
147
+ }
148
+ }
149
+
150
+ .logo {
151
+ width: 160px;
152
+ position: relative;
153
+ display: inline-flex;
154
+ flex-flow: column nowrap;
155
+ align-items: flex-end;
156
+ margin-bottom: 60px;
157
+ }
158
+
159
+ .logo__link {
160
+ display: inline-flex;
161
+ padding-right: 35px;
162
+ transition: opacity 0.3s;
163
+ }
164
+
165
+ .logo__visual {
166
+ line-height: 0;
167
+ margin-bottom: 4px;
168
+ position: relative;
169
+ width: 50px;
170
+ height: 17px;
171
+ }
172
+
173
+ .logo__visual::before,
174
+ .logo__visual::after {
175
+ content: '';
176
+ position: absolute;
177
+ transform-origin: center;
178
+ }
179
+
180
+ .logo__visual::before {
181
+ left: 0;
182
+ top: 50%;
183
+ width: 100%;
184
+ height: 1px;
185
+ margin-top: -0.5px;
186
+ background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 50%, rgba(0,0,0,0) 100%);
187
+ animation: scaleX .5s ease .05s forwards;
188
+ transform: scaleX(0);
189
+ }
190
+
191
+ .logo__visual::after {
192
+ top: 0;
193
+ left: 50%;
194
+ height: 100%;
195
+ width: 1px;
196
+ background: linear-gradient(0deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 50%, rgba(0,0,0,0) 100%);
197
+ animation: scaleY .5s ease .1s forwards;
198
+ transform: scaleY(0);
199
+ }
200
+
201
+ .logo--white svg {
202
+ fill: #fff;
203
+ }
204
+
205
+ .logo--white .logo__visual::before {
206
+ background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 50%, rgba(255,255,255,0) 100%);
207
+ }
208
+
209
+ .logo--white .logo__visual::after {
210
+ background: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 50%, rgba(255,255,255,0) 100%);
211
+ }
212
+
213
+ .component-container {
214
+ border-radius: 16px;
215
+ padding: 5px 30px;
216
+ background-color: hsl(240, 100%, 0%);
217
+ }
218
+
219
+ .render-count span {
220
+ font-weight: bold;
221
+ color: hsl(20, 100%, 50%);
222
+ }
223
+
224
+ .myClassName {
225
+ padding: 10px;
226
+ margin-left: -10px;
227
+ border: 1px solid #fff;
228
+ border-top: none;
229
+ border-bottom: none;
230
+ border-radius: 8px;
231
+ }
@@ -0,0 +1 @@
1
+ @import url('./default.css');
@@ -0,0 +1,137 @@
1
+ import possibleAttributes from './possibleAttributes.js';
2
+ import path from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import _jsxUtils, { escapeHtml } from './jsxUtils.js';
5
+
6
+ // WARN: сделать вставку html без аттрибута нельзя, потому что тогда нужно писать новый синтаксис для vscode
7
+ const configUrl = pathToFileURL(path.join(process.cwd(), 'jtsx.config.js'));
8
+ const loadedConfig = (await import(configUrl.href).catch(() => ({}))).default;
9
+
10
+ let config = {
11
+ attributeParser: {},
12
+ ...loadedConfig
13
+ };
14
+
15
+ // Какие аттрибуты должны быть заменены
16
+ const AttributeMapper = (val) => ({
17
+ tabIndex: 'tabindex',
18
+ className: 'class',
19
+ readOnly: 'readonly',
20
+ }[val] || val);
21
+
22
+ const voidElements = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr'];
23
+ const isVoidElt = (tagName) => voidElements.includes(tagName);
24
+ const spacer = ' ';
25
+
26
+ const objectIntoAttrs = (object) => {
27
+ if (!object) return '';
28
+
29
+ const attrMap = Object.keys(object).map((attr, i) => {
30
+ const value = object[attr];
31
+ let finalValue;
32
+
33
+ if (typeof value === 'function') {
34
+ // TODO: в ошибках показывать файл и возможно строку
35
+ console.warn(`Inline functions not allowed. Attribute ${attr} will be ignored:`);
36
+ console.warn(value.toString());
37
+ return;
38
+ }
39
+
40
+ const customAttr = attr.split(':')?.[0];
41
+
42
+ if (customAttr && config?.attributeParser?.[customAttr]) {
43
+ const customAttrVal = config.attributeParser[customAttr](attr, value);
44
+ console.assert(attr, `The function "config.attributeParser['${customAttr}']" is expected to return new attribute and value`);
45
+
46
+ return spacer + customAttrVal;
47
+ }
48
+
49
+ if (attr === '__raw' || attr === '__escape') {
50
+ return; // prevent attribute rendering
51
+ }
52
+
53
+ if (attr.toLowerCase() === 'classname') {
54
+ attr = 'class';
55
+ }
56
+
57
+ if (possibleAttributes[attr] && possibleAttributes[attr] !== attr) {
58
+ console.warn(`Warning! Replace "${attr}" with native html property "${possibleAttributes[attr]}"`);
59
+ }
60
+
61
+ if (attr === 'style' && typeof value === 'object') {
62
+ finalValue = Object.keys(value).map((key, i) => {
63
+ const v = value[key];
64
+ return `${key}: ${v};`;
65
+ }).join(' ');
66
+ } else {
67
+ finalValue = value;
68
+ }
69
+
70
+ if (!finalValue) {
71
+ return;
72
+ }
73
+
74
+ const result = spacer + `${attr}="${finalValue}"`;
75
+
76
+ return result;
77
+ })
78
+ .filter(a => a);
79
+
80
+ return attrMap;
81
+ }
82
+
83
+ const joinChildrens = (children) => {
84
+ return children.map(c => {
85
+ if (Array.isArray(c)) {
86
+ return c.join(spacer);
87
+ }
88
+
89
+ return c;
90
+ }).filter(c => c !== false)
91
+ }
92
+
93
+ const createTag = (tagName, attrs, children) => {
94
+ const attributes = objectIntoAttrs(attrs);
95
+ const tagArray = [
96
+ '<',
97
+ tagName,
98
+ ...attributes
99
+ ]
100
+
101
+ tagArray.push(isVoidElt(tagName) ? '/>' : '>');
102
+ tagArray.push(...joinChildrens(children));
103
+
104
+ if (attrs?.__raw) { tagArray.push(attrs.__raw) }
105
+
106
+ if (attrs?.__escape) { tagArray.push(escapeHtml(attrs.__escape)) }
107
+
108
+ !isVoidElt(tagName) && tagArray.push('</' + tagName + '>');
109
+
110
+ const result = tagArray.join('');
111
+
112
+ return result;
113
+ }
114
+
115
+ const _jsx = (tagName, attrs, ...children) => {
116
+ try {
117
+ if (typeof tagName === 'function') {
118
+ return tagName({ ...attrs, children: children.length === 1 ? children[0] : children });
119
+ }
120
+
121
+ const tag = createTag(tagName, attrs, children);
122
+ return tag;
123
+ } catch (error) {
124
+ throw new Error(error);
125
+ }
126
+ }
127
+
128
+ const _jsxFragment = ({ children, ...attrs }) => {
129
+ return children.join(' ');
130
+ }
131
+
132
+ /* export {
133
+ DOMcreateElement as h,
134
+ DOMcreateFragment as Fragment,
135
+ } */
136
+
137
+ export { _jsx, _jsxFragment, _jsxUtils }
@@ -0,0 +1,18 @@
1
+ const entityMap = {
2
+ "&": 'amp',
3
+ "<": 'lt',
4
+ ">": 'gt',
5
+ '"': 'quot',
6
+ "'": '#39',
7
+ "/": '#x2F',
8
+ };
9
+
10
+ const escapeHtml = (str) => String(str).replace(/[&<>"'\/\\]/g, (s) => `&${entityMap[s]};`);
11
+
12
+ export default {
13
+ escapeHtml
14
+ }
15
+
16
+ export {
17
+ escapeHtml
18
+ }