Skip to content

Commit 574521c

Browse files
committed
🍚 Add html & svg components.
1 parent c2c62cc commit 574521c

File tree

181 files changed

+2165
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+2165
-6
lines changed

.prettierignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
src/html/components
2+
src/svg

dazzler/assets/meta-ts.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ function walk(directory, components = {}) {
136136
return 'bool';
137137
} else if (propName === '[]') {
138138
return 'array';
139-
} else if (propName === 'Element') {
139+
} else if (
140+
propName === 'Element'
141+
|| propName === 'ReactNode'
142+
|| propName === 'ReactElement'
143+
) {
140144
return 'node';
141145
}
142146
return propName
@@ -265,7 +269,7 @@ function walk(directory, components = {}) {
265269
tags.map((t) =>
266270
R.concat(
267271
['@', t.name],
268-
t.text.map((e) => e.text)
272+
(t.text || []).map((e) => e.text)
269273
)
270274
)
271275
)
@@ -285,7 +289,9 @@ function walk(directory, components = {}) {
285289

286290
// There is only one parameter for functional components: props
287291
const p = params[0];
288-
if (p.name === 'props' || params.length === 1) return p;
292+
if (p.name === 'props' || params.length === 1) {
293+
return p;
294+
}
289295
}
290296
return null;
291297
};

dazzler/components/html/__init__.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from dazzler.system import (
2+
Package as _Package,
3+
assets_to_requirements as _ass_to_req
4+
)
5+
6+
from dazzler._assets import (
7+
assets as _assets,
8+
assets_dev as _dev,
9+
assets_dist_path as _dist_path,
10+
assets_dev_path as _dev_path,
11+
)
12+
13+
from ._imports_ import * # noqa: F401, F403
14+
from ._imports_ import __all__
15+
16+
_name = 'html'
17+
_package_name = f'dazzler_{_name}'
18+
19+
20+
_components = []
21+
for _c in __all__:
22+
_components.append(locals()[_c])
23+
24+
package = _Package(
25+
_package_name,
26+
components=_components,
27+
requirements=_ass_to_req(
28+
_dist_path, _assets.get(_name, {}),
29+
dev_data=_dev.get(_name, {}),
30+
dev_path=_dev_path,
31+
package_name=_package_name,
32+
)
33+
)

dazzler/components/svg/__init__.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from dazzler.system import (
2+
Package as _Package,
3+
assets_to_requirements as _ass_to_req
4+
)
5+
6+
from dazzler._assets import (
7+
assets as _assets,
8+
assets_dev as _dev,
9+
assets_dist_path as _dist_path,
10+
assets_dev_path as _dev_path,
11+
)
12+
13+
from ._imports_ import * # noqa: F401, F403
14+
from ._imports_ import __all__
15+
16+
_name = 'svg'
17+
_package_name = f'dazzler_{_name}'
18+
19+
20+
_components = []
21+
for _c in __all__:
22+
_components.append(locals()[_c])
23+
24+
package = _Package(
25+
_package_name,
26+
components=_components,
27+
requirements=_ass_to_req(
28+
_dist_path, _assets.get(_name, {}),
29+
dev_data=_dev.get(_name, {}),
30+
dev_path=_dev_path,
31+
package_name=_package_name,
32+
)
33+
)

dazzler/system/_generator.py

+4
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ async def generate_components(metadata, output_path, executor):
341341

342342
for data in metadata.values():
343343
name = data['displayName']
344+
props = data.get('props')
345+
if not props:
346+
print(f'Invalid component {name}')
347+
continue
344348
names.append(name)
345349
futures.append(
346350
executor.execute(

justfile

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ install:
1515
alias i := install
1616

1717
# Build everything
18-
build:
18+
build: html-generator
1919
npm run build
2020

2121
alias b := build
@@ -84,6 +84,10 @@ electron:
8484
electron-build TARGET="dir":
8585
dazzler -c tests/electron/dazzler.toml electron-build tests/electron/electron_app.py --target {{TARGET}}
8686

87+
# Build the html & svg components.
88+
html-generator:
89+
node src/html/html-generator.js
90+
8791
# Generate a component package:
8892
generate PACKAGE *ARGS:
8993
dazzler generate {{src}}/{{PACKAGE}}/js/components {{components}}/{{PACKAGE}} {{ARGS}}

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"build:electron:components": "webpack --config webpack.electron-renderer.config.js",
1414
"build:electron:components::dev": "npm run build:electron:components -- --mode=development",
1515
"build:dazzler::core": "dazzler generate src/core/js/components dazzler/components/core --ts",
16+
"build:dazzler::html": "dazzler generate src/html/components dazzler/components/html --ts",
17+
"build:dazzler::svg": "dazzler generate src/svg/components dazzler/components/svg --ts",
1618
"build:dazzler::test": "dazzler generate src/internal/test_components/components tests/components/spec_components",
1719
"build:dazzler::ts": "dazzler generate src/internal/ts_components/components tests/components/ts_components --ts",
1820
"build:dazzler::extra": "dazzler generate src/extra/js/components dazzler/components/extra --ts",
@@ -21,7 +23,7 @@
2123
"build:dazzler::auth": "dazzler generate src/auth/js/components dazzler/components/auth --ts",
2224
"build:dazzler::icons": "dazzler generate src/icons/js/components dazzler/components/icons",
2325
"build:dazzler::electron": "dazzler generate src/electron/renderer/components dazzler/components/electron --ts",
24-
"build:dazzler": "run-p build:dazzler::core build:dazzler::test build:dazzler::extra build:dazzler::calendar build:dazzler::markdown build:dazzler::auth build:dazzler::icons build:dazzler::ts build:dazzler::electron",
26+
"build:dazzler": "run-p build:dazzler::core build:dazzler::test build:dazzler::extra build:dazzler::calendar build:dazzler::markdown build:dazzler::auth build:dazzler::icons build:dazzler::ts build:dazzler::electron build:dazzler::html build:dazzler::svg",
2527
"build:docs": "docs/build.sh",
2628
"build": "run-s build:webpack build:dev build:electron build:electron:components build:electron:components::dev",
2729
"watch": "npm run build:dev -- --watch",

src/commons/js/casing.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {last, slice, toPairs} from 'ramda';
2+
import {AnyDict} from './types';
23

34
export function camelToSnakeCase(s: string): string {
45
return s
@@ -38,7 +39,10 @@ export function camelToSpinal(s: string): string {
3839
.reduce((p, n) => p + n);
3940
}
4041

41-
export function transformKeys(obj: object, transform: Function): object {
42+
export function transformKeys(
43+
obj: AnyDict,
44+
transform: typeof camelToSnakeCase
45+
): AnyDict {
4246
// @ts-ignore
4347
return toPairs(obj).reduce((a, [k, v]) => {
4448
a[transform(k)] = v;

src/commons/js/enhancer.ts

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {DazzlerHtmlProps, UpdateAspectFunc} from './types';
2+
import {assoc, omit, pipe, pick} from 'ramda';
3+
4+
const omittedProps = [
5+
'class_name',
6+
'identity',
7+
'updateAspects',
8+
'handle_clicks',
9+
'clicks',
10+
'handle_hover',
11+
'is_hovered',
12+
'handle_load',
13+
'is_loaded',
14+
'handle_keys',
15+
'last_key',
16+
'handle_focus',
17+
'is_focused',
18+
];
19+
20+
const clickKeys = [
21+
'altKey',
22+
'button',
23+
'buttons',
24+
'clientX',
25+
'clientY',
26+
'ctrlKey',
27+
'metaKey',
28+
'movementX',
29+
'movementY',
30+
'offsetX',
31+
'offsetY',
32+
'pageX',
33+
'pageY',
34+
'screenX',
35+
'screenY',
36+
'shiftKey',
37+
'x',
38+
'y',
39+
];
40+
41+
const onClick =
42+
(clicks: number, updateAspects: UpdateAspectFunc) => (event: MouseEvent) =>
43+
updateAspects({
44+
clicks: (clicks || 0) + 1,
45+
click_event: pick(clickKeys, event),
46+
});
47+
48+
const updateFactory =
49+
<T>(key: string, value: T, updateAspects: UpdateAspectFunc) =>
50+
() =>
51+
updateAspects({[key]: value});
52+
53+
export function enhanceProps(props: DazzlerHtmlProps) {
54+
let newProps: any = {
55+
...omit(omittedProps, props),
56+
className: props.class_name,
57+
id: props.id || props.identity,
58+
};
59+
if (props.handle_clicks) {
60+
newProps = assoc(
61+
'onClick',
62+
onClick(props.clicks, props.updateAspects),
63+
newProps
64+
);
65+
}
66+
if (props.handle_hover) {
67+
newProps = pipe(
68+
assoc(
69+
'onMouseEnter',
70+
updateFactory('is_hovered', true, props.updateAspects)
71+
),
72+
assoc(
73+
'onMouseLeave',
74+
updateFactory('is_hovered', false, props.updateAspects)
75+
)
76+
)(newProps);
77+
}
78+
if (props.handle_focus) {
79+
newProps = pipe(
80+
assoc(
81+
'onFocus',
82+
updateFactory('is_focused', true, props.updateAspects)
83+
),
84+
assoc(
85+
'onBlur',
86+
updateFactory('is_focused', false, props.updateAspects)
87+
)
88+
)(newProps);
89+
}
90+
return newProps;
91+
}

src/commons/js/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
transformKeys,
1919
} from './casing';
2020
import {getCommonStyles, getPresetsClassNames} from './styling';
21+
import {enhanceProps} from './enhancer';
2122

2223
export {
2324
toTimestamp,
@@ -35,4 +36,5 @@ export {
3536
getCommonStyles,
3637
getPresetsClassNames,
3738
throttle,
39+
enhanceProps,
3840
};

src/commons/js/types.d.ts

+34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {AriaAttributes, DOMAttributes} from 'react';
2+
13
type Dict<T> = {[key: string]: T};
24
type StringDict = {[key: string]: string};
35
type AnyDict = Dict<any>;
@@ -196,3 +198,35 @@ export interface CommonPresetsProps {
196198
*/
197199
preset_size?: PresetSize;
198200
}
201+
202+
type DazzlerHtmlProps = {
203+
id?: string;
204+
205+
handle_clicks?: boolean;
206+
clicks?: number;
207+
click_event?: any;
208+
209+
handle_hover?: boolean;
210+
is_hovered?: boolean;
211+
212+
handle_load?: boolean;
213+
is_loaded?: boolean;
214+
215+
handle_focus?: boolean;
216+
is_focused?: boolean;
217+
} & DazzlerProps;
218+
219+
type InvalidHtmlProps =
220+
| 'dangerouslySetInnerHTML'
221+
| 'defaultChecked'
222+
| 'defaultValue'
223+
| 'suppressContentEditableWarning'
224+
| 'suppressHydrationWarning'
225+
| 'className'
226+
| 'ref'
227+
| 'key'
228+
| 'async';
229+
230+
type EventsProps = keyof Omit<DOMAttributes<any>, 'children'>;
231+
type AriaProps = keyof AriaAttributes;
232+
type HtmlOmittedProps = InvalidHtmlProps | EventsProps | AriaProps;

src/html/components/A.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const A = (props: Props) => <a {...enhanceProps(props)} />
8+
9+
export default React.memo(A);

src/html/components/Abbr.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Abbr = (props: Props) => <abbr {...enhanceProps(props)} />
8+
9+
export default React.memo(Abbr);

src/html/components/Address.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Address = (props: Props) => <address {...enhanceProps(props)} />
8+
9+
export default React.memo(Address);

src/html/components/Area.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.AreaHTMLAttributes<HTMLAreaElement>, HTMLAreaElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Area = (props: Props) => <area {...enhanceProps(props)} />
8+
9+
export default React.memo(Area);

src/html/components/Article.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Article = (props: Props) => <article {...enhanceProps(props)} />
8+
9+
export default React.memo(Article);

src/html/components/Aside.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Aside = (props: Props) => <aside {...enhanceProps(props)} />
8+
9+
export default React.memo(Aside);

src/html/components/Audio.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.AudioHTMLAttributes<HTMLAudioElement>, HTMLAudioElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const Audio = (props: Props) => <audio {...enhanceProps(props)} />
8+
9+
export default React.memo(Audio);

src/html/components/B.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
import {enhanceProps} from 'commons';
3+
import {HtmlOmittedProps, DazzlerHtmlProps} from '../../commons/js/types';
4+
5+
type Props = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, HtmlOmittedProps> & DazzlerHtmlProps;
6+
7+
const B = (props: Props) => <b {...enhanceProps(props)} />
8+
9+
export default React.memo(B);

0 commit comments

Comments
 (0)