Enable phonenumberinput to have value set via ref.master
@@ -67,8 +67,13 @@ | |||||
# Others | # Others | ||||
- [X] Add `select-none` to input labels, etc. | - [X] Add `select-none` to input labels, etc. | ||||
- [X] Add indicators to components (select, datetime input 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! | - [ ] Test all components! | ||||
- [ ] Where to put the "click-to-copy" textboxes? Does `Swatch` | - [ ] Where to put the "click-to-copy" textboxes? Does `Swatch` | ||||
belong to this category? | belong to this category? | ||||
- [ ] Add `aria-*` attributes to all components | - [ ] Add `aria-*` attributes to all components | ||||
- [ ] react-refractor, fix rendering on Lynx! | - [ ] react-refractor, fix rendering on Lynx! | ||||
- [ ] Limit component props to only those that are relevant |
@@ -85,11 +85,41 @@ export const PhoneNumberInput = React.forwardRef< | |||||
const defaultRef = React.useRef<PhoneNumberInputDerivedElement>(null); | const defaultRef = React.useRef<PhoneNumberInputDerivedElement>(null); | ||||
const ref = forwardedRef ?? defaultRef; | 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) => { | const handlePhoneInputChange = (phoneNumberValue: Value) => { | ||||
if (!(typeof ref === 'object' && ref)) { | if (!(typeof ref === 'object' && ref)) { | ||||
return; | return; | ||||
} | } | ||||
const { current: input } = ref; | |||||
const { current: input } = defaultRef; | |||||
if (!input) { | if (!input) { | ||||
return; | return; | ||||
} | } | ||||
@@ -156,7 +186,7 @@ export const PhoneNumberInput = React.forwardRef< | |||||
size={length} | size={length} | ||||
value={value} | value={value} | ||||
onChange={onChange} | onChange={onChange} | ||||
ref={ref} | |||||
ref={defaultRef} | |||||
aria-labelledby={labelId} | aria-labelledby={labelId} | ||||
type="tel" | type="tel" | ||||
id={id} | id={id} | ||||
@@ -2,8 +2,11 @@ import {NextPage} from 'next'; | |||||
import {DefaultLayout} from '@/components/DefaultLayout'; | import {DefaultLayout} from '@/components/DefaultLayout'; | ||||
import {Section, Subsection} from '@/components/Section'; | import {Section, Subsection} from '@/components/Section'; | ||||
import * as Formatted from '@tesseract-design/web-formatted-react'; | 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 TemporalPage: NextPage = () => { | ||||
const phoneNumberRef = useRef<HTMLInputElement>(null); | |||||
return ( | return ( | ||||
<DefaultLayout title="Formatted"> | <DefaultLayout title="Formatted"> | ||||
<Section title="PhoneNumberInput"> | <Section title="PhoneNumberInput"> | ||||
@@ -18,6 +21,25 @@ const TemporalPage: NextPage = () => { | |||||
onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.value)}} | onChange={(e) => { console.log('change', e.currentTarget.name, e.currentTarget, e.currentTarget.value)}} | ||||
/> | /> | ||||
</Subsection> | </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> | ||||
<Section title="EmailInput"> | <Section title="EmailInput"> | ||||
<Subsection title="Default"> | <Subsection title="Default"> | ||||