{"_id":"@algojudge/uva-explorer-react","_rev":"2-ae17a18ce2f2733473d5f9b4e39d74cf","name":"@algojudge/uva-explorer-react","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@algojudge/uva-explorer-react","version":"0.1.0","keywords":["uva","online-judge","competitive-programming","react","iframe","problem-picker"],"license":"MIT","_id":"@algojudge/uva-explorer-react@0.1.0","maintainers":[{"name":"kisielewski","email":"pkisielewski@patkis.pl"}],"homepage":"https://uvaexplorer.algojudge.app/","bugs":{"url":"https://github.com/AlgoJudge/UVaExplorer-Web/issues"},"dist":{"shasum":"eb3e61b9b63277ccb95cc05aa7928ede5f539931","tarball":"https://registry.npmjs.org/@algojudge/uva-explorer-react/-/uva-explorer-react-0.1.0.tgz","fileCount":19,"integrity":"sha512-zrQdrGGZ+sgVI7N3OdyphEiEqssF2ev2EE77FRfCNIC6ovQL01QMoyY4Gi40/7Kn+YOzn3VWEH9FAwmp/BixBA==","signatures":[{"sig":"MEUCIQC7wJG4TCDenMSPaPCfg1iqXgpFE/Qai6rJv98jS1BhKAIgNsVqp3RF//p25Ku0YwUEMEF4Zg1cUav0SsrKYIyAS0M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32348},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"8ee19e1fb7e1a52437dfc4a341c7271348c485e5","scripts":{"test":"npm run build && node --test test/*.node.mjs","build":"npm run clean && tsc","check":"tsc --noEmit && npm run test","clean":"node scripts/clean.mjs","release:check":"npm run check && npm pack --dry-run && node scripts/check-publish.mjs","prepublishOnly":"npm run release:check"},"_npmUser":{"name":"kisielewski","email":"pkisielewski@patkis.pl"},"repository":{"url":"git+https://github.com/AlgoJudge/UVaExplorer-Web.git","type":"git","directory":"integrations/react-picker"},"_npmVersion":"10.9.2","description":"Typed React wrapper for the UVa Explorer problem picker iframe protocol","directories":{},"sideEffects":false,"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.3.1","typescript":"^5.9.2","@types/react":"^18.3.0"},"peerDependencies":{"react":">=18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/uva-explorer-react_0.1.0_1786850007686_0.030701915666342394","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@algojudge/uva-explorer-react","version":"0.2.0","type":"module","description":"Typed React wrapper for the UVa Explorer problem picker iframe protocol","keywords":["uva","online-judge","competitive-programming","react","iframe","problem-picker"],"scripts":{"clean":"node scripts/clean.mjs","build":"npm run clean && tsc","test":"npm run build && node --test test/*.node.mjs","check":"tsc --noEmit && npm run test","release:check":"npm run check && npm pack --dry-run && node scripts/check-publish.mjs","prepublishOnly":"npm run release:check"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"sideEffects":false,"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AlgoJudge/UVaExplorer-Web.git","directory":"integrations/react-picker"},"homepage":"https://uvaexplorer.algojudge.app/","bugs":{"url":"https://github.com/AlgoJudge/UVaExplorer-Web/issues"},"publishConfig":{"access":"public"},"peerDependencies":{"react":">=18.2.0"},"devDependencies":{"@types/react":"^18.3.0","react":"^18.3.1","typescript":"^5.9.2"},"gitHead":"54fdfdef38eeac774c223e22ff53b301a81b603b","_id":"@algojudge/uva-explorer-react@0.2.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-GVnMAXkDq9wtguzo7va6nzjyUcvQgROLqwJxObvQkqA1XnfY6GJnwOBN9cXcITz/I5bhaUSbqQNksfcuuZ5PyA==","shasum":"570d5ea12cc810c4943810c44313ae6b153bc511","tarball":"https://registry.npmjs.org/@algojudge/uva-explorer-react/-/uva-explorer-react-0.2.0.tgz","fileCount":19,"unpackedSize":36086,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBuVUzDXUxVA+PTHjkZ7Mr4LpCRPNuY/n7+gnnUJxFzvAiAzcP5PGbQZjHz3SyRQgDSQeLTJkOnuuAkghQXGXZsKJA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:65b10eee-c2ef-4cae-b881-5ee18e976e14"}},"directories":{},"maintainers":[{"name":"kisielewski","email":"pkisielewski@patkis.pl"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/uva-explorer-react_0.2.0_1787606407302_0.11198345740672244"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-16T03:13:27.574Z","modified":"2026-08-24T21:20:07.607Z","0.1.0":"2026-08-16T03:13:27.826Z","0.2.0":"2026-08-24T21:20:07.453Z"},"bugs":{"url":"https://github.com/AlgoJudge/UVaExplorer-Web/issues"},"license":"MIT","homepage":"https://uvaexplorer.algojudge.app/","keywords":["uva","online-judge","competitive-programming","react","iframe","problem-picker"],"repository":{"type":"git","url":"git+https://github.com/AlgoJudge/UVaExplorer-Web.git","directory":"integrations/react-picker"},"description":"Typed React wrapper for the UVa Explorer problem picker iframe protocol","maintainers":[{"name":"kisielewski","email":"pkisielewski@patkis.pl"}],"readme":"# UVa Explorer React picker\n\nA small, ESM-only typed React wrapper around the UVa Explorer iframe protocol. It validates `event.origin`, `event.source`, protocol version, message type, and payload shape; performs the version 1 handshake; reinitializes after iframe reloads; and exposes typed lifecycle callbacks. React 18.2 or newer is required.\n\nFull documentation and a live iframe example: [uvaexplorer.algojudge.app/docs/picker/](https://uvaexplorer.algojudge.app/docs/picker/).\n\nRelease history is available in [CHANGELOG.md](CHANGELOG.md).\n\n## Installation\n\n```shell\nnpm install @algojudge/uva-explorer-react\n```\n\n## Usage\n\n```tsx\nimport { useState } from \"react\";\nimport { UvaProblemPicker, type UvaPickerProblem } from \"@algojudge/uva-explorer-react\";\n\nexport function ContestProblemField() {\n  const [problemNumbers, setProblemNumbers] = useState([100, 101]);\n  const [problems, setProblems] = useState<UvaPickerProblem[]>([]);\n\n  return (\n    <>\n      <UvaProblemPicker\n        language=\"en\"\n        problemNumbers={problemNumbers}\n        accessToken={accessTokenFromYourServer}\n        options={{ hideLangPicker: true, showAiPanel: true, showFilters: true, filtersMode: \"summary\" }}\n        onConfirm={(message) => {\n          setProblemNumbers(message.problemNumbers);\n          setProblems(message.problems);\n        }}\n        onCancel={() => console.log(\"cancelled\")}\n        style={{ width: \"100%\", height: 720, border: 0 }}\n      />\n      <output>{problems.map((problem) => problem.number).join(\", \")}</output>\n    </>\n  );\n}\n```\n\nThe optional `src` property defaults to `https://uvaexplorer.algojudge.app/picker/`. Set it only for a self-hosted deployment. A trusted server should exchange its long-lived Explorer key through `POST /api/access/token`, then return the one-hour token to the browser:\n\n```tsx\n<UvaProblemPicker\n  accessToken={shortLivedAccessToken}\n  onConfirm={({ problemNumbers }) => console.log(problemNumbers)}\n/>\n```\n\nThe component places the token in the iframe URL fragment. The picker consumes and removes it immediately, and never sends it back to the embedding application through `postMessage`. Never ship a long-lived access key in frontend code. The legacy `accessKey` property remains available for compatibility with trusted integrations. The host application's CSP must allow `https://uvaexplorer.algojudge.app` in `frame-src`. Do not use `sandbox` unless it includes the permissions required by the application; the component intentionally does not choose a sandbox policy for its host.\n\n`showAiPanel` and `showFilters` default to `true`. `filtersMode` accepts `\"summary\"` (the default compact overview) or `\"expanded\"`. The AI panel is still silently hidden when the key does not have the `ai` feature.\n\n## Public API\n\n- `UvaProblemPicker` — iframe component with controlled initial selection and typed callbacks.\n- `createUvaExplorerPickerUrl` — creates a picker URL with an optional `key` or `token` fragment credential.\n- `UVA_EXPLORER_PICKER_URL` — hosted picker URL used by default.\n- `UVA_PICKER_PROTOCOL_VERSION` — current protocol version (`1`).\n- `isUvaPickerMessage` — runtime validator for messages sent by the picker.\n- Message, problem, language, option, and component-prop TypeScript types are exported from the package root.\n\nThe package contains no CSS and does not modify global styles. Size the iframe using normal iframe properties such as `className`, `style`, `width`, and `height`.\n","readmeFilename":"README.md"}