Skip to content

Commit e9f4956

Browse files
committed
Add literal prop typing support
1 parent 73fd470 commit e9f4956

File tree

6 files changed

+50
-2
lines changed

6 files changed

+50
-2
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
ignore_props = ['ignored_prop']
2+
3+
custom_imports = {
4+
"*": ["import json"]
5+
}
6+
7+
def generate_style(*_):
8+
return "dict"
9+
10+
custom_props = {
11+
"*": {
12+
"obj": generate_style
13+
}
14+
}

@plotly/dash-generator-test-component-typescript/generator.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,23 @@ describe('Test Typescript component metadata generation', () => {
271271
);
272272
expect(objectOfComponents).toBe("node");
273273
}
274+
);
275+
276+
test(
277+
'union and literal values', () => {
278+
const propType = R.path(
279+
propPath('TypeScriptComponent', 'union_enum').concat(
280+
'type'
281+
),
282+
metadata
283+
);
284+
expect(propType.name).toBe('union');
285+
expect(propType.value.length).toBe(3);
286+
expect(propType.value[0].name).toBe('number');
287+
expect(propType.value[1].name).toBe('literal');
288+
expect(propType.value[2].name).toBe('literal');
289+
expect(propType.value[1].value).toBe('small');
290+
}
274291
)
275292
});
276293

@plotly/dash-generator-test-component-typescript/src/props.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export type TypescriptComponentProps = {
4747

4848
object_of_string?: {[k: string]: string};
4949
object_of_components?: {[k: string]: JSX.Element};
50+
ignored_prop?: {ignore: {me: string}};
51+
union_enum?: number | 'small' | 'large'
5052
};
5153

5254
export type WrappedHTMLProps = {

dash/development/_generate_prop_types.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Generate it instead with the provided metadata.json
33
# for them to be able to report invalid prop
44

5+
import json
56
import os
67
import re
78

@@ -79,6 +80,10 @@ def generate_tuple(*_):
7980
return "pt.array"
8081

8182

83+
def generate_literal(prop_info):
84+
return f"pt.oneOf([{json.dumps(prop_info['value'])}])"
85+
86+
8287
prop_types = {
8388
"array": generate_type("array"),
8489
"arrayOf": generate_array_of,
@@ -97,6 +102,7 @@ def generate_tuple(*_):
97102
"enum": generate_enum,
98103
"objectOf": generate_object_of,
99104
"tuple": generate_tuple,
105+
"literal": generate_literal,
100106
}
101107

102108

dash/development/_py_prop_typing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ def generate_enum(type_info, *_):
140140
return f"Literal[{', '.join(values)}]"
141141

142142

143+
def generate_literal(type_info, *_):
144+
return f"Literal[{json.dumps(type_info['value'])}]"
145+
146+
143147
def _get_custom_prop(custom_props, component_name, prop_name):
144148
customs = custom_props.get(component_name) or custom_props.get("*", {})
145149
return customs.get(prop_name)
@@ -193,4 +197,5 @@ def get_prop_typing(
193197
"enum": generate_enum,
194198
"objectOf": generate_object_of,
195199
"tuple": generate_tuple,
200+
"literal": generate_literal,
196201
}

dash/extract-meta.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const BANNED_TYPES = [
6767
'ChildNode',
6868
'ParentNode',
6969
];
70-
const unionSupport = PRIMITIVES.concat('boolean', 'Element');
70+
const unionSupport = PRIMITIVES.concat('boolean', 'Element', 'enum');
7171

7272
const reArray = new RegExp(`(${unionSupport.join('|')})\\[\\]`);
7373

@@ -261,12 +261,16 @@ function gatherComponents(sources, components = {}) {
261261
typeName = 'object';
262262
}
263263
}
264+
if (t.value) {
265+
// A literal value
266+
return true;
267+
}
264268
return (
265269
unionSupport.includes(typeName) ||
266270
isArray(checker.typeToString(t))
267271
);
268272
})
269-
.map(t => getPropType(t, propObj, parentType));
273+
.map(t => t.value ? {name: 'literal', value: t.value} : getPropType(t, propObj, parentType));
270274

271275
if (!value.length) {
272276
name = 'any';

0 commit comments

Comments
 (0)