Browse Source

Add proxy to phonenumberinput

Enable phonenumberinput to have value set via ref.
master
TheoryOfNekomata 10 months ago
parent
commit
181a212b6b
3 changed files with 59 additions and 2 deletions
  1. +5
    -0
      TODO.md
  2. +32
    -2
      categories/formatted/react/src/components/PhoneNumberInput/index.tsx
  3. +22
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/formatted/index.tsx

+ 5
- 0
TODO.md View File

@@ -67,8 +67,13 @@
# Others
- [X] Add `select-none` to input labels, etc.
- [X] Add indicators to components (select, datetime input etc)
- [ ] Add proxies for setting component values
- [ ] formatted/phonenumberinput
- [ ] multichoice/taginput
- [ ] blob/fileselectbox (?)
- [ ] Test all components!
- [ ] Where to put the "click-to-copy" textboxes? Does `Swatch`
belong to this category?
- [ ] Add `aria-*` attributes to all components
- [ ] react-refractor, fix rendering on Lynx!
- [ ] Limit component props to only those that are relevant

+ 32
- 2
categories/formatted/react/src/components/PhoneNumberInput/index.tsx View File

@@ -85,11 +85,41 @@ export const PhoneNumberInput = React.forwardRef<
const defaultRef = React.useRef<PhoneNumberInputDerivedElement>(null);
const ref = forwardedRef ?? defaultRef;

React.useEffect(() => {
const { current: currentRaw } = defaultRef;
const current = currentRaw as unknown as PhoneNumberInputDerivedElement;
const forwardedRefProxy = new Proxy(current, {
get(target, prop, receiver) {
return Reflect.get(target, prop, receiver) as unknown;
},
set(target, prop, newValue, receiver) {
if (prop === 'value') {
setPhoneNumber(newValue as string);
current.value = newValue as string;
return true;
}
return Reflect.set(target, prop, newValue, receiver);
},
}) as unknown as PhoneNumberInputDerivedElement;

if (typeof forwardedRef === 'function') {
forwardedRef(forwardedRefProxy);
return;
}

if (typeof forwardedRef === 'object' && forwardedRef) {
const mutableForwardedRef = forwardedRef as React.MutableRefObject<
PhoneNumberInputDerivedElement
>;
mutableForwardedRef.current = forwardedRefProxy;
}
}, [forwardedRef, defaultRef]);

const handlePhoneInputChange = (phoneNumberValue: Value) => {
if (!(typeof ref === 'object' && ref)) {
return;
}
const { current: input } = ref;
const { current: input } = defaultRef;
if (!input) {
return;
}
@@ -156,7 +186,7 @@ export const PhoneNumberInput = React.forwardRef<
size={length}
value={value}
onChange={onChange}
ref={ref}
ref={defaultRef}
aria-labelledby={labelId}
type="tel"
id={id}


+ 22
- 0
showcases/web-kitchensink-reactnext/src/pages/categories/formatted/index.tsx View File

@@ -2,8 +2,11 @@ import {NextPage} from 'next';
import {DefaultLayout} from '@/components/DefaultLayout';
import {Section, Subsection} from '@/components/Section';
import * as Formatted from '@tesseract-design/web-formatted-react';
import {useRef} from 'react';
import {ActionButton} from '@tesseract-design/web-action-react';

const TemporalPage: NextPage = () => {
const phoneNumberRef = useRef<HTMLInputElement>(null);
return (
<DefaultLayout title="Formatted">
<Section title="PhoneNumberInput">
@@ -18,6 +21,25 @@ const TemporalPage: NextPage = () => {
onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.value)}}
/>
</Subsection>
<Subsection title="With Ref">
<Formatted.PhoneNumberInput
label="Phone"
name="phone"
enhanced
border
ref={phoneNumberRef}
onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.value)}}
/>
<ActionButton
onClick={() => {
if (phoneNumberRef.current) {
phoneNumberRef.current.value = '+639123456789';
}
}}
>
Set Value
</ActionButton>
</Subsection>
</Section>
<Section title="EmailInput">
<Subsection title="Default">


Loading…
Cancel
Save