@seed-design/react-field 0.0.0-alpha-20260414104312

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,204 @@
1
+ 'use client';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { composeRefs } from '@radix-ui/react-compose-refs';
4
+ import { elementProps, dataAttr, inputProps, labelProps, ariaAttr, mergeProps } from '@seed-design/dom-utils';
5
+ import { Primitive } from '@seed-design/react-primitive';
6
+ import { useId, useState, useCallback, createContext, useContext, forwardRef } from 'react';
7
+ import { useSupports } from '@seed-design/react-supports';
8
+
9
+ const getLabelId = (id)=>`field:${id}:label`;
10
+ const getInputId = (id)=>`field:${id}:input`;
11
+ const getDescriptionId = (id)=>`field:${id}:description`;
12
+ const getErrorMessageId = (id)=>`field:${id}:error-message`;
13
+
14
+ function useFieldState() {
15
+ const [isHovered, setIsHovered] = useState(false);
16
+ const [isActive, setIsActive] = useState(false);
17
+ const [isFocused, setIsFocused] = useState(false);
18
+ const [isFocusVisible, setIsFocusVisible] = useState(false);
19
+ const [isLabelRendered, setIsLabelRendered] = useState(false);
20
+ const labelRef = useCallback((node)=>{
21
+ setIsLabelRendered(!!node);
22
+ }, []);
23
+ const [isDescriptionRendered, setIsDescriptionRendered] = useState(false);
24
+ const descriptionRef = useCallback((node)=>{
25
+ setIsDescriptionRendered(!!node);
26
+ }, []);
27
+ const [isErrorMessageRendered, setIsErrorMessageRendered] = useState(false);
28
+ const errorMessageRef = useCallback((node)=>{
29
+ setIsErrorMessageRendered(!!node);
30
+ }, []);
31
+ return {
32
+ refs: {
33
+ label: labelRef,
34
+ description: descriptionRef,
35
+ errorMessage: errorMessageRef
36
+ },
37
+ isHovered,
38
+ isActive,
39
+ isFocused,
40
+ isFocusVisible,
41
+ renderedElements: {
42
+ label: isLabelRendered,
43
+ description: isDescriptionRendered,
44
+ errorMessage: isErrorMessageRendered
45
+ },
46
+ setIsHovered,
47
+ setIsActive,
48
+ setIsFocused,
49
+ setIsFocusVisible
50
+ };
51
+ }
52
+ function useField(props) {
53
+ const id = useId();
54
+ const { disabled = false, invalid = false, readOnly = false, required = false } = props;
55
+ const isFocusVisibleSupported = useSupports("selector(:focus-visible)");
56
+ const { refs, renderedElements, isHovered, isActive, isFocused, isFocusVisible, setIsHovered, setIsActive, setIsFocused, setIsFocusVisible } = useFieldState();
57
+ const ariaDescribedBy = [
58
+ renderedElements.description ? getDescriptionId(id) : false,
59
+ renderedElements.errorMessage ? getErrorMessageId(id) : false
60
+ ].filter(Boolean).join(" ") || undefined;
61
+ const stateProps = elementProps({
62
+ "data-hover": dataAttr(isHovered),
63
+ "data-active": dataAttr(isActive),
64
+ "data-focus": dataAttr(isFocused),
65
+ "data-focus-visible": dataAttr(isFocusVisible),
66
+ "data-readonly": dataAttr(readOnly),
67
+ "data-disabled": dataAttr(disabled),
68
+ "data-invalid": dataAttr(invalid)
69
+ });
70
+ return {
71
+ refs,
72
+ active: isActive,
73
+ focused: isFocused,
74
+ invalid,
75
+ required,
76
+ setIsFocused,
77
+ setIsFocusVisible,
78
+ stateProps,
79
+ rootProps: elementProps({
80
+ ...stateProps,
81
+ onPointerMove () {
82
+ setIsHovered(true);
83
+ },
84
+ onPointerDown () {
85
+ setIsActive(true);
86
+ },
87
+ onPointerUp () {
88
+ setIsActive(false);
89
+ },
90
+ onPointerLeave () {
91
+ setIsHovered(false);
92
+ setIsActive(false);
93
+ }
94
+ }),
95
+ labelProps: labelProps({
96
+ ...stateProps,
97
+ id: getLabelId(id),
98
+ htmlFor: getInputId(id)
99
+ }),
100
+ inputProps: inputProps({
101
+ disabled,
102
+ readOnly,
103
+ name: props.name || id,
104
+ id: getInputId(id)
105
+ }),
106
+ inputAriaAttributes: elementProps({
107
+ ...renderedElements.label && {
108
+ "aria-labelledby": getLabelId(id)
109
+ },
110
+ "aria-describedby": ariaDescribedBy,
111
+ "aria-required": ariaAttr(required),
112
+ "aria-invalid": ariaAttr(invalid),
113
+ "aria-readonly": ariaAttr(readOnly),
114
+ "aria-disabled": ariaAttr(disabled)
115
+ }),
116
+ inputHandlers: inputProps({
117
+ onChange: (event)=>{
118
+ if (isFocusVisibleSupported) {
119
+ setIsFocusVisible(event.target.matches(":focus-visible"));
120
+ }
121
+ },
122
+ onBlur () {
123
+ setIsFocused(false);
124
+ if (isFocusVisibleSupported) {
125
+ setIsFocusVisible(false);
126
+ }
127
+ },
128
+ onFocus (event) {
129
+ setIsFocused(true);
130
+ if (isFocusVisibleSupported) {
131
+ setIsFocusVisible(event.target.matches(":focus-visible"));
132
+ }
133
+ }
134
+ }),
135
+ descriptionProps: elementProps({
136
+ ...stateProps,
137
+ id: getDescriptionId(id)
138
+ }),
139
+ errorMessageProps: elementProps({
140
+ ...stateProps,
141
+ id: getErrorMessageId(id),
142
+ "aria-live": "polite"
143
+ })
144
+ };
145
+ }
146
+
147
+ const FieldContext = /*#__PURE__*/ createContext(null);
148
+ const FieldProvider = FieldContext.Provider;
149
+ function useFieldContext({ strict = true } = {}) {
150
+ const context = useContext(FieldContext);
151
+ if (!context && strict) {
152
+ throw new Error("useFieldContext must be used within a Field");
153
+ }
154
+ return context;
155
+ }
156
+
157
+ const FieldRoot = /*#__PURE__*/ forwardRef((props, ref)=>{
158
+ const { readOnly, disabled, invalid, required, name, ...otherProps } = props;
159
+ const api = useField({
160
+ disabled,
161
+ invalid,
162
+ required,
163
+ readOnly,
164
+ name
165
+ });
166
+ const mergedProps = mergeProps(api.rootProps, otherProps);
167
+ return /*#__PURE__*/ jsx(FieldProvider, {
168
+ value: api,
169
+ children: /*#__PURE__*/ jsx(Primitive.div, {
170
+ ref: ref,
171
+ ...mergedProps
172
+ })
173
+ });
174
+ });
175
+ FieldRoot.displayName = "FieldRoot";
176
+ const FieldLabel = /*#__PURE__*/ forwardRef((props, ref)=>{
177
+ const { refs, labelProps } = useFieldContext();
178
+ const mergedProps = mergeProps(labelProps, props);
179
+ return /*#__PURE__*/ jsx(Primitive.label, {
180
+ ref: composeRefs(refs.label, ref),
181
+ ...mergedProps
182
+ });
183
+ });
184
+ FieldLabel.displayName = "FieldLabel";
185
+ const FieldDescription = /*#__PURE__*/ forwardRef((props, ref)=>{
186
+ const { refs, descriptionProps } = useFieldContext();
187
+ const mergedProps = mergeProps(descriptionProps, props);
188
+ return /*#__PURE__*/ jsx(Primitive.span, {
189
+ ref: composeRefs(refs.description, ref),
190
+ ...mergedProps
191
+ });
192
+ });
193
+ FieldDescription.displayName = "FieldDescription";
194
+ const FieldErrorMessage = /*#__PURE__*/ forwardRef((props, ref)=>{
195
+ const { refs, errorMessageProps } = useFieldContext();
196
+ const mergedProps = mergeProps(errorMessageProps, props);
197
+ return /*#__PURE__*/ jsx(Primitive.div, {
198
+ ref: composeRefs(refs.errorMessage, ref),
199
+ ...mergedProps
200
+ });
201
+ });
202
+ FieldErrorMessage.displayName = "FieldErrorMessage";
203
+
204
+ export { FieldDescription as F, FieldErrorMessage as a, FieldLabel as b, FieldRoot as c, useFieldContext as u };
@@ -0,0 +1,208 @@
1
+ 'use client';
2
+ var jsxRuntime = require('react/jsx-runtime');
3
+ var reactComposeRefs = require('@radix-ui/react-compose-refs');
4
+ var domUtils = require('@seed-design/dom-utils');
5
+ var reactPrimitive = require('@seed-design/react-primitive');
6
+ var react = require('react');
7
+ var reactSupports = require('@seed-design/react-supports');
8
+
9
+ const getLabelId = (id)=>`field:${id}:label`;
10
+ const getInputId = (id)=>`field:${id}:input`;
11
+ const getDescriptionId = (id)=>`field:${id}:description`;
12
+ const getErrorMessageId = (id)=>`field:${id}:error-message`;
13
+
14
+ function useFieldState() {
15
+ const [isHovered, setIsHovered] = react.useState(false);
16
+ const [isActive, setIsActive] = react.useState(false);
17
+ const [isFocused, setIsFocused] = react.useState(false);
18
+ const [isFocusVisible, setIsFocusVisible] = react.useState(false);
19
+ const [isLabelRendered, setIsLabelRendered] = react.useState(false);
20
+ const labelRef = react.useCallback((node)=>{
21
+ setIsLabelRendered(!!node);
22
+ }, []);
23
+ const [isDescriptionRendered, setIsDescriptionRendered] = react.useState(false);
24
+ const descriptionRef = react.useCallback((node)=>{
25
+ setIsDescriptionRendered(!!node);
26
+ }, []);
27
+ const [isErrorMessageRendered, setIsErrorMessageRendered] = react.useState(false);
28
+ const errorMessageRef = react.useCallback((node)=>{
29
+ setIsErrorMessageRendered(!!node);
30
+ }, []);
31
+ return {
32
+ refs: {
33
+ label: labelRef,
34
+ description: descriptionRef,
35
+ errorMessage: errorMessageRef
36
+ },
37
+ isHovered,
38
+ isActive,
39
+ isFocused,
40
+ isFocusVisible,
41
+ renderedElements: {
42
+ label: isLabelRendered,
43
+ description: isDescriptionRendered,
44
+ errorMessage: isErrorMessageRendered
45
+ },
46
+ setIsHovered,
47
+ setIsActive,
48
+ setIsFocused,
49
+ setIsFocusVisible
50
+ };
51
+ }
52
+ function useField(props) {
53
+ const id = react.useId();
54
+ const { disabled = false, invalid = false, readOnly = false, required = false } = props;
55
+ const isFocusVisibleSupported = reactSupports.useSupports("selector(:focus-visible)");
56
+ const { refs, renderedElements, isHovered, isActive, isFocused, isFocusVisible, setIsHovered, setIsActive, setIsFocused, setIsFocusVisible } = useFieldState();
57
+ const ariaDescribedBy = [
58
+ renderedElements.description ? getDescriptionId(id) : false,
59
+ renderedElements.errorMessage ? getErrorMessageId(id) : false
60
+ ].filter(Boolean).join(" ") || undefined;
61
+ const stateProps = domUtils.elementProps({
62
+ "data-hover": domUtils.dataAttr(isHovered),
63
+ "data-active": domUtils.dataAttr(isActive),
64
+ "data-focus": domUtils.dataAttr(isFocused),
65
+ "data-focus-visible": domUtils.dataAttr(isFocusVisible),
66
+ "data-readonly": domUtils.dataAttr(readOnly),
67
+ "data-disabled": domUtils.dataAttr(disabled),
68
+ "data-invalid": domUtils.dataAttr(invalid)
69
+ });
70
+ return {
71
+ refs,
72
+ active: isActive,
73
+ focused: isFocused,
74
+ invalid,
75
+ required,
76
+ setIsFocused,
77
+ setIsFocusVisible,
78
+ stateProps,
79
+ rootProps: domUtils.elementProps({
80
+ ...stateProps,
81
+ onPointerMove () {
82
+ setIsHovered(true);
83
+ },
84
+ onPointerDown () {
85
+ setIsActive(true);
86
+ },
87
+ onPointerUp () {
88
+ setIsActive(false);
89
+ },
90
+ onPointerLeave () {
91
+ setIsHovered(false);
92
+ setIsActive(false);
93
+ }
94
+ }),
95
+ labelProps: domUtils.labelProps({
96
+ ...stateProps,
97
+ id: getLabelId(id),
98
+ htmlFor: getInputId(id)
99
+ }),
100
+ inputProps: domUtils.inputProps({
101
+ disabled,
102
+ readOnly,
103
+ name: props.name || id,
104
+ id: getInputId(id)
105
+ }),
106
+ inputAriaAttributes: domUtils.elementProps({
107
+ ...renderedElements.label && {
108
+ "aria-labelledby": getLabelId(id)
109
+ },
110
+ "aria-describedby": ariaDescribedBy,
111
+ "aria-required": domUtils.ariaAttr(required),
112
+ "aria-invalid": domUtils.ariaAttr(invalid),
113
+ "aria-readonly": domUtils.ariaAttr(readOnly),
114
+ "aria-disabled": domUtils.ariaAttr(disabled)
115
+ }),
116
+ inputHandlers: domUtils.inputProps({
117
+ onChange: (event)=>{
118
+ if (isFocusVisibleSupported) {
119
+ setIsFocusVisible(event.target.matches(":focus-visible"));
120
+ }
121
+ },
122
+ onBlur () {
123
+ setIsFocused(false);
124
+ if (isFocusVisibleSupported) {
125
+ setIsFocusVisible(false);
126
+ }
127
+ },
128
+ onFocus (event) {
129
+ setIsFocused(true);
130
+ if (isFocusVisibleSupported) {
131
+ setIsFocusVisible(event.target.matches(":focus-visible"));
132
+ }
133
+ }
134
+ }),
135
+ descriptionProps: domUtils.elementProps({
136
+ ...stateProps,
137
+ id: getDescriptionId(id)
138
+ }),
139
+ errorMessageProps: domUtils.elementProps({
140
+ ...stateProps,
141
+ id: getErrorMessageId(id),
142
+ "aria-live": "polite"
143
+ })
144
+ };
145
+ }
146
+
147
+ const FieldContext = /*#__PURE__*/ react.createContext(null);
148
+ const FieldProvider = FieldContext.Provider;
149
+ function useFieldContext({ strict = true } = {}) {
150
+ const context = react.useContext(FieldContext);
151
+ if (!context && strict) {
152
+ throw new Error("useFieldContext must be used within a Field");
153
+ }
154
+ return context;
155
+ }
156
+
157
+ const FieldRoot = /*#__PURE__*/ react.forwardRef((props, ref)=>{
158
+ const { readOnly, disabled, invalid, required, name, ...otherProps } = props;
159
+ const api = useField({
160
+ disabled,
161
+ invalid,
162
+ required,
163
+ readOnly,
164
+ name
165
+ });
166
+ const mergedProps = domUtils.mergeProps(api.rootProps, otherProps);
167
+ return /*#__PURE__*/ jsxRuntime.jsx(FieldProvider, {
168
+ value: api,
169
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.div, {
170
+ ref: ref,
171
+ ...mergedProps
172
+ })
173
+ });
174
+ });
175
+ FieldRoot.displayName = "FieldRoot";
176
+ const FieldLabel = /*#__PURE__*/ react.forwardRef((props, ref)=>{
177
+ const { refs, labelProps } = useFieldContext();
178
+ const mergedProps = domUtils.mergeProps(labelProps, props);
179
+ return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.label, {
180
+ ref: reactComposeRefs.composeRefs(refs.label, ref),
181
+ ...mergedProps
182
+ });
183
+ });
184
+ FieldLabel.displayName = "FieldLabel";
185
+ const FieldDescription = /*#__PURE__*/ react.forwardRef((props, ref)=>{
186
+ const { refs, descriptionProps } = useFieldContext();
187
+ const mergedProps = domUtils.mergeProps(descriptionProps, props);
188
+ return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.span, {
189
+ ref: reactComposeRefs.composeRefs(refs.description, ref),
190
+ ...mergedProps
191
+ });
192
+ });
193
+ FieldDescription.displayName = "FieldDescription";
194
+ const FieldErrorMessage = /*#__PURE__*/ react.forwardRef((props, ref)=>{
195
+ const { refs, errorMessageProps } = useFieldContext();
196
+ const mergedProps = domUtils.mergeProps(errorMessageProps, props);
197
+ return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.div, {
198
+ ref: reactComposeRefs.composeRefs(refs.errorMessage, ref),
199
+ ...mergedProps
200
+ });
201
+ });
202
+ FieldErrorMessage.displayName = "FieldErrorMessage";
203
+
204
+ exports.FieldDescription = FieldDescription;
205
+ exports.FieldErrorMessage = FieldErrorMessage;
206
+ exports.FieldLabel = FieldLabel;
207
+ exports.FieldRoot = FieldRoot;
208
+ exports.useFieldContext = useFieldContext;
package/lib/index.cjs ADDED
@@ -0,0 +1,16 @@
1
+ var Field12s = require('./Field-12s-t41MRyBm.cjs');
2
+
3
+ var Field_namespace = {
4
+ __proto__: null,
5
+ Description: Field12s.FieldDescription,
6
+ ErrorMessage: Field12s.FieldErrorMessage,
7
+ Label: Field12s.FieldLabel,
8
+ Root: Field12s.FieldRoot
9
+ };
10
+
11
+ exports.FieldDescription = Field12s.FieldDescription;
12
+ exports.FieldErrorMessage = Field12s.FieldErrorMessage;
13
+ exports.FieldLabel = Field12s.FieldLabel;
14
+ exports.FieldRoot = Field12s.FieldRoot;
15
+ exports.useFieldContext = Field12s.useFieldContext;
16
+ exports.Field = Field_namespace;