{"version":3,"sources":["../../../src/lib/save-button.tsx"],"sourcesContent":["import { Flex, Slot, Slottable, Spinner, Text } from \"@radix-ui/themes\";\nimport { CheckIcon } from \"@radix-ui/react-icons\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { namespaceClassNames } from \"./utils.js\";\nimport { Button, type ButtonProps } from \"./elements.js\";\nimport { Translation } from \"./i18n/translation.js\";\n\nconst DONE_TIMEOUT_MS = 1500;\nconst SAVING_TIMEOUT_MS = 600;\n\ninterface SaveButtonProps extends ButtonProps {\n  asChild?: boolean;\n  children: React.ReactNode;\n  loading?: boolean;\n  done?: boolean;\n  onDone?: () => void;\n}\n\nexport function SaveButton({\n  asChild = false,\n  children,\n  loading,\n  done,\n  onDone,\n  ...props\n}: SaveButtonProps) {\n  const [state, setState] = useState<\"idle\" | \"loading\" | \"done\">(\n    loading ? \"loading\" : done ? \"done\" : \"idle\",\n  );\n  const loadingStartTime = useRef<number | null>(null);\n  const ButtonComponent = asChild ? Slot : Button;\n\n  useEffect(() => {\n    if (loading) {\n      // FIXME: This should be refactored\n      // eslint-disable-next-line react-hooks/set-state-in-effect\n      setState(\"loading\");\n      loadingStartTime.current = Date.now();\n    } else if (done) {\n      const currentTime = Date.now();\n      const loadingDuration = loadingStartTime.current\n        ? currentTime - loadingStartTime.current\n        : 0;\n\n      // If loading lasted less than 500 ms, wait for the remaining time\n      const remainingDelay = Math.max(0, SAVING_TIMEOUT_MS - loadingDuration);\n\n      let doneTimer: number | null = null;\n      const savedTimer = window.setTimeout(() => {\n        setState(\"done\");\n\n        doneTimer = window.setTimeout(() => {\n          onDone?.();\n        }, DONE_TIMEOUT_MS);\n      }, remainingDelay);\n\n      return () => {\n        window.clearTimeout(savedTimer);\n        if (doneTimer !== null) {\n          window.clearTimeout(doneTimer);\n        }\n      };\n    } else if (!loading && !done) {\n      setState(\"idle\");\n    }\n  }, [loading, done, onDone]);\n\n  return (\n    <ButtonComponent\n      {...props}\n      className={namespaceClassNames(\"save-button\")}\n      data-save-state={state}\n    >\n      <Slottable>{children}</Slottable>\n      {state === \"loading\" && (\n        <Flex\n          as=\"span\"\n          align=\"center\"\n          justify=\"center\"\n          position=\"absolute\"\n          inset=\"0\"\n        >\n          <Spinner size=\"1\" />\n        </Flex>\n      )}\n\n      {state === \"done\" && (\n        <Flex\n          as=\"span\"\n          align=\"center\"\n          justify=\"center\"\n          position=\"absolute\"\n          inset=\"0\"\n          gap=\"1\"\n        >\n          <CheckIcon\n            width=\"18px\"\n            height=\"18px\"\n            style={{ marginLeft: \"-4px\" }}\n            className={namespaceClassNames(\"save-button__done-icon\")}\n          />\n          <Text className={namespaceClassNames(\"save-button__done-text\")}>\n            <Translation\n              defaultMessage=\"Done\"\n              id=\"wjt0K3\"\n              description=\"Button label indicating an action has completed successfully\"\n            />\n          </Text>\n        </Flex>\n      )}\n    </ButtonComponent>\n  );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyEM;AAzEN,oBAAqD;AACrD,yBAA0B;AAC1B,mBAA4C;AAC5C,mBAAoC;AACpC,sBAAyC;AACzC,yBAA4B;AAE5B,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAUnB,SAAS,WAAW;AAAA,EACzB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,CAAC,OAAO,QAAQ,QAAI;AAAA,IACxB,UAAU,YAAY,OAAO,SAAS;AAAA,EACxC;AACA,QAAM,uBAAmB,qBAAsB,IAAI;AACnD,QAAM,kBAAkB,UAAU,qBAAO;AAEzC,8BAAU,MAAM;AACd,QAAI,SAAS;AAGX,eAAS,SAAS;AAClB,uBAAiB,UAAU,KAAK,IAAI;AAAA,IACtC,WAAW,MAAM;AACf,YAAM,cAAc,KAAK,IAAI;AAC7B,YAAM,kBAAkB,iBAAiB,UACrC,cAAc,iBAAiB,UAC/B;AAGJ,YAAM,iBAAiB,KAAK,IAAI,GAAG,oBAAoB,eAAe;AAEtE,UAAI,YAA2B;AAC/B,YAAM,aAAa,OAAO,WAAW,MAAM;AACzC,iBAAS,MAAM;AAEf,oBAAY,OAAO,WAAW,MAAM;AAClC,mBAAS;AAAA,QACX,GAAG,eAAe;AAAA,MACpB,GAAG,cAAc;AAEjB,aAAO,MAAM;AACX,eAAO,aAAa,UAAU;AAC9B,YAAI,cAAc,MAAM;AACtB,iBAAO,aAAa,SAAS;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,WAAW,CAAC,WAAW,CAAC,MAAM;AAC5B,eAAS,MAAM;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,MAAM,CAAC;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,eAAW,kCAAoB,aAAa;AAAA,MAC5C,mBAAiB;AAAA,MAEjB;AAAA,oDAAC,2BAAW,UAAS;AAAA,QACpB,UAAU,aACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YAEN,sDAAC,yBAAQ,MAAK,KAAI;AAAA;AAAA,QACpB;AAAA,QAGD,UAAU,UACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,UAAS;AAAA,YACT,OAAM;AAAA,YACN,KAAI;AAAA,YAEJ;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAM;AAAA,kBACN,QAAO;AAAA,kBACP,OAAO,EAAE,YAAY,OAAO;AAAA,kBAC5B,eAAW,kCAAoB,wBAAwB;AAAA;AAAA,cACzD;AAAA,cACA,4CAAC,sBAAK,eAAW,kCAAoB,wBAAwB,GAC3D;AAAA,gBAAC;AAAA;AAAA,kBACC,gBAAe;AAAA,kBACf,IAAG;AAAA,kBACH,aAAY;AAAA;AAAA,cACd,GACF;AAAA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}