Skip to content

Commit 7b1d764

Browse files
committed
Render disabled components
1 parent 1488173 commit 7b1d764

2 files changed

Lines changed: 23 additions & 6 deletions

File tree

src/index.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ const InteractiveNotMemoized: PolymorphicForwardRefExoticComponent<
200200

201201
////////////////////////////////////
202202

203+
// if disabled and As is a component, will need to re-render if there is a new ref
204+
// to know if the DOM element supports disabled because don't have access to the DOM element on the first render,
205+
// the forceUpdate only happens after the first render (and only if disabled and As component),
206+
// and when the As component renders a different DOM element while in the disabled state
207+
const disabledAndAsComponent = React.useRef<boolean>(false);
208+
disabledAndAsComponent.current = disabled && typeof As !== 'string';
209+
const [, forceUpdateDisabledComponent] = React.useState(false);
210+
211+
////////////////////////////////////
212+
203213
// support passed in ref prop as object or callback, and track ref locally
204214
const localRef = React.useRef<Element | null>(null);
205215
const callbackRef = React.useCallback(
@@ -210,6 +220,12 @@ const InteractiveNotMemoized: PolymorphicForwardRefExoticComponent<
210220
} else if (ref) {
211221
ref.current = node;
212222
}
223+
224+
// if disabled and As is a component, and receive a new ref (i.e. callbackRef is called)
225+
// then re-render to pass the disabled prop to the As component if the DOM element supports it
226+
if (disabledAndAsComponent.current) {
227+
forceUpdateDisabledComponent((s) => !s);
228+
}
213229
},
214230
[ref],
215231
);
@@ -782,11 +798,10 @@ const InteractiveNotMemoized: PolymorphicForwardRefExoticComponent<
782798
// if the As DOM element supports the disabled prop, then pass through the disabled prop
783799
if (
784800
elementSupportsDisabled(
785-
localRef.current ||
786-
// on the first render localRef.current will be null, but should still pass through disabled prop if supported
787-
(typeof As === 'string'
788-
? { tagName: (As as string).toUpperCase() }
789-
: {}),
801+
// on the first render localRef.current will be null, but should still pass through disabled prop if supported
802+
typeof As === 'string'
803+
? { tagName: (As as string).toUpperCase() }
804+
: localRef.current || {},
790805
)
791806
) {
792807
disabledProps.disabled = true;

src/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ export const spaceKeyTrigger: ElementTagNameAndType = ({ tagName, type }) =>
2525

2626
// elements that support the disabled attribute
2727
export const elementSupportsDisabled: ElementTagNameAndType = ({ tagName }) =>
28-
['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'].includes(tagName as string);
28+
['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA', 'FIELDSET'].includes(
29+
tagName as string,
30+
);
2931

3032
interface CursorPointer {
3133
(

0 commit comments

Comments
 (0)