@uiw/react-json-view 0.0.1

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/src/value.tsx ADDED
@@ -0,0 +1,172 @@
1
+ import { FC, Fragment, PropsWithChildren } from 'react';
2
+
3
+ const isFloat = (n: number) => (Number(n) === n && n % 1 !== 0) || isNaN(n);
4
+ export const typeMap = {
5
+ string: {
6
+ color: 'var(--w-rjv-type-string-color, #cb4b16)',
7
+ label: 'string',
8
+ },
9
+ number: {
10
+ color: 'var(--w-rjv-type-int-color, #268bd2)',
11
+ label: 'int',
12
+ },
13
+ float: {
14
+ color: 'var(--w-rjv-type-float-color, #859900)',
15
+ label: 'float',
16
+ },
17
+ bigint: {
18
+ color: 'var(--w-rjv-type-bigint-color, #268bd2)',
19
+ label: 'bigint',
20
+ },
21
+ boolean: {
22
+ color: 'var(--w-rjv-type-boolean-color, #2aa198)',
23
+ label: 'bool',
24
+ },
25
+ date: {
26
+ color: 'var(--w-rjv-type-date-color, #586e75)',
27
+ label: 'date',
28
+ },
29
+ null: {
30
+ color: 'var(--w-rjv-type-null-color, #d33682)',
31
+ label: 'null',
32
+ },
33
+ NaN: {
34
+ color: 'var(--w-rjv-type-nan-color, #859900)',
35
+ label: 'NaN',
36
+ },
37
+ undefined: {
38
+ color: 'var(--w-rjv-type-undefined-color, #586e75)',
39
+ label: 'undefined',
40
+ },
41
+ };
42
+
43
+ export const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>> = ({
44
+ children = ':',
45
+ style,
46
+ ...props
47
+ }) => (
48
+ <span className="w-rjv-colon" style={{ paddingRight: 3, ...style }} {...props}>
49
+ {children}
50
+ </span>
51
+ );
52
+
53
+ export interface ValueViewProps<T>
54
+ extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
55
+ keyName?: string;
56
+ value: T;
57
+ displayDataTypes: boolean;
58
+ renderKey?: JSX.Element;
59
+ renderValue?: (props: React.HTMLAttributes<HTMLSpanElement> & { type: TypeProps['type'] }) => JSX.Element;
60
+ }
61
+
62
+ export function ValueView<T>(props: ValueViewProps<T>) {
63
+ const { value, keyName, renderKey, renderValue, displayDataTypes, ...reset } = props;
64
+
65
+ let type = typeof value as TypeProps['type'];
66
+ let content = '';
67
+ let color = '';
68
+ let style = {} as React.CSSProperties;
69
+ if (typeof value === 'number') {
70
+ type = isFloat(value) ? 'float' : 'number';
71
+ content = value.toString();
72
+ }
73
+ if (typeof value === 'boolean') {
74
+ type = 'boolean';
75
+ content = value.toString();
76
+ }
77
+ if (typeof value === 'object' && value instanceof Date) {
78
+ type = 'date';
79
+ content = value.toString();
80
+ }
81
+ let typeView = <Type type={type} />;
82
+ if (value === null) {
83
+ type = 'null';
84
+ content = `${value}`.toLocaleUpperCase();
85
+ typeView = <Fragment />;
86
+ style = { fontWeight: 'bold' };
87
+ }
88
+ if (value === undefined) {
89
+ type = 'undefined';
90
+ content = String(value);
91
+ typeView = <Fragment />;
92
+ }
93
+ if (typeof value === 'bigint') {
94
+ type = 'bigint';
95
+ content = `${value}n`;
96
+ }
97
+ if (typeof value === 'string') {
98
+ content = `"${value}"`;
99
+ }
100
+
101
+ if (!displayDataTypes) {
102
+ typeView = <Fragment />;
103
+ }
104
+ color = typeMap[type]?.color || '';
105
+ if (content && typeof content === 'string') {
106
+ const valueView = renderValue ? (
107
+ renderValue({
108
+ className: 'w-rjv-value',
109
+ style: { color, ...style },
110
+ type,
111
+ children: content,
112
+ })
113
+ ) : (
114
+ <Label color={color} style={style} className="w-rjv-value">
115
+ {content}
116
+ </Label>
117
+ );
118
+ return (
119
+ <Label {...reset}>
120
+ {renderKey}
121
+ <Colon />
122
+ {typeView}
123
+ {valueView}
124
+ </Label>
125
+ );
126
+ }
127
+ return (
128
+ <Label {...reset}>
129
+ {renderKey}
130
+ <Colon />
131
+ {typeView}
132
+ </Label>
133
+ );
134
+ }
135
+
136
+ export interface LabelProps extends React.HTMLAttributes<HTMLSpanElement> {
137
+ color?: string;
138
+ fontSize?: number;
139
+ opacity?: number;
140
+ paddingRight?: number;
141
+ }
142
+
143
+ export const Label: FC<PropsWithChildren<LabelProps>> = ({
144
+ children,
145
+ color,
146
+ fontSize,
147
+ opacity,
148
+ paddingRight,
149
+ style,
150
+ ...reset
151
+ }) => (
152
+ <span style={{ color, fontSize, opacity, paddingRight, ...style }} {...reset}>
153
+ {children}
154
+ </span>
155
+ );
156
+
157
+ export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
158
+ type: keyof typeof typeMap;
159
+ }
160
+
161
+ export const Type: FC<PropsWithChildren<TypeProps>> = (props) => {
162
+ const { type } = props;
163
+ const color = typeMap[type]?.color;
164
+ const label = typeMap[type]?.label;
165
+ if (color && label) {
166
+ return (
167
+ <Label color={color} fontSize={11} opacity={0.8} paddingRight={4} className="w-rjv-type" data-type={type}>
168
+ {label}
169
+ </Label>
170
+ );
171
+ }
172
+ };