a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

focus poll inputs

+58 -31
+10 -1
components/Blocks/BlockCommands.tsx
··· 24 24 import { useEditorStates } from "src/state/useEditorState"; 25 25 import { elementId } from "src/utils/elementId"; 26 26 import { usePollBlockUIState } from "./PollBlock"; 27 + import { focusElement } from "components/Input"; 27 28 28 29 type Props = { 29 30 parent: string; ··· 212 213 type: "block", 213 214 onSelect: async (rep, props) => { 214 215 let entity = await createBlockWithType(rep, props, "poll"); 216 + let pollOptionEntity = v7(); 215 217 await rep.mutate.addPollOption({ 216 218 pollEntity: entity, 217 - pollOptionEntity: v7(), 219 + pollOptionEntity, 218 220 pollOptionName: "", 219 221 factID: v7(), 220 222 permission_set: props.entity_set, ··· 227 229 permission_set: props.entity_set, 228 230 }); 229 231 usePollBlockUIState.setState((s) => ({ [entity]: { state: "editing" } })); 232 + setTimeout(() => { 233 + focusElement( 234 + document.getElementById( 235 + elementId.block(entity).pollInput(pollOptionEntity), 236 + ) as HTMLInputElement | null, 237 + ); 238 + }, 20); 230 239 }, 231 240 }, 232 241
+13 -4
components/Blocks/PollBlock.tsx
··· 2 2 import { BlockProps } from "./Block"; 3 3 import { ButtonPrimary, ButtonSecondary } from "components/Buttons"; 4 4 import { useCallback, useEffect, useState } from "react"; 5 - import { Input } from "components/Input"; 5 + import { focusElement, Input } from "components/Input"; 6 6 import { CheckTiny, CloseTiny, InfoSmall } from "components/Icons"; 7 7 import { Separator } from "components/Layout"; 8 8 import { useEntitySetContext } from "components/EntitySetProvider"; ··· 13 13 import { voteOnPoll } from "actions/pollActions"; 14 14 import { create } from "zustand"; 15 15 import { poll_votes_on_entity } from "drizzle/schema"; 16 + import { elementId } from "src/utils/elementId"; 16 17 17 18 export let usePollBlockUIState = create( 18 19 () => ··· 316 317 317 318 <button 318 319 className="pollAddOption w-fit flex gap-2 items-center justify-start text-sm text-accent-contrast" 319 - onClick={() => { 320 - rep?.mutate.addPollOption({ 320 + onClick={async () => { 321 + let pollOptionEntity = v7(); 322 + await rep?.mutate.addPollOption({ 321 323 pollEntity: props.entityID, 322 - pollOptionEntity: v7(), 324 + pollOptionEntity, 323 325 pollOptionName: "", 324 326 permission_set: permission_set.set, 325 327 factID: v7(), 326 328 }); 329 + 330 + focusElement( 331 + document.getElementById( 332 + elementId.block(props.entityID).pollInput(pollOptionEntity), 333 + ) as HTMLInputElement | null, 334 + ); 327 335 }} 328 336 > 329 337 Add an Option ··· 386 394 return ( 387 395 <div className="flex gap-2 items-center"> 388 396 <Input 397 + id={elementId.block(props.pollEntity).pollInput(props.entityID)} 389 398 type="text" 390 399 className="pollOptionInput w-full input-with-border" 391 400 placeholder="Option here..."
+35 -26
components/Input.tsx
··· 12 12 useEffect(() => { 13 13 if (!isIOS()) return; 14 14 if (props.autoFocus) { 15 - let fakeInput = document.createElement("input"); 16 - fakeInput.setAttribute("type", "text"); 17 - fakeInput.style.position = "fixed"; 18 - fakeInput.style.height = "0px"; 19 - fakeInput.style.width = "0px"; 20 - fakeInput.style.fontSize = "16px"; // disable auto zoom 21 - document.body.appendChild(fakeInput); 22 - fakeInput.focus(); 23 - setTimeout(() => { 24 - if (!ref.current) return; 25 - ref.current.style.transform = "translateY(-2000px)"; 26 - ref.current?.focus(); 27 - fakeInput.remove(); 28 - ref.current.value = " "; 29 - ref.current.setSelectionRange(1, 1); 30 - requestAnimationFrame(() => { 31 - if (ref.current) { 32 - ref.current.style.transform = ""; 33 - } 34 - }); 35 - setTimeout(() => { 36 - if (!ref.current) return; 37 - ref.current.value = ""; 38 - ref.current.setSelectionRange(0, 0); 39 - }, 50); 40 - }, 20); 15 + focusElement(ref.current); 41 16 } 42 17 }, [props.autoFocus]); 43 18 ··· 50 25 /> 51 26 ); 52 27 } 28 + 29 + export const focusElement = (el?: HTMLInputElement | null) => { 30 + if (!isIOS()) { 31 + el?.focus(); 32 + return; 33 + } 34 + 35 + let fakeInput = document.createElement("input"); 36 + fakeInput.setAttribute("type", "text"); 37 + fakeInput.style.position = "fixed"; 38 + fakeInput.style.height = "0px"; 39 + fakeInput.style.width = "0px"; 40 + fakeInput.style.fontSize = "16px"; // disable auto zoom 41 + document.body.appendChild(fakeInput); 42 + fakeInput.focus(); 43 + setTimeout(() => { 44 + if (!el) return; 45 + el.style.transform = "translateY(-2000px)"; 46 + el?.focus(); 47 + fakeInput.remove(); 48 + el.value = " "; 49 + el.setSelectionRange(1, 1); 50 + requestAnimationFrame(() => { 51 + if (el) { 52 + el.style.transform = ""; 53 + } 54 + }); 55 + setTimeout(() => { 56 + if (!el) return; 57 + el.value = ""; 58 + el.setSelectionRange(0, 0); 59 + }, 50); 60 + }, 20); 61 + }; 53 62 54 63 export const InputWithLabel = ( 55 64 props: {