@spark-web/field 0.0.0-snapshot-release-20260409001813
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/CHANGELOG.md +965 -0
- package/CLAUDE.md +80 -0
- package/README.md +132 -0
- package/dist/declarations/src/context.d.ts +15 -0
- package/dist/declarations/src/field.d.ts +53 -0
- package/dist/declarations/src/index.d.ts +4 -0
- package/dist/spark-web-field.cjs.d.ts +2 -0
- package/dist/spark-web-field.cjs.dev.js +212 -0
- package/dist/spark-web-field.cjs.js +7 -0
- package/dist/spark-web-field.cjs.prod.js +212 -0
- package/dist/spark-web-field.esm.js +204 -0
- package/package.json +39 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var react$1 = require('@emotion/react');
|
|
7
|
+
var a11y = require('@spark-web/a11y');
|
|
8
|
+
var box = require('@spark-web/box');
|
|
9
|
+
var icon = require('@spark-web/icon');
|
|
10
|
+
var stack = require('@spark-web/stack');
|
|
11
|
+
var text = require('@spark-web/text');
|
|
12
|
+
var theme = require('@spark-web/theme');
|
|
13
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
14
|
+
|
|
15
|
+
var FieldContext = /*#__PURE__*/react.createContext(null);
|
|
16
|
+
var FieldContextProvider = FieldContext.Provider;
|
|
17
|
+
var FIELD_CONTEXT_ERROR_MESSAGE = 'Input components must be inside a `Field`.';
|
|
18
|
+
function useFieldContext() {
|
|
19
|
+
var ctx = react.useContext(FieldContext);
|
|
20
|
+
if (!ctx) {
|
|
21
|
+
throw new Error(FIELD_CONTEXT_ERROR_MESSAGE);
|
|
22
|
+
}
|
|
23
|
+
return ctx;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Using a [context](https://reactjs.org/docs/context.html), the field
|
|
28
|
+
* component connects the label, description, and message to the input element.
|
|
29
|
+
*/
|
|
30
|
+
var Field = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
|
|
31
|
+
var children = _ref.children,
|
|
32
|
+
idProp = _ref.id,
|
|
33
|
+
data = _ref.data,
|
|
34
|
+
description = _ref.description,
|
|
35
|
+
_ref$disabled = _ref.disabled,
|
|
36
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
37
|
+
label = _ref.label,
|
|
38
|
+
adornment = _ref.adornment,
|
|
39
|
+
_ref$labelVisibility = _ref.labelVisibility,
|
|
40
|
+
labelVisibility = _ref$labelVisibility === void 0 ? 'visible' : _ref$labelVisibility,
|
|
41
|
+
message = _ref.message,
|
|
42
|
+
secondaryLabel = _ref.secondaryLabel,
|
|
43
|
+
_ref$tone = _ref.tone,
|
|
44
|
+
tone = _ref$tone === void 0 ? 'neutral' : _ref$tone,
|
|
45
|
+
_ref$readOnly = _ref.readOnly,
|
|
46
|
+
readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly;
|
|
47
|
+
var _useFieldIds = useFieldIds(idProp),
|
|
48
|
+
descriptionId = _useFieldIds.descriptionId,
|
|
49
|
+
inputId = _useFieldIds.inputId,
|
|
50
|
+
messageId = _useFieldIds.messageId;
|
|
51
|
+
|
|
52
|
+
// field context
|
|
53
|
+
var invalid = Boolean(message && tone === 'critical');
|
|
54
|
+
var fieldContext = react.useMemo(function () {
|
|
55
|
+
return [{
|
|
56
|
+
disabled: disabled,
|
|
57
|
+
invalid: invalid,
|
|
58
|
+
readOnly: readOnly
|
|
59
|
+
}, {
|
|
60
|
+
'aria-describedby': a11y.mergeIds(message && messageId, description ? descriptionId : undefined),
|
|
61
|
+
'aria-invalid': invalid || undefined,
|
|
62
|
+
id: inputId
|
|
63
|
+
}];
|
|
64
|
+
}, [description, descriptionId, disabled, inputId, invalid, message, messageId, readOnly]);
|
|
65
|
+
|
|
66
|
+
// label prep
|
|
67
|
+
var hiddenLabel = jsxRuntime.jsxs(a11y.VisuallyHidden, {
|
|
68
|
+
as: "label",
|
|
69
|
+
htmlFor: inputId,
|
|
70
|
+
children: [label, " ", secondaryLabel]
|
|
71
|
+
});
|
|
72
|
+
var labelElement = {
|
|
73
|
+
hidden: hiddenLabel,
|
|
74
|
+
visible: jsxRuntime.jsx(box.Box, {
|
|
75
|
+
as: "label",
|
|
76
|
+
htmlFor: inputId,
|
|
77
|
+
children: jsxRuntime.jsxs(text.Text, {
|
|
78
|
+
tone: disabled || readOnly ? 'field' : 'neutral',
|
|
79
|
+
weight: "semibold",
|
|
80
|
+
children: [label, ' ', secondaryLabel && jsxRuntime.jsx(text.Text, {
|
|
81
|
+
inline: true,
|
|
82
|
+
tone: disabled || readOnly ? 'field' : 'muted',
|
|
83
|
+
weight: "regular",
|
|
84
|
+
children: secondaryLabel
|
|
85
|
+
})]
|
|
86
|
+
})
|
|
87
|
+
}),
|
|
88
|
+
'reserve-space': jsxRuntime.jsxs(react.Fragment, {
|
|
89
|
+
children: [hiddenLabel, jsxRuntime.jsx(text.Text, {
|
|
90
|
+
"aria-hidden": true,
|
|
91
|
+
children: "\xA0"
|
|
92
|
+
})]
|
|
93
|
+
})
|
|
94
|
+
};
|
|
95
|
+
var LabelWrapper = labelVisibility === 'hidden' ? react.Fragment : FieldLabelWrapper;
|
|
96
|
+
return jsxRuntime.jsx(FieldContextProvider, {
|
|
97
|
+
value: fieldContext,
|
|
98
|
+
children: jsxRuntime.jsxs(stack.Stack, {
|
|
99
|
+
ref: forwardedRef,
|
|
100
|
+
data: data,
|
|
101
|
+
gap: "medium",
|
|
102
|
+
children: [jsxRuntime.jsxs(LabelWrapper, {
|
|
103
|
+
children: [labelElement[labelVisibility], adornment]
|
|
104
|
+
}), description && (typeof description === 'string' ? jsxRuntime.jsx(text.Text, {
|
|
105
|
+
tone: "muted",
|
|
106
|
+
size: "small",
|
|
107
|
+
id: descriptionId,
|
|
108
|
+
children: description
|
|
109
|
+
}) : jsxRuntime.jsx(box.Box, {
|
|
110
|
+
as: "label",
|
|
111
|
+
htmlFor: descriptionId,
|
|
112
|
+
children: description
|
|
113
|
+
})), children, message && jsxRuntime.jsx(FieldMessage, {
|
|
114
|
+
tone: tone,
|
|
115
|
+
id: messageId,
|
|
116
|
+
message: message
|
|
117
|
+
})]
|
|
118
|
+
})
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
Field.displayName = 'Field';
|
|
122
|
+
|
|
123
|
+
// Utils
|
|
124
|
+
// ------------------------------
|
|
125
|
+
|
|
126
|
+
function useFieldIds(id) {
|
|
127
|
+
var inputId = a11y.useId(id);
|
|
128
|
+
var descriptionId = a11y.composeId(inputId, 'description');
|
|
129
|
+
var messageId = a11y.composeId(inputId, 'message');
|
|
130
|
+
return {
|
|
131
|
+
descriptionId: descriptionId,
|
|
132
|
+
inputId: inputId,
|
|
133
|
+
messageId: messageId
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Styled components
|
|
138
|
+
// ------------------------------
|
|
139
|
+
function FieldLabelWrapper(_ref2) {
|
|
140
|
+
var children = _ref2.children;
|
|
141
|
+
return jsxRuntime.jsx(box.Box, {
|
|
142
|
+
display: "flex",
|
|
143
|
+
alignItems: "center",
|
|
144
|
+
justifyContent: "spaceBetween",
|
|
145
|
+
gap: "large",
|
|
146
|
+
children: children
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
var messageToneMap = {
|
|
150
|
+
critical: 'critical',
|
|
151
|
+
neutral: 'muted',
|
|
152
|
+
positive: 'positive'
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// NOTE: use icons in addition to color for folks with visions issues
|
|
156
|
+
var messageIconMap = {
|
|
157
|
+
critical: icon.ExclamationCircleIcon,
|
|
158
|
+
neutral: null,
|
|
159
|
+
positive: icon.CheckCircleIcon
|
|
160
|
+
};
|
|
161
|
+
var FieldMessage = function FieldMessage(_ref3) {
|
|
162
|
+
var message = _ref3.message,
|
|
163
|
+
id = _ref3.id,
|
|
164
|
+
tone = _ref3.tone;
|
|
165
|
+
var textTone = messageToneMap[tone];
|
|
166
|
+
var Icon = messageIconMap[tone];
|
|
167
|
+
return jsxRuntime.jsxs(box.Box, {
|
|
168
|
+
display: "flex",
|
|
169
|
+
gap: "xsmall",
|
|
170
|
+
children: [Icon ? jsxRuntime.jsx(IndicatorContainer, {
|
|
171
|
+
children: jsxRuntime.jsx(Icon, {
|
|
172
|
+
size: "xxsmall",
|
|
173
|
+
tone: tone
|
|
174
|
+
})
|
|
175
|
+
}) : null, jsxRuntime.jsx(text.Text, {
|
|
176
|
+
tone: textTone,
|
|
177
|
+
size: "small",
|
|
178
|
+
id: id,
|
|
179
|
+
children: message
|
|
180
|
+
})]
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
function IndicatorContainer(_ref4) {
|
|
184
|
+
var children = _ref4.children;
|
|
185
|
+
var theme$1 = theme.useTheme();
|
|
186
|
+
var _theme$typography$tex = theme$1.typography.text.small,
|
|
187
|
+
mobile = _theme$typography$tex.mobile,
|
|
188
|
+
tablet = _theme$typography$tex.tablet;
|
|
189
|
+
var responsiveStyles = theme$1.utils.responsiveStyles({
|
|
190
|
+
mobile: {
|
|
191
|
+
height: mobile.capHeight
|
|
192
|
+
},
|
|
193
|
+
tablet: {
|
|
194
|
+
height: tablet.capHeight
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
return jsxRuntime.jsx(box.Box, {
|
|
198
|
+
display: "flex",
|
|
199
|
+
alignItems: "center",
|
|
200
|
+
"aria-hidden": true,
|
|
201
|
+
cursor: "default",
|
|
202
|
+
flexShrink: 0,
|
|
203
|
+
css: react$1.css(responsiveStyles),
|
|
204
|
+
children: children
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
exports.Field = Field;
|
|
209
|
+
exports.FieldContextProvider = FieldContextProvider;
|
|
210
|
+
exports.FieldMessage = FieldMessage;
|
|
211
|
+
exports.useFieldContext = useFieldContext;
|
|
212
|
+
exports.useFieldIds = useFieldIds;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { createContext, useContext, forwardRef, useMemo, Fragment } from 'react';
|
|
2
|
+
import { css } from '@emotion/react';
|
|
3
|
+
import { mergeIds, VisuallyHidden, useId, composeId } from '@spark-web/a11y';
|
|
4
|
+
import { Box } from '@spark-web/box';
|
|
5
|
+
import { ExclamationCircleIcon, CheckCircleIcon } from '@spark-web/icon';
|
|
6
|
+
import { Stack } from '@spark-web/stack';
|
|
7
|
+
import { Text } from '@spark-web/text';
|
|
8
|
+
import { useTheme } from '@spark-web/theme';
|
|
9
|
+
import { jsxs, jsx } from '@emotion/react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
var FieldContext = /*#__PURE__*/createContext(null);
|
|
12
|
+
var FieldContextProvider = FieldContext.Provider;
|
|
13
|
+
var FIELD_CONTEXT_ERROR_MESSAGE = 'Input components must be inside a `Field`.';
|
|
14
|
+
function useFieldContext() {
|
|
15
|
+
var ctx = useContext(FieldContext);
|
|
16
|
+
if (!ctx) {
|
|
17
|
+
throw new Error(FIELD_CONTEXT_ERROR_MESSAGE);
|
|
18
|
+
}
|
|
19
|
+
return ctx;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Using a [context](https://reactjs.org/docs/context.html), the field
|
|
24
|
+
* component connects the label, description, and message to the input element.
|
|
25
|
+
*/
|
|
26
|
+
var Field = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
27
|
+
var children = _ref.children,
|
|
28
|
+
idProp = _ref.id,
|
|
29
|
+
data = _ref.data,
|
|
30
|
+
description = _ref.description,
|
|
31
|
+
_ref$disabled = _ref.disabled,
|
|
32
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
33
|
+
label = _ref.label,
|
|
34
|
+
adornment = _ref.adornment,
|
|
35
|
+
_ref$labelVisibility = _ref.labelVisibility,
|
|
36
|
+
labelVisibility = _ref$labelVisibility === void 0 ? 'visible' : _ref$labelVisibility,
|
|
37
|
+
message = _ref.message,
|
|
38
|
+
secondaryLabel = _ref.secondaryLabel,
|
|
39
|
+
_ref$tone = _ref.tone,
|
|
40
|
+
tone = _ref$tone === void 0 ? 'neutral' : _ref$tone,
|
|
41
|
+
_ref$readOnly = _ref.readOnly,
|
|
42
|
+
readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly;
|
|
43
|
+
var _useFieldIds = useFieldIds(idProp),
|
|
44
|
+
descriptionId = _useFieldIds.descriptionId,
|
|
45
|
+
inputId = _useFieldIds.inputId,
|
|
46
|
+
messageId = _useFieldIds.messageId;
|
|
47
|
+
|
|
48
|
+
// field context
|
|
49
|
+
var invalid = Boolean(message && tone === 'critical');
|
|
50
|
+
var fieldContext = useMemo(function () {
|
|
51
|
+
return [{
|
|
52
|
+
disabled: disabled,
|
|
53
|
+
invalid: invalid,
|
|
54
|
+
readOnly: readOnly
|
|
55
|
+
}, {
|
|
56
|
+
'aria-describedby': mergeIds(message && messageId, description ? descriptionId : undefined),
|
|
57
|
+
'aria-invalid': invalid || undefined,
|
|
58
|
+
id: inputId
|
|
59
|
+
}];
|
|
60
|
+
}, [description, descriptionId, disabled, inputId, invalid, message, messageId, readOnly]);
|
|
61
|
+
|
|
62
|
+
// label prep
|
|
63
|
+
var hiddenLabel = jsxs(VisuallyHidden, {
|
|
64
|
+
as: "label",
|
|
65
|
+
htmlFor: inputId,
|
|
66
|
+
children: [label, " ", secondaryLabel]
|
|
67
|
+
});
|
|
68
|
+
var labelElement = {
|
|
69
|
+
hidden: hiddenLabel,
|
|
70
|
+
visible: jsx(Box, {
|
|
71
|
+
as: "label",
|
|
72
|
+
htmlFor: inputId,
|
|
73
|
+
children: jsxs(Text, {
|
|
74
|
+
tone: disabled || readOnly ? 'field' : 'neutral',
|
|
75
|
+
weight: "semibold",
|
|
76
|
+
children: [label, ' ', secondaryLabel && jsx(Text, {
|
|
77
|
+
inline: true,
|
|
78
|
+
tone: disabled || readOnly ? 'field' : 'muted',
|
|
79
|
+
weight: "regular",
|
|
80
|
+
children: secondaryLabel
|
|
81
|
+
})]
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
'reserve-space': jsxs(Fragment, {
|
|
85
|
+
children: [hiddenLabel, jsx(Text, {
|
|
86
|
+
"aria-hidden": true,
|
|
87
|
+
children: "\xA0"
|
|
88
|
+
})]
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
var LabelWrapper = labelVisibility === 'hidden' ? Fragment : FieldLabelWrapper;
|
|
92
|
+
return jsx(FieldContextProvider, {
|
|
93
|
+
value: fieldContext,
|
|
94
|
+
children: jsxs(Stack, {
|
|
95
|
+
ref: forwardedRef,
|
|
96
|
+
data: data,
|
|
97
|
+
gap: "medium",
|
|
98
|
+
children: [jsxs(LabelWrapper, {
|
|
99
|
+
children: [labelElement[labelVisibility], adornment]
|
|
100
|
+
}), description && (typeof description === 'string' ? jsx(Text, {
|
|
101
|
+
tone: "muted",
|
|
102
|
+
size: "small",
|
|
103
|
+
id: descriptionId,
|
|
104
|
+
children: description
|
|
105
|
+
}) : jsx(Box, {
|
|
106
|
+
as: "label",
|
|
107
|
+
htmlFor: descriptionId,
|
|
108
|
+
children: description
|
|
109
|
+
})), children, message && jsx(FieldMessage, {
|
|
110
|
+
tone: tone,
|
|
111
|
+
id: messageId,
|
|
112
|
+
message: message
|
|
113
|
+
})]
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
Field.displayName = 'Field';
|
|
118
|
+
|
|
119
|
+
// Utils
|
|
120
|
+
// ------------------------------
|
|
121
|
+
|
|
122
|
+
function useFieldIds(id) {
|
|
123
|
+
var inputId = useId(id);
|
|
124
|
+
var descriptionId = composeId(inputId, 'description');
|
|
125
|
+
var messageId = composeId(inputId, 'message');
|
|
126
|
+
return {
|
|
127
|
+
descriptionId: descriptionId,
|
|
128
|
+
inputId: inputId,
|
|
129
|
+
messageId: messageId
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Styled components
|
|
134
|
+
// ------------------------------
|
|
135
|
+
function FieldLabelWrapper(_ref2) {
|
|
136
|
+
var children = _ref2.children;
|
|
137
|
+
return jsx(Box, {
|
|
138
|
+
display: "flex",
|
|
139
|
+
alignItems: "center",
|
|
140
|
+
justifyContent: "spaceBetween",
|
|
141
|
+
gap: "large",
|
|
142
|
+
children: children
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
var messageToneMap = {
|
|
146
|
+
critical: 'critical',
|
|
147
|
+
neutral: 'muted',
|
|
148
|
+
positive: 'positive'
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// NOTE: use icons in addition to color for folks with visions issues
|
|
152
|
+
var messageIconMap = {
|
|
153
|
+
critical: ExclamationCircleIcon,
|
|
154
|
+
neutral: null,
|
|
155
|
+
positive: CheckCircleIcon
|
|
156
|
+
};
|
|
157
|
+
var FieldMessage = function FieldMessage(_ref3) {
|
|
158
|
+
var message = _ref3.message,
|
|
159
|
+
id = _ref3.id,
|
|
160
|
+
tone = _ref3.tone;
|
|
161
|
+
var textTone = messageToneMap[tone];
|
|
162
|
+
var Icon = messageIconMap[tone];
|
|
163
|
+
return jsxs(Box, {
|
|
164
|
+
display: "flex",
|
|
165
|
+
gap: "xsmall",
|
|
166
|
+
children: [Icon ? jsx(IndicatorContainer, {
|
|
167
|
+
children: jsx(Icon, {
|
|
168
|
+
size: "xxsmall",
|
|
169
|
+
tone: tone
|
|
170
|
+
})
|
|
171
|
+
}) : null, jsx(Text, {
|
|
172
|
+
tone: textTone,
|
|
173
|
+
size: "small",
|
|
174
|
+
id: id,
|
|
175
|
+
children: message
|
|
176
|
+
})]
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
function IndicatorContainer(_ref4) {
|
|
180
|
+
var children = _ref4.children;
|
|
181
|
+
var theme = useTheme();
|
|
182
|
+
var _theme$typography$tex = theme.typography.text.small,
|
|
183
|
+
mobile = _theme$typography$tex.mobile,
|
|
184
|
+
tablet = _theme$typography$tex.tablet;
|
|
185
|
+
var responsiveStyles = theme.utils.responsiveStyles({
|
|
186
|
+
mobile: {
|
|
187
|
+
height: mobile.capHeight
|
|
188
|
+
},
|
|
189
|
+
tablet: {
|
|
190
|
+
height: tablet.capHeight
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return jsx(Box, {
|
|
194
|
+
display: "flex",
|
|
195
|
+
alignItems: "center",
|
|
196
|
+
"aria-hidden": true,
|
|
197
|
+
cursor: "default",
|
|
198
|
+
flexShrink: 0,
|
|
199
|
+
css: css(responsiveStyles),
|
|
200
|
+
children: children
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export { Field, FieldContextProvider, FieldMessage, useFieldContext, useFieldIds };
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spark-web/field",
|
|
3
|
+
"version": "0.0.0-snapshot-release-20260409001813",
|
|
4
|
+
"homepage": "https://github.com/brighte-labs/spark-web#readme",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/brighte-labs/spark-web.git",
|
|
8
|
+
"directory": "packages/field"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/spark-web-field.cjs.js",
|
|
11
|
+
"module": "dist/spark-web-field.esm.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"CHANGELOG.md",
|
|
14
|
+
"CLAUDE.md",
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@babel/runtime": "^7.25.0",
|
|
20
|
+
"@emotion/react": "^11.14.0",
|
|
21
|
+
"@spark-web/a11y": "^5.3.0",
|
|
22
|
+
"@spark-web/box": "0.0.0-snapshot-release-20260409001813",
|
|
23
|
+
"@spark-web/icon": "^5.1.0",
|
|
24
|
+
"@spark-web/stack": "0.0.0-snapshot-release-20260409001813",
|
|
25
|
+
"@spark-web/text": "0.0.0-snapshot-release-20260409001813",
|
|
26
|
+
"@spark-web/theme": "^5.13.0",
|
|
27
|
+
"@spark-web/utils": "^5.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "^19.1.0",
|
|
31
|
+
"react": "^19.1.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=14"
|
|
38
|
+
}
|
|
39
|
+
}
|