Repository: facebook/stylex Branch: main Commit: 7d91ac25b300 Files: 985 Total size: 12.3 MB Directory structure: gitextract_gl0n7f1_/ ├── .eslintrc.js ├── .flowconfig ├── .github/ │ ├── CODEOWNERS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.yml │ │ └── feature.yml │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── benchmarks.yml │ ├── tests.yml │ └── typos.toml ├── .gitignore ├── .prettierignore ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── .watchmanconfig ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples/ │ ├── example-bun/ │ │ ├── .eslintrc.js │ │ ├── README.md │ │ ├── bunfig.toml │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── build.mjs │ │ │ ├── dev.mjs │ │ │ └── start.mjs │ │ └── src/ │ │ ├── App.jsx │ │ ├── global.css │ │ ├── globalTokens.stylex.js │ │ ├── index.dev.html │ │ ├── index.html │ │ └── main.jsx │ ├── example-cli/ │ │ ├── .gitignore │ │ ├── .stylex.json5 │ │ ├── README.md │ │ ├── package.json │ │ ├── source/ │ │ │ ├── app/ │ │ │ │ ├── CardThemes.ts │ │ │ │ ├── CardTokens.stylex.ts │ │ │ │ ├── Counter.tsx │ │ │ │ ├── globalTokens.stylex.ts │ │ │ │ ├── globals.css │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ └── components/ │ │ │ └── Card.tsx │ │ └── tsconfig.json │ ├── example-esbuild/ │ │ ├── .eslintrc.js │ │ ├── README.md │ │ ├── package.json │ │ ├── public/ │ │ │ └── index.html │ │ ├── scripts/ │ │ │ └── build.mjs │ │ └── src/ │ │ ├── App.jsx │ │ ├── global.css │ │ └── globalTokens.stylex.js │ ├── example-nextjs/ │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── InteractiveCard.tsx │ │ │ ├── app.css │ │ │ ├── darkMode.stylex.ts │ │ │ ├── globalTokens.stylex.ts │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ ├── babel.config.js │ │ ├── components/ │ │ │ ├── Card.tsx │ │ │ └── CardTokens.stylex.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── postcss.config.js │ │ └── tsconfig.json │ ├── example-react-router/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── server.js │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ └── MainArticle.tsx │ │ │ ├── entry.browser.tsx │ │ │ ├── entry.rsc.tsx │ │ │ ├── entry.ssr.tsx │ │ │ ├── routes/ │ │ │ │ ├── about/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── config.ts │ │ │ │ ├── home/ │ │ │ │ │ └── route.tsx │ │ │ │ └── root/ │ │ │ │ ├── DevStyleXInject.tsx │ │ │ │ ├── client.tsx │ │ │ │ └── route.tsx │ │ │ └── stylex.css │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── example-redwoodsdk/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app/ │ │ │ │ ├── DevStyleXInject.tsx │ │ │ │ ├── Document.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── Copy.tsx │ │ │ │ ├── headers.ts │ │ │ │ ├── pages/ │ │ │ │ │ ├── Counter.tsx │ │ │ │ │ ├── Home.tsx │ │ │ │ │ └── Welcome.tsx │ │ │ │ ├── root.css │ │ │ │ └── shared/ │ │ │ │ └── links.ts │ │ │ ├── client.tsx │ │ │ └── worker.tsx │ │ ├── tsconfig.json │ │ ├── types/ │ │ │ ├── css.d.ts │ │ │ ├── rw.d.ts │ │ │ └── vite.d.ts │ │ ├── vite.config.mts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── example-rollup/ │ │ ├── README.md │ │ ├── babel.config.mjs │ │ ├── index.html │ │ ├── package.json │ │ ├── rollup.config.mjs │ │ └── src/ │ │ ├── App.js │ │ └── index.js │ ├── example-rspack/ │ │ ├── README.md │ │ ├── package.json │ │ ├── public/ │ │ │ └── index.html │ │ ├── rspack.config.js │ │ └── src/ │ │ ├── App.jsx │ │ ├── global.css │ │ └── main.jsx │ ├── example-storybook/ │ │ ├── .babelrc.cjs │ │ ├── .storybook/ │ │ │ ├── main.ts │ │ │ ├── preview.ts │ │ │ └── vitest.setup.ts │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── postcss.config.mjs │ │ ├── stories/ │ │ │ ├── Button.stories.ts │ │ │ ├── Button.tsx │ │ │ ├── Card.stories.ts │ │ │ ├── Card.tsx │ │ │ └── styles.css │ │ ├── vite-storybook.config.ts │ │ └── vitest.config.ts │ ├── example-vite/ │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.jsx │ │ │ ├── index.css │ │ │ └── main.jsx │ │ └── vite.config.mjs │ ├── example-vite-react/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ └── main.tsx │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts │ ├── example-vite-rsc/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── DevStyleXInject.tsx │ │ │ ├── action.tsx │ │ │ ├── client.tsx │ │ │ ├── framework/ │ │ │ │ ├── entry.browser.tsx │ │ │ │ ├── entry.rsc.tsx │ │ │ │ └── entry.ssr.tsx │ │ │ ├── index.css │ │ │ └── root.tsx │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── example-waku/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── public/ │ │ │ └── robots.txt │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── DevStyleXInject.tsx │ │ │ │ ├── counter.tsx │ │ │ │ ├── footer.tsx │ │ │ │ └── header.tsx │ │ │ ├── global.css │ │ │ ├── pages/ │ │ │ │ ├── _layout.tsx │ │ │ │ ├── about.tsx │ │ │ │ └── index.tsx │ │ │ └── pages.gen.ts │ │ ├── tsconfig.json │ │ └── waku.config.ts │ └── example-webpack/ │ ├── .babelrc.js │ ├── .eslintrc.js │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src/ │ │ ├── App.jsx │ │ ├── app.css │ │ ├── components/ │ │ │ └── CTAButton.jsx │ │ ├── index.js │ │ └── tokens.stylex.js │ └── webpack.config.js ├── flow-typed/ │ ├── babel-plugins.js │ ├── environments/ │ │ ├── bom.js │ │ ├── cssom.js │ │ ├── dom.js │ │ ├── html.js │ │ ├── jsx.js │ │ ├── node.js │ │ └── streams.js │ ├── flow-api-translator.js │ ├── npm/ │ │ ├── @babel/ │ │ │ ├── cli_vx.x.x.js │ │ │ ├── core.js │ │ │ ├── eslint-parser_vx.x.x.js │ │ │ ├── generator.js │ │ │ ├── helper-module-imports.js │ │ │ ├── node_vx.x.x.js │ │ │ ├── parser.js │ │ │ ├── preset-env_vx.x.x.js │ │ │ ├── preset-flow_vx.x.x.js │ │ │ ├── preset-react_vx.x.x.js │ │ │ ├── preset-typescript_vx.x.x.js │ │ │ ├── traverse.js │ │ │ └── types.js │ │ ├── @chromatic-com/ │ │ │ └── storybook_vx.x.x.js │ │ ├── @csstools/ │ │ │ └── css-tokenizer_v3.x.x.js │ │ ├── ansis_vx.x.x.js │ │ ├── autoprefixer_vx.x.x.js │ │ ├── babel-loader_vx.x.x.js │ │ ├── benchmark_vx.x.x.js │ │ ├── brotli-size_vx.x.x.js │ │ ├── chalk_v4.x.x.js │ │ ├── clean-css_vx.x.x.js │ │ ├── clsx_v1.x.x.js │ │ ├── codemirror_vx.x.x.js │ │ ├── colors_v1.x.x.js │ │ ├── cross-env_vx.x.x.js │ │ ├── css-loader_vx.x.x.js │ │ ├── css-mediaquery_vx.x.x.js │ │ ├── css-shorthand-expand_vx.x.x.js │ │ ├── esbuild_vx.x.x.js │ │ ├── estree.js │ │ ├── fast-glob_vx.x.x.js │ │ ├── fb-watchman_vx.x.x.js │ │ ├── file-loader_vx.x.x.js │ │ ├── flow-bin_v0.x.x.js │ │ ├── flow-enums-runtime_v0.x.x.js │ │ ├── glob-parent_vx.x.x.js │ │ ├── html-webpack-plugin_vx.x.x.js │ │ ├── husky_vx.x.x.js │ │ ├── invariant_v2.x.x.js │ │ ├── is-glob_vx.x.x.js │ │ ├── jest-environment-jsdom_vx.x.x.js │ │ ├── jest_v27.x.x.js │ │ ├── jest_vx.x.x.js │ │ ├── js-yaml_v4.x.x.js │ │ ├── json5_vx.x.x.js │ │ ├── mkdirp_v1.x.x.js │ │ ├── next_vx.x.x.js │ │ ├── playwright_vx.x.x.js │ │ ├── postcss-loader_vx.x.x.js │ │ ├── postcss-nesting_vx.x.x.js │ │ ├── postcss-value-parser_vx.x.x.js │ │ ├── postcss_vx.x.x.js │ │ ├── react-codemirror2_vx.x.x.js │ │ ├── react-refresh_vx.x.x.js │ │ ├── react-syntax-highlighter_vx.x.x.js │ │ ├── rimraf_v5.x.x.js │ │ ├── rollup-plugin-jsx-remove-attributes_vx.x.x.js │ │ ├── rollup-plugin-node-externals_vx.x.x.js │ │ ├── rollup.js │ │ ├── scripts_vx.x.x.js │ │ ├── semver_v7.x.x.js │ │ ├── serve_vx.x.x.js │ │ ├── storybook_vx.x.x.js │ │ ├── string-natural-compare_v3.x.x.js │ │ ├── styled-jsx_vx.x.x.js │ │ ├── stylelint_vx.x.x.js │ │ ├── styleq_vx.x.x.js │ │ ├── terser_vx.x.x.js │ │ ├── typescript-eslint_vx.x.x.js │ │ ├── typescript_vx.x.x.js │ │ ├── unplugin_vx.x.x.js │ │ ├── vite-plugin-dts_vx.x.x.js │ │ ├── vitest_vx.x.x.js │ │ ├── webpack-cli_vx.x.x.js │ │ ├── webpack-dev-server_vx.x.x.js │ │ ├── webpack_v5.x.x.js │ │ └── yargs_v17.x.x.js │ └── stubs.js ├── flow-typed.config.json ├── package.json ├── packages/ │ ├── @stylexjs/ │ │ ├── babel-plugin/ │ │ │ ├── .babelrc │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── __fixtures__/ │ │ │ │ │ └── constants.stylex.js │ │ │ │ ├── evaluation-import-test.js │ │ │ │ ├── legacy/ │ │ │ │ │ ├── stylex-transform-call-test.js │ │ │ │ │ ├── stylex-transform-legacy-shorthands-test.js │ │ │ │ │ ├── transform-legacy-polyfills-test.js │ │ │ │ │ ├── transform-logical-properties-test.js │ │ │ │ │ ├── transform-logical-values-test.js │ │ │ │ │ └── transform-pre-plugin-test.js │ │ │ │ ├── transform-import-export-test.js │ │ │ │ ├── transform-polyfills-test.js │ │ │ │ ├── transform-process-test.js │ │ │ │ ├── transform-stylex-create-test.js │ │ │ │ ├── transform-stylex-createTheme-test.js │ │ │ │ ├── transform-stylex-defineConsts-test.js │ │ │ │ ├── transform-stylex-defineMarker-test.js │ │ │ │ ├── transform-stylex-defineVars-test.js │ │ │ │ ├── transform-stylex-keyframes-test.js │ │ │ │ ├── transform-stylex-positionTry-test.js │ │ │ │ ├── transform-stylex-props-test.js │ │ │ │ ├── transform-stylex-viewTransitionClass-test.js │ │ │ │ ├── transform-stylex-when-test.js │ │ │ │ ├── transform-value-normalization-test.js │ │ │ │ ├── validation-import-export-test.js │ │ │ │ ├── validation-stylex-create-test.js │ │ │ │ ├── validation-stylex-createTheme-test.js │ │ │ │ ├── validation-stylex-defineConsts-test.js │ │ │ │ ├── validation-stylex-defineMarker-test.js │ │ │ │ ├── validation-stylex-defineVars-test.js │ │ │ │ └── validation-stylex-keyframes-test.js │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── rollup.config.mjs │ │ │ └── src/ │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── shared/ │ │ │ │ ├── README.md │ │ │ │ ├── common-types.d.ts │ │ │ │ ├── common-types.js │ │ │ │ ├── hash.js │ │ │ │ ├── index.js │ │ │ │ ├── messages.js │ │ │ │ ├── physical-rtl/ │ │ │ │ │ ├── generate-ltr.js │ │ │ │ │ └── generate-rtl.js │ │ │ │ ├── preprocess-rules/ │ │ │ │ │ ├── PreRule.js │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── PreRule-test.js │ │ │ │ │ │ └── flatten-raw-style-obj-test.js │ │ │ │ │ ├── application-order.js │ │ │ │ │ ├── basic-validation.js │ │ │ │ │ ├── flatten-raw-style-obj.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── legacy-expand-shorthands.js │ │ │ │ │ └── property-specificity.js │ │ │ │ ├── stylex-consts-utils.js │ │ │ │ ├── stylex-create-theme.d.ts │ │ │ │ ├── stylex-create-theme.js │ │ │ │ ├── stylex-create.js │ │ │ │ ├── stylex-defaultMarker.js │ │ │ │ ├── stylex-define-consts.js │ │ │ │ ├── stylex-define-vars.d.ts │ │ │ │ ├── stylex-define-vars.js │ │ │ │ ├── stylex-first-that-works.js │ │ │ │ ├── stylex-keyframes.js │ │ │ │ ├── stylex-position-try.js │ │ │ │ ├── stylex-vars-utils.js │ │ │ │ ├── stylex-view-transition-class.js │ │ │ │ ├── types/ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── stylex-types-test.js │ │ │ │ │ ├── index.d.ts │ │ │ │ │ └── index.js │ │ │ │ ├── utils/ │ │ │ │ │ ├── Rule.js │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ ├── convert-to-className-test.js │ │ │ │ │ │ ├── split-css-value-test.js │ │ │ │ │ │ └── transform-value-test.js │ │ │ │ │ ├── convert-to-className.js │ │ │ │ │ ├── dashify.js │ │ │ │ │ ├── default-options.js │ │ │ │ │ ├── file-based-identifier.js │ │ │ │ │ ├── generate-css-rule.js │ │ │ │ │ ├── normalize-value.js │ │ │ │ │ ├── normalizers/ │ │ │ │ │ │ ├── convert-camel-case-values.js │ │ │ │ │ │ ├── detect-unclosed-fns.js │ │ │ │ │ │ ├── font-size-px-to-rem.js │ │ │ │ │ │ ├── leading-zero.js │ │ │ │ │ │ ├── quotes.js │ │ │ │ │ │ ├── timings.js │ │ │ │ │ │ ├── whitespace.js │ │ │ │ │ │ └── zero-dimensions.js │ │ │ │ │ ├── object-utils.js │ │ │ │ │ ├── rule-utils.js │ │ │ │ │ ├── split-css-value.js │ │ │ │ │ └── transform-value.js │ │ │ │ ├── validate.js │ │ │ │ └── when/ │ │ │ │ └── when.js │ │ │ ├── utils/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── evaluate-path-test.js │ │ │ │ │ ├── js-to-ast-test.js │ │ │ │ │ └── state-manager-test.js │ │ │ │ ├── add-sourcemap-data.js │ │ │ │ ├── ast-helpers.js │ │ │ │ ├── dev-classname.js │ │ │ │ ├── evaluate-path.js │ │ │ │ ├── evaluation-errors.js │ │ │ │ ├── helpers.js │ │ │ │ ├── js-to-ast.js │ │ │ │ ├── state-manager.js │ │ │ │ └── validate.js │ │ │ └── visitors/ │ │ │ ├── __tests__/ │ │ │ │ └── parse-stylex-create-arg-test.js │ │ │ ├── imports.js │ │ │ ├── parse-stylex-create-arg.js │ │ │ ├── stylex-create-theme.js │ │ │ ├── stylex-create.js │ │ │ ├── stylex-default-marker.js │ │ │ ├── stylex-define-consts.js │ │ │ ├── stylex-define-marker.js │ │ │ ├── stylex-define-vars.js │ │ │ ├── stylex-keyframes.js │ │ │ ├── stylex-merge.js │ │ │ ├── stylex-position-try.js │ │ │ ├── stylex-props.js │ │ │ └── stylex-view-transition-class.js │ │ ├── cli/ │ │ │ ├── .babelrc.js │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── __mocks__/ │ │ │ │ │ ├── snapshot/ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── button.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── nonjs.txt │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ └── home.js │ │ │ │ │ │ └── stylex_bundle.css │ │ │ │ │ ├── snapshot2/ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── button.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── nonjs.txt │ │ │ │ │ │ └── pages/ │ │ │ │ │ │ └── home.js │ │ │ │ │ ├── source/ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── button.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── nonjs.txt │ │ │ │ │ │ └── pages/ │ │ │ │ │ │ └── home.js │ │ │ │ │ └── source2/ │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── button.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── nonjs.txt │ │ │ │ │ └── pages/ │ │ │ │ │ └── home.js │ │ │ │ └── compile-stylex-folder-test.js │ │ │ ├── package.json │ │ │ ├── rollup.config.mjs │ │ │ └── src/ │ │ │ ├── cache.js │ │ │ ├── config.js │ │ │ ├── errors.js │ │ │ ├── files.js │ │ │ ├── hash.js │ │ │ ├── index.js │ │ │ ├── modules.js │ │ │ ├── options.js │ │ │ ├── plugins.js │ │ │ ├── transform.js │ │ │ └── watcher.js │ │ ├── create-stylex-app/ │ │ │ ├── .babelrc.js │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.js │ │ │ │ ├── templates.js │ │ │ │ └── utils/ │ │ │ │ ├── fetch-template.js │ │ │ │ ├── files.js │ │ │ │ └── packages.js │ │ │ └── templates.json │ │ ├── eslint-plugin/ │ │ │ ├── .babelrc │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── stylex-enforce-extension-test.js │ │ │ │ ├── stylex-no-conflicting-props-test.js │ │ │ │ ├── stylex-no-legacy-contextual-styles-test.js │ │ │ │ ├── stylex-no-lookahead-selectors-test.js │ │ │ │ ├── stylex-no-nonstandard-styles-test.js │ │ │ │ ├── stylex-no-unused-test.js │ │ │ │ ├── stylex-sort-keys-test.js │ │ │ │ ├── stylex-valid-shorthands-test.js │ │ │ │ └── stylex-valid-styles-test.js │ │ │ ├── flow_modules/ │ │ │ │ ├── eslint/ │ │ │ │ │ ├── eslint-ast.js.flow │ │ │ │ │ ├── eslint-rule.js.flow │ │ │ │ │ └── index.js.flow │ │ │ │ └── estree/ │ │ │ │ └── index.js.flow │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── rollup.config.mjs │ │ │ └── src/ │ │ │ ├── index.js │ │ │ ├── reference/ │ │ │ │ ├── cleanOrderPriorities.js │ │ │ │ ├── cssProperties.js │ │ │ │ ├── namedColors.js │ │ │ │ └── recessOrderPriorities.js │ │ │ ├── rules/ │ │ │ │ ├── isAbsoluteLength.js │ │ │ │ ├── isAnimationName.js │ │ │ │ ├── isCSSVariable.js │ │ │ │ ├── isHexColor.js │ │ │ │ ├── isNumber.js │ │ │ │ ├── isPercentage.js │ │ │ │ ├── isPositionTryFallbacks.js │ │ │ │ ├── isRelativeLength.js │ │ │ │ ├── isString.js │ │ │ │ ├── isStylexResolvedVarsToken.js │ │ │ │ ├── makeLiteralRule.js │ │ │ │ ├── makeRangeRule.js │ │ │ │ ├── makeRegExRule.js │ │ │ │ └── makeUnionRule.js │ │ │ ├── stylex-enforce-extension.js │ │ │ ├── stylex-no-conflicting-props.js │ │ │ ├── stylex-no-legacy-contextual-styles.js │ │ │ ├── stylex-no-lookahead-selectors.js │ │ │ ├── stylex-no-nonstandard-styles.js │ │ │ ├── stylex-no-unused.js │ │ │ ├── stylex-sort-keys.js │ │ │ ├── stylex-valid-shorthands.js │ │ │ ├── stylex-valid-styles.js │ │ │ └── utils/ │ │ │ ├── createImportTracker.js │ │ │ ├── evaluate.js │ │ │ ├── getDistance.js │ │ │ ├── getPropertyName.js │ │ │ ├── getPropertyPriorityAndType.js │ │ │ ├── getSourceCode.js │ │ │ ├── isWhiteSpaceOrEmpty.js │ │ │ ├── makeVariableCheckingRule.js │ │ │ ├── resolveKey.js │ │ │ ├── split-css-value.js │ │ │ └── splitShorthands.js │ │ ├── postcss-plugin/ │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── __auto_discovery_fixtures__/ │ │ │ │ │ ├── README.md │ │ │ │ │ ├── babel.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ └── src/ │ │ │ │ │ ├── local-rsd.js │ │ │ │ │ ├── local-stylex.js │ │ │ │ │ └── types.d.ts │ │ │ │ ├── __fixtures__/ │ │ │ │ │ ├── .babelrc.js │ │ │ │ │ ├── import-sources-object.js │ │ │ │ │ ├── import-sources-string.js │ │ │ │ │ ├── styles-second.js │ │ │ │ │ └── styles.js │ │ │ │ └── index-test.js │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ └── src/ │ │ │ ├── builder.js │ │ │ ├── bundler.js │ │ │ ├── discovery.js │ │ │ ├── index.js │ │ │ └── plugin.js │ │ ├── rollup-plugin/ │ │ │ ├── .babelrc.cjs │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── __fixtures__/ │ │ │ │ │ ├── .babelrc.json │ │ │ │ │ ├── index.js │ │ │ │ │ ├── npmStyles.js │ │ │ │ │ └── otherStyles.js │ │ │ │ └── index-test.js │ │ │ ├── package.json │ │ │ └── src/ │ │ │ └── index.js │ │ ├── shared/ │ │ │ ├── .babelrc │ │ │ ├── package.json │ │ │ └── src/ │ │ │ ├── index.js │ │ │ └── utils/ │ │ │ └── property-priorities.js │ │ ├── stylex/ │ │ │ ├── .babelrc.js │ │ │ ├── README.md │ │ │ ├── __tests__/ │ │ │ │ ├── createOrderedCSSStyleSheet-test.js │ │ │ │ ├── createSheet-test.js │ │ │ │ ├── inject-test.js │ │ │ │ └── stylex-test.js │ │ │ ├── flow-tests/ │ │ │ │ ├── stylex-create.js.flow │ │ │ │ ├── test1.js.flow │ │ │ │ ├── test2.js.flow │ │ │ │ ├── test3.js.flow │ │ │ │ ├── test4.js.flow │ │ │ │ ├── theming/ │ │ │ │ │ ├── ButtonTokenThemes.js │ │ │ │ │ └── ButtonTokens.stylex.js │ │ │ │ └── theming1.js.flow │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── rollup.config.mjs │ │ │ └── src/ │ │ │ ├── inject.js │ │ │ ├── stylesheet/ │ │ │ │ ├── createCSSStyleSheet.js │ │ │ │ ├── createOrderedCSSStyleSheet.js │ │ │ │ ├── createSheet.js │ │ │ │ └── utils.js │ │ │ ├── stylex.js │ │ │ └── types/ │ │ │ ├── StyleXCSSTypes.js │ │ │ ├── StyleXOpaqueTypes.js │ │ │ ├── StyleXTypes.d.ts │ │ │ ├── StyleXTypes.js │ │ │ ├── StyleXUtils.js │ │ │ └── VarTypes.js │ │ └── unplugin/ │ │ ├── .babelrc.cjs │ │ ├── README.md │ │ ├── __tests__/ │ │ │ └── unplugin.test.js │ │ ├── babel-plugins/ │ │ │ └── add-mjs-extension.js │ │ ├── package.json │ │ └── src/ │ │ ├── bun.d.ts │ │ ├── bun.js │ │ ├── consts.js │ │ ├── core.d.ts │ │ ├── core.js │ │ ├── dev-inject-middleware.js │ │ ├── esbuild.d.ts │ │ ├── esbuild.js │ │ ├── farm.d.ts │ │ ├── farm.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── rolldown.d.ts │ │ ├── rolldown.js │ │ ├── rollup.d.ts │ │ ├── rollup.js │ │ ├── rspack.d.ts │ │ ├── rspack.js │ │ ├── unloader.d.ts │ │ ├── unloader.js │ │ ├── vite.d.ts │ │ ├── vite.js │ │ ├── webpack.d.ts │ │ └── webpack.js │ ├── benchmarks/ │ │ ├── compare.js │ │ ├── package.json │ │ ├── perf/ │ │ │ ├── fixtures/ │ │ │ │ ├── colors.stylex.js │ │ │ │ ├── create-basic.js │ │ │ │ ├── create-complex.js │ │ │ │ ├── createTheme-basic.js │ │ │ │ ├── createTheme-complex.js │ │ │ │ └── sizes.stylex.js │ │ │ ├── helpers.js │ │ │ ├── run.js │ │ │ └── tests/ │ │ │ ├── transform-create-tests.js │ │ │ └── transform-create-theme-tests.js │ │ └── size/ │ │ ├── fixtures/ │ │ │ ├── index.js │ │ │ ├── lotsOfStyles.js │ │ │ └── lotsOfStylesDynamic.js │ │ ├── rollup.config.mjs │ │ └── run.js │ ├── docs/ │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── cli.json │ │ ├── content/ │ │ │ ├── blog/ │ │ │ │ ├── 2023-12-05-introducing-stylex.md │ │ │ │ ├── 2023-12-29-Release-v0.4.1.md │ │ │ │ ├── 2024-01-25-Release-v0.5.0.md │ │ │ │ ├── 2024-04-16-Release-v0.6.1.mdx │ │ │ │ ├── 2024-06-25-Release-v0.7.0.mdx │ │ │ │ ├── 2024-06-28-Release-v0.7.3.mdx │ │ │ │ ├── 2024-10-06-Release-v0.8.0.mdx │ │ │ │ ├── 2024-11-01-Release-v0.9.3.mdx │ │ │ │ ├── 2025-01-02-Release-v0.10.0.mdx │ │ │ │ ├── 2025-01-17-Release-v0.10.1.mdx │ │ │ │ ├── 2025-02-27-Release-v0.11.0.mdx │ │ │ │ ├── 2025-04-10-Release-v0.12.0.mdx │ │ │ │ ├── 2025-05-19-Release-v0.13.0.mdx │ │ │ │ ├── 2025-06-30-Release-v0.14.0.mdx │ │ │ │ ├── 2025-07-31-Release-v0.15.0.mdx │ │ │ │ ├── 2025-09-25-Release-v0.16.0.mdx │ │ │ │ ├── 2025-11-25-Release-v0.17.1.mdx │ │ │ │ └── 2026-01-01-new-year-new-website.mdx │ │ │ └── docs/ │ │ │ ├── acknowledgements.mdx │ │ │ ├── api/ │ │ │ │ ├── configuration/ │ │ │ │ │ ├── babel-plugin.mdx │ │ │ │ │ ├── eslint-plugin.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ ├── postcss-plugin.mdx │ │ │ │ │ └── unplugin.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── javascript/ │ │ │ │ │ ├── create.mdx │ │ │ │ │ ├── createTheme.mdx │ │ │ │ │ ├── defineConsts.mdx │ │ │ │ │ ├── defineVars.mdx │ │ │ │ │ ├── env.mdx │ │ │ │ │ ├── firstThatWorks.mdx │ │ │ │ │ ├── keyframes.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ ├── positionTry.mdx │ │ │ │ │ ├── props.mdx │ │ │ │ │ ├── types.mdx │ │ │ │ │ ├── viewTransitionClass.mdx │ │ │ │ │ └── when.mdx │ │ │ │ └── types/ │ │ │ │ ├── StaticStyles.mdx │ │ │ │ ├── StyleXStyles.mdx │ │ │ │ ├── StyleXStylesWithout.mdx │ │ │ │ ├── Theme.mdx │ │ │ │ ├── VarGroup.mdx │ │ │ │ └── meta.json │ │ │ ├── ecosystem.mdx │ │ │ ├── index.mdx │ │ │ ├── learn/ │ │ │ │ ├── index.mdx │ │ │ │ ├── installation/ │ │ │ │ │ ├── cli.mdx │ │ │ │ │ ├── esbuild.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ ├── nextjs.mdx │ │ │ │ │ ├── postcss.mdx │ │ │ │ │ ├── rspack.mdx │ │ │ │ │ ├── vite/ │ │ │ │ │ │ ├── index.mdx │ │ │ │ │ │ ├── meta.json │ │ │ │ │ │ ├── react-router.mdx │ │ │ │ │ │ ├── redwoodsdk.mdx │ │ │ │ │ │ ├── vite-react.mdx │ │ │ │ │ │ ├── vite-rsc.mdx │ │ │ │ │ │ └── waku.mdx │ │ │ │ │ └── webpack.mdx │ │ │ │ ├── meta.json │ │ │ │ ├── recipes/ │ │ │ │ │ ├── context-driven-styles.mdx │ │ │ │ │ ├── descendant-styles.mdx │ │ │ │ │ ├── light-dark-themes.mdx │ │ │ │ │ ├── merge-themes.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ ├── reset-themes.mdx │ │ │ │ │ ├── shareable-tokens.mdx │ │ │ │ │ └── variants.mdx │ │ │ │ ├── static-types.mdx │ │ │ │ ├── styling-ui/ │ │ │ │ │ ├── defining-styles.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ └── using-styles.mdx │ │ │ │ ├── theming/ │ │ │ │ │ ├── creating-themes.mdx │ │ │ │ │ ├── defining-variables.mdx │ │ │ │ │ ├── meta.json │ │ │ │ │ ├── using-variables.mdx │ │ │ │ │ └── variable-types.mdx │ │ │ │ └── thinking-in-stylex.mdx │ │ │ ├── llm-resources.mdx │ │ │ └── meta.json │ │ ├── package.json │ │ ├── source.config.ts │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── AnimatedGradientBox/ │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── tokens.stylex.ts │ │ │ │ ├── CtaButton.tsx │ │ │ │ ├── DevStyleXHMR.tsx │ │ │ │ ├── Dial.tsx │ │ │ │ ├── Footer.tsx │ │ │ │ ├── Logo.tsx │ │ │ │ ├── LogoBold.tsx │ │ │ │ ├── Playground/ │ │ │ │ │ ├── Dialogs.tsx │ │ │ │ │ ├── DynamicPlayground.tsx │ │ │ │ │ ├── Menu.tsx │ │ │ │ │ ├── Tabs.tsx │ │ │ │ │ ├── demoConstants.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── StylexAnimatedLogo.tsx │ │ │ │ ├── TypingWord.tsx │ │ │ │ ├── ZStack.tsx │ │ │ │ ├── icons/ │ │ │ │ │ ├── Bluesky.tsx │ │ │ │ │ └── MetaOpenSource.tsx │ │ │ │ ├── layout/ │ │ │ │ │ ├── docs.tsx │ │ │ │ │ ├── home/ │ │ │ │ │ │ ├── SidebarToggle.tsx │ │ │ │ │ │ ├── client.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── shared/ │ │ │ │ │ ├── client.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── mdx/ │ │ │ │ │ ├── Callout.tsx │ │ │ │ │ ├── Cards.tsx │ │ │ │ │ ├── CodeBlock.tsx │ │ │ │ │ ├── Details.tsx │ │ │ │ │ ├── Heading.tsx │ │ │ │ │ ├── Image.tsx │ │ │ │ │ ├── LLMFiles.tsx │ │ │ │ │ ├── Link.tsx │ │ │ │ │ ├── PackageInstall.tsx │ │ │ │ │ ├── ScrollableCodeBlock.tsx │ │ │ │ │ ├── Table.tsx │ │ │ │ │ ├── Tabs.tsx │ │ │ │ │ ├── VersionTag.tsx │ │ │ │ │ ├── WhenDemo.tsx │ │ │ │ │ ├── core.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── markers.stylex.ts │ │ │ │ │ └── mdx.stylex.ts │ │ │ │ ├── navigation-menu.tsx │ │ │ │ ├── provider.tsx │ │ │ │ ├── search-dialog.tsx │ │ │ │ ├── search-toggle.tsx │ │ │ │ ├── sidebar.tsx │ │ │ │ ├── theme-toggle.tsx │ │ │ │ └── ui/ │ │ │ │ ├── button.tsx │ │ │ │ ├── collapsible.tsx │ │ │ │ ├── popover.tsx │ │ │ │ └── scroll-area.tsx │ │ │ ├── contexts/ │ │ │ │ └── SidebarContext.tsx │ │ │ ├── hooks/ │ │ │ │ └── useStateWithCallback.tsx │ │ │ ├── pages/ │ │ │ │ ├── (home)/ │ │ │ │ │ ├── _layout.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── (playground)/ │ │ │ │ │ ├── _layout.tsx │ │ │ │ │ └── playground.tsx │ │ │ │ ├── _layout.tsx │ │ │ │ ├── api/ │ │ │ │ │ ├── blog-atom.xml.ts │ │ │ │ │ ├── blog-rss.xml.ts │ │ │ │ │ ├── llms-full.txt.ts │ │ │ │ │ └── search.ts │ │ │ │ ├── blog/ │ │ │ │ │ ├── [...slugs].tsx │ │ │ │ │ ├── _layout.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── docs/ │ │ │ │ ├── [...slugs].tsx │ │ │ │ └── _layout.tsx │ │ │ ├── styles/ │ │ │ │ └── globals.css │ │ │ ├── theming/ │ │ │ │ └── vars.stylex.ts │ │ │ └── waku.server.ts │ │ ├── static/ │ │ │ └── llm/ │ │ │ ├── stylex-authoring.md │ │ │ └── stylex-installation.md │ │ ├── tsconfig.json │ │ ├── vercel.json │ │ └── waku.config.ts │ ├── old-docs/ │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .stylelintrc.js │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── blog/ │ │ │ ├── 2023-12-05-introducing-stylex.md │ │ │ ├── 2023-12-29-Release-v0.4.1.md │ │ │ ├── 2024-01-25-Release-v0.5.0.md │ │ │ ├── 2024-04-16-Release-v0.6.1.mdx │ │ │ ├── 2024-06-25-Release-v0.7.0.mdx │ │ │ ├── 2024-06-28-Release-v0.7.3.mdx │ │ │ ├── 2024-10-06-Release-v0.8.0.mdx │ │ │ ├── 2024-11-01-Release-v0.9.3.mdx │ │ │ ├── 2025-01-02-Release-v0.10.0.mdx │ │ │ ├── 2025-01-17-Release-v0.10.1.mdx │ │ │ ├── 2025-02-27-Release-v0.11.0.mdx │ │ │ ├── 2025-04-10-Release-v0.12.0.mdx │ │ │ ├── 2025-05-19-Release-v0.13.0.mdx │ │ │ ├── 2025-06-30-Release-v0.14.0.mdx │ │ │ ├── 2025-07-31-Release-v0.15.0.mdx │ │ │ ├── 2025-09-25-Release-v0.16.0.mdx │ │ │ ├── 2025-11-25-Release-v0.17.1.mdx │ │ │ └── authors.yml │ │ ├── components/ │ │ │ ├── AnimatedGradientBox/ │ │ │ │ ├── AnimatedGradientBox.js │ │ │ │ └── tokens.stylex.js │ │ │ ├── CtaButton.js │ │ │ ├── Dial.js │ │ │ ├── LoadingSpinner.js │ │ │ ├── Logo.js │ │ │ ├── LogoBold.js │ │ │ ├── LogoDownloadModal.js │ │ │ ├── Playground.js │ │ │ ├── StylexAnimatedLogo.js │ │ │ ├── VersionTag.js │ │ │ ├── YouTube.js │ │ │ ├── ZStack.js │ │ │ ├── examples/ │ │ │ │ └── dev-install.js │ │ │ ├── hooks/ │ │ │ │ ├── useDebounced.js │ │ │ │ ├── useId.js │ │ │ │ └── useViewTransition.js │ │ │ └── playground-utils/ │ │ │ └── files.js │ │ ├── docs/ │ │ │ ├── api/ │ │ │ │ ├── configuration/ │ │ │ │ │ ├── _category_.json │ │ │ │ │ ├── babel-plugin.mdx │ │ │ │ │ ├── eslint-plugin.mdx │ │ │ │ │ ├── postcss-plugin.mdx │ │ │ │ │ └── unplugin.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── javascript/ │ │ │ │ │ ├── _category_.json │ │ │ │ │ ├── create.mdx │ │ │ │ │ ├── createTheme.mdx │ │ │ │ │ ├── defineConsts.mdx │ │ │ │ │ ├── defineVars.mdx │ │ │ │ │ ├── firstThatWorks.mdx │ │ │ │ │ ├── keyframes.mdx │ │ │ │ │ ├── positionTry.mdx │ │ │ │ │ ├── props.mdx │ │ │ │ │ ├── types.mdx │ │ │ │ │ ├── viewTransitionClass.mdx │ │ │ │ │ └── when.mdx │ │ │ │ └── types/ │ │ │ │ ├── StaticStyles.mdx │ │ │ │ ├── StyleXStyles.mdx │ │ │ │ ├── StyleXStylesWithout.mdx │ │ │ │ ├── Theme.mdx │ │ │ │ ├── VarGroup.mdx │ │ │ │ └── _category_.json │ │ │ └── learn/ │ │ │ ├── 02-thinking-in-stylex.mdx │ │ │ ├── 03-installation.mdx │ │ │ ├── 04-styling-ui/ │ │ │ │ ├── 01-defining-styles.mdx │ │ │ │ ├── 02-using-styles.mdx │ │ │ │ └── _category_.json │ │ │ ├── 05-theming/ │ │ │ │ ├── 01-defining-variables.mdx │ │ │ │ ├── 02-using-variables.mdx │ │ │ │ ├── 03-creating-themes.mdx │ │ │ │ ├── 04-variable-types.mdx │ │ │ │ └── _category_.json │ │ │ ├── 06-recipes/ │ │ │ │ ├── 01-context-driven-styles.mdx │ │ │ │ ├── 02-variants.mdx │ │ │ │ ├── 03-descendant styles.mdx │ │ │ │ ├── 04-reset-themes.mdx │ │ │ │ ├── 05-merge-themes.mdx │ │ │ │ ├── 06-light-dark-themes.mdx │ │ │ │ └── _category_.json │ │ │ ├── 06-static-types.mdx │ │ │ ├── 07-ecosystem.mdx │ │ │ ├── 08-acknowledgements.mdx │ │ │ └── index.mdx │ │ ├── docusaurus.config.js │ │ ├── eslintrc-legacy.js │ │ ├── package.json │ │ ├── serve.json │ │ ├── sidebars.js │ │ ├── src/ │ │ │ ├── css/ │ │ │ │ └── custom.css │ │ │ ├── pages/ │ │ │ │ ├── index.js │ │ │ │ └── playground.js │ │ │ └── theme/ │ │ │ ├── Footer/ │ │ │ │ └── index.js │ │ │ ├── Logo/ │ │ │ │ └── index.js │ │ │ └── MDXComponents/ │ │ │ ├── Details.js │ │ │ └── DetailsTokens.stylex.js │ │ └── static/ │ │ ├── .nojekyll │ │ └── robots.txt │ ├── scripts/ │ │ ├── README.md │ │ ├── flow-translator/ │ │ │ ├── flow-module-utils.js │ │ │ ├── generate-types.js │ │ │ └── rewrite-imports.js │ │ └── package.json │ ├── shared-ui/ │ │ ├── package.json │ │ └── src/ │ │ ├── index.tsx │ │ └── tokens.stylex.ts │ ├── style-value-parser/ │ │ ├── .babelrc │ │ ├── README.md │ │ ├── __benchmarks__/ │ │ │ ├── alpha-value.bench.mjs │ │ │ ├── angle-percentage.bench.mjs │ │ │ ├── angle.bench.mjs │ │ │ ├── basic-shape.bench.mjs │ │ │ ├── blend-mode.bench.mjs │ │ │ ├── calc-constant.bench.mjs │ │ │ ├── color.bench.mjs │ │ │ ├── common-types.bench.mjs │ │ │ ├── custom-ident.bench.mjs │ │ │ ├── dashed-ident.bench.mjs │ │ │ ├── dimension.bench.mjs │ │ │ ├── easing-function.bench.mjs │ │ │ ├── filter-function.bench.mjs │ │ │ ├── flex.bench.mjs │ │ │ ├── frequency.bench.mjs │ │ │ ├── length-percentage.bench.mjs │ │ │ └── length.bench.mjs │ │ ├── jest.config.cjs │ │ ├── package.json │ │ └── src/ │ │ ├── __tests__/ │ │ │ └── token-parser-test.js │ │ ├── at-queries/ │ │ │ ├── __tests__/ │ │ │ │ ├── media-query-transform-test.js │ │ │ │ ├── parse-media-query-test.js │ │ │ │ └── validation-media-query-test.js │ │ │ ├── media-query-transform.js │ │ │ ├── media-query.js │ │ │ └── messages.js │ │ ├── base-types.js │ │ ├── css-types/ │ │ │ ├── __tests__/ │ │ │ │ ├── alpha-value-test.js │ │ │ │ ├── angle-percentage-test.js │ │ │ │ ├── angle-test.js │ │ │ │ ├── basic-shape.js │ │ │ │ ├── blend-mode-test.js │ │ │ │ ├── calc-constant.js │ │ │ │ ├── calc-test.js │ │ │ │ ├── color-test.js │ │ │ │ ├── custom-ident-test.js │ │ │ │ ├── dashed-ident-test.js │ │ │ │ ├── easing-function-test.js │ │ │ │ ├── filter-function-test.js │ │ │ │ ├── flex-test.js │ │ │ │ ├── frequency-test.js │ │ │ │ ├── length-percentage-test.js │ │ │ │ ├── length-test.js │ │ │ │ ├── position-test.js │ │ │ │ ├── resolution-test.js │ │ │ │ ├── time-test.js │ │ │ │ └── transform-function-test.js │ │ │ ├── alpha-value.js │ │ │ ├── angle-percentage.js │ │ │ ├── angle.js │ │ │ ├── basic-shape.js │ │ │ ├── blend-mode.js │ │ │ ├── calc-constant.js │ │ │ ├── calc.js │ │ │ ├── color.js │ │ │ ├── common-types.js │ │ │ ├── custom-ident.js │ │ │ ├── dashed-ident.js │ │ │ ├── dimension.js │ │ │ ├── easing-function.js │ │ │ ├── filter-function.js │ │ │ ├── flex.js │ │ │ ├── frequency.js │ │ │ ├── length-percentage.js │ │ │ ├── length.js │ │ │ ├── position.js │ │ │ ├── resolution.js │ │ │ ├── time.js │ │ │ └── transform-function.js │ │ ├── index.js │ │ ├── properties/ │ │ │ ├── __tests__/ │ │ │ │ ├── border-radius.test.js │ │ │ │ ├── box-shadow.test.js │ │ │ │ └── transform.js │ │ │ ├── border-radius.js │ │ │ ├── box-shadow.js │ │ │ └── transform.js │ │ ├── properties.js │ │ ├── token-parser.js │ │ └── token-types.js │ └── typescript-tests/ │ ├── package.json │ ├── src/ │ │ ├── babel-plugin.ts │ │ ├── env.ts │ │ ├── exports.ts │ │ ├── test1.tsx │ │ ├── test2.tsx │ │ ├── test3.tsx │ │ ├── test4.tsx │ │ ├── test5.tsx │ │ ├── themes.ts │ │ ├── theming/ │ │ │ ├── ButtonTokenThemes.ts │ │ │ └── ButtonTokens.stylex.ts │ │ ├── theming1.tsx │ │ └── typetests.ts │ └── tsconfig.json └── tools/ ├── README.md ├── eslint/ │ └── copyright-header.txt ├── husky/ │ └── pre-commit └── npm/ └── release.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ const path = require('path'); module.exports = { settings: { react: { pragma: 'React', version: '18.0', flowVersion: '0.261.2', // Flow version }, 'ft-flow': { onlyFilesWithFlowAnnotation: true, }, }, // babel parser to support ES6/7 features parser: 'hermes-eslint', extends: ['plugin:ft-flow/recommended', 'prettier'], plugins: ['ft-flow', 'react', 'headers'], env: { browser: true, es6: true, jest: true, node: true, }, ignorePatterns: [ 'build', 'coverage', 'dist', 'flow-typed', 'lib', 'flow_modules', 'node_modules', 'next-env.d.ts', 'next.config.js', '**/__mocks__/snapshot*', '**/storybook-static/**', '**/examples/example-cli/src/**', '**/*.d.ts', '**/pages.gen.ts', ], overrides: [ { files: ['*.ts', '*.tsx'], parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { jsx: true, }, }, rules: { 'ft-flow/space-after-type-colon': 'off', 'ft-flow/generic-spacing': 'off', 'ft-flow/no-types-missing-file-annotation': 'off', }, }, ], globals: { $Call: 'readonly', $Diff: 'readonly', $ElementType: 'readonly', $Exact: 'readonly', $FlowFixMe: 'readonly', $Keys: 'readonly', $NonMaybeType: 'readonly', $ObjMap: 'readonly', $ObjMapConst: 'readonly', $ObjMapi: 'readonly', $PropertyType: 'readonly', $ReactOnly: 'readonly', $ReactOnlyArray: 'readonly', $ReadOnlyMap: 'readonly', $ReadOnlySet: 'readonly', $Rest: 'readonly', $TupleMap: 'readonly', $Values: 'readonly', Partial: 'readonly', }, rules: { 'headers/header-format': [ 'error', { source: 'file', path: path.join(__dirname, './tools/eslint/copyright-header.txt'), }, ], camelcase: 0, 'constructor-super': 2, 'default-case': [2, { commentPattern: '^no default$' }], eqeqeq: [2, 'allow-null'], 'handle-callback-err': [2, '^(err|error)$'], 'new-cap': [2, { newIsCap: true, capIsNew: false }], 'no-alert': 1, 'no-array-constructor': 2, 'no-caller': 2, 'no-case-declarations': 2, 'no-class-assign': 2, 'no-cond-assign': 2, 'no-const-assign': 2, 'no-control-regex': 2, 'no-debugger': 2, 'no-delete-var': 2, 'no-dupe-args': 2, 'no-dupe-class-members': 2, 'no-dupe-keys': 2, 'no-duplicate-case': 2, 'no-empty-character-class': 2, 'no-empty-pattern': 2, 'no-eval': 2, 'no-ex-assign': 2, 'no-extend-native': 2, 'no-extra-bind': 2, 'no-extra-boolean-cast': 2, 'no-fallthrough': 2, 'no-floating-decimal': 2, 'no-func-assign': 2, 'no-implied-eval': 2, 'no-inner-declarations': [2, 'functions'], 'no-invalid-regexp': 2, 'no-irregular-whitespace': 2, 'no-iterator': 2, 'no-label-var': 2, 'no-labels': [2, { allowLoop: false, allowSwitch: false }], 'no-lone-blocks': 2, 'no-loop-func': 2, 'no-multi-str': 2, 'no-native-reassign': 2, 'no-negated-in-lhs': 2, 'no-new': 2, 'no-new-func': 2, 'no-new-object': 2, 'no-new-require': 2, 'no-new-symbol': 2, 'no-new-wrappers': 2, 'no-obj-calls': 2, 'no-octal': 2, 'no-octal-escape': 2, 'no-path-concat': 2, 'no-proto': 2, 'no-redeclare': 2, 'no-regex-spaces': 2, 'no-return-assign': [2, 'except-parens'], 'no-script-url': 2, 'no-self-assign': 2, 'no-self-compare': 2, 'no-sequences': 2, 'no-shadow-restricted-names': 2, 'no-sparse-arrays': 2, 'no-this-before-super': 2, 'no-throw-literal': 2, 'no-undef': 0, 'no-undef-init': 2, 'no-unexpected-multiline': 2, 'no-unmodified-loop-condition': 2, 'no-unneeded-ternary': [2, { defaultAssignment: false }], 'no-unreachable': 2, 'no-unsafe-finally': 2, 'no-unused-vars': [ 2, { vars: 'all', argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, ], 'no-useless-call': 2, 'no-useless-computed-key': 2, 'no-useless-concat': 2, 'no-useless-constructor': 2, 'no-useless-escape': 2, 'no-var': 2, 'no-with': 2, 'prefer-const': 2, 'prefer-rest-params': 2, quotes: [2, 'single', 'avoid-escape'], radix: 2, 'use-isnan': 2, 'valid-typeof': 2, yoda: [2, 'never'], // flow 'ft-flow/space-after-type-colon': [2, 'always', { allowLineBreak: true }], 'ft-flow/generic-spacing': 0, // react 'react/display-name': 0, 'react/jsx-no-bind': 0, 'react/jsx-no-duplicate-props': 2, 'react/jsx-no-undef': 2, 'react/jsx-pascal-case': 2, 'react/jsx-sort-props': 2, 'react/jsx-uses-react': 2, 'react/jsx-uses-vars': 2, 'react/no-did-mount-set-state': 0, 'react/no-did-update-set-state': 2, 'react/no-direct-mutation-state': 2, 'react/no-multi-comp': 0, 'react/no-string-refs': 2, 'react/no-unknown-property': 2, 'react/prefer-es6-class': 2, 'react/prop-types': 0, 'react/react-in-jsx-scope': 0, 'react/self-closing-comp': 2, 'react/sort-comp': 0, 'react/sort-prop-types': 2, 'react/wrap-multilines': 0, }, }; ================================================ FILE: .flowconfig ================================================ [ignore] .*/build/.* .*/dist/.* .*/example-*/.* .*/lib/.* .*/malformed_package_json/.* [include] [lints] [options] experimental.pattern_matching=true enums=true emoji=true casting_syntax=as exact_by_default=true experimental.const_params=true module.use_strict=true munge_underscores=true module.name_mapper='^@stylexjs/babel-plugin$' -> '/packages/@stylexjs/babel-plugin/src/index.js' module.name_mapper='^@stylexjs/stylex$' -> '/packages/@stylexjs/stylex/src/stylex.js' module.name_mapper='^@stylexjs/shared$' -> '/packages/@stylexjs/shared/src/index.js' module.name_mapper='^style-value-parser$' -> '/packages/style-value-parser/src/index.js' ; type-stubs module.system.node.resolve_dirname=flow_modules module.system.node.resolve_dirname=node_modules [strict] ================================================ FILE: .github/CODEOWNERS ================================================ * @ezzak @Jta26 @mellyeliu @necolas @nmn @vincentriemer ================================================ FILE: .github/CODE_OF_CONDUCT.md ================================================ # Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. This Code of Conduct also applies outside the project spaces when there is a reasonable belief that an individual's behavior may have a negative impact on the project or its community. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing ## Reporting Issues and Asking Questions Before opening an issue, please search the issue tracker to make sure your issue hasn't already been reported. Please note that your issue may be closed if it doesn't include the information requested in the issue template. ## Getting started Visit the issue tracker to find a list of open issues that need attention. Fork, then clone the repo: ``` git clone https://github.com/your-username/stylex.git ``` Make sure you have yarn@1.22 and node@>=16 installed. Then install the package dependencies: ``` yarn install ``` ## Automated tests To run the linter: ``` yarn lint ``` To run flow: ``` yarn flow ``` ## Compile and build To compile the source code: ``` yarn build ``` To run all the tests (will build automatically): ``` yarn test ``` …in watch mode (will build only once): ``` yarn test --watch ``` ## Documentation If necessary, first build the StyleX packages (`yarn build`), then start the docs locally: ``` yarn workspace docs start ``` ### New Features Please, familiarize yourself with [StyleX's goals and architectural principles](https://stylexjs.com/docs/learn/thinking-in-stylex/), and open an issue with a proposal when suggesting a new feature of behavioural change. We don't want you to waste your efforts on a pull request that we won't want to accept. ## Pull requests **Before submitting a pull request**, please make sure the following is done: 1. Fork the repository and create your branch from `main`. 2. If you've added code that should be tested, add tests! 3. If you've changed APIs, update the documentation. 4. Ensure the tests pass (`yarn test`). You can now submit a pull request, referencing any issues it addresses. Please try to keep your pull request focused in scope and avoid including unrelated commits. After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements. Thank you for contributing! ## Typical Editor setup ### VS Code If you're using Visual Studio Code, we recommend the following setup for the best experience. #### Extensions We recommend you have the following extensions installed: - [Flow Language Support](https://marketplace.visualstudio.com/items?itemName=flowtype.flow-for-vscode) - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) #### Turn off Typescript within JS files Additionally, since StyleX is authored with the [Flow typesystem](https://flow.org), it is helpful to turn off Typescript type-checking within Javascript files: ```json { "javascript.validate.enable": false } ``` ================================================ FILE: .github/ISSUE_TEMPLATE/bug.yml ================================================ name: Bug report description: File a bug report labels: ["bug"] body: - type: textarea attributes: label: Describe the issue description: Please provide a concise description of what you're experiencing. Providing screenshots is also helpful. validations: required: true - type: textarea attributes: label: Expected behavior description: Please provide a concise description of what you expected to happen. validations: required: true - type: textarea attributes: label: Steps to reproduce description: Please describe the precise steps needed to reproduce the behavior. placeholder: | Mention package versions and environment (platform, browser, etc)... 1. ... 2. ... validations: required: true - type: textarea attributes: label: Test case description: Please provide a reduced test case that reproduces the issue. validations: required: false - type: textarea attributes: label: Additional comments description: You're welcome to provide additional context and proposed solutions. ================================================ FILE: .github/ISSUE_TEMPLATE/feature.yml ================================================ name: Feature request description: If you have a suggestion… labels: ["enhancement"] body: - type: textarea attributes: label: Describe the feature request description: Please provide a concise description of the request, potential solutions, and additional context. validations: required: true ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## What changed / motivation ? Please include relevant motivation and context ## Linked PR/Issues Fixes # (issue) ## Additional Context Screenshots, Tests, Anything Else ## Pre-flight checklist - [ ] I have read the contributing guidelines [Contribution Guidelines](https://github.com/facebook/stylex/blob/main/.github/CONTRIBUTING.md) - [ ] Performed a self-review of my code ================================================ FILE: .github/workflows/benchmarks.yml ================================================ name: benchmarks on: [pull_request] jobs: perf: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 50 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - name: 'Setup temporary files' run: | echo "BASE_JSON=$(mktemp)" >> $GITHUB_ENV echo "PATCH_JSON=$(mktemp)" >> $GITHUB_ENV - name: 'Benchmark base' run: | git checkout -f ${{ github.event.pull_request.base.sha }} git clean -fdx yarn install --frozen-lockfile --silent if yarn workspace benchmarks run perf -- -o ${{ env.BASE_JSON }}; then echo "Ran successfully on base branch" else echo "{}" > ${{ env.BASE_JSON }} # Empty JSON as default echo "Benchmark script not found on base branch, using default values" fi - name: 'Benchmark patch' run: | git checkout -f ${{ github.event.pull_request.head.sha }} git clean -fdx yarn install --frozen-lockfile --silent yarn workspace benchmarks run perf -- -o ${{ env.PATCH_JSON }} echo "Ran successfully on patch branch" - name: 'Collect results' id: collect run: | echo "table<> $GITHUB_OUTPUT yarn workspace benchmarks run compare -- ${{ env.BASE_JSON }} ${{ env.PATCH_JSON }} >> markdown cat markdown >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: 'Post comment' uses: edumserrano/find-create-or-update-comment@v3 with: issue-number: ${{ github.event.pull_request.number }} body-includes: '' comment-author: 'github-actions[bot]' body: | ### workflow: benchmarks/perf Comparison of performance test results, measured in operations per second. Larger is better. ${{ steps.collect.outputs.table }} edit-mode: replace size: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 50 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - name: 'Setup temporary files' run: | echo "BASE_JSON=$(mktemp)" >> $GITHUB_ENV echo "PATCH_JSON=$(mktemp)" >> $GITHUB_ENV - name: 'Benchmark base' run: | git checkout -f ${{ github.event.pull_request.base.sha }} git clean -fdx yarn install --frozen-lockfile --silent if yarn workspace benchmarks run size -- -o ${{ env.BASE_JSON }}; then echo "Ran successfully on base branch" else echo "{}" > ${{ env.BASE_JSON }} # Empty JSON as default echo "Benchmark script not found on base branch, using default values" fi - name: 'Benchmark patch' run: | git checkout -f ${{ github.event.pull_request.head.sha }} git clean -fdx yarn install --frozen-lockfile --silent yarn workspace benchmarks run size -- -o ${{ env.PATCH_JSON }} echo "Ran successfully on patch branch" - name: 'Collect results' id: collect run: | echo "table<> $GITHUB_OUTPUT yarn workspace benchmarks run compare -- ${{ env.BASE_JSON }} ${{ env.PATCH_JSON }} >> markdown cat markdown >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: 'Post comment' uses: edumserrano/find-create-or-update-comment@v3 with: issue-number: ${{ github.event.pull_request.number }} body-includes: '' comment-author: 'github-actions[bot]' body: | ### workflow: benchmarks/size Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better. ${{ steps.collect.outputs.table }} edit-mode: replace ================================================ FILE: .github/workflows/tests.yml ================================================ name: tests on: push: branches: - 'main' pull_request: types: [opened, synchronize, reopened] jobs: flow: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - run: yarn install --frozen-lockfile - run: yarn flow packages: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - run: yarn install --frozen-lockfile - run: yarn test:packages prettier: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - run: yarn install --frozen-lockfile - run: yarn prettier:report lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'yarn' cache-dependency-path: yarn.lock - run: corepack prepare yarn@1.22.22 --activate - run: yarn install --frozen-lockfile - run: yarn lint:report spelling: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: crate-ci/typos@master with: config: .github/workflows/typos.toml ================================================ FILE: .github/workflows/typos.toml ================================================ [files] extend-exclude = [ "*.snap", "flow-typed/*", # Too many false positives on inline snapshots "packages/**/__tests__/", # Fixture data has lots of typos "packages/benchmarks/**/fixtures/", ] [default.extend-words] # Ignore false-positives stylex = "stylex" nd = "nd" ================================================ FILE: .gitignore ================================================ *.log* .DS_Store .build .docusaurus .stylex build coverage dist lib node_modules storybook-static ================================================ FILE: .prettierignore ================================================ .build .docusaurus .next .stylex build coverage lib flow_modules node_modules **/__mocks__/snapshot* packages/benchmarks/size/fixtures/lotsOfStyles.js flow-typed examples/example-storybook/storybook-static examples/example-cli/src packages/docs/.source ================================================ FILE: .vscode/extensions.json ================================================ { "recommendations": [ "flowtype.flow-for-vscode" ] } ================================================ FILE: .vscode/settings.json ================================================ { "javascript.validate.enable": false } ================================================ FILE: .watchmanconfig ================================================ {} ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## 0.18.1 (Mar 5, 2026) - Add simple `sx={}` JSX prop syntax as an alternative to `stylex.props`. - Fix `unplugin` `generateBundle` hook to use `emitFile` instead of direct bundle assignment. ## 0.18.0 (Mar 3, 2026) - Add `stylex.env` API for compile-time constants and shareable design tokens. - New `create-stylex-app` CLI for scaffolding projects with `npx create-stylex-app`. - Add Bun support and improvements to the `unplugin` bundler plugin. - Support attribute selectors in `stylex.when` and conditional styles. - Fix priority calculation for compound pseudo selectors. ## 0.17.5 (Jan 12. 2026) - New `no-conflicting-props` lint rule. - Add `disallowedPropertiesValidation` config to disable property compiler errors by default. - Preserve units in zero values for CSS variables. - Fix `unplugin` cache invalidation on style changes. - Add `env` compiler option to expose `stylex.env` compile-time constants. ## 0.17.4 (Dec 18. 2025) - New playground within the docs website. - Fix named exports detection on Turbopack. ## 0.17.3 (Dec 12, 2025) - Add docs for setup instructions. - Improve AST detection for `.stylex` named exports - Add browser rollup bundle. - Fix unplugin file suffix parsing. ## 0.17.2 (Dec 1, 2025) - Pass importSources to babel plugin in `unplugin` plugin. - Fix custom typescript typedef mistake. ## 0.17.1 (Nov 26, 2025) - Add support for compiling stylex from imported packages. - Add runtime injection support for `defineConsts` constants. - Show full debug file paths. - Fix media query ordering for queries with 'screen and'. - Add `debugFilePath` config option. - Fix unitless zoom bug for float values. - Fix props compilation for array mutations. ## 0.17.0 (Nov 18, 2025) - Add docs for ESLint rules and `stylex.when` API. - Add `defineMarker()` for custom markers for selector combinators. - New unplugin bundler plugin implementation for various bundlers (Vite, Webpack, Rspack, Rollup, etc.). - Enhance `stylex.props` to precompile more often for better performance. - Order pseudo-classes and `stylex.when` selectors according to priorities in `sort-keys. - Add support for ternary and logical expressions in `valid-styles`. - Bump specificity of `stylex.when` selectors over defaults. - Add polyfill for logical float values in legacy mode. ## 0.16.3 (Oct 27, 2025) - Add configs to `sort-keys` property ordering. - Create new `defineConsts` specific file extension. - Add `defineConsts` and various file extension support to `enforce-extension`. - Add config for custom module resolution. - Turn `enableMediaQueryOrder` on by default. - Updates to docs and Flow. ## 0.16.2 (Oct 13, 2025) - Handle descendant selector styles in `valid-styles` rule. - Adjust descendant selector `.when` priorities. - Fix `defineVars` and `createTheme` at-rules priorities. - Update `defineConsts` types for non-stylex usage. ## 0.16.1 (Oct 2, 2025) - New `no-lookahead-selector` lint rule to flag certain descendant and sibling selectors. - Fix priorities for descendant and sibling selectors. - Fix color functions for `valid-shorthands` rule. - Fix hoisting issues with duplicate keys in `create` calls. - Add storybook example. ## 0.16.0 (Sep 25, 2025) - Added support for descendant and shared selectors. - Support CSS variable overrides with `defineConsts`. - Add `valid-styles` support to CSS variable overrides in `create` calls. - Replace `valid-styles` object check with Flow typing ## 0.15.4 (Sep 7, 2025) - Add configuration modes to `processStylexRules`. - Support local resolved constants, `positionTry`, and '0' values in `valid-styles` ESLint rule. - Implement `defineConsts` for dynamic styles. - Create `.transformed` file extension for preresolved variables. ## 0.15.3 (Aug 13, 2025) - Optimize precomputed `props` calls in JSX. - Fix class name construction for dynamic contextual styles. - Handle all unit values in media query rewriting. ## 0.15.2 (Aug 1, 2025) - Exclude private dependencies from `@stylexjs/babel-plugin` package. - Reduce chances of dynamic variable name collisions. ## 0.15.1 (Aug 1, 2025) ### Fixes - Hoist stylex.create and static className objects to the top level for support inside functions. ## 0.15.0 (Jul 31, 2025) ### New features - Enable media query ordering and parsing behind `enableMediaQueryOrder` flag. - Integrate media query parser for automatic media query validation and normalization. ### Fixes - Implement merging of width, height, and ranges in media query transformer. - Optimize dynamic styles output for conditionals and template literals. - Fix TypeScript types for `stylex.types.*` functions. - Fix opaque type issues for InlineStyles. ## 0.14.3 (Jul 22, 2025) ### Fixes - Do not emit class names for `null` or `undefined` dynamic styles. - Optimize dynamic styles output for binary and unary expressions. ## 0.14.2 (Jul 14, 2025) ### Fixes - ESLint plugin style validation for length properties (#1136) - Remove legacy RTL flipping of boxShadow, cursor, textShadow values. ## 0.14.1 (Jul 3, 2025) ### Fixes - Another fix for TypeScript types. ## 0.14.0 (Jun 30, 2025) ### New features - Add `viewTransitionClass` API for creating CSS View Transitions. - ESLint plugin includes `validImports` options for all rules. - ESLint plugin includes autofix for all remaining nonstandard CSS properties when using the `valid-styles` rule. ### Breaking changes - Make `property-specificity` the default `styleResolution`. ### Fixes - Fix theming in dev/debug mode. - Avoid putting certain `@-rules` in `@layer` blocks. - Fix type exports for TypeScript. ## 0.13.1 (May 21, 2025) ### Fixes - Export additional Types. ## 0.13.0 (May 19, 2025) ### New features - Add `positionTry` API for creating `@property-try` declarations. - Add `defineConsts` API for inlining constant values. - Re-write of the runtime style injection module to be more reliable. ### Breaking changes - The `runtimeInjection` compiler option is now disabled by default when `dev` is true. - The ESLint rule `no-legacy-conditional-styles` is renamed to `no-legacy-contextual-styles`. - The `useRemForFontSize` compiler option is renamed to `enableFontSizePxToRem`. It is disabled by default and should not be used directly. - The `genConditionalClasses` compiler option is renamed to `enableInlinedConditionalMerge`. It is enabled by default and should not be used directly. - The `attrs` API is removed due to low usage and redundancy with the `props` API. ### Fixes - Fix the TypeScript types for themes and types functions. - Fix the creation of duplicate classNames when defining nested pseudo-classes. - Fix that allows the ESLint plugin to support use of `importSources` object syntax in `validImports`. - Fix incorrect compiler error messages. - Fix a bug that incorrectly wrapped CSS variables in quotes when used in the `content` property. - Fix a bug in the `firstThatWorks` API when the last value was a variable. - Allow `importSources` to be configured in the PostCSS plugin for React Strict DOM compatibility. ### Deprecations - Deprecate `@stylexjs/shared` package. ## 0.12.0 (Apr 10, 2025) ### New features - Hash keys in compiled style objects to reduce generated code size. - New eslint rule to flag use of legacy Media Query and pseudo-class syntax. ### Fixes - Fix pseudo-elements bug in dynamic styles. - Performance improvements to `createTheme` compilation by caching object evaluation. - Disallow spreading in `create` calls. ### Deprecations - Deprecate `@stylexjs/dev-runtime` package. - Deprecate `@stylexjs/esbuild-plugin` package. - Deprecate `@stylexjs/nextjs-plugin` package. - Deprecate `@stylexjs/open-props` package. - Deprecate `@stylexjs/webpack-plugin` package. ## 0.11.1 (Mar 3, 2025) ### Fixes - Fix `create` compilation regression for string and number keys. - Fix babel path resolution within monorepos. ## 0.11.0 (Feb 27, 2025) ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) Meta Platforms, Inc. and affiliates. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # StyleX · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/facebook/stylex/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/@stylexjs/stylex.svg?style=flat)](https://www.npmjs.com/package/@stylexjs/stylex) [![tests](https://github.com/facebook/stylex/actions/workflows/tests.yml/badge.svg)](https://github.com/facebook/stylex/actions/workflows/tests.yml) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/facebook/stylex/blob/main/.github/CONTRIBUTING.md) StyleX is a JavaScript library for defining styles for optimized user interfaces. ## Documentation [Documentation Website](https://stylexjs.com) Documentation for individual packages can be found in their respective README files. Start with [`@stylexjs/stylex`](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/stylex). ### Example Here is a simple example of StyleX use: ```js import * as stylex from '@stylexjs/stylex'; const styles = stylex.create({ root: { padding: 10, }, element: { backgroundColor: 'red', }, }); const styleProps = stylex.props(styles.root, styles.element); ``` ## Development This is the development monorepo for StyleX. ### Structure - `.github` - Contains workflows used by GitHub Actions. - Contains issue templates and contribution guidelines. - `examples` - Contains examples using StyleX and its integration with build tools. - `packages` - Contains the public and private packages managed in the monorepo. - [babel-plugin](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/babel-plugin) - [benchmarks](https://github.com/facebook/stylex/blob/main/packages/benchmarks) - [cli](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/cli) - [docs](https://github.com/facebook/stylex/blob/main/packages/docs) - [eslint-plugin](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/eslint-plugin) - [postcss-plugin](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/postcss-plugin) - [rollup-plugin](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/rollup-plugin) - [scripts](https://github.com/facebook/stylex/blob/main/packages/scripts) - [shared](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/babel-plugin/shared) - [style-value-parser](https://github.com/facebook/stylex/blob/main/packages/style-value-parser) - [stylex](https://github.com/facebook/stylex/blob/main/packages/@stylexjs/stylex) ### Tasks First, `yarn install` the yarn workspace. - `build` - Use `yarn build` to run the build script in every package. - Use `yarn workspace build` to run the build script for a specific package. - `test` - Use `yarn test` to run tests for every package. - Use `yarn workspace test` to run the test script for a specific package. More details can be found in the contributing guide below. ## Contributing Development happens in the open on GitHub and we are grateful for contributions including bug fixes, improvements, and ideas. ### Code of Conduct This project expects all participants to adhere to Meta's OSS [Code of Conduct](https://opensource.fb.com/code-of-conduct/). Please read the full text so that you can understand what actions will and will not be tolerated. ### Contributing Guide Read the [contributing guide](https://github.com/facebook/stylex/blob/main/.github/CONTRIBUTING.md) to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes. ### Architectural Principles Before proposing a change or addition to the StyleX API, you should familiarize yourself with the [goals and architectural principles](https://stylexjs.com/docs/learn/thinking-in-stylex/) of the project. ### License StyleX is [MIT licensed](./LICENSE). ================================================ FILE: examples/example-bun/.eslintrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ module.exports = { plugins: ['@stylexjs'], rules: { '@stylexjs/valid-styles': 'error', 'ft-flow/space-after-type-colon': 0, 'ft-flow/no-types-missing-file-annotation': 0, 'ft-flow/generic-spacing': 0, }, }; ================================================ FILE: examples/example-bun/README.md ================================================ # StyleX with Bun This example bundles a React app with Bun while compiling StyleX via `@stylexjs/unplugin`. The unplugin uses its esbuild adapter (Bun’s plugin API is esbuild-compatible) to compile StyleX at build time, aggregate the generated styles, and append them to the CSS asset emitted from `src/global.css`. ### Prerequisites - Bun 1.1+ - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Build script (`scripts/build.mjs`) The production build script wires the unplugin into `Bun.build`: ```js import stylex from '@stylexjs/unplugin'; await Bun.build({ entrypoints: ['src/main.jsx'], outdir: 'dist', metafile: true, plugins: [ stylex.esbuild({ useCSSLayers: true, importSources: ['@stylexjs/stylex'], }), ], }); ``` - `metafile: true` lets the plugin locate CSS assets emitted by Bun. - `useCSSLayers: true` wraps StyleX output in `@layer` declarations for predictable specificity. ## CSS entry points - Production uses `src/global.css` so Bun emits a CSS asset; StyleX appends aggregated styles during `npm run example:build`. - Development writes `dist/stylex.dev.css`, which the Bun plugin rewrites on every StyleX transform so the dev server can hot-reload CSS. ## Dev server integration The Bun dev server uses `bunfig.toml` with `@stylexjs/unplugin/bun`, which writes generated StyleX rules into `dist/stylex.dev.css` (marked with `--stylex-injection`). `dist/` is generated output and should remain gitignored. ## Commands ```bash # Production bundle + StyleX CSS extraction npm run example:build # Bun dev server with HMR at http://localhost:3000 npm run example:dev # Serve the generated bundle (run example:build first) npm run example:start ``` The dev server uses Bun's fullstack mode, bundling `dist/index.dev.html` on request with `development: true` and the StyleX Bun plugin. Production builds write `dist/index.html` alongside the bundled assets. ================================================ FILE: examples/example-bun/bunfig.toml ================================================ [serve.static] plugins = ["@stylexjs/unplugin/bun"] ================================================ FILE: examples/example-bun/package.json ================================================ { "private": true, "name": "example-bun", "version": "0.18.1", "description": "Example: StyleX with Bun via @stylexjs/unplugin", "main": "src/App.jsx", "scripts": { "example:build": "bun run scripts/build.mjs", "example:dev": "bun run scripts/dev.mjs", "example:start": "bun run scripts/start.mjs", "example:lint": "eslint \"**/*.{js,jsx}\"" }, "license": "MIT", "dependencies": { "@stylexjs/stylex": "0.18.1", "react": "^19.2.0", "react-dom": "^19.2.0" }, "devDependencies": { "@stylexjs/unplugin": "0.18.1", "@stylexjs/eslint-plugin": "0.18.1", "eslint": "^8.57.1" } } ================================================ FILE: examples/example-bun/scripts/build.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import path from 'path'; import { fileURLToPath } from 'url'; import stylex from '@stylexjs/unplugin'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const entrypoint = path.resolve(__dirname, '..', 'src', 'main.jsx'); const outdir = path.resolve(__dirname, '..', 'dist'); const htmlTemplate = path.resolve(__dirname, '..', 'src', 'index.html'); const htmlOutput = path.resolve(outdir, 'index.html'); async function build() { const result = await Bun.build({ entrypoints: [entrypoint], outdir, target: 'browser', minify: true, metafile: true, plugins: [ stylex.esbuild({ useCSSLayers: true, importSources: ['@stylexjs/stylex'], unstable_moduleResolution: { type: 'commonJS', rootDir: path.resolve(__dirname, '../../..'), }, }), ], }); if (!result.success) { console.error('Bun build failed.'); for (const message of result.logs) { console.error(message); } process.exit(1); } try { await Bun.write(htmlOutput, await Bun.file(htmlTemplate).text()); } catch (error) { console.error('Failed to write dist/index.html.'); console.error(error); process.exit(1); } } build(); ================================================ FILE: examples/example-bun/scripts/dev.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import path from 'path'; import { mkdir } from 'fs/promises'; import { fileURLToPath, pathToFileURL } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const distDir = path.resolve(__dirname, '..', 'dist'); const htmlTemplate = path.resolve(__dirname, '..', 'src', 'index.dev.html'); const htmlOutput = path.resolve(distDir, 'index.dev.html'); async function dev() { await mkdir(distDir, { recursive: true }); await Bun.write(htmlOutput, await Bun.file(htmlTemplate).text()); const homepage = (await import(pathToFileURL(htmlOutput).href)).default; const port = Number(process.env.PORT) || 3000; const server = Bun.serve({ port, development: true, routes: { '/': homepage, }, }); console.log(`Dev server running at http://localhost:${server.port}`); } dev(); ================================================ FILE: examples/example-bun/scripts/start.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const distDir = path.resolve(__dirname, '..', 'dist'); const port = Number(process.env.PORT) || 3000; const server = Bun.serve({ port, async fetch(request) { const url = new URL(request.url); const pathname = url.pathname === '/' ? '/index.html' : url.pathname; const filePath = path.join(distDir, pathname); const file = Bun.file(filePath); if (await file.exists()) { return new Response(file); } return new Response('Not found', { status: 404 }); }, }); console.log(`Server running at http://localhost:${server.port}`); ================================================ FILE: examples/example-bun/src/App.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as React from 'react'; import * as stylex from '@stylexjs/stylex'; import { colors, fonts, sizes } from './globalTokens.stylex'; export default function App() { return (
StyleX + Bun + unplugin
); } const styles = stylex.create({ main: { minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: colors.gray0, }, card: { backgroundColor: colors.blue9, padding: sizes.spacing5, borderRadius: sizes.spacing2, justifyContent: 'center', display: 'flex', alignItems: 'center', color: colors.gray0, fontFamily: fonts.mono, }, }); ================================================ FILE: examples/example-bun/src/global.css ================================================ :root { --stylex-injection: 0; } ================================================ FILE: examples/example-bun/src/globalTokens.stylex.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; export const colors = stylex.defineVars({ pink7: '#d6336c', blue9: '#1864ab', gray0: '#999', }); export const fonts = stylex.defineVars({ mono: 'Dank Mono,Operator Mono,Inconsolata,Fira Mono,ui-monospace,SF Mono,Monaco,Droid Sans Mono,Source Code Pro,monospace', }); export const sizes = stylex.defineVars({ spacing5: '1.5rem', spacing2: '.5rem', }); ================================================ FILE: examples/example-bun/src/index.dev.html ================================================ @stylexjs/unplugin (bun dev)
================================================ FILE: examples/example-bun/src/index.html ================================================ @stylexjs/unplugin (bun)
================================================ FILE: examples/example-bun/src/main.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import './global.css'; import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.jsx'; createRoot(document.getElementById('root')).render(); ================================================ FILE: examples/example-cli/.gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # stylex compiled src ================================================ FILE: examples/example-cli/.stylex.json5 ================================================ { input: ['./source'], output: ['./src'], cssBundleName: 'stylex_bundle.css', babelPresets: [ ['@babel/preset-typescript', { allExtensions: true, isTSX: true }], // '@babel/preset-react', ], styleXConfig: { aliases: { '@/*': ['./source/*'], }, }, // watch: true, } ================================================ FILE: examples/example-cli/README.md ================================================ # @stylexjs/cli example using StyleX TBD ================================================ FILE: examples/example-cli/package.json ================================================ { "private": true, "name": "example-cli", "version": "0.18.1", "scripts": { "example:build": "stylex --config .stylex.json5" }, "dependencies": { "react": "^19.2.0", "react-dom": "^19.2.0" }, "devDependencies": { "@babel/preset-react": "^7.25.7", "@babel/preset-typescript": "^7.25.7", "@stylexjs/cli": "0.18.1", "@types/react": "^19.2.6", "@types/react-dom": "^19.2.3", "typescript": "^5.9.3" } } ================================================ FILE: examples/example-cli/source/app/CardThemes.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import * as stylex from '@stylexjs/stylex'; import { tokens } from './CardTokens.stylex'; export const minorOffset = stylex.createTheme(tokens, { arrowTransform: 'translateX(5px)', }); export const majorOffset = stylex.createTheme(tokens, { arrowTransform: 'translateX(10px)', }); export const reset = stylex.createTheme(tokens, {}); ================================================ FILE: examples/example-cli/source/app/CardTokens.stylex.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import * as stylex from '@stylexjs/stylex'; export const tokens = stylex.defineVars({ arrowTransform: 'translateX(0)', }); ================================================ FILE: examples/example-cli/source/app/Counter.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use client'; import * as stylex from '@stylexjs/stylex'; import { spacing, text, globalTokens as $, colors, } from '@/app/globalTokens.stylex'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return (
99 && styles.largeNumber, )} > {count}
); } const DARK = '@media (prefers-color-scheme: dark)' as const; const styles = stylex.create({ container: { display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', borderRadius: spacing.md, borderWidth: 1, borderStyle: 'solid', borderColor: colors.blue7, padding: spacing.xxxs, fontFamily: $.fontSans, gap: spacing.xs, }, button: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '6rem', aspectRatio: 1, color: colors.blue7, backgroundColor: { default: colors.gray3, ':hover': colors.gray4, [DARK]: { default: colors.gray9, ':hover': colors.gray8, }, }, borderWidth: 0, borderStyle: 'none', borderRadius: spacing.xs, padding: spacing.xs, margin: spacing.xs, cursor: 'pointer', fontSize: text.h2, transform: { default: null, ':hover': 'scale(1.025)', ':active': 'scale(0.975)', }, }, count: { fontSize: text.h2, fontWeight: 100, color: colors.lime7, minWidth: '6rem', textAlign: 'center', fontFamily: $.fontMono, }, largeNumber: { fontSize: text.h3, }, }); ================================================ FILE: examples/example-cli/source/app/globalTokens.stylex.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; /** * o--o o o o o-O-o o-o o--o o-o o o o-O-o o-o * | | | | | | \ | o o |\ | | | * O-o | | | | | O O-o | | | \ | | o-o * | | | | | | / | o o | \| | | * o O---o o-o o-O-o o-o o o-o o o o o--o * * Reference: https://utopia.fyi/type/calculator * * The following constants are used to calculate fluid typography. * Feel free to change these initial numbers to suit your needs. * * StyleX can compute all of this at compile time as all the information * is statically available in the same file and the only functions used are * the Math.pow and Math.round functions. * * NOTE: Any custom functions will not be able to be computed at compile time. */ const MIN_WIDTH = 320; const MAX_WIDTH = 1240; const MIN_SCALE = 1.2; const MAX_SCALE = 1.333; const MIN_BASE_SIZE = 16; const MAX_BASE_SIZE = 20; // Font sizes in `rem` units const MIN_FONT = { xxs: Math.round(MIN_BASE_SIZE / Math.pow(MIN_SCALE, 3) / 0.16) / 100, xs: Math.round(MIN_BASE_SIZE / Math.pow(MIN_SCALE, 2) / 0.16) / 100, sm: Math.round(MIN_BASE_SIZE / MIN_SCALE / 0.16) / 100, p: Math.round(MIN_BASE_SIZE / 4) / 4, h5: Math.round((MIN_BASE_SIZE * MIN_SCALE) / 0.16) / 100, h4: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 2)) / 0.16) / 100, h3: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 3)) / 0.16) / 100, h2: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 4)) / 0.16) / 100, h1: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 5)) / 0.16) / 100, }; // Font sizes in `rem` units const MAX_FONT = { xxs: Math.round(MAX_BASE_SIZE / Math.pow(MAX_SCALE, 3) / 0.16) / 100, xs: Math.round(MAX_BASE_SIZE / Math.pow(MAX_SCALE, 2) / 0.16) / 100, sm: Math.round(MAX_BASE_SIZE / MAX_SCALE / 0.16) / 100, p: Math.round(MAX_BASE_SIZE / 4) / 4, h5: Math.round((MAX_BASE_SIZE * MAX_SCALE) / 0.16) / 100, h4: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 2)) / 0.16) / 100, h3: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 3)) / 0.16) / 100, h2: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 4)) / 0.16) / 100, h1: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 5)) / 0.16) / 100, }; const SLOPE = { xxs: (16 * (MAX_FONT.xxs - MIN_FONT.xxs)) / (MAX_WIDTH - MIN_WIDTH), xs: (16 * (MAX_FONT.xs - MIN_FONT.xs)) / (MAX_WIDTH - MIN_WIDTH), sm: (16 * (MAX_FONT.sm - MIN_FONT.sm)) / (MAX_WIDTH - MIN_WIDTH), p: (16 * (MAX_FONT.p - MIN_FONT.p)) / (MAX_WIDTH - MIN_WIDTH), h5: (16 * (MAX_FONT.h5 - MIN_FONT.h5)) / (MAX_WIDTH - MIN_WIDTH), h4: (16 * (MAX_FONT.h4 - MIN_FONT.h4)) / (MAX_WIDTH - MIN_WIDTH), h3: (16 * (MAX_FONT.h3 - MIN_FONT.h3)) / (MAX_WIDTH - MIN_WIDTH), h2: (16 * (MAX_FONT.h2 - MIN_FONT.h2)) / (MAX_WIDTH - MIN_WIDTH), h1: (16 * (MAX_FONT.h1 - MIN_FONT.h1)) / (MAX_WIDTH - MIN_WIDTH), }; const INTERCEPT = { xxs: Math.round(100 * (MIN_FONT.xxs - SLOPE.xxs * (MIN_WIDTH / 16))) / 100, xs: Math.round(100 * (MIN_FONT.xs - SLOPE.xs * (MIN_WIDTH / 16))) / 100, sm: Math.round(100 * (MIN_FONT.sm - SLOPE.sm * (MIN_WIDTH / 16))) / 100, p: Math.round(100 * (MIN_FONT.p - SLOPE.p * (MIN_WIDTH / 16))) / 100, h5: Math.round(100 * (MIN_FONT.h5 - SLOPE.h5 * (MIN_WIDTH / 16))) / 100, h4: Math.round(100 * (MIN_FONT.h4 - SLOPE.h4 * (MIN_WIDTH / 16))) / 100, h3: Math.round(100 * (MIN_FONT.h3 - SLOPE.h3 * (MIN_WIDTH / 16))) / 100, h2: Math.round(100 * (MIN_FONT.h2 - SLOPE.h2 * (MIN_WIDTH / 16))) / 100, h1: Math.round(100 * (MIN_FONT.h1 - SLOPE.h1 * (MIN_WIDTH / 16))) / 100, }; // prettier-ignore export const text = stylex.defineVars({ xxs: `clamp(${ Math.min(MIN_FONT.xxs) }rem, calc(${ INTERCEPT.xxs }rem + ${ Math.round(10000 * SLOPE.xxs) / 100 }vw), ${ Math.max(MAX_FONT.xxs) }rem)`, xs: `clamp(${ Math.min(MIN_FONT.xs ) }rem, calc(${ INTERCEPT.xs }rem + ${ Math.round(10000 * SLOPE.xs ) / 100 }vw), ${ Math.max(MAX_FONT.xs ) }rem)`, sm: `clamp(${ Math.min(MIN_FONT.sm ) }rem, calc(${ INTERCEPT.sm }rem + ${ Math.round(10000 * SLOPE.sm ) / 100 }vw), ${ Math.max(MAX_FONT.sm ) }rem)`, p: `clamp(${ Math.min(MIN_FONT.p ) }rem, calc(${ INTERCEPT.p }rem + ${ Math.round(10000 * SLOPE.p ) / 100 }vw), ${ Math.max(MAX_FONT.p ) }rem)`, h5: `clamp(${ Math.min(MIN_FONT.h5 ) }rem, calc(${ INTERCEPT.h5 }rem + ${ Math.round(10000 * SLOPE.h5 ) / 100 }vw), ${ Math.max(MAX_FONT.h5 ) }rem)`, h4: `clamp(${ Math.min(MIN_FONT.h4 ) }rem, calc(${ INTERCEPT.h4 }rem + ${ Math.round(10000 * SLOPE.h4 ) / 100 }vw), ${ Math.max(MAX_FONT.h4 ) }rem)`, h3: `clamp(${ Math.min(MIN_FONT.h3 ) }rem, calc(${ INTERCEPT.h3 }rem + ${ Math.round(10000 * SLOPE.h3 ) / 100 }vw), ${ Math.max(MAX_FONT.h3 ) }rem)`, h2: `clamp(${ Math.min(MIN_FONT.h2 ) }rem, calc(${ INTERCEPT.h2 }rem + ${ Math.round(10000 * SLOPE.h2 ) / 100 }vw), ${ Math.max(MAX_FONT.h2 ) }rem)`, h1: `clamp(${ Math.min(MIN_FONT.h1 ) }rem, calc(${ INTERCEPT.h1 }rem + ${ Math.round(10000 * SLOPE.h1 ) / 100 }vw), ${ Math.max(MAX_FONT.h1 ) }rem)`, }); /** * o--o o o o o-O-o o-o o-o o--o O o-o o--o * | | | | | | \ | | | / \ / | * O-o | | | | | O o-o O--o o---oO O-o * | | | | | | / | | | | \ | * o O---o o-o o-O-o o-o o--o o o o o-o o--o * * Reference: https://utopia.fyi/space/calculator * * Similar to the fluid typography, we can create fluid values for spacing. * Using similar formulas and similar scales. * * NOTE: It is common to have more varied needs for spacing than for font-size. * So feel free to add some more values by following the pattern below. * * EXCEPT: We are using `px` instead of `rem` * ------------------------------------------ * When talking about font-size, it is the best practice to use * `rem` so that an end user can change the font-size using the * browser's font-size setting. * * However, when talking about spacing, it is the best practice to * use `px` because using `rems` here makes font-size behave like zoom. * * Users that prefer larger text, don't necessarily want larger spacing as well. * */ const MULT = { xxxs: 0.25, xxs: 0.5, xs: 0.75, sm: 1, md: 1.5, lg: 2, xl: 3, xxl: 4, xxxl: 6, xxxxl: 8, }; const MIN_SPACE = { xxxs: MULT.xxxs * MIN_BASE_SIZE, xxs: MULT.xxs * MIN_BASE_SIZE, xs: MULT.xs * MIN_BASE_SIZE, sm: MULT.sm * MIN_BASE_SIZE, md: MULT.md * MIN_BASE_SIZE, lg: MULT.lg * MIN_BASE_SIZE, xl: MULT.xl * MIN_BASE_SIZE, xxl: MULT.xxl * MIN_BASE_SIZE, xxxl: MULT.xxxl * MIN_BASE_SIZE, xxxxl: MULT.xxxxl * MIN_BASE_SIZE, }; const MAX_SPACE = { xxxs: MULT.xxxs * MAX_BASE_SIZE, xxs: MULT.xxs * MAX_BASE_SIZE, xs: MULT.xs * MAX_BASE_SIZE, sm: MULT.sm * MAX_BASE_SIZE, md: MULT.md * MAX_BASE_SIZE, lg: MULT.lg * MAX_BASE_SIZE, xl: MULT.xl * MAX_BASE_SIZE, xxl: MULT.xxl * MAX_BASE_SIZE, xxxl: MULT.xxxl * MAX_BASE_SIZE, xxxxl: MULT.xxxxl * MAX_BASE_SIZE, }; const SLOPE_SPACE = { xxxs: (MAX_SPACE.xxxs - MIN_SPACE.xxxs) / (MAX_WIDTH - MIN_WIDTH), xxs: (MAX_SPACE.xxs - MIN_SPACE.xxs) / (MAX_WIDTH - MIN_WIDTH), xs: (MAX_SPACE.xs - MIN_SPACE.xs) / (MAX_WIDTH - MIN_WIDTH), sm: (MAX_SPACE.sm - MIN_SPACE.sm) / (MAX_WIDTH - MIN_WIDTH), md: (MAX_SPACE.md - MIN_SPACE.md) / (MAX_WIDTH - MIN_WIDTH), lg: (MAX_SPACE.lg - MIN_SPACE.lg) / (MAX_WIDTH - MIN_WIDTH), xl: (MAX_SPACE.xl - MIN_SPACE.xl) / (MAX_WIDTH - MIN_WIDTH), xxl: (MAX_SPACE.xxl - MIN_SPACE.xxl) / (MAX_WIDTH - MIN_WIDTH), xxxl: (MAX_SPACE.xxxl - MIN_SPACE.xxxl) / (MAX_WIDTH - MIN_WIDTH), xxxxl: (MAX_SPACE.xxxxl - MIN_SPACE.xxxxl) / (MAX_WIDTH - MIN_WIDTH), }; // rounded to the nearest 0.25px const INTERCEPT_SPACE = { xxxs: Math.round(4 * (MIN_SPACE.xxxs - SLOPE_SPACE.xxxs * MIN_WIDTH)) / 4, xxs: Math.round(4 * (MIN_SPACE.xxs - SLOPE_SPACE.xxs * MIN_WIDTH)) / 4, xs: Math.round(4 * (MIN_SPACE.xs - SLOPE_SPACE.xs * MIN_WIDTH)) / 4, sm: Math.round(4 * (MIN_SPACE.sm - SLOPE_SPACE.sm * MIN_WIDTH)) / 4, md: Math.round(4 * (MIN_SPACE.md - SLOPE_SPACE.md * MIN_WIDTH)) / 4, lg: Math.round(4 * (MIN_SPACE.lg - SLOPE_SPACE.lg * MIN_WIDTH)) / 4, xl: Math.round(4 * (MIN_SPACE.xl - SLOPE_SPACE.xl * MIN_WIDTH)) / 4, xxl: Math.round(4 * (MIN_SPACE.xxl - SLOPE_SPACE.xxl * MIN_WIDTH)) / 4, xxxl: Math.round(4 * (MIN_SPACE.xxxl - SLOPE_SPACE.xxxl * MIN_WIDTH)) / 4, xxxxl: Math.round(4 * (MIN_SPACE.xxxxl - SLOPE_SPACE.xxxxl * MIN_WIDTH)) / 4, }; // prettier-ignore export const spacing = stylex.defineVars({ xxxs: `clamp(${MIN_SPACE.xxxs }px, calc(${INTERCEPT_SPACE.xxxs }px + ${ Math.round(10000 * SLOPE_SPACE.xxxs ) / 100 }vw), ${MAX_SPACE.xxxs }px)`, xxs: `clamp(${MIN_SPACE.xxs }px, calc(${INTERCEPT_SPACE.xxs }px + ${ Math.round(10000 * SLOPE_SPACE.xxs ) / 100 }vw), ${MAX_SPACE.xxs }px)`, xs: `clamp(${MIN_SPACE.xs }px, calc(${INTERCEPT_SPACE.xs }px + ${ Math.round(10000 * SLOPE_SPACE.xs ) / 100 }vw), ${MAX_SPACE.xs }px)`, sm: `clamp(${MIN_SPACE.sm }px, calc(${INTERCEPT_SPACE.sm }px + ${ Math.round(10000 * SLOPE_SPACE.sm ) / 100 }vw), ${MAX_SPACE.sm }px)`, md: `clamp(${MIN_SPACE.md }px, calc(${INTERCEPT_SPACE.md }px + ${ Math.round(10000 * SLOPE_SPACE.md ) / 100 }vw), ${MAX_SPACE.md }px)`, lg: `clamp(${MIN_SPACE.lg }px, calc(${INTERCEPT_SPACE.lg }px + ${ Math.round(10000 * SLOPE_SPACE.lg ) / 100 }vw), ${MAX_SPACE.lg }px)`, xl: `clamp(${MIN_SPACE.xl }px, calc(${INTERCEPT_SPACE.xl }px + ${ Math.round(10000 * SLOPE_SPACE.xl ) / 100 }vw), ${MAX_SPACE.xl }px)`, xxl: `clamp(${MIN_SPACE.xxl }px, calc(${INTERCEPT_SPACE.xxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxl ) / 100 }vw), ${MAX_SPACE.xxl }px)`, xxxl: `clamp(${MIN_SPACE.xxxl }px, calc(${INTERCEPT_SPACE.xxxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxxl ) / 100 }vw), ${MAX_SPACE.xxxl }px)`, xxxxl: `clamp(${MIN_SPACE.xxxxl }px, calc(${INTERCEPT_SPACE.xxxxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxxxl ) / 100 }vw), ${MAX_SPACE.xxxxl }px)`, }); /** * Color Tokens */ const DARK_MODE = '@media (prefers-color-scheme: dark)'; export const globalTokens = stylex.defineVars({ maxWidth: `${MAX_WIDTH}px`, fontMono: [ 'ui-monospace', 'Menlo', 'Monaco', '"Cascadia Mono"', '"Segoe UI Mono"', '"Roboto Mono"', '"Oxygen Mono"', '"Ubuntu Monospace"', '"Source Code Pro"', '"Fira Mono"', '"Droid Sans Mono"', '"Courier New"', 'monospace', ].join(', '), fontSans: [ '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', '"Noto Sans"', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', '"Noto Color Emoji"', ].join(', '), foregroundR: { default: '0', [DARK_MODE]: '255' }, foregroundG: { default: '0', [DARK_MODE]: '255' }, foregroundB: { default: '0', [DARK_MODE]: '255' }, bgStartRGB: { default: 'rgb(214, 219, 220)', [DARK_MODE]: 'rgb(0, 0, 0)' }, bgEndR: { default: '255', [DARK_MODE]: '0' }, bgEndG: { default: '255', [DARK_MODE]: '0' }, bgEndB: { default: '255', [DARK_MODE]: '0' }, calloutRGB: { default: 'rgb(238, 240, 241)', [DARK_MODE]: 'rgb(20, 20, 20)' }, calloutRGB50: { default: 'rgba(238, 240, 241, 0.5)', [DARK_MODE]: 'rgba(20, 20, 20, 0.5)', }, calloutBorderR: { default: '172', [DARK_MODE]: '108' }, calloutBorderG: { default: '175', [DARK_MODE]: '108' }, calloutBorderB: { default: '176', [DARK_MODE]: '108' }, cardR: { default: '180', [DARK_MODE]: '100' }, cardG: { default: '185', [DARK_MODE]: '100' }, cardB: { default: '188', [DARK_MODE]: '100' }, cardBorderR: { default: '131', [DARK_MODE]: '200' }, cardBorderG: { default: '134', [DARK_MODE]: '200' }, cardBorderB: { default: '135', [DARK_MODE]: '200' }, primaryGlow: { default: `conic-gradient(${[ 'from 180deg at 50% 50%', '#16abff33 0deg', '#0885ff33 55deg', '#54d6ff33 120deg', '#0071ff33 160deg', 'transparent 360deg', ].join(', ')})`, [DARK_MODE]: 'radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0))', }, secondaryGlow: { default: 'radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))', [DARK_MODE]: `linear-gradient(${[ 'to bottom right', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0.3)', ].join(', ')})`, }, }); export const scales = stylex.defineVars({ small: 'scale(0.95)', medium: 'scale(1)', large: 'scale(1.2)', }); export const colors = stylex.defineVars({ blue3: '#74c0fc', blue7: '#1c7ed6', gray3: '#dee2e6', gray4: '#ced4da', gray8: '#343a40', gray9: '#212529', lime7: '#74b816', }); ================================================ FILE: examples/example-cli/source/app/globals.css ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ @layer reset { * { box-sizing: border-box; padding: 0; margin: 0; } } ================================================ FILE: examples/example-cli/source/app/layout.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import './globals.css'; import { globalTokens as $ } from './globalTokens.stylex'; import * as stylex from '@stylexjs/stylex'; export const metadata = { title: 'Create Next App', description: 'Generated by create next app', }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } const DARK = '@media (prefers-color-scheme: dark)'; const styles = stylex.create({ html: { colorScheme: 'light dark', }, reset: { minHeight: '100%', margin: 0, padding: 0, }, body: { color: `rgba(${$.foregroundR}, ${$.foregroundG}, ${$.foregroundB}, 1)`, backgroundImage: { default: 'linear-gradient(to bottom, rgb(214, 219, 220), white)', [DARK]: 'linear-gradient(to bottom, rgb(20, 22, 27), black)', }, }, }); ================================================ FILE: examples/example-cli/source/app/page.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import React from 'react'; import * as stylex from '@stylexjs/stylex'; import Card from '../components/Card'; import { globalTokens as $, spacing, text, scales, } from './globalTokens.stylex'; import Counter from './Counter'; const HOMEPAGE = 'https://stylexjs.com'; export default function Home() { return (

Get started by editing  app/page.tsx

Next.js App Dir♥️️StyleX

); } const MEDIA_MOBILE = '@media (max-width: 700px)' as const; const MEDIA_TABLET = '@media (min-width: 701px) and (max-width: 1120px)' as const; const beat = stylex.keyframes({ '0%': { transform: scales.medium }, '10%': { transform: scales.large }, '20%': { transform: scales.medium }, '30%': { transform: scales.large }, '40%': { transform: scales.medium }, '90%': { transform: scales.small }, '100%': { transform: scales.medium }, }); const style = stylex.create({ main: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'space-between', minHeight: '100vh', paddingTop: spacing.xxl, paddingBottom: { default: spacing.xxl, [MEDIA_MOBILE]: spacing.md, }, }, hero: { flexGrow: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: spacing.xl, }, h1: { fontSize: text.h1, lineHeight: 1, fontFamily: $.fontSans, fontWeight: 400, textAlign: 'center', display: 'flex', gap: spacing.md, whiteSpace: 'nowrap', flexDirection: { default: 'row', [MEDIA_MOBILE]: 'column', }, }, emoji: { position: 'relative', fontFamily: 'sans-serif', top: { default: 0, [MEDIA_MOBILE]: spacing.xxxs, }, animationName: beat, animationDuration: '2s', animationIterationCount: 'infinite', animationTimingFunction: 'linear', }, description: { display: 'inherit', justifyContent: 'inherit', alignItems: 'inherit', fontSize: text.sm, maxWidth: $.maxWidth, width: '100%', zIndex: 2, fontFamily: $.fontMono, }, descLink: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: spacing.xxs, padding: { [MEDIA_MOBILE]: spacing.sm }, }, descP: { display: { [MEDIA_MOBILE]: 'flex' }, position: { default: 'relative', [MEDIA_MOBILE]: 'fixed', }, justifyContent: { [MEDIA_MOBILE]: 'center' }, alignItems: { [MEDIA_MOBILE]: 'center' }, width: { [MEDIA_MOBILE]: '100%' }, margin: 0, paddingInline: spacing.sm, paddingTop: { default: spacing.sm, [MEDIA_MOBILE]: spacing.lg, }, paddingBottom: { default: spacing.sm, [MEDIA_MOBILE]: spacing.md, }, backgroundColor: $.calloutRGB50, backgroundImage: { default: null, [MEDIA_MOBILE]: `linear-gradient(to bottom, ${$.bgStartRGB}, ${$.calloutRGB50})`, }, borderWidth: { default: '1px', [MEDIA_MOBILE]: '0', }, borderStyle: 'solid', borderColor: `rgba(${$.calloutBorderR}, ${$.calloutBorderG}, ${$.calloutBorderB}, 0.3)`, borderBottomColor: { default: null, [MEDIA_MOBILE]: `rgba(${$.calloutBorderR}, ${$.calloutBorderG}, ${$.calloutBorderB}, 0.25)`, }, borderRadius: { default: spacing.xs, [MEDIA_MOBILE]: 0, }, inset: { [MEDIA_MOBILE]: '0 0 auto' }, }, code: { fontWeight: 700, fontFamily: $.fontMono, }, grid: { display: 'grid', gridTemplateColumns: { default: 'repeat(4, minmax(25%, auto))', [MEDIA_MOBILE]: '1fr', [MEDIA_TABLET]: 'repeat(2, 50%)', }, width: $.maxWidth, maxWidth: { default: '100%', [MEDIA_MOBILE]: 320, }, textAlign: { [MEDIA_MOBILE]: 'center' }, }, }); ================================================ FILE: examples/example-cli/source/components/Card.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; import { globalTokens as $, spacing, text, colors, } from '../app/globalTokens.stylex'; import { tokens } from '../app/CardTokens.stylex'; type Props = Readonly<{ title: string; body: string; href: string; }>; export default function Card({ title, body, href }: Props) { return (

{title}

{body}

); } type TMobile = '@media (max-width: 700px)'; const MOBILE: TMobile = '@media (max-width: 700px)' as TMobile; const REDUCE_MOTION = '@media (prefers-reduced-motion: reduce)' as const; const bgDefault = `rgba(${$.cardR}, ${$.cardG}, ${$.cardB}, 0)` as const; const styles = stylex.create({ link: { display: { default: 'flex', [MOBILE]: 'block', }, alignItems: 'center', justifyContent: 'flex-start', flexDirection: 'column', borderRadius: spacing.xs, backgroundColor: { default: bgDefault, ':hover': `rgba(${$.cardR}, ${$.cardG}, ${$.cardB}, 0.1)`, }, borderWidth: 1, borderStyle: 'solid', borderColor: { default: `rgba(${$.cardBorderR}, ${$.cardBorderG}, ${$.cardBorderB}, 0)`, ':hover': `rgba(${$.cardBorderR}, ${$.cardBorderG}, ${$.cardBorderB}, 0.1)`, }, color: 'inherit', fontFamily: $.fontSans, padding: spacing.sm, transitionProperty: 'background-color, border-color', transitionDuration: '400ms', textAlign: 'center', textDecoration: 'none', [tokens.arrowTransform]: { default: 'translateX(0)', ':hover': 'translateX(4px)', }, }, h2: { color: colors.blue3, fontSize: text.h4, fontWeight: 600, marginBottom: { default: spacing.xs, [MOBILE]: spacing.xxs, }, }, span: { display: 'inline-block', transitionProperty: 'transform', transform: tokens.arrowTransform, transitionDuration: { default: '200ms', [REDUCE_MOTION]: '0s', }, }, p: { margin: 0, opacity: 0.6, fontSize: text.p, textWrap: 'balance', lineHeight: 1.5, maxWidth: '30ch', }, color: (color: string) => ({ color }), width: (width: string) => ({ width }), }); ================================================ FILE: examples/example-cli/tsconfig.json ================================================ { "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [], "paths": { "@/*": ["./source/*"] } }, "exclude": ["node_modules"] } ================================================ FILE: examples/example-esbuild/.eslintrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ module.exports = { plugins: ['@stylexjs'], rules: { '@stylexjs/valid-styles': 'error', 'ft-flow/space-after-type-colon': 0, 'ft-flow/no-types-missing-file-annotation': 0, 'ft-flow/generic-spacing': 0, }, }; ================================================ FILE: examples/example-esbuild/README.md ================================================ # StyleX with esbuild This example bundles a React app with esbuild while compiling StyleX via `@stylexjs/unplugin`. The plugin extracts StyleX styles at build time, aggregates them, and appends the result to an existing CSS file produced by esbuild. ### Prerequisites - Node.js 18+ - [`esbuild`](https://esbuild.github.io/) (installed locally) - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Build script (`scripts/build.mjs`) The build script wires the unplugin into esbuild: ```js import stylex from '@stylexjs/unplugin'; esbuild.build({ entryPoints: ['src/App.jsx'], bundle: true, metafile: true, plugins: [ stylex.esbuild({ useCSSLayers: true, importSources: ['@stylexjs/stylex'], unstable_moduleResolution: { type: 'commonJS' }, }), ], }); ``` - `metafile: true` lets the plugin locate CSS assets emitted by esbuild. - `useCSSLayers: true` ensures the generated StyleX output is wrapped in CSS `@layer` declarations which enforces specificity. StyleX will use a polyfill based on ID selectors if omitted. ## CSS entry point (`src/global.css`) The project imports `src/global.css` so esbuild emits a CSS asset. The StyleX plugin appends the aggregated styles to that file during `npm run example:build`. ## Commands ```bash # Production bundle + CSS extraction npm run example:build ``` Use `npm run example:build` whenever you need a fresh `public/dist` folder containing both the JS bundle and the StyleX-enriched CSS. ================================================ FILE: examples/example-esbuild/package.json ================================================ { "private": true, "name": "example-esbuild", "version": "0.18.1", "description": "Simple esbuild example for @stylexjs/unplugin", "main": "src/App.jsx", "scripts": { "example:build": "node scripts/build.mjs", "example:lint": "eslint \"**/*.{js,jsx}\"" }, "license": "MIT", "dependencies": { "@stylexjs/stylex": "0.18.1", "react": "^19.2.0", "react-dom": "^19.2.0" }, "devDependencies": { "@stylexjs/unplugin": "0.18.1", "@stylexjs/eslint-plugin": "0.18.1", "esbuild": "^0.27.0", "eslint": "^8.57.1" } } ================================================ FILE: examples/example-esbuild/public/index.html ================================================ @stylexjs/unplugin (esbuild)
================================================ FILE: examples/example-esbuild/scripts/build.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import path from 'path'; import { fileURLToPath } from 'url'; import esbuild from 'esbuild'; import stylex from '@stylexjs/unplugin'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const BUILD_DIR_NAME = 'public/dist'; const OUTFILE = `${BUILD_DIR_NAME}/bundle.js`; esbuild .build({ entryPoints: [path.resolve(__dirname, '..', 'src/App.jsx')], bundle: true, outfile: OUTFILE, minify: true, metafile: true, // lets the plugin find CSS outputs, if any plugins: [ // See all options in the babel plugin configuration docs: // https://stylexjs.com/docs/api/configuration/babel-plugin/ stylex.esbuild({ useCSSLayers: true, importSources: ['@stylexjs/stylex'], unstable_moduleResolution: { type: 'commonJS', rootDir: path.resolve(__dirname, '../../..'), }, }), ], }) .catch(() => process.exit(1)); ================================================ FILE: examples/example-esbuild/src/App.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ 'use strict'; import './global.css'; import * as React from 'react'; import { createRoot } from 'react-dom/client'; import * as stylex from '@stylexjs/stylex'; import { colors, fonts, sizes } from './globalTokens.stylex'; const styles = stylex.create({ main: { width: '100vw', height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: colors.pink7, }, card: { backgroundColor: colors.blue9, padding: sizes.spacing5, borderRadius: sizes.spacing2, justifyContent: 'center', display: 'flex', alignItems: 'center', color: colors.gray0, fontFamily: fonts.mono, }, }); function App() { return (
Blue rounded rectangle
); } createRoot(document.getElementById('root')).render(); ================================================ FILE: examples/example-esbuild/src/global.css ================================================ :root { --stylex-injection: 0; } ================================================ FILE: examples/example-esbuild/src/globalTokens.stylex.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; export const colors = stylex.defineVars({ pink7: '#d6336c', blue9: '#1864ab', gray0: '#f8f9fa', }); export const fonts = stylex.defineVars({ mono: 'Dank Mono,Operator Mono,Inconsolata,Fira Mono,ui-monospace,SF Mono,Monaco,Droid Sans Mono,Source Code Pro,monospace', }); export const sizes = stylex.defineVars({ spacing5: '1.5rem', spacing2: '.5rem', }); ================================================ FILE: examples/example-nextjs/.eslintrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ module.exports = { plugins: ['@stylexjs'], rules: { // The Eslint rule still needs work, but you can // enable it to test things out. '@stylexjs/valid-styles': 'error', 'ft-flow/space-after-type-colon': 0, 'ft-flow/no-types-missing-file-annotation': 0, 'ft-flow/generic-spacing': 0, }, }; ================================================ FILE: examples/example-nextjs/.gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js .yarn/install-state.gz # testing /coverage # next.js /.next/ /out/ # production /build # misc .DS_Store *.pem # debug npm-debug.log* yarn-debug.log* yarn-error.log* # local env files .env*.local # vercel .vercel # typescript *.tsbuildinfo next-env.d.ts ================================================ FILE: examples/example-nextjs/README.md ================================================ # Next.js example using StyleX This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) which then uses the StyleX Babel and PostCSS plugins to compile StyleX. ## Getting Started First, run the development server: ```bash npm run example:dev # or yarn example:dev # or pnpm example:dev # or bun example:dev ``` Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. ## Setup Enabling StyleX compilation involves three steps: ### Define the `babel.config.js` file ```tsx const path = require('path'); const dev = process.env.NODE_ENV !== 'production'; module.exports = { presets: ['next/babel'], plugins: [ [ '@stylexjs/babel-plugin', // See all options in the babel plugin configuration docs: // https://stylexjs.com/docs/api/configuration/babel-plugin/ { dev, runtimeInjection: false, enableInlinedConditionalMerge: true, treeshakeCompensation: true, aliases: { '@/*': [path.join(__dirname, '*')], }, unstable_moduleResolution: { type: 'commonJS', }, }, ], ], }; ``` Ensure that the `next/babel` preset is used as well as the `@stylexjs/babel-plugin` with your configuration. It is preferable to use a JS/TS file for this config to help in the next part... ### Define the `postcss.config.js` ```tsx const babelConfig = require('./babel.config'); module.exports = { plugins: { '@stylexjs/postcss-plugin': { include: ['app/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}'], babelConfig: { babelrc: false, parserOpts: { plugins: ['typescript', 'jsx'], }, plugins: babelConfig.plugins, }, useCSSLayers: true, }, autoprefixer: {}, }, }; ``` Here, the `@stylexjs/postcss-plugin` must be used and configured. The `include` property takes a list of glob patterns to find all the files where styles should be extracted. `babelConfig` should be configured with at least the same StyleX Babel plugin as in your Babel config. It is important to ensure that your Babel config file and your PostCSS config are configured with the same options, so it's usually best to import your Babel config from your PostCSS config to share it. ### Ensure a CSS file is imported by every route of your app It's usually best to do this by global layout. The CSS file *must* contain the `@stylex` directive. ```css /** * Any reset styles */ @layer resets { * { box-sizing: border-box; padding: 0; margin: 0; } } /** * The @stylex directive is used by the @stylexjs/postcss-plugin. * It is automatically replaced with generated CSS during builds. */ @stylex; ``` --- Once these two files are defines, Next.js will automatically use Babel to transform your JS file with the StyleX plugin and the PostCSS plugin will be used to generate your final CSS file ================================================ FILE: examples/example-nextjs/app/InteractiveCard.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ 'use client'; import * as stylex from '@stylexjs/stylex'; import { spacing, text, globalTokens as $, colors, } from './globalTokens.stylex'; import { useState } from 'react'; export const redTheme = stylex.createTheme(colors, { accent: '#e03131', accentLight: 'rgba(224, 49, 49, 0.08)', accentFaded: 'rgba(224, 49, 49, 0.19)', }); export const greenTheme = stylex.createTheme(colors, { accent: '#2f9e44', accentLight: 'rgba(47, 158, 68, 0.08)', accentFaded: 'rgba(47, 158, 68, 0.19)', }); export const blueTheme = stylex.createTheme(colors, { accent: '#1c7ed6', accentLight: 'rgba(28, 126, 214, 0.08)', accentFaded: 'rgba(28, 126, 214, 0.19)', }); export const THEMES = [ { name: 'Red', theme: redTheme }, { name: 'Green', theme: greenTheme }, { name: 'Blue', theme: blueTheme }, ] as const; type Props = Readonly<{ themeIndex: number; onThemeChange: (_index: number) => void; isDark: boolean; onDarkModeChange: (_isDark: boolean) => void; }>; export default function InteractiveCard({ themeIndex, onThemeChange, isDark, onDarkModeChange, }: Props) { const [count, setCount] = useState(0); return (
Theme
{THEMES.map((t, i) => ( ))}
Mode
Counter
99 && styles.largeNumber, )} > {count}
); } const DARK = '@media (prefers-color-scheme: dark)' as const; const styles = stylex.create({ card: { display: 'flex', flexDirection: 'column', gap: spacing.sm, padding: spacing.lg, borderRadius: spacing.md, borderWidth: 2, borderStyle: 'solid', borderColor: colors.accent, backgroundColor: $.surfaceCard, boxShadow: $.surfaceCardShadow, fontFamily: $.fontSans, width: '100%', maxWidth: 400, transitionProperty: 'border-color, box-shadow', transitionDuration: '300ms', }, label: { fontSize: text.xs, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.05em', color: colors.accent, transitionProperty: 'color', transitionDuration: '300ms', }, themeRow: { display: 'flex', justifyContent: 'center', gap: spacing.xs, }, themeButton: { display: 'flex', alignItems: 'center', gap: spacing.xxs, paddingInline: spacing.sm, paddingBlock: spacing.xs, borderRadius: spacing.xs, borderWidth: 1, borderStyle: 'solid', borderColor: { default: colors.gray3, [DARK]: colors.gray8, }, backgroundColor: { default: 'transparent', ':hover': { default: colors.gray2, [DARK]: colors.gray9, }, }, color: 'inherit', cursor: 'pointer', fontSize: text.sm, fontFamily: $.fontSans, transitionProperty: 'background-color, border-color', transitionDuration: '200ms', }, themeButtonActive: { fontWeight: 600, borderColor: colors.accent, backgroundColor: colors.accentLight, }, dot: { width: 10, height: 10, borderRadius: '50%', flexShrink: 0, backgroundColor: colors.accent, }, divider: { height: 2, marginBlock: spacing.xxs, borderRadius: 1, backgroundColor: colors.accentFaded, transitionProperty: 'background-color', transitionDuration: '300ms', }, counterRow: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: spacing.md, }, counterButton: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: 48, height: 48, borderRadius: spacing.xs, borderWidth: 1, borderStyle: 'solid', borderColor: colors.accent, color: colors.accent, backgroundColor: { default: 'transparent', ':hover': { default: colors.gray2, [DARK]: colors.gray9, }, }, cursor: 'pointer', fontSize: text.h4, fontWeight: 300, fontFamily: $.fontSans, transitionProperty: 'background-color, transform, color, border-color', transitionDuration: '200ms', transform: { default: null, ':active': 'scale(0.95)', }, }, count: { fontSize: text.h2, fontWeight: 200, minWidth: 80, textAlign: 'center', fontFamily: $.fontMono, color: colors.accent, transitionProperty: 'color', transitionDuration: '300ms', }, largeNumber: { fontSize: text.h3, }, }); ================================================ FILE: examples/example-nextjs/app/app.css ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ @layer resets { * { box-sizing: border-box; padding: 0; margin: 0; } html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } } /** * The @stylex directive is used by the @stylexjs/postcss-plugin. * It is automatically replaced with generated CSS during builds. */ @stylex; ================================================ FILE: examples/example-nextjs/app/darkMode.stylex.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; import { globalTokens } from './globalTokens.stylex'; export const darkTheme = stylex.createTheme(globalTokens, { foregroundR: '255', foregroundG: '255', foregroundB: '255', bgStartRGB: 'rgb(0, 0, 0)', bgEndR: '0', bgEndG: '0', bgEndB: '0', calloutRGB: 'rgb(20, 20, 20)', calloutRGB50: 'rgba(20, 20, 20, 0.5)', calloutBorderR: '108', calloutBorderG: '108', calloutBorderB: '108', cardR: '100', cardG: '100', cardB: '100', cardBorderR: '200', cardBorderG: '200', cardBorderB: '200', primaryGlow: 'radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0))', secondaryGlow: `linear-gradient(${[ 'to bottom right', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0.3)', ].join(', ')})`, surfaceBg: '#0f1117', surfaceCard: '#1a1b26', surfaceCardShadow: '0 4px 24px rgba(0,0,0,0.3)', surfaceHover: 'rgba(255,255,255,0.04)', }); export const lightTheme = stylex.createTheme(globalTokens, { foregroundR: '0', foregroundG: '0', foregroundB: '0', bgStartRGB: 'rgb(214, 219, 220)', bgEndR: '255', bgEndG: '255', bgEndB: '255', calloutRGB: 'rgb(238, 240, 241)', calloutRGB50: 'rgba(238, 240, 241, 0.5)', calloutBorderR: '172', calloutBorderG: '175', calloutBorderB: '176', cardR: '180', cardG: '185', cardB: '188', cardBorderR: '131', cardBorderG: '134', cardBorderB: '135', primaryGlow: `conic-gradient(${[ 'from 180deg at 50% 50%', '#16abff33 0deg', '#0885ff33 55deg', '#54d6ff33 120deg', '#0071ff33 160deg', 'transparent 360deg', ].join(', ')})`, secondaryGlow: 'radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))', surfaceBg: '#fafafa', surfaceCard: 'white', surfaceCardShadow: '0 4px 24px rgba(0,0,0,0.06)', surfaceHover: 'rgba(0,0,0,0.02)', }); ================================================ FILE: examples/example-nextjs/app/globalTokens.stylex.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; /** * o--o o o o o-O-o o-o o--o o-o o o o-O-o o-o * | | | | | | \ | o o |\ | | | * O-o | | | | | O O-o | | | \ | | o-o * | | | | | | / | o o | \| | | * o O---o o-o o-O-o o-o o o-o o o o o--o * * Reference: https://utopia.fyi/type/calculator * * The following constants are used to calculate fluid typography. * Feel free to change these initial numbers to suit your needs. * * StyleX can compute all of this at compile time as all the information * is statically available in the same file and the only functions used are * the Math.pow and Math.round functions. * * NOTE: Any custom functions will not be able to be computed at compile time. */ const MIN_WIDTH = 320; const MAX_WIDTH = 1240; const MIN_SCALE = 1.2; const MAX_SCALE = 1.333; const MIN_BASE_SIZE = 16; const MAX_BASE_SIZE = 20; // Font sizes in `rem` units const MIN_FONT = { xxs: Math.round(MIN_BASE_SIZE / Math.pow(MIN_SCALE, 3) / 0.16) / 100, xs: Math.round(MIN_BASE_SIZE / Math.pow(MIN_SCALE, 2) / 0.16) / 100, sm: Math.round(MIN_BASE_SIZE / MIN_SCALE / 0.16) / 100, p: Math.round(MIN_BASE_SIZE / 4) / 4, h5: Math.round((MIN_BASE_SIZE * MIN_SCALE) / 0.16) / 100, h4: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 2)) / 0.16) / 100, h3: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 3)) / 0.16) / 100, h2: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 4)) / 0.16) / 100, h1: Math.round((MIN_BASE_SIZE * Math.pow(MIN_SCALE, 5)) / 0.16) / 100, }; // Font sizes in `rem` units const MAX_FONT = { xxs: Math.round(MAX_BASE_SIZE / Math.pow(MAX_SCALE, 3) / 0.16) / 100, xs: Math.round(MAX_BASE_SIZE / Math.pow(MAX_SCALE, 2) / 0.16) / 100, sm: Math.round(MAX_BASE_SIZE / MAX_SCALE / 0.16) / 100, p: Math.round(MAX_BASE_SIZE / 4) / 4, h5: Math.round((MAX_BASE_SIZE * MAX_SCALE) / 0.16) / 100, h4: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 2)) / 0.16) / 100, h3: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 3)) / 0.16) / 100, h2: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 4)) / 0.16) / 100, h1: Math.round((MAX_BASE_SIZE * Math.pow(MAX_SCALE, 5)) / 0.16) / 100, }; const SLOPE = { xxs: (16 * (MAX_FONT.xxs - MIN_FONT.xxs)) / (MAX_WIDTH - MIN_WIDTH), xs: (16 * (MAX_FONT.xs - MIN_FONT.xs)) / (MAX_WIDTH - MIN_WIDTH), sm: (16 * (MAX_FONT.sm - MIN_FONT.sm)) / (MAX_WIDTH - MIN_WIDTH), p: (16 * (MAX_FONT.p - MIN_FONT.p)) / (MAX_WIDTH - MIN_WIDTH), h5: (16 * (MAX_FONT.h5 - MIN_FONT.h5)) / (MAX_WIDTH - MIN_WIDTH), h4: (16 * (MAX_FONT.h4 - MIN_FONT.h4)) / (MAX_WIDTH - MIN_WIDTH), h3: (16 * (MAX_FONT.h3 - MIN_FONT.h3)) / (MAX_WIDTH - MIN_WIDTH), h2: (16 * (MAX_FONT.h2 - MIN_FONT.h2)) / (MAX_WIDTH - MIN_WIDTH), h1: (16 * (MAX_FONT.h1 - MIN_FONT.h1)) / (MAX_WIDTH - MIN_WIDTH), }; const INTERCEPT = { xxs: Math.round(100 * (MIN_FONT.xxs - SLOPE.xxs * (MIN_WIDTH / 16))) / 100, xs: Math.round(100 * (MIN_FONT.xs - SLOPE.xs * (MIN_WIDTH / 16))) / 100, sm: Math.round(100 * (MIN_FONT.sm - SLOPE.sm * (MIN_WIDTH / 16))) / 100, p: Math.round(100 * (MIN_FONT.p - SLOPE.p * (MIN_WIDTH / 16))) / 100, h5: Math.round(100 * (MIN_FONT.h5 - SLOPE.h5 * (MIN_WIDTH / 16))) / 100, h4: Math.round(100 * (MIN_FONT.h4 - SLOPE.h4 * (MIN_WIDTH / 16))) / 100, h3: Math.round(100 * (MIN_FONT.h3 - SLOPE.h3 * (MIN_WIDTH / 16))) / 100, h2: Math.round(100 * (MIN_FONT.h2 - SLOPE.h2 * (MIN_WIDTH / 16))) / 100, h1: Math.round(100 * (MIN_FONT.h1 - SLOPE.h1 * (MIN_WIDTH / 16))) / 100, }; // prettier-ignore export const text = stylex.defineVars({ xxs: `clamp(${ Math.min(MIN_FONT.xxs) }rem, calc(${ INTERCEPT.xxs }rem + ${ Math.round(10000 * SLOPE.xxs) / 100 }vw), ${ Math.max(MAX_FONT.xxs) }rem)`, xs: `clamp(${ Math.min(MIN_FONT.xs ) }rem, calc(${ INTERCEPT.xs }rem + ${ Math.round(10000 * SLOPE.xs ) / 100 }vw), ${ Math.max(MAX_FONT.xs ) }rem)`, sm: `clamp(${ Math.min(MIN_FONT.sm ) }rem, calc(${ INTERCEPT.sm }rem + ${ Math.round(10000 * SLOPE.sm ) / 100 }vw), ${ Math.max(MAX_FONT.sm ) }rem)`, p: `clamp(${ Math.min(MIN_FONT.p ) }rem, calc(${ INTERCEPT.p }rem + ${ Math.round(10000 * SLOPE.p ) / 100 }vw), ${ Math.max(MAX_FONT.p ) }rem)`, h5: `clamp(${ Math.min(MIN_FONT.h5 ) }rem, calc(${ INTERCEPT.h5 }rem + ${ Math.round(10000 * SLOPE.h5 ) / 100 }vw), ${ Math.max(MAX_FONT.h5 ) }rem)`, h4: `clamp(${ Math.min(MIN_FONT.h4 ) }rem, calc(${ INTERCEPT.h4 }rem + ${ Math.round(10000 * SLOPE.h4 ) / 100 }vw), ${ Math.max(MAX_FONT.h4 ) }rem)`, h3: `clamp(${ Math.min(MIN_FONT.h3 ) }rem, calc(${ INTERCEPT.h3 }rem + ${ Math.round(10000 * SLOPE.h3 ) / 100 }vw), ${ Math.max(MAX_FONT.h3 ) }rem)`, h2: `clamp(${ Math.min(MIN_FONT.h2 ) }rem, calc(${ INTERCEPT.h2 }rem + ${ Math.round(10000 * SLOPE.h2 ) / 100 }vw), ${ Math.max(MAX_FONT.h2 ) }rem)`, h1: `clamp(${ Math.min(MIN_FONT.h1 ) }rem, calc(${ INTERCEPT.h1 }rem + ${ Math.round(10000 * SLOPE.h1 ) / 100 }vw), ${ Math.max(MAX_FONT.h1 ) }rem)`, }); /** * o--o o o o o-O-o o-o o-o o--o O o-o o--o * | | | | | | \ | | | / \ / | * O-o | | | | | O o-o O--o o---oO O-o * | | | | | | / | | | | \ | * o O---o o-o o-O-o o-o o--o o o o o-o o--o * * Reference: https://utopia.fyi/space/calculator * * Similar to the fluid typography, we can create fluid values for spacing. * Using similar formulas and similar scales. * * NOTE: It is common to have more varied needs for spacing than for font-size. * So feel free to add some more values by following the pattern below. * * EXCEPT: We are using `px` instead of `rem` * ------------------------------------------ * When talking about font-size, it is the best practice to use * `rem` so that an end user can change the font-size using the * browser's font-size setting. * * However, when talking about spacing, it is the best practice to * use `px` because using `rems` here makes font-size behave like zoom. * * Users that prefer larger text, don't necessarily want larger spacing as well. * */ const MULT = { xxxs: 0.25, xxs: 0.5, xs: 0.75, sm: 1, md: 1.5, lg: 2, xl: 3, xxl: 4, xxxl: 6, xxxxl: 8, }; const MIN_SPACE = { xxxs: MULT.xxxs * MIN_BASE_SIZE, xxs: MULT.xxs * MIN_BASE_SIZE, xs: MULT.xs * MIN_BASE_SIZE, sm: MULT.sm * MIN_BASE_SIZE, md: MULT.md * MIN_BASE_SIZE, lg: MULT.lg * MIN_BASE_SIZE, xl: MULT.xl * MIN_BASE_SIZE, xxl: MULT.xxl * MIN_BASE_SIZE, xxxl: MULT.xxxl * MIN_BASE_SIZE, xxxxl: MULT.xxxxl * MIN_BASE_SIZE, }; const MAX_SPACE = { xxxs: MULT.xxxs * MAX_BASE_SIZE, xxs: MULT.xxs * MAX_BASE_SIZE, xs: MULT.xs * MAX_BASE_SIZE, sm: MULT.sm * MAX_BASE_SIZE, md: MULT.md * MAX_BASE_SIZE, lg: MULT.lg * MAX_BASE_SIZE, xl: MULT.xl * MAX_BASE_SIZE, xxl: MULT.xxl * MAX_BASE_SIZE, xxxl: MULT.xxxl * MAX_BASE_SIZE, xxxxl: MULT.xxxxl * MAX_BASE_SIZE, }; const SLOPE_SPACE = { xxxs: (MAX_SPACE.xxxs - MIN_SPACE.xxxs) / (MAX_WIDTH - MIN_WIDTH), xxs: (MAX_SPACE.xxs - MIN_SPACE.xxs) / (MAX_WIDTH - MIN_WIDTH), xs: (MAX_SPACE.xs - MIN_SPACE.xs) / (MAX_WIDTH - MIN_WIDTH), sm: (MAX_SPACE.sm - MIN_SPACE.sm) / (MAX_WIDTH - MIN_WIDTH), md: (MAX_SPACE.md - MIN_SPACE.md) / (MAX_WIDTH - MIN_WIDTH), lg: (MAX_SPACE.lg - MIN_SPACE.lg) / (MAX_WIDTH - MIN_WIDTH), xl: (MAX_SPACE.xl - MIN_SPACE.xl) / (MAX_WIDTH - MIN_WIDTH), xxl: (MAX_SPACE.xxl - MIN_SPACE.xxl) / (MAX_WIDTH - MIN_WIDTH), xxxl: (MAX_SPACE.xxxl - MIN_SPACE.xxxl) / (MAX_WIDTH - MIN_WIDTH), xxxxl: (MAX_SPACE.xxxxl - MIN_SPACE.xxxxl) / (MAX_WIDTH - MIN_WIDTH), }; // rounded to the nearest 0.25px const INTERCEPT_SPACE = { xxxs: Math.round(4 * (MIN_SPACE.xxxs - SLOPE_SPACE.xxxs * MIN_WIDTH)) / 4, xxs: Math.round(4 * (MIN_SPACE.xxs - SLOPE_SPACE.xxs * MIN_WIDTH)) / 4, xs: Math.round(4 * (MIN_SPACE.xs - SLOPE_SPACE.xs * MIN_WIDTH)) / 4, sm: Math.round(4 * (MIN_SPACE.sm - SLOPE_SPACE.sm * MIN_WIDTH)) / 4, md: Math.round(4 * (MIN_SPACE.md - SLOPE_SPACE.md * MIN_WIDTH)) / 4, lg: Math.round(4 * (MIN_SPACE.lg - SLOPE_SPACE.lg * MIN_WIDTH)) / 4, xl: Math.round(4 * (MIN_SPACE.xl - SLOPE_SPACE.xl * MIN_WIDTH)) / 4, xxl: Math.round(4 * (MIN_SPACE.xxl - SLOPE_SPACE.xxl * MIN_WIDTH)) / 4, xxxl: Math.round(4 * (MIN_SPACE.xxxl - SLOPE_SPACE.xxxl * MIN_WIDTH)) / 4, xxxxl: Math.round(4 * (MIN_SPACE.xxxxl - SLOPE_SPACE.xxxxl * MIN_WIDTH)) / 4, }; // prettier-ignore export const spacing = stylex.defineVars({ xxxs: `clamp(${MIN_SPACE.xxxs }px, calc(${INTERCEPT_SPACE.xxxs }px + ${ Math.round(10000 * SLOPE_SPACE.xxxs ) / 100 }vw), ${MAX_SPACE.xxxs }px)`, xxs: `clamp(${MIN_SPACE.xxs }px, calc(${INTERCEPT_SPACE.xxs }px + ${ Math.round(10000 * SLOPE_SPACE.xxs ) / 100 }vw), ${MAX_SPACE.xxs }px)`, xs: `clamp(${MIN_SPACE.xs }px, calc(${INTERCEPT_SPACE.xs }px + ${ Math.round(10000 * SLOPE_SPACE.xs ) / 100 }vw), ${MAX_SPACE.xs }px)`, sm: `clamp(${MIN_SPACE.sm }px, calc(${INTERCEPT_SPACE.sm }px + ${ Math.round(10000 * SLOPE_SPACE.sm ) / 100 }vw), ${MAX_SPACE.sm }px)`, md: `clamp(${MIN_SPACE.md }px, calc(${INTERCEPT_SPACE.md }px + ${ Math.round(10000 * SLOPE_SPACE.md ) / 100 }vw), ${MAX_SPACE.md }px)`, lg: `clamp(${MIN_SPACE.lg }px, calc(${INTERCEPT_SPACE.lg }px + ${ Math.round(10000 * SLOPE_SPACE.lg ) / 100 }vw), ${MAX_SPACE.lg }px)`, xl: `clamp(${MIN_SPACE.xl }px, calc(${INTERCEPT_SPACE.xl }px + ${ Math.round(10000 * SLOPE_SPACE.xl ) / 100 }vw), ${MAX_SPACE.xl }px)`, xxl: `clamp(${MIN_SPACE.xxl }px, calc(${INTERCEPT_SPACE.xxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxl ) / 100 }vw), ${MAX_SPACE.xxl }px)`, xxxl: `clamp(${MIN_SPACE.xxxl }px, calc(${INTERCEPT_SPACE.xxxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxxl ) / 100 }vw), ${MAX_SPACE.xxxl }px)`, xxxxl: `clamp(${MIN_SPACE.xxxxl }px, calc(${INTERCEPT_SPACE.xxxxl }px + ${ Math.round(10000 * SLOPE_SPACE.xxxxl ) / 100 }vw), ${MAX_SPACE.xxxxl }px)`, }); /** * Color Tokens */ const DARK_MODE = '@media (prefers-color-scheme: dark)'; export const globalTokens = stylex.defineVars({ maxWidth: `${MAX_WIDTH}px`, fontMono: [ 'ui-monospace', 'Menlo', 'Monaco', '"Cascadia Mono"', '"Segoe UI Mono"', '"Roboto Mono"', '"Oxygen Mono"', '"Ubuntu Monospace"', '"Source Code Pro"', '"Fira Mono"', '"Droid Sans Mono"', '"Courier New"', 'monospace', ].join(', '), fontSans: [ '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', '"Noto Sans"', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', '"Noto Color Emoji"', ].join(', '), foregroundR: { default: '0', [DARK_MODE]: '255' }, foregroundG: { default: '0', [DARK_MODE]: '255' }, foregroundB: { default: '0', [DARK_MODE]: '255' }, bgStartRGB: { default: 'rgb(214, 219, 220)', [DARK_MODE]: 'rgb(0, 0, 0)' }, bgEndR: { default: '255', [DARK_MODE]: '0' }, bgEndG: { default: '255', [DARK_MODE]: '0' }, bgEndB: { default: '255', [DARK_MODE]: '0' }, calloutRGB: { default: 'rgb(238, 240, 241)', [DARK_MODE]: 'rgb(20, 20, 20)' }, calloutRGB50: { default: 'rgba(238, 240, 241, 0.5)', [DARK_MODE]: 'rgba(20, 20, 20, 0.5)', }, calloutBorderR: { default: '172', [DARK_MODE]: '108' }, calloutBorderG: { default: '175', [DARK_MODE]: '108' }, calloutBorderB: { default: '176', [DARK_MODE]: '108' }, cardR: { default: '180', [DARK_MODE]: '100' }, cardG: { default: '185', [DARK_MODE]: '100' }, cardB: { default: '188', [DARK_MODE]: '100' }, cardBorderR: { default: '131', [DARK_MODE]: '200' }, cardBorderG: { default: '134', [DARK_MODE]: '200' }, cardBorderB: { default: '135', [DARK_MODE]: '200' }, primaryGlow: { default: `conic-gradient(${[ 'from 180deg at 50% 50%', '#16abff33 0deg', '#0885ff33 55deg', '#54d6ff33 120deg', '#0071ff33 160deg', 'transparent 360deg', ].join(', ')})`, [DARK_MODE]: 'radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0))', }, secondaryGlow: { default: 'radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))', [DARK_MODE]: `linear-gradient(${[ 'to bottom right', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0)', 'rgba(1, 65, 255, 0.3)', ].join(', ')})`, }, surfaceBg: { default: '#fafafa', [DARK_MODE]: '#0f1117' }, surfaceCard: { default: 'white', [DARK_MODE]: '#1a1b26' }, surfaceCardShadow: { default: '0 4px 24px rgba(0,0,0,0.06)', [DARK_MODE]: '0 4px 24px rgba(0,0,0,0.3)', }, surfaceHover: { default: 'rgba(0,0,0,0.02)', [DARK_MODE]: 'rgba(255,255,255,0.04)', }, }); export const scales = stylex.defineVars({ small: 'scale(0.95)', medium: 'scale(1)', large: 'scale(1.2)', }); export const colors = stylex.defineVars({ accent: '#1c7ed6', accentLight: 'rgba(28, 126, 214, 0.08)', accentFaded: 'rgba(28, 126, 214, 0.19)', blue3: '#74c0fc', blue5: '#4285F4', blue7: '#1c7ed6', purple: '#5B45DE', purple6: '#7C6AE8', emerald: '#0ca678', gray2: '#e9ecef', gray3: '#dee2e6', gray4: '#ced4da', gray5: '#adb5bd', gray6: '#868e96', gray8: '#343a40', gray9: '#212529', lime7: '#74b816', }); ================================================ FILE: examples/example-nextjs/app/layout.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import './app.css'; import { globalTokens as $ } from '@/app/globalTokens.stylex'; import * as stylex from '@stylexjs/stylex'; export const metadata = { title: 'Next.js + StyleX', description: 'The expressive styling system for ambitious interfaces', }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } const styles = stylex.create({ html: { colorScheme: 'light dark', }, reset: { minHeight: '100%', margin: 0, padding: 0, }, body: { backgroundColor: $.surfaceBg, }, }); ================================================ FILE: examples/example-nextjs/app/page.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ 'use client'; import React, { useState, useEffect } from 'react'; import * as stylex from '@stylexjs/stylex'; import Card from '@/components/Card'; import { globalTokens as $, spacing, text, colors, } from './globalTokens.stylex'; import InteractiveCard, { THEMES } from './InteractiveCard'; import { darkTheme, lightTheme } from './darkMode.stylex'; const HOMEPAGE = 'https://stylexjs.com'; export default function Home() { const [themeIndex, setThemeIndex] = useState(2); const [isDark, setIsDark] = useState(false); useEffect(() => { const mq = window.matchMedia('(prefers-color-scheme: dark)'); setIsDark(mq.matches); const handler = (e: MediaQueryListEvent) => setIsDark(e.matches); mq.addEventListener('change', handler); return () => mq.removeEventListener('change', handler); }, []); return (

Next.js + StyleX

The expressive styling system for ambitious interfaces

); } const MEDIA_MOBILE = '@media (max-width: 700px)' as const; const MEDIA_TABLET = '@media (min-width: 701px) and (max-width: 1120px)' as const; const DARK = '@media (prefers-color-scheme: dark)' as const; const style = stylex.create({ main: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: spacing.xxxl, minHeight: '100vh', paddingTop: spacing.xxxl, paddingBottom: { default: spacing.xxl, [MEDIA_MOBILE]: spacing.lg, }, paddingInline: spacing.md, backgroundColor: $.surfaceBg, color: `rgba(${$.foregroundR}, ${$.foregroundG}, ${$.foregroundB}, 1)`, }, hero: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: spacing.lg, width: '100%', maxWidth: 480, }, h1: { fontSize: text.h1, lineHeight: 1, fontFamily: $.fontSans, fontWeight: 700, textAlign: 'center', letterSpacing: '-0.02em', whiteSpace: 'nowrap', flexDirection: { default: 'row', [MEDIA_MOBILE]: 'column', }, }, plus: { fontWeight: 300, color: colors.accent, transitionProperty: 'color', transitionDuration: '300ms', }, subtitle: { fontSize: text.p, lineHeight: 1.6, fontFamily: $.fontSans, textAlign: 'center', color: { default: colors.gray5, [DARK]: colors.gray6, }, maxWidth: '36ch', textWrap: 'balance', }, grid: { display: 'grid', gridTemplateColumns: { default: 'repeat(4, minmax(25%, auto))', [MEDIA_MOBILE]: '1fr', [MEDIA_TABLET]: 'repeat(2, 50%)', }, gap: spacing.sm, width: $.maxWidth, maxWidth: { default: '100%', [MEDIA_MOBILE]: 320, }, textAlign: { [MEDIA_MOBILE]: 'center' }, }, }); ================================================ FILE: examples/example-nextjs/babel.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ const path = require('path'); const dev = process.env.NODE_ENV !== 'production'; module.exports = { presets: ['next/babel'], plugins: [ [ '@stylexjs/babel-plugin', // See all options in the babel plugin configuration docs: // https://stylexjs.com/docs/api/configuration/babel-plugin/ { dev, runtimeInjection: false, enableInlinedConditionalMerge: true, treeshakeCompensation: true, aliases: { '@/*': [path.join(__dirname, '*')], }, unstable_moduleResolution: { type: 'commonJS', }, }, ], ], }; ================================================ FILE: examples/example-nextjs/components/Card.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as stylex from '@stylexjs/stylex'; import { globalTokens as $, spacing, text, colors, } from '@/app/globalTokens.stylex'; import { cardMarker, headingMarker } from './CardTokens.stylex'; type Props = Readonly<{ title: string; body: string; href: string; }>; export default function Card({ title, body, href }: Props) { return (

{title}

{body}

); } type TMobile = '@media (max-width: 700px)'; const MOBILE: TMobile = '@media (max-width: 700px)' as TMobile; const REDUCE_MOTION = '@media (prefers-reduced-motion: reduce)' as const; const DARK = '@media (prefers-color-scheme: dark)' as const; const styles = stylex.create({ link: { display: { default: 'flex', [MOBILE]: 'block', }, alignItems: 'center', justifyContent: 'flex-start', flexDirection: 'column', borderRadius: spacing.sm, backgroundColor: { default: 'transparent', ':hover': $.surfaceHover, }, borderWidth: 1, borderStyle: 'solid', borderColor: { default: colors.gray2, ':hover': colors.accent, [DARK]: { default: colors.gray8, ':hover': colors.accent, }, }, color: 'inherit', fontFamily: $.fontSans, padding: spacing.md, transitionProperty: 'background-color, border-color, transform, box-shadow', transitionDuration: '300ms', textAlign: 'center', textDecoration: 'none', transform: { default: null, ':hover': 'translateY(-2px)', }, boxShadow: { default: 'none', ':hover': '0 4px 16px rgba(0, 0, 0, 0.08)', }, }, h2: { color: colors.accent, fontSize: text.h4, fontWeight: 600, marginBottom: { default: spacing.xs, [MOBILE]: spacing.xxs, }, transitionProperty: 'color', transitionDuration: '300ms', }, span: { display: 'inline-block', transitionProperty: 'transform', transform: { default: null, [stylex.when.ancestor(':hover', cardMarker)]: 'translateX(10px)', [stylex.when.ancestor(':hover', headingMarker)]: 'translateX(4px)', }, transitionDuration: { default: '200ms', [REDUCE_MOTION]: '0s', }, }, p: { margin: 0, opacity: 0.6, fontSize: text.p, textWrap: 'balance', lineHeight: 1.5, maxWidth: '30ch', }, }); ================================================ FILE: examples/example-nextjs/components/CardTokens.stylex.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import * as stylex from '@stylexjs/stylex'; export const cardMarker = stylex.defineMarker(); export const headingMarker = stylex.defineMarker(); ================================================ FILE: examples/example-nextjs/next.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ /** @type {import('next').NextConfig} */ const path = require('path'); module.exports = {}; ================================================ FILE: examples/example-nextjs/package.json ================================================ { "private": true, "name": "example-nextjs", "version": "0.18.1", "scripts": { "clean": "shx rm -rf .next", "example:build": "next build", "example:dev": "next dev", "example:lint": "next lint", "example:start": "next start" }, "dependencies": { "@stylexjs/stylex": "0.18.1", "next": "^16.0.7", "react": "^19.0.0-rc-de68d2f4-20241204", "react-dom": "^19.0.0-rc-de68d2f4-20241204" }, "devDependencies": { "autoprefixer": "^10.4.20", "@stylexjs/eslint-plugin": "0.18.1", "@stylexjs/postcss-plugin": "0.18.1", "@types/json-schema": "^7.0.15", "@types/node": "^22.7.6", "@types/react": "^18.3.0", "@types/react-dom": "^18.3.0", "@typescript-eslint/parser": "^8.48.1", "eslint": "^9.39.1", "eslint-config-next": "^16.0.6", "typescript": "^5.9.3", "client-only": "0.0.1" } } ================================================ FILE: examples/example-nextjs/postcss.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ const babelConfig = require('./babel.config'); module.exports = { plugins: { '@stylexjs/postcss-plugin': { include: ['app/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}'], babelConfig: { babelrc: false, parserOpts: { plugins: ['typescript', 'jsx'], }, plugins: babelConfig.plugins, }, useCSSLayers: true, }, autoprefixer: {}, }, }; ================================================ FILE: examples/example-nextjs/tsconfig.json ================================================ { "compilerOptions": { "target": "es5", "lib": [ "dom", "dom.iterable", "esnext" ], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": [ "./*" ] } }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts" ], "exclude": [ "node_modules" ] } ================================================ FILE: examples/example-react-router/.gitignore ================================================ .DS_Store node_modules .env dist ================================================ FILE: examples/example-react-router/README.md ================================================ # React Router + RSC + StyleX ⚠️ **EXPERIMENTAL**: This template demonstrates React Server Components with React Router. ## Highlights - 🧪 React Server Components powered by Vite’s RSC plugin - 🧵 Styling via [`@stylexjs/stylex`](https://stylexjs.com/) compiled by [`@stylexjs/unplugin`](https://www.npmjs.com/package/@stylexjs/unplugin) - 🧭 React Router 7 data APIs + server actions - ⚡️ Instant HMR during `example:dev` - 🔣 TypeScript out of the box ## Scripts ```bash npm install # install dependencies npm run example:dev # start Vite dev server with RSC + StyleX rm -rf dist && npm run example:build # optional clean + production build npm run example:start # run the Express server using the dist/ output npm run example:typecheck # type-check without emitting files ``` Dev server runs on `http://localhost:5173` by default. ## StyleX integration The Vite config registers the StyleX unplugin before the RSC plugin so that both client and server bundles share the same compiled CSS: ```ts import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [ stylex.vite({ useCSSLayers: true }), react(), rsc({ /* ... */ }), ], }); ``` - `src/stylex.css` is imported from the root route. This ensures Vite always emits a CSS asset that the unplugin can append to. - During development the layout injects the virtual StyleX runtime and stylesheet so HMR picks up CSS changes without reloading: ```tsx { import.meta.env.DEV ? ( <> ); ================================================ FILE: examples/example-redwoodsdk/src/app/components/Copy.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use client'; import { useState } from 'react'; import * as stylex from '@stylexjs/stylex'; export function Copy({ textToCopy }: { textToCopy: string }) { const [copied, setCopied] = useState(false); const handleCopy = () => { navigator.clipboard.writeText(textToCopy).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); }); }; return ( ); } const styles = stylex.create({ copyButton: { backgroundColor: 'transparent', color: '#ffad48', borderWidth: 0, borderRadius: 4, paddingBlock: 4, paddingInline: 12, cursor: 'pointer', fontSize: 16, fontWeight: 700, ':hover': { backgroundColor: 'rgba(255,255,255,0.1)' }, }, }); ================================================ FILE: examples/example-redwoodsdk/src/app/headers.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { RouteMiddleware } from 'rwsdk/router'; export const setCommonHeaders = (): RouteMiddleware => ({ response, rw: { nonce } }) => { if (!import.meta.env.VITE_IS_DEV_SERVER) { // Forces browsers to always use HTTPS for a specified time period (2 years) response.headers.set( 'Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload', ); } // Forces browser to use the declared content-type instead of trying to guess/sniff it response.headers.set('X-Content-Type-Options', 'nosniff'); // Stops browsers from sending the referring webpage URL in HTTP headers response.headers.set('Referrer-Policy', 'no-referrer'); // Explicitly disables access to specific browser features/APIs response.headers.set( 'Permissions-Policy', 'geolocation=(), microphone=(), camera=()', ); // Defines trusted sources for content loading and script execution: response.headers.set( 'Content-Security-Policy', `default-src 'self'; script-src 'self' 'unsafe-eval' 'nonce-${nonce}' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; frame-ancestors 'self'; frame-src 'self' https://challenges.cloudflare.com; object-src 'none';`, ); }; ================================================ FILE: examples/example-redwoodsdk/src/app/pages/Counter.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use client'; import { useState } from 'react'; import * as stylex from '@stylexjs/stylex'; const styles = stylex.create({ container: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 10, padding: 10, }, button: { backgroundColor: 'tomato', borderStyle: 'none', appearance: 'none', color: 'white', paddingInline: 20, paddingBlock: 10, borderRadius: 5, margin: 10, }, count: { fontFamily: 'monospace', fontSize: 20, }, }); export function Counter() { const [count, setCount] = useState(0); return (
{count}
); } ================================================ FILE: examples/example-redwoodsdk/src/app/pages/Home.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { Welcome } from './Welcome.js'; export const Home = () => { // _Feel free to delete this element and its import_ return ; }; ================================================ FILE: examples/example-redwoodsdk/src/app/pages/Welcome.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; import { Button } from '@stylexjs/shared-ui'; import { tokens } from '@stylexjs/shared-ui/tokens.stylex'; import { Copy } from '../components/Copy'; export const Welcome = () => { return (

Welcome to RedwoodSDK x StyleX

You’ve just installed the starter project. Here’s what to do next.

Next steps

  1. Read the{' '} Quick Start {' '} to learn the basics.
  2. Explore React Server Components and Server Functions in the{' '} Docs .
  3. Join the community to ask questions and share what you’re building.

Deploy to Cloudflare

RedwoodSDK runs on Cloudflare Workers. Here’s the quickest way to deploy.

$ pnpm release

Need more detail? Read the{' '} Cloudflare deployment guide .

); }; const opacity = (color: string, percentage: number) => `color-mix(in oklab, ${color} ${percentage}%, transparent)`; const styles = stylex.create({ container: { maxWidth: 1100, marginInline: 'auto', paddingBlock: 80, paddingInline: 32, fontFamily: "Noto Sans, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, 'Helvetica Neue', Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", color: '#1a1a1a', minHeight: '100vh', }, header: { marginBottom: 64 }, title: { fontFamily: 'Playfair Display, serif', fontSize: 64, fontWeight: 700, lineHeight: 0.9, margin: 0, }, subtitle: { fontFamily: "Noto Sans, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, 'Helvetica Neue', Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", fontSize: 26, marginTop: 12, }, section: { marginBottom: 64 }, sectionTitle: { fontFamily: 'Playfair Display, serif', fontSize: 40, fontWeight: 700, marginBottom: 16, }, list: { listStylePosition: 'inside', listStyleType: 'decimal', paddingLeft: 0, fontSize: 20, lineHeight: 1.6, }, listItem: { marginBottom: 12 }, link: { color: '#f47238', fontWeight: 700, textDecorationLine: 'none', ':hover': { color: '#ffad48' }, }, codeBlock: { backgroundColor: '#1b1b1b', color: '#ffad48', padding: 16, borderRadius: 8, fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', fontSize: 20, display: 'flex', alignItems: 'center', gap: 8, marginTop: 16, }, codePrompt: { color: '#f47238' }, code: { flexGrow: 1 }, btn: { backgroundColor: { default: opacity(tokens.primaryColor, 50), ':hover': opacity(tokens.primaryColor, 95), }, transform: { default: null, ':active': 'scale(0.97)', }, transitionProperty: 'transform', transitionDuration: { default: '0.3s', ':active': '0.05s', }, }, }); ================================================ FILE: examples/example-redwoodsdk/src/app/root.css ================================================ :root { --stylex-injection: 0; } ================================================ FILE: examples/example-redwoodsdk/src/app/shared/links.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { defineLinks } from 'rwsdk/router'; export const link = defineLinks(['/']); ================================================ FILE: examples/example-redwoodsdk/src/client.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { initClient } from 'rwsdk/client'; initClient(); if (import.meta.env.DEV) { // @ts-ignore import('virtual:stylex:css-only'); } ================================================ FILE: examples/example-redwoodsdk/src/worker.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { render, route } from 'rwsdk/router'; import { defineApp } from 'rwsdk/worker'; import './app/root.css'; import { Document } from '@/app/Document'; import { setCommonHeaders } from '@/app/headers'; import { Home } from '@/app/pages/Home'; import { Counter } from './app/pages/Counter'; export type AppContext = {}; export default defineApp([ setCommonHeaders(), ({ ctx }) => { // setup ctx here ctx; }, render(Document, [route('/', Home), route('/counter', Counter)]), ]); ================================================ FILE: examples/example-redwoodsdk/tsconfig.json ================================================ { "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "target": "es2021", /* Specify a set of bundled library declaration files that describe the target runtime environment. */ "lib": ["DOM", "DOM.Iterable", "ESNext", "ES2022"], /* Specify what JSX code is generated. */ "jsx": "react-jsx", /* Specify what module code is generated. */ "module": "es2022", /* Specify how TypeScript looks up a file from a given module specifier. */ "moduleResolution": "bundler", /* Specify type package names to be included without being referenced in a source file. */ "types": [ "@cloudflare/workers-types", "./worker-configuration.d.ts", "./types/rw.d.ts", "./types/vite.d.ts" ], "paths": { "@/*": ["./src/*"] }, /* Enable importing .json files */ "resolveJsonModule": true, /* Enable error reporting in type-checked JavaScript files. */ "checkJs": false, /* Disable emitting files from a compilation. */ "noEmit": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ "isolatedModules": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "allowSyntheticDefaultImports": true, /* Ensure that casing is correct in imports. */ "forceConsistentCasingInFileNames": true, /* Enable all strict type-checking options. */ "strict": true, /* Skip type checking all .d.ts files. */ "skipLibCheck": true }, "exclude": ["node_modules", ".tmp"] } ================================================ FILE: examples/example-redwoodsdk/types/css.d.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ declare module '*.module.css' { const classes: { readonly [key: string]: string }; export default classes; } declare module '*.css' {} declare module '*.css?url' { export default string; } ================================================ FILE: examples/example-redwoodsdk/types/rw.d.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { AppContext } from '../src/worker'; declare module 'rwsdk/worker' { // eslint-disable-next-line no-unused-vars interface DefaultAppContext extends AppContext {} } ================================================ FILE: examples/example-redwoodsdk/types/vite.d.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ declare module '*?url' { const result: string; export default result; } ================================================ FILE: examples/example-redwoodsdk/vite.config.mts ================================================ import { defineConfig } from 'vite'; import { redwood } from 'rwsdk/vite'; import { cloudflare } from '@cloudflare/vite-plugin'; import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [ cloudflare({ viteEnvironment: { name: 'worker' }, }), redwood(), // @ts-ignore stylex.vite({ // Keep transforms on in dev, but only expose the CSS endpoint (no runtime/HTML injection) devMode: 'css-only', devPersistToDisk: true, dev: process.env.NODE_ENV === 'development', runtimeInjection: false, }), ], }); ================================================ FILE: examples/example-redwoodsdk/worker-configuration.d.ts ================================================ /* eslint-disable */ // Generated by Wrangler by running `wrangler types --include-runtime false` (hash: 6b6db21c80ba9cfeb812f12bd8b8b3e4) declare namespace Cloudflare { interface GlobalProps { mainModule: typeof import('./src/worker'); } interface Env { ASSETS: Fetcher; } } interface Env extends Cloudflare.Env {} ================================================ FILE: examples/example-redwoodsdk/wrangler.jsonc ================================================ { // Schema reference for wrangler configuration "$schema": "node_modules/wrangler/config-schema.json", // Name of your worker "name": "__change_me__", // Entry point for your worker "main": "src/worker.tsx", // Compatibility settings "compatibility_date": "2025-08-21", "compatibility_flags": ["nodejs_compat"], // Assets configuration "assets": { "binding": "ASSETS" }, // Observability settings "observability": { "enabled": true }, // Environment variables "vars": { // Add your environment variables here } } ================================================ FILE: examples/example-rollup/README.md ================================================ # Rollup example using StyleX TBD ================================================ FILE: examples/example-rollup/babel.config.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ const config = { assumptions: { iterableIsArray: true, }, comments: false, presets: [ [ '@babel/preset-react', { runtime: 'automatic', }, ], '@babel/preset-flow', ], }; export default config; ================================================ FILE: examples/example-rollup/index.html ================================================ StyleX with Rollup
================================================ FILE: examples/example-rollup/package.json ================================================ { "private": true, "name": "example-rollup", "version": "0.18.1", "description": "A simple rollup example to test stylexjs/rollup-plugin", "main": "index.js", "scripts": { "example:build": "rollup --config ./rollup.config.mjs", "example:dev": "rollup --config ./rollup.config.mjs --watch", "example:serve": "serve" }, "license": "MIT", "dependencies": { "@stylexjs/stylex": "0.18.1", "react": "^19.2.0", "react-dom": "^19.2.0" }, "devDependencies": { "@babel/core": "^7.18.2", "@babel/preset-env": "^7.18.2", "@babel/preset-flow": "^7.27.1", "@babel/preset-react": "^7.17.12", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.7", "@stylexjs/rollup-plugin": "0.18.1", "rollup": "^4.59.0", "serve": "^14.2.4" } } ================================================ FILE: examples/example-rollup/rollup.config.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { babel } from '@rollup/plugin-babel'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; import replace from '@rollup/plugin-replace'; import stylexPlugin from '@stylexjs/rollup-plugin'; const babelPlugin = babel({ babelHelpers: 'bundled', }); const config = { input: './src/index.js', output: { file: './.build/bundle.js', format: 'cjs', }, // See all options in the babel plugin configuration docs: // https://stylexjs.com/docs/api/configuration/babel-plugin/ plugins: [ babelPlugin, resolve(), commonjs(), replace({ 'process.env.NODE_ENV': JSON.stringify( process.env.NODE_ENV || 'development', ), preventAssignment: true, }), stylexPlugin({ fileName: 'stylex.css', runtimeInjection: true, }), ], }; export default config; ================================================ FILE: examples/example-rollup/src/App.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; import * as stylex from '@stylexjs/stylex'; export default function App() { return (
Content
); } const styles = stylex.create({ main: { width: '100vw', height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'lightblue', }, card: { backgroundColor: '#fefefe', padding: '1rem', borderRadius: 10, justifyContent: 'center', display: 'flex', alignItems: 'center', color: '#333', fontFamily: 'Arial', }, }); ================================================ FILE: examples/example-rollup/src/index.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( , ); ================================================ FILE: examples/example-rspack/README.md ================================================ # Rspack Example with StyleX This project demonstrates how to run StyleX inside Rspack via `@stylexjs/unplugin`. The plugin compiles StyleX at build time and appends the generated CSS to the stylesheet emitted by `CssExtractRspackPlugin`. ### Prerequisites - Node.js 18+ - `@rspack/cli` / `@rspack/core` - `MiniCssExtractRspackPlugin` (bundled with Rspack) or another CSS extractor - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Rspack configuration (`rspack.config.js`) ```javascript const path = require('path'); const rspack = require('@rspack/core'); const stylex = require('@stylexjs/unplugin').default; module.exports = { entry: { app: path.resolve(__dirname, 'src/main.jsx') }, plugins: [ stylex.rspack({}), new rspack.CssExtractRspackPlugin({ filename: 'index.css' }), ], module: { rules: [ { test: /\.[jt]sx?$/, loader: 'builtin:swc-loader' }, { test: /\.css$/, use: [rspack.CssExtractRspackPlugin.loader, 'css-loader'] }, ], }, }; ``` - `stylex.rspack()` injects the plugin into the webpack-compatible compiler hooks. - The CSS extract plugin ensures there is a concrete CSS asset for StyleX to append to. ## CSS entry point (`src/global.css`) The app imports `src/global.css` so every build produces `index.css`. The StyleX plugin appends its aggregated CSS to that file during both dev and production builds. ## Commands ```bash # Start the Rspack dev server with StyleX transforms npm run example:dev # Production build with aggregated StyleX CSS in dist/index.css npm run example:build ``` Execute the scripts from `examples/example-rspack`. The `dist/` output already contains the StyleX CSS merged into `index.css`. ================================================ FILE: examples/example-rspack/package.json ================================================ { "name": "example-rspack", "private": true, "version": "0.18.1", "description": "Example: StyleX with Rspack via @stylexjs/unplugin", "scripts": { "example:build": "rspack build --config ./rspack.config.js", "example:dev": "rspack serve --config ./rspack.config.js" }, "dependencies": { "react": "^19.2.0", "react-dom": "^19.2.0", "@stylexjs/stylex": "0.18.1" }, "devDependencies": { "@rspack/cli": "^1.6.4", "@rspack/core": "^1.6.4", "css-loader": "^7.1.2", "@stylexjs/unplugin": "0.18.1" } } ================================================ FILE: examples/example-rspack/public/index.html ================================================ StyleX + Rspack
================================================ FILE: examples/example-rspack/rspack.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ const path = require('path'); const rspack = require('@rspack/core'); const stylex = require('@stylexjs/unplugin').default; /** @type {import('@rspack/core').Configuration} */ module.exports = { mode: 'development', context: __dirname, entry: { app: path.resolve(__dirname, 'src/main.jsx'), }, experiments: { // Disable built-in CSS experiment when using extract plugin css: false, }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', clean: true, }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], }, module: { rules: [ { test: /\.[jt]sx?$/, exclude: /node_modules/, loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'ecmascript', jsx: true }, transform: { react: { runtime: 'automatic' } }, }, }, }, { test: /\.css$/, use: [rspack.CssExtractRspackPlugin.loader, 'css-loader'], }, ], }, plugins: [ // Use the unplugin adapter for Rspack/webpack stylex.rspack({}), new rspack.CssExtractRspackPlugin({ filename: 'index.css' }), ], devServer: { static: { directory: path.join(__dirname, 'public'), }, port: 5174, }, }; ================================================ FILE: examples/example-rspack/src/App.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; export default function App() { return (

StyleX + Rspack + unplugin

); } const styles = stylex.create({ app: { minHeight: '100vh', display: 'grid', placeItems: 'center', backgroundColor: '#f7f5ff', }, title: { color: 'rebeccapurple', fontSize: 32, fontWeight: 700, }, }); ================================================ FILE: examples/example-rspack/src/global.css ================================================ /* Ensure Rspack produces a CSS asset to inject StyleX into */ :root { --brand-color: #663399; } body { margin: 0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; } ================================================ FILE: examples/example-rspack/src/main.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import './global.css'; import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.jsx'; const root = createRoot(document.getElementById('root')); root.render(); ================================================ FILE: examples/example-storybook/.babelrc.cjs ================================================ const path = require('path') module.exports = { presets: [ ['@babel/preset-react', {runtime: 'automatic'}], '@babel/preset-typescript' ], plugins: [ [ '@stylexjs/babel-plugin', { debug: process.env.NODE_ENV === 'development', unstable_moduleResolution: { type: 'commonJS' } } ] ] } ================================================ FILE: examples/example-storybook/.storybook/main.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import type { StorybookConfig } from '@storybook/react-vite'; import { join, dirname } from 'node:path'; function getAbsolutePath(value: string): any { return dirname(require.resolve(join(value, 'package.json'))); } const config: StorybookConfig = { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', ], addons: [ getAbsolutePath('@storybook/addon-links'), getAbsolutePath('@storybook/addon-docs'), getAbsolutePath('@chromatic-com/storybook'), ], framework: { name: getAbsolutePath('@storybook/react-vite'), options: {}, }, typescript: { /* infer property docs from typescript types */ reactDocgen: 'react-docgen-typescript', reactDocgenTypescriptOptions: { shouldExtractLiteralValuesFromEnum: true, shouldRemoveUndefinedFromOptional: true, propFilter: (prop) => { /* does property have documentation? */ const hasDoc = prop.description !== ''; /* is property defined in external dependency package? */ const isExternal = prop.parent && /node_modules/.test(prop.parent.fileName); return hasDoc && !isExternal; }, }, }, core: { /* use builder-vite for fast startup times and near-instant HMR */ builder: { name: '@storybook/builder-vite', options: { /* use a different config for static build for self-contained setup to include external deps (like react) into the served package */ viteConfigPath: './vite-storybook.config.ts', }, }, disableTelemetry: true, }, }; export default config; ================================================ FILE: examples/example-storybook/.storybook/preview.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import '../stories/styles.css'; /** @type { import('@storybook/react-vite').Preview } */ const preview = { parameters: { controls: { matchers: { color: /(background|color)$/i, date: /Date$/i, }, }, }, }; export default preview; ================================================ FILE: examples/example-storybook/.storybook/vitest.setup.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import * as a11yAddonAnnotations from '@storybook/addon-a11y/preview'; import { setProjectAnnotations } from '@storybook/react-vite'; import * as projectAnnotations from './preview'; // This is an important step to apply the right configuration when testing your stories. // More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]); ================================================ FILE: examples/example-storybook/README.md ================================================ # Storybook example using StyleX This is a [Storybook](https://storybook.js.org/) project that demonstrates how to use StyleX with component documentation and testing. ## Getting Started First, run the development server: ```bash npm run storybook ``` Open [http://localhost:6006](http://localhost:6006) with your browser to see the Storybook interface. You can start editing the components by modifying files in the `stories/` directory. Storybook will automatically reload as you edit the files. ## Static build of the Storybook To build the static Storybook for deployment: ```bash npm run build-storybook ``` ## Learn More To learn more about Storybook and StyleX, take a look at the following resources: - [Storybook Documentation](https://storybook.js.org/docs) - learn about Storybook features and API. - [StyleX Documentation](https://stylexjs.com/docs) - learn about StyleX features and usage. - [Learn Storybook](https://storybook.js.org/tutorials) - interactive Storybook tutorials. You can check out [the Storybook GitHub repository](https://github.com/storybookjs/storybook) and [the StyleX GitHub repository](https://github.com/facebook/stylex) - your feedback and contributions are welcome! ================================================ FILE: examples/example-storybook/eslint.config.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import stylexPlugin from '@stylexjs/eslint-plugin'; import tseslint, { parser as typescriptParser } from 'typescript-eslint'; import storybookPlugin from 'eslint-plugin-storybook'; import importPlugin from 'eslint-plugin-import'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const typescriptPlugin = tseslint.config({ files: ['**/*.ts', '**/*.tsx'], extends: [...tseslint.configs.recommended], rules: { '@typescript-eslint/no-unused-vars': [ 'error', { caughtErrors: 'none', argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_', varsIgnorePattern: '^_.', }, ], '@typescript-eslint/object-curly-spacing': ['warn'], '@typescript-eslint/consistent-type-imports': ['error'], 'no-undef': 'off', }, }); export default [ { ignores: ['postcss.config.*', 'storybook-static/'], }, { plugins: { '@stylexjs': stylexPlugin, ...typescriptPlugin, ...storybookPlugin.configs['flat/recommended'], import: importPlugin, }, languageOptions: { parser: typescriptParser, parserOptions: { ecmaVersion: 12, sourceType: 'module', tsconfigRootDir: __dirname, ecmaFeatures: { jsx: true, }, }, }, settings: { 'import/ignore': ['node_modules'], react: { version: 'detect', }, }, rules: { '@stylexjs/valid-styles': 'error', 'ft-flow/space-after-type-colon': 0, 'ft-flow/no-types-missing-file-annotation': 0, 'ft-flow/generic-spacing': 0, }, }, ]; ================================================ FILE: examples/example-storybook/package.json ================================================ { "private": true, "name": "example-storybook", "version": "0.18.1", "scripts": { "example:dev": "storybook dev -p 6006 --no-open", "storybook": "storybook dev -p 6006 --no-open", "build-storybook": "storybook build", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix" }, "devDependencies": { "@chromatic-com/storybook": "^4.1.1", "@storybook/addon-a11y": "^9.1.7", "@storybook/addon-docs": "^9.1.7", "@storybook/addon-links": "^9.1.7", "@storybook/addon-vitest": "^9.1.7", "@storybook/react-vite": "^9.1.7", "@stylexjs/babel-plugin": "0.18.1", "@stylexjs/eslint-plugin": "0.18.1", "@stylexjs/postcss-plugin": "0.18.1", "@stylexjs/stylex": "0.18.1", "@typescript-eslint/eslint-plugin": "^8.44.0", "@typescript-eslint/parser": "^8.44.0", "@vitejs/plugin-react": "^5.0.3", "@vitest/browser": "^4.0.13", "@vitest/coverage-v8": "^4.0.13", "autoprefixer": "^10.4.21", "eslint": "^9.36.0", "eslint-plugin-import": "^2.32.0", "eslint-plugin-storybook": "^9.1.7", "playwright": "^1.55.0", "postcss-nesting": "^13.0.2", "prop-types": "^15.8.1", "rollup-plugin-jsx-remove-attributes": "^3.1.1", "rollup-plugin-node-externals": "^8.1.1", "storybook": "^9.1.19", "typescript-eslint": "^8.44.0", "vite-plugin-dts": "^4.5.4", "vitest": "^4.0.13" } } ================================================ FILE: examples/example-storybook/postcss.config.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import autoprefixer from 'autoprefixer'; import nesting from 'postcss-nesting'; import stylex from '@stylexjs/postcss-plugin'; import babelConfig from './.babelrc.cjs'; /** @type {import('postcss-load-config').Config} */ const config = { plugins: [ nesting, stylex({ include: ['stories/**/*.{ts,tsx}'], useCSSLayers: process.env.NODE_ENV !== 'production', babelConfig: { babelrc: false, parserOpts: { plugins: ['typescript', 'jsx'], }, plugins: babelConfig.plugins, }, }), autoprefixer, ], }; export default config; ================================================ FILE: examples/example-storybook/stories/Button.stories.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import { fn } from 'storybook/test'; import { Button } from './Button'; import { Meta, StoryObj } from '@storybook/react-vite'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta: Meta = { title: 'Example/Button', component: Button, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout layout: 'centered', }, // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs tags: ['autodocs'], // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args args: { onClick: fn() }, argTypes: { variant: { control: { type: 'select' }, options: ['primary', 'secondary', 'danger'], description: 'The variant of the button', }, size: { control: { type: 'select' }, options: ['small', 'medium', 'large'], }, }, }; export default meta; type Story = StoryObj; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args export const Primary: Story = { args: { variant: 'primary', label: 'Primary Button', }, }; export const Secondary: Story = { args: { variant: 'secondary', label: 'Secondary Button', }, }; export const Danger: Story = { args: { variant: 'danger', label: 'Danger Button', }, }; export const Small: Story = { args: { size: 'small', label: 'Small Button', }, }; export const Medium: Story = { args: { size: 'medium', label: 'Medium Button', }, }; export const Large: Story = { args: { size: 'large', label: 'Large Button', }, }; ================================================ FILE: examples/example-storybook/stories/Button.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import { FC } from 'react'; import * as stylex from '@stylexjs/stylex'; export const buttonStyles = stylex.create({ base: { fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', fontWeight: 500, cursor: 'pointer', borderWidth: 0, borderStyle: 'none', borderColor: 'transparent', borderRadius: 6, transition: 'all 0.2s ease', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', textDecoration: 'none', transform: { default: 'translateY(0)', ':hover': 'translateY(-1px)', ':active': 'translateY(0)', }, boxShadow: { default: 'none', ':hover': '0 4px 8px rgba(0, 0, 0, 0.12)', }, }, primary: { backgroundColor: { default: '#0066cc', ':hover': '#0052a3', }, color: 'white', }, secondary: { backgroundColor: { default: '#f5f5f5', ':hover': '#e8e8e8', }, color: '#333', borderWidth: 1, borderStyle: 'solid', borderColor: '#ddd', }, danger: { backgroundColor: { default: '#dc3545', ':hover': '#c82333', }, color: 'white', }, small: { fontSize: 12, padding: '6px 12px', minHeight: 28, }, medium: { fontSize: 14, padding: '8px 16px', minHeight: 36, }, large: { fontSize: 16, padding: '12px 24px', minHeight: 44, }, }); type ButtonProps = { /** * The size of the button * @default 'medium' */ size?: 'small' | 'medium' | 'large'; /** The variant of the button * @default 'primary' */ variant?: 'primary' | 'secondary' | 'danger'; /** * The label of the button * @example 'Click me' */ label: string; /** * Function to call when the button is clicked */ onClick?: () => void; }; export const Button: FC = ({ size = 'medium', variant = 'primary', label, onClick, }) => { return ( ); }; ================================================ FILE: examples/example-storybook/stories/Card.stories.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import type { Meta, StoryObj } from '@storybook/react'; import { Card } from './Card'; const meta: Meta = { title: 'Example/Card', component: Card, argTypes: { elevated: { control: 'boolean' }, title: { control: 'text' }, content: { control: 'text' }, }, parameters: { layout: 'centered', }, tags: ['autodocs'], }; export default meta; type Story = StoryObj; export const Default: Story = { args: { title: 'Card Title', content: 'This is some example content for the card component.', }, }; export const Elevated: Story = { args: { title: 'Elevated Card', content: 'This card has an elevated shadow effect.', elevated: true, }, }; ================================================ FILE: examples/example-storybook/stories/Card.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import { FC } from 'react'; import * as stylex from '@stylexjs/stylex'; export const cardStyles = stylex.create({ base: { backgroundColor: 'white', borderRadius: 8, padding: 16, boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)', borderWidth: 1, borderStyle: 'solid', borderColor: '#e0e0e0', maxWidth: 300, }, title: { fontSize: 18, fontWeight: 'bold', marginBottom: 8, color: '#333', }, content: { fontSize: 14, lineHeight: 1.5, color: '#666', }, elevated: { boxShadow: '0 4px 8px rgba(0, 0, 0, 0.15)', }, }); type CardProps = { title: string; content: string; elevated?: boolean; }; export const Card: FC = ({ title, content, elevated = false }) => { return (

{title}

{content}

); }; ================================================ FILE: examples/example-storybook/stories/styles.css ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ /* StyleX styles will be injected here by PostCSS */ @stylex; ================================================ FILE: examples/example-storybook/vite-storybook.config.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ /// import react from '@vitejs/plugin-react'; import removeTestIdAttribute from 'rollup-plugin-jsx-remove-attributes'; import externals from 'rollup-plugin-node-externals'; import { defineConfig } from 'vite'; import dts from 'vite-plugin-dts'; import type { PluginOption, UserConfig } from 'vite'; export const plugins = [ react({ babel: { babelrc: true, }, }), dts({ entryRoot: 'stories/', }), removeTestIdAttribute({ attributes: ['data-testid'], usage: 'vite', }), ] as PluginOption[]; export const config: UserConfig = { plugins: [...plugins, externals()], }; // https://vitejs.dev/config/ export default defineConfig(() => { return { ...config, }; }); ================================================ FILE: examples/example-storybook/vitest.config.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { defineConfig } from 'vitest/config'; import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'; const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); // More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon export default defineConfig({ test: { projects: [ { extends: true, plugins: [ // The plugin will run tests for the stories defined in your Storybook config // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest storybookTest({ configDir: path.join(dirname, '.storybook') }), ], test: { name: 'storybook', browser: { enabled: true, headless: true, provider: 'playwright', instances: [{ browser: 'chromium' }], }, setupFiles: ['.storybook/vitest.setup.ts'], }, }, ], }, }); ================================================ FILE: examples/example-vite/README.md ================================================ # Vite Example with StyleX This project shows how to wire StyleX into a Vite + React application using `@stylexjs/unplugin`. The plugin compiles StyleX at build time, aggregates the generated CSS, and injects it into the CSS emitted by Vite. ### Prerequisites - Node.js 18+ - [`vite`](https://vite.dev/) and `@vitejs/plugin-react` - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Vite configuration (`vite.config.mjs`) ```javascript import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [stylex.vite(), react()], }); ``` - `stylex.vite()` enables StyleX transforms for both dev and build. - React Fast Refresh continues to work because the StyleX plugin runs before `@vitejs/plugin-react`. ## CSS entry point (`src/index.css`) The app imports `src/index.css` so that Vite always emits a CSS asset. During `npm run example:build`, the StyleX plugin appends the aggregated styles to that file (defaulting to `style.css`/`index.css`). ## Commands ```bash # Start the Vite dev server with StyleX transforms npm run example:dev # Production build with a single StyleX CSS injection npm run example:build # Preview the production build locally npm run example:serve ``` Run these scripts from `examples/example-vite`. The output `dist/` folder contains both the JS bundle and the StyleX-enriched CSS. ================================================ FILE: examples/example-vite/index.html ================================================ StyleX + Vite
================================================ FILE: examples/example-vite/package.json ================================================ { "name": "example-vite", "private": true, "version": "0.18.1", "description": "Example: StyleX with Vite via @stylexjs/unplugin", "scripts": { "example:dev": "vite", "example:build": "vite build", "example:serve": "vite preview" }, "dependencies": { "react": "^19.2.0", "react-dom": "^19.2.0", "@stylexjs/stylex": "0.18.1", "@stylexjs/shared-ui": "0.18.1" }, "devDependencies": { "vite": "^7.2.4", "@stylexjs/unplugin": "0.18.1", "@vitejs/plugin-react": "latest" } } ================================================ FILE: examples/example-vite/src/App.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; import { Button } from '@stylexjs/shared-ui'; import { tokens } from '@stylexjs/shared-ui/tokens.stylex'; export default function App() { return (

StyleX + Vite + unplugin

); } const styles = stylex.create({ app: { minHeight: '100%', display: 'grid', placeItems: 'center', }, title: { color: tokens.primaryColor, fontSize: 28, fontWeight: 700, }, }); ================================================ FILE: examples/example-vite/src/index.css ================================================ /* Ensure a CSS asset exists for StyleX to append to at build time */ :root { --bg: #f8f9fb; } html, body, #root { height: 100%; } body { margin: 0; background: var(--bg); } ================================================ FILE: examples/example-vite/src/main.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import './index.css'; import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.jsx'; createRoot(document.getElementById('root')).render(); ================================================ FILE: examples/example-vite/vite.config.mjs ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { defineConfig } from 'vite'; import stylex from '@stylexjs/unplugin'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [stylex.vite(), react()], build: { // Ensure CSS is extracted into assets (default), we also import src/index.css }, }); ================================================ FILE: examples/example-vite-react/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/example-vite-react/README.md ================================================ # React + Vite + StyleX This example is a TypeScript-ready React project that runs on Vite while compiling StyleX through `@stylexjs/unplugin`. The plugin extracts StyleX styles at build time and appends them to the CSS emitted by Vite, so the browser only downloads a single stylesheet. ### Prerequisites - Node.js 18+ - [`vite`](https://vite.dev/) with `@vitejs/plugin-react` - `typescript` and `tsc -b` for type-checking the build - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Vite configuration (`vite.config.ts`) ```ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [stylex.vite(), react()], }); ``` - `stylex.vite()` runs before the React plugin to keep Fast Refresh intact. - The TypeScript-aware ESLint + compiler setup already points to the correct `tsconfigRootDir`, so no extra configuration is required. ## CSS entry point (`src/index.css`) The root component imports `src/index.css`, ensuring that Vite emits a CSS file in both dev and build. During `npm run example:build`, the StyleX plugin appends its aggregated output to that asset (defaulting to `style.css`/`index.css`). ## Commands ```bash # HMR-ready dev server with StyleX transforms npm run example:dev # Type-check + Vite build + StyleX CSS aggregation npm run example:build # Preview the production build npm run example:serve ``` Use `npm run lint` for ESLint checks (StyleX lint rules are included). Run all commands from `examples/example-vite-react`. ================================================ FILE: examples/example-vite-react/eslint.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import js from '@eslint/js'; import globals from 'globals'; import reactHooks from 'eslint-plugin-react-hooks'; import reactRefresh from 'eslint-plugin-react-refresh'; import tseslint from 'typescript-eslint'; import { defineConfig, globalIgnores } from 'eslint/config'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export default defineConfig([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite, ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, parserOptions: { tsconfigRootDir: __dirname, }, }, }, ]); ================================================ FILE: examples/example-vite-react/index.html ================================================ example-vite-react
================================================ FILE: examples/example-vite-react/package.json ================================================ { "name": "example-vite-react", "private": true, "version": "0.18.1", "type": "module", "scripts": { "example:dev": "vite", "example:build": "tsc -b && vite build", "lint": "eslint .", "example:serve": "vite preview" }, "dependencies": { "react": "^19.2.0", "react-dom": "^19.2.0", "@stylexjs/stylex": "0.18.1", "@stylexjs/shared-ui": "0.18.1" }, "devDependencies": { "@eslint/js": "^9.36.0", "@types/node": "^24.6.0", "@types/react": "^19.2.6", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.0.4", "@stylexjs/unplugin": "0.18.1", "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9.36.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.22", "globals": "^16.4.0", "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", "vite": "^7.1.7" } } ================================================ FILE: examples/example-vite-react/src/App.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { useState } from 'react'; import reactLogo from './assets/react.svg'; import viteLogo from '/vite.svg'; import * as stylex from '@stylexjs/stylex'; import { Button } from '@stylexjs/shared-ui'; import { tokens } from '@stylexjs/shared-ui/tokens.stylex'; export default function App() { const [count, setCount] = useState(0); return (

Vite + React

Edit src/App.tsx and save to test HMR

Click on the Vite and React logos to learn more

); } const spin = stylex.keyframes({ from: { transform: 'rotate(0deg)' }, to: { transform: 'rotate(360deg)' }, }); const styles = stylex.create({ container: { minHeight: '100vh', display: 'grid', placeItems: 'center', padding: '2rem', textAlign: 'center', }, inner: { maxWidth: 1280, }, logo: { height: '6em', padding: '1.5em', willChange: 'filter', transitionProperty: 'filter', transitionDuration: '300ms', filter: { ':hover': 'drop-shadow(0 0 2em #646cffaa)' }, }, reactLogo: { filter: { ':hover': 'drop-shadow(0 0 2em #61dafbaa)' }, }, animated: { animationName: { '@media (prefers-reduced-motion: no-preference)': spin }, animationDuration: { '@media (prefers-reduced-motion: no-preference)': '20s', }, animationTimingFunction: { '@media (prefers-reduced-motion: no-preference)': 'linear', }, animationIterationCount: { '@media (prefers-reduced-motion: no-preference)': 'infinite', }, }, card: { padding: '2em' }, readTheDocs: { color: '#888' }, link: { fontWeight: 500, color: '#646cff', textDecoration: 'none', }, linkHover: { color: { default: null, ':hover': '#535bf2' } }, h1: { fontSize: '3.2em', lineHeight: '1.1', color: tokens.primaryColor }, button: { borderRadius: 8, borderWidth: 1, borderStyle: 'solid', borderColor: 'transparent', padding: '0.6em 1.2em', fontSize: '1em', fontWeight: 500, fontFamily: 'inherit', backgroundColor: 'hotpink', color: 'white', cursor: 'pointer', transitionProperty: 'border-color', transitionDuration: '250ms', }, buttonInteractive: { borderColor: { ':hover': '#646cff' }, outline: { ':focus-visible': '4px auto -webkit-focus-ring-color' }, }, }); ================================================ FILE: examples/example-vite-react/src/index.css ================================================ /* Placeholder to ensure Vite emits a CSS asset for StyleX aggregation. */ :root { --stylex-injection: 0; } ================================================ FILE: examples/example-vite-react/src/main.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; // Keep a minimal CSS to ensure a CSS asset exists for StyleX injection import './index.css'; import App from './App.tsx'; createRoot(document.getElementById('root')!).render( , ); ================================================ FILE: examples/example-vite-react/tsconfig.app.json ================================================ { "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "types": ["vite/client"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["src"] } ================================================ FILE: examples/example-vite-react/tsconfig.json ================================================ { "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] } ================================================ FILE: examples/example-vite-react/tsconfig.node.json ================================================ { "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2023", "lib": ["ES2023"], "module": "ESNext", "types": ["node"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["vite.config.ts"] } ================================================ FILE: examples/example-vite-react/vite.config.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import stylex from '@stylexjs/unplugin'; // https://vite.dev/config/ export default defineConfig({ plugins: [stylex.vite(), react({})], }); ================================================ FILE: examples/example-vite-rsc/.gitignore ================================================ node_modules dist ================================================ FILE: examples/example-vite-rsc/README.md ================================================ # Vite + React Server Components + StyleX This example layers [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc) on top of React, while `@stylexjs/unplugin` compiles StyleX at build time. Each RSC/SSR/client environment receives a single CSS asset with the aggregated StyleX output appended. ### Prerequisites - Node.js 18+ - Vite plus `@vitejs/plugin-rsc` and `@vitejs/plugin-react` - `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Vite configuration (`vite.config.ts`) ```ts import rsc from '@vitejs/plugin-rsc'; import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [ rsc({ /* RSC environment inputs configured below */ }), react(), stylex.vite(), ], environments: { rsc: { build: { rollupOptions: { input: { index: './src/framework/entry.rsc.tsx' } }, }, }, ssr: { build: { rollupOptions: { input: { index: './src/framework/entry.ssr.tsx' } }, }, }, client: { build: { rollupOptions: { input: { index: './src/framework/entry.browser.tsx' }, }, }, }, }, }); ``` - `stylex.vite()` automatically runs for each environment, so every output bundle gets the correct CSS appended. - The example keeps the default plugin options, but you can pass `useCSSLayers`, custom import sources, etc. if needed. ## CSS entry point (`src/index.css`) The framework root imports `src/index.css` so each RSC build emits a CSS asset. During `npm run example:build`, the StyleX plugin appends the aggregated styles from both client and server components to that file. ## Dev-only CSS/runtime injection RSC environments own their HTML shell, so `src/root.tsx` injects the virtual StyleX runtime and stylesheet while `import.meta.env.DEV` is true: ```tsx { import.meta.env.DEV ? ( <> rscStream, ); // browser root component to (re-)render RSC payload as state function BrowserRoot() { const [payload, setPayload_] = React.useState(initialPayload); React.useEffect(() => { setPayload = (v) => React.startTransition(() => setPayload_(v)); }, [setPayload_]); // re-fetch/render on client side navigation React.useEffect(() => { return listenNavigation(() => fetchRscPayload()); }, []); return payload.root; } // re-fetch RSC and trigger re-rendering async function fetchRscPayload() { const payload = await createFromFetch( fetch(window.location.href), ); setPayload(payload); } // register a handler which will be internally called by React // on server function request after hydration. setServerCallback(async (id, args) => { const url = new URL(window.location.href); const temporaryReferences = createTemporaryReferenceSet(); const payload = await createFromFetch( fetch(url, { method: 'POST', body: await encodeReply(args, { temporaryReferences }), headers: { 'x-rsc-action': id, }, }), { temporaryReferences }, ); setPayload(payload); return payload.returnValue; }); // hydration const browserRoot = ( ); hydrateRoot(document, browserRoot, { formState: initialPayload.formState, }); // implement server HMR by triggering re-fetch/render of RSC upon server code change if (import.meta.hot) { import.meta.hot.on('rsc:update', () => { fetchRscPayload(); }); } } // a little helper to setup events interception for client side navigation function listenNavigation(onNavigation: () => void) { window.addEventListener('popstate', onNavigation); const oldPushState = window.history.pushState; window.history.pushState = function (...args) { const res = oldPushState.apply(this, args); onNavigation(); return res; }; const oldReplaceState = window.history.replaceState; window.history.replaceState = function (...args) { const res = oldReplaceState.apply(this, args); onNavigation(); return res; }; function onClick(e: MouseEvent) { const link = (e.target as Element).closest('a'); if ( link && link instanceof HTMLAnchorElement && link.href && (!link.target || link.target === '_self') && link.origin === location.origin && !link.hasAttribute('download') && e.button === 0 && // left clicks only !e.metaKey && // open in new tab (mac) !e.ctrlKey && // open in new tab (windows) !e.altKey && // download !e.shiftKey && !e.defaultPrevented ) { e.preventDefault(); history.pushState(null, '', link.href); } } document.addEventListener('click', onClick); return () => { document.removeEventListener('click', onClick); window.removeEventListener('popstate', onNavigation); window.history.pushState = oldPushState; window.history.replaceState = oldReplaceState; }; } main(); ================================================ FILE: examples/example-vite-rsc/src/framework/entry.rsc.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { renderToReadableStream, createTemporaryReferenceSet, decodeReply, loadServerAction, decodeAction, decodeFormState, } from '@vitejs/plugin-rsc/rsc'; import type { ReactFormState } from 'react-dom/client'; import { Root } from '../root.tsx'; // The schema of payload which is serialized into RSC stream on rsc environment // and deserialized on ssr/client environments. export type RscPayload = { // this demo renders/serializes/deserizlies entire root html element // but this mechanism can be changed to render/fetch different parts of components // based on your own route conventions. root: React.ReactNode; // server action return value of non-progressive enhancement case returnValue?: unknown; // server action form state (e.g. useActionState) of progressive enhancement case formState?: ReactFormState; }; // the plugin by default assumes `rsc` entry having default export of request handler. // however, how server entries are executed can be customized by registering // own server handler e.g. `@cloudflare/vite-plugin`. export default async function handler(request: Request): Promise { // handle server function request const isAction = request.method === 'POST'; let returnValue: unknown | undefined; let formState: ReactFormState | undefined; let temporaryReferences: unknown | undefined; if (isAction) { // x-rsc-action header exists when action is called via `ReactClient.setServerCallback`. const actionId = request.headers.get('x-rsc-action'); if (actionId) { const contentType = request.headers.get('content-type'); const body = contentType?.startsWith('multipart/form-data') ? await request.formData() : await request.text(); temporaryReferences = createTemporaryReferenceSet(); const args = await decodeReply(body, { temporaryReferences }); const action = await loadServerAction(actionId); returnValue = await action.apply(null, args); } else { // otherwise server function is called via `
` // before hydration (e.g. when javascript is disabled). // aka progressive enhancement. const formData = await request.formData(); const decodedAction = await decodeAction(formData); const result = await decodedAction(); formState = await decodeFormState(result, formData); } } // serialization from React VDOM tree to RSC stream. // we render RSC stream after handling server function request // so that new render reflects updated state from server function call // to achieve single round trip to mutate and fetch from server. const url = new URL(request.url); const rscPayload: RscPayload = { root: , formState, returnValue, }; const rscOptions = { temporaryReferences }; const rscStream = renderToReadableStream(rscPayload, rscOptions); // respond RSC stream without HTML rendering based on framework's convention. // here we use request header `content-type`. // additionally we allow `?__rsc` and `?__html` to easily view payload directly. const isRscRequest = (!request.headers.get('accept')?.includes('text/html') && !url.searchParams.has('__html')) || url.searchParams.has('__rsc'); if (isRscRequest) { return new Response(rscStream, { headers: { 'content-type': 'text/x-component;charset=utf-8', vary: 'accept', }, }); } // Delegate to SSR environment for html rendering. // The plugin provides `loadModule` helper to allow loading SSR environment entry module // in RSC environment. however this can be customized by implementing own runtime communication // e.g. `@cloudflare/vite-plugin`'s service binding. const ssrEntryModule = await import.meta.viteRsc.loadModule< typeof import('./entry.ssr.tsx') >('ssr', 'index'); const htmlStream = await ssrEntryModule.renderHTML(rscStream, { formState, // allow quick simulation of javascript disabled browser debugNojs: url.searchParams.has('__nojs'), }); // respond html return new Response(htmlStream, { headers: { 'Content-type': 'text/html', vary: 'accept', }, }); } if (import.meta.hot) { import.meta.hot.accept(); } ================================================ FILE: examples/example-vite-rsc/src/framework/entry.ssr.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { createFromReadableStream } from '@vitejs/plugin-rsc/ssr'; import React from 'react'; import type { ReactFormState } from 'react-dom/client'; import { renderToReadableStream } from 'react-dom/server.edge'; import { injectRSCPayload } from 'rsc-html-stream/server'; import type { RscPayload } from './entry.rsc'; export async function renderHTML( rscStream: ReadableStream, options: { formState?: ReactFormState; nonce?: string; debugNojs?: boolean; }, ) { // duplicate one RSC stream into two. // - one for SSR (ReactClient.createFromReadableStream below) // - another for browser hydration payload by injecting . const [rscStream1, rscStream2] = rscStream.tee(); // deserialize RSC stream back to React VDOM let payload: Promise | undefined; function SsrRoot() { // deserialization needs to be kicked off inside ReactDOMServer context // for ReactDomServer preinit/preloading to work payload ??= createFromReadableStream(rscStream1); return {React.use(payload).root}; } // Add an empty component in between `SsrRoot` and user `root` to avoid React SSR bugs. // SsrRoot (use) // => FixSsrThenable // => root (which potentially has `lazy` + `use`) // https://github.com/facebook/react/issues/33937#issuecomment-3091349011 function FixSsrThenable(props: React.PropsWithChildren) { return props.children; } // render html (traditional SSR) const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent('index'); const htmlStream = await renderToReadableStream(, { bootstrapScriptContent: options?.debugNojs ? undefined : bootstrapScriptContent, nonce: options?.nonce, formState: options?.formState, }); let responseStream: ReadableStream = htmlStream; if (!options?.debugNojs) { // initial RSC stream is injected in HTML stream as // using utility made by devongovett https://github.com/devongovett/rsc-html-stream responseStream = responseStream.pipeThrough( injectRSCPayload(rscStream2, { nonce: options?.nonce, }), ); } return responseStream; } ================================================ FILE: examples/example-vite-rsc/src/index.css ================================================ :root { --stylex-injection: 0; } ================================================ FILE: examples/example-vite-rsc/src/root.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import './index.css'; // keep minimal to ensure CSS asset exists in build import viteLogo from '/vite.svg'; import { DevStyleXInject } from './DevStyleXInject'; import { getServerCounter, updateServerCounter } from './action.tsx'; import reactLogo from './assets/react.svg'; import { ClientCounter } from './client.tsx'; import * as stylex from '@stylexjs/stylex'; export function Root(props: { url: URL }) { return ( Vite + RSC + StyleX ); } function App(props: { url: URL }) { return (

Vite + RSC

Request URL: {props.url?.href}
  • Edit src/client.tsx to test client HMR.
  • Edit src/root.tsx to test server HMR.
  • Visit{' '} ?__rsc {' '} to view RSC stream payload.
  • Visit{' '} ?__nojs {' '} to test server action without js enabled.
); } const styles = stylex.create({ root: { margin: 0, minHeight: '100vh', display: 'grid', placeItems: 'center', textAlign: 'center', }, logo: { height: '6em', padding: '1.5em', willChange: 'filter', transitionProperty: 'filter', transitionDuration: '300ms', filter: { default: null, ':hover': 'drop-shadow(0 0 2em #646cffaa)', }, }, reactLogo: { filter: { default: null, ':hover': 'drop-shadow(0 0 2em #61dafbaa)', }, }, card: { padding: '2em' }, readTheDocs: { color: '#888' }, h1: { fontSize: '3.2em', lineHeight: '1.1' }, link: { fontWeight: 500, color: '#646cff', textDecoration: 'none' }, linkHover: { color: { ':hover': '#535bf2' } }, button: { borderRadius: 8, borderWidth: 1, borderStyle: 'solid', borderColor: 'transparent', padding: '0.6em 1.2em', fontSize: '1em', fontWeight: 500, fontFamily: 'inherit', backgroundColor: 'green', color: 'white', cursor: 'pointer', transitionProperty: 'border-color', transitionDuration: '250ms', }, }); ================================================ FILE: examples/example-vite-rsc/tsconfig.json ================================================ { "compilerOptions": { "erasableSyntaxOnly": true, "allowImportingTsExtensions": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "skipLibCheck": true, "verbatimModuleSyntax": true, "noEmit": true, "moduleResolution": "Bundler", "module": "ESNext", "target": "ESNext", "lib": ["ESNext", "DOM", "DOM.Iterable"], "types": ["vite/client", "@vitejs/plugin-rsc/types"], "jsx": "react-jsx" } } ================================================ FILE: examples/example-vite-rsc/vite.config.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import rsc from '@vitejs/plugin-rsc'; import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; import stylex from '@stylexjs/unplugin'; export default defineConfig({ plugins: [ rsc({ // `entries` option is only a shorthand for specifying each `rollupOptions.input` below // > entries: { rsc, ssr, client }, // // by default, the plugin setup request handler based on `default export` of `rsc` environment `rollupOptions.input.index`. // This can be disabled when setting up own server handler e.g. `@cloudflare/vite-plugin`. // > serverHandler: false }), // use any of react plugins https://github.com/vitejs/vite-plugin-react // to enable client component HMR react(), // @ts-expect-error stylex.vite({}), // use https://github.com/antfu-collective/vite-plugin-inspect // to understand internal transforms required for RSC. // import("vite-plugin-inspect").then(m => m.default()), ], // specify entry point for each environment. // (currently the plugin assumes `rollupOptions.input.index` for some features.) environments: { // `rsc` environment loads modules with `react-server` condition. // this environment is responsible for: // - RSC stream serialization (React VDOM -> RSC stream) // - server functions handling rsc: { build: { rollupOptions: { input: { index: './src/framework/entry.rsc.tsx', }, }, }, }, // `ssr` environment loads modules without `react-server` condition. // this environment is responsible for: // - RSC stream deserialization (RSC stream -> React VDOM) // - traditional SSR (React VDOM -> HTML string/stream) ssr: { build: { rollupOptions: { input: { index: './src/framework/entry.ssr.tsx', }, }, }, }, // client environment is used for hydration and client-side rendering // this environment is responsible for: // - RSC stream deserialization (RSC stream -> React VDOM) // - traditional CSR (React VDOM -> Browser DOM tree mount/hydration) // - refetch and re-render RSC // - calling server functions client: { build: { rollupOptions: { input: { index: './src/framework/entry.browser.tsx', }, }, }, }, }, }); ================================================ FILE: examples/example-waku/.gitignore ================================================ node_modules dist .env* *.tsbuildinfo .cache .DS_Store *.pem ================================================ FILE: examples/example-waku/README.md ================================================ # Waku + StyleX This example shows how to integrate StyleX into a Waku application. The Vite layer powering Waku runs `@stylexjs/unplugin`, which compiles StyleX modules, aggregates the generated CSS, and appends it to the emitted CSS assets so the browser only loads a single stylesheet. ### Prerequisites - Node.js 18+ - [`waku`](https://waku.gg) CLI/runtime - `@stylexjs/stylex` and `@stylexjs/unplugin` ## Install dependencies ```bash npm install ``` ## Waku/Vite configuration (`waku.config.ts`) ```ts import react from '@vitejs/plugin-react'; import stylex from '@stylexjs/unplugin'; import { defineConfig } from 'waku/config'; export default defineConfig({ vite: { plugins: [ stylex.vite({ useCSSLayers: true, devMode: 'css-only', devPersistToDisk: true, runtimeInjection: false, }), react({ babel: { plugins: ['babel-plugin-react-compiler'] } }), ], }, }); ``` - `devMode: 'css-only'` exposes the `/virtual:stylex.css` endpoint in dev. - `devPersistToDisk` lets multiple Waku environments (client/server) share StyleX rules while developing. ## CSS entry point (`src/global.css`) `src/global.css` keeps a minimal reset so Waku always emits at least one CSS asset. The StyleX plugin appends its aggregated output to that file during `npm run example:build`. ## Dev-only CSS injection & HMR Because Waku owns the root HTML shell, the layout mounts a tiny client component that adds the dev stylesheet link _and_ triggers a JS import so Vite registers StyleX for HMR: ```tsx // src/components/DevStyleXInject.tsx function DevStyleXInjectImpl() { useEffect(() => { import('virtual:stylex:css-only'); }, []); return ; } export const DevStyleXInject = import.meta.env.DEV ? DevStyleXInjectImpl : () => null; ``` Add `` near the top of `src/pages/_layout.tsx`. The `link` ensures the aggregated StyleX CSS loads in dev, and the `useEffect` import keeps CSS hot reload working even though the root HTML is owned by Waku instead of Vite. ## Commands ```bash # Start the Waku dev server with live StyleX transforms npm run example:dev # Production build (all Waku environments + aggregated StyleX CSS) npm run example:build # Preview the production build npm run example:serve ``` Run the scripts from `examples/example-waku`. The generated `dist/` output already contains the StyleX CSS bundled into the Waku client assets. ================================================ FILE: examples/example-waku/package.json ================================================ { "name": "example-waku", "version": "0.18.1", "type": "module", "private": true, "scripts": { "example:dev": "waku dev", "example:build": "waku build", "example:serve": "waku start" }, "dependencies": { "@stylexjs/stylex": "0.18.1", "react": "^19.2.3", "react-dom": "^19.2.3", "react-server-dom-webpack": "19.2.1", "waku": "1.0.0-alpha.0", "@stylexjs/shared-ui": "0.18.1" }, "devDependencies": { "@stylexjs/unplugin": "0.18.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "5.1.0", "babel-plugin-react-compiler": "1.0.0", "typescript": "5.9.3" } } ================================================ FILE: examples/example-waku/public/robots.txt ================================================ User-agent: * Disallow: /RSC/ ================================================ FILE: examples/example-waku/src/components/DevStyleXInject.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use client'; import { useEffect } from 'react'; function DevStyleXInjectImpl() { useEffect(() => { if (import.meta.env.DEV) { // @ts-ignore import('virtual:stylex:css-only'); } }, []); return ; } export function DevStyleXInject({ cssHref }: { cssHref: string }) { return import.meta.env.DEV ? ( ) : ( ); } ================================================ FILE: examples/example-waku/src/components/counter.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use client'; import * as stylex from '@stylexjs/stylex'; import { useState } from 'react'; import { Button } from '@stylexjs/shared-ui'; import { tokens } from '@stylexjs/shared-ui/tokens.stylex'; export function Counter() { const [count, setCount] = useState(0); const handleIncrement = () => setCount((c) => c + 1); return (
Count: {count}
); } const opacity = (color: string, percentage: number) => `color-mix(in oklab, ${color} ${percentage}%, transparent)`; const styles = stylex.create({ wrapper: { marginBlockStart: '1rem', marginInline: '-1rem', borderWidth: 1, borderStyle: 'dashed', borderColor: '#60a5fa', backgroundColor: opacity(tokens.primaryColor, 5), borderRadius: 6, padding: '1rem', }, button: { marginBlockStart: '0.5rem', borderWidth: 0, }, }); ================================================ FILE: examples/example-waku/src/components/footer.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; export const Footer = () => { return ( ); }; const styles = stylex.create({ container: { padding: '1.5rem', position: { default: 'static', '@media (min-width: 1024px)': 'fixed', }, insetBlockEnd: { default: 'auto', '@media (min-width: 1024px)': 0, }, insetInlineStart: { default: 'auto', '@media (min-width: 1024px)': 0, }, }, link: { marginTop: '1rem', display: 'inline-block', textDecorationLine: 'underline', color: '#2563eb', }, }); ================================================ FILE: examples/example-waku/src/components/header.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; import { Link } from 'waku'; export const Header = () => { return (

Waku starter

); }; const styles = stylex.create({ container: { display: 'flex', alignItems: 'center', gap: '1rem', padding: '1.5rem', position: { default: null, '@media (min-width: 1024px)': 'fixed', }, top: { default: null, '@media (min-width: 1024px)': 0, }, insetInlineStart: { default: null, '@media (min-width: 1024px)': 0, }, }, title: { fontSize: '1.125rem', fontWeight: 700, letterSpacing: '-0.01em', margin: 0, }, link: { color: '#0f172a', textDecorationLine: 'none', }, }); ================================================ FILE: examples/example-waku/src/global.css ================================================ @layer reset { :root { color: #0f172a; font-family: 'Nunito', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background-color: #f5f7fb; } body { margin: 0; min-height: 100vh; background-color: #f5f7fb; } #root, #app, #__waku { min-height: 100%; } } /* StyleX CSS from @stylexjs/unplugin will be appended here at build time. */ ================================================ FILE: examples/example-waku/src/pages/_layout.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import '../global.css'; import * as stylex from '@stylexjs/stylex'; import type { ReactNode } from 'react'; import { Footer } from '../components/footer'; import { Header } from '../components/header'; import { DevStyleXInject } from '../components/DevStyleXInject'; type RootLayoutProps = { children: ReactNode }; export default async function RootLayout({ children }: RootLayoutProps) { const data = await getData(); return (
{children}
); } const getData = async () => { const data = { description: 'An internet website!', icon: '/images/favicon.png', }; return data; }; export const getConfig = async () => { return { render: 'static', } as const; }; const styles = stylex.create({ root: { minHeight: '100vh', backgroundColor: '#f5f7fb', color: '#0f172a', fontFamily: "'Nunito', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", }, main: { display: 'flex', flexDirection: 'column', gap: '1.5rem', alignItems: 'center', margin: { default: '1.5rem', '@media (min-width: 1024px)': 0, }, minHeight: { default: 'auto', '@media (min-width: 1024px)': '100svh', }, justifyContent: { default: 'flex-start', '@media (min-width: 1024px)': 'center', }, }, }); ================================================ FILE: examples/example-waku/src/pages/about.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; import { Link } from 'waku'; export default async function AboutPage() { const data = await getData(); return (
{data.title}

{data.headline}

{data.body}

Return home
); } const getData = async () => { const data = { title: 'About', headline: 'About Waku', body: 'The minimal React framework', }; return data; }; export const getConfig = async () => { return { render: 'static', } as const; }; const styles = stylex.create({ section: { display: 'flex', flexDirection: 'column', gap: '1rem', minHeight: '16rem', minWidth: '16rem', }, headline: { fontSize: '2.25rem', fontWeight: 700, letterSpacing: '-0.025em', margin: 0, }, body: { margin: 0, color: '#1f2937', fontSize: '1rem', }, link: { marginTop: '1rem', display: 'inline-block', textDecorationLine: 'underline', color: '#2563eb', }, }); ================================================ FILE: examples/example-waku/src/pages/index.tsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; import { Link } from 'waku'; import { Counter } from '../components/counter'; export default async function HomePage() { const data = await getData(); return (
{data.title}

{data.headline}

{data.body}

About page
); } const getData = async () => { const data = { title: 'Waku', headline: 'Waku', body: 'Hello world!', }; return data; }; export const getConfig = async () => { return { render: 'static', } as const; }; const styles = stylex.create({ section: { display: 'flex', flexDirection: 'column', gap: '1rem', minHeight: '16rem', minWidth: '16rem', }, headline: { fontSize: '2.25rem', fontWeight: 700, letterSpacing: '-0.025em', margin: 0, }, body: { margin: 0, color: '#1f2937', fontSize: '1rem', }, link: { marginTop: '1rem', display: 'inline-block', textDecorationLine: 'underline', color: '#2563eb', }, }); ================================================ FILE: examples/example-waku/src/pages.gen.ts ================================================ // deno-fmt-ignore-file // biome-ignore format: generated types do not need formatting // prettier-ignore import type { PathsForPages, GetConfigResponse } from 'waku/router'; // prettier-ignore import type { getConfig as File_About_getConfig } from './pages/about'; // prettier-ignore import type { getConfig as File_Index_getConfig } from './pages/index'; // prettier-ignore type Page = | ({ path: '/about' } & GetConfigResponse) | ({ path: '/' } & GetConfigResponse); // prettier-ignore declare module 'waku/router' { interface RouteConfig { paths: PathsForPages; } interface CreatePagesConfig { pages: Page; } } ================================================ FILE: examples/example-waku/tsconfig.json ================================================ { "compilerOptions": { "strict": true, "target": "esnext", "noEmit": true, "isolatedModules": true, "moduleDetection": "force", "downlevelIteration": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "skipLibCheck": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "jsx": "react-jsx" } } ================================================ FILE: examples/example-waku/waku.config.ts ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import react from '@vitejs/plugin-react'; import stylex from '@stylexjs/unplugin'; import { defineConfig } from 'waku/config'; const stylexPlugin = stylex.vite({ debug: process.env.NODE_ENV === 'development', enableDebugClassNames: false, enableDevClassNames: false, useCSSLayers: true, devMode: 'css-only', devPersistToDisk: true, runtimeInjection: false, }); export default defineConfig({ vite: { plugins: [ // @ts-ignore stylexPlugin, // @ts-ignore react({ babel: { // There is a bug with react compiler at the moment. // plugins: ['babel-plugin-react-compiler'], }, }), ], }, }); ================================================ FILE: examples/example-webpack/.babelrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; ================================================ FILE: examples/example-webpack/.eslintrc.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ module.exports = { plugins: ['@stylexjs'], rules: { '@stylexjs/valid-styles': 'error', '@stylexjs/no-unused': 'error', '@stylexjs/valid-shorthands': 'warn', '@stylexjs/sort-keys': 'warn', }, }; ================================================ FILE: examples/example-webpack/README.md ================================================ # Webpack Example with StyleX This example demonstrates how to configure StyleX with Webpack for a React application using `@stylexjs/unplugin`. The unplugin compiles StyleX at build time, aggregates the CSS, and appends it to a CSS asset emitted by Webpack. ### Prerequisites Set up the following tooling: - MiniCssExtractPlugin (or another CSS extractor) so Webpack produces a CSS asset for StyleX to append to. - A CSS file that is imported for every route of your app which contains any global styles such as a CSS reset. ## Overview This setup includes: - **Webpack** for bundling plus **MiniCssExtractPlugin** for CSS extraction - **@stylexjs/unplugin** for StyleX compilation + CSS aggregation - **ESLint** for StyleX-specific linting rules ## Configuration Files ### 1. Package Dependencies (`package.json`) ```bash # Install runtime StyleX package npm install @stylexjs/stylex # Install dev dependencies npm install -D @stylexjs/unplugin @stylexjs/eslint-plugin ``` ### 2. Babel Configuration (`.babelrc.js`) Babel now only needs to handle React/ES features. StyleX compilation is handled by the unplugin. ```javascript module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; ``` ### 3. Webpack Configuration (`webpack.config.js`) Register `@stylexjs/unplugin` so it can transform StyleX imports and append CSS to the extracted stylesheet. ```javascript const fs = require('node:fs'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const stylex = require('@stylexjs/unplugin').default; const templatePath = path.resolve(__dirname, 'index.html'); module.exports = { // ... devServer: { watchFiles: [templatePath, path.resolve(__dirname, 'src/**/*')], }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [{ loader: 'babel-loader' }], }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ], }, plugins: [ new HtmlWebpackPlugin({ inject: true, templateContent: () => fs.readFileSync(templatePath, 'utf-8'), }), stylex.webpack({ // Recommended useCSSLayers: true, }), new MiniCssExtractPlugin(), ], }; ``` ### 4. ESLint Configuration (`.eslintrc.js`) StyleX-specific linting rules: ```javascript module.exports = { plugins: ['@stylexjs'], rules: { '@stylexjs/valid-styles': 'error', '@stylexjs/no-unused': 'error', '@stylexjs/valid-shorthands': 'warn', '@stylexjs/sort-keys': 'warn', }, }; ``` ### 5. CSS entry point (`src/app.css`) Ensure there is at least one CSS file bundled by Webpack so the unplugin has an injection target. StyleX CSS will be appended to this file automatically, and because the plugin is configured with `useCSSLayers: true`, the generated output respects CSS layer ordering alongside your existing `@layer` blocks. ## Commands ```bash # Development server npm run example:dev # Production build npm run example:build # Serve built files npm run example:serve ``` ================================================ FILE: examples/example-webpack/index.html ================================================ React with webpack
================================================ FILE: examples/example-webpack/package.json ================================================ { "private": true, "name": "example-webpack", "version": "0.18.1", "description": "Example: StyleX with Webpack via @stylexjs/unplugin", "main": "index.js", "scripts": { "example:dev": "webpack serve --config ./webpack.config.js --mode development", "example:serve": "serve dist", "example:build": "webpack --mode production" }, "license": "MIT", "devDependencies": { "@babel/core": "^7.28.4", "@babel/preset-env": "^7.28.3", "@babel/preset-react": "^7.27.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.1", "@stylexjs/eslint-plugin": "0.18.1", "@stylexjs/unplugin": "0.18.1", "babel-loader": "^10.0.0", "css-loader": "^7.1.2", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.6.0", "mini-css-extract-plugin": "^2.9.4", "react-refresh": "^0.18.0", "serve": "^14.2.5", "webpack": "^5.101.3", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.2" }, "dependencies": { "@stylexjs/stylex": "0.18.1", "react": "^19.1.1", "react-dom": "^19.1.1" } } ================================================ FILE: examples/example-webpack/src/App.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React from 'react'; import webpackLogo from './assets/webpack.svg'; import stylexLogo from './assets/stylex.svg'; import * as stylex from '@stylexjs/stylex'; import { colors } from './tokens.stylex'; import './app.css'; import CtaButton from './components/CTAButton'; export default function App() { return (

Webpack + StyleX

Get Started Thinking in StyleX
); } const styles = stylex.create({ main: { padding: '2rem', gap: '2rem', alignItems: 'center', display: 'flex', flexDirection: 'column', justifyContent: 'center', height: '100vh', }, logoContainer: { gap: '2rem', display: 'flex', }, logo: { transition: 'filter 300ms', filter: { default: null, ':hover': 'drop-shadow(0 0 2em #646cffaa)', }, willChange: 'filter', height: '6em', }, header: { color: colors.textPrimary, fontSize: '3.2em', lineHeight: 1.1, }, card: { gap: '2rem', display: 'flex', }, }); ================================================ FILE: examples/example-webpack/src/app.css ================================================ @layer reset { * { box-sizing: border-box; padding: 0; margin: 0; } body { background-color: #f5f3f7; font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; } @media (prefers-color-scheme: dark) { body { background-color: #242424; } } } /* StyleX CSS from @stylexjs/unplugin will be appended to this file at build time. */ ================================================ FILE: examples/example-webpack/src/components/CTAButton.jsx ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as React from 'react'; import * as stylex from '@stylexjs/stylex'; import { colors } from '../tokens.stylex'; export default function CtaButton({ children, color, to }) { return ( {children} ); } const styles = stylex.create({ base: { borderRadius: 8, paddingBlock: '0.75rem', paddingInline: '2rem', textDecoration: { default: 'none', ':hover': 'none', }, alignItems: 'center', backgroundColor: colors.fg1, boxShadow: { default: '0 0 2px rgba(0,0,0,0.35)', ':hover': '0 0 10px rgba(0,0,0,0.75)', }, color: colors.bg1, display: 'flex', fontWeight: 'bold', justifyContent: 'center', scale: { default: '1', ':hover': '1.02', ':active': '0.98', }, transitionDuration: { default: '0.2s', ':active': '0.1s', }, transitionProperty: 'scale, boxShadow', whiteSpace: 'nowrap', }, pink: { backgroundColor: `hsl(${colors.pinkH}, ${colors.pinkS}, ${colors.pinkL})`, boxShadow: { default: `0 0 2px hsla(${colors.pinkH}, ${colors.pinkS}, ${colors.pinkL}, 0.35)`, ':hover': `0 0 10px hsla(${colors.pinkH}, ${colors.pinkS}, ${colors.pinkL}, 0.75)`, }, color: colors.white, }, blue: { backgroundColor: `hsl(${colors.cyanH}, ${colors.cyanS}, ${colors.cyanL})`, boxShadow: { default: `0 0 2px hsla(${colors.cyanH}, ${colors.cyanS}, ${colors.cyanL}, 0.35)`, ':hover': `0 0 10px hsla(${colors.cyanH}, ${colors.cyanS}, ${colors.cyanL}, 0.75)`, }, color: colors.white, }, }); ================================================ FILE: examples/example-webpack/src/index.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App'; const domNode = document.getElementById('app'); const root = createRoot(domNode); root.render(); ================================================ FILE: examples/example-webpack/src/tokens.stylex.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import * as stylex from '@stylexjs/stylex'; const DARK = '@media (prefers-color-scheme: dark)'; export const colors = stylex.defineVars({ textPrimary: { default: '#000', [DARK]: '#fff' }, white: { default: '#fff', [DARK]: '#fff' }, fg1: { default: 'hsl(0, 0%, 0%)', [DARK]: 'hsl(0, 0%, 100%)' }, bg1: { default: 'hsl(276, 17%, 96%)', [DARK]: 'hsl(276, 17%, 96%)' }, pinkH: 295, pinkS: '62%', pinkL: '60%', cyanH: 202, cyanS: '100%', cyanL: '50%', }); ================================================ FILE: examples/example-webpack/webpack.config.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ const fs = require('node:fs'); const path = require('path'); const templatePath = path.resolve(__dirname, 'index.html'); const templateContent = () => fs.readFileSync(templatePath, 'utf-8'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const stylex = require('@stylexjs/unplugin').default; const config = (env, argv) => { const isHot = argv.hot; return { entry: { main: path.resolve(__dirname, 'src/index.js'), }, output: { path: path.resolve(__dirname, './dist'), }, devServer: { static: { directory: path.resolve(__dirname, 'dist'), }, watchFiles: [templatePath, path.resolve(__dirname, 'src/**/*')], }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: require.resolve('babel-loader'), options: { plugins: [ isHot && require.resolve('react-refresh/babel'), ].filter(Boolean), }, }, ], }, { test: /\.(css)$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, { test: /\.svg$/i, issuer: /\.[jt]sx?$/, use: ['file-loader'], }, ], }, resolve: { extensions: ['*', '.js', '.jsx'], }, plugins: [ new HtmlWebpackPlugin({ inject: true, templateContent, }), stylex.webpack({ useCSSLayers: true, }), new MiniCssExtractPlugin(), isHot && new ReactRefreshWebpackPlugin(), ].filter(Boolean), cache: true, }; }; module.exports = config; ================================================ FILE: flow-typed/babel-plugins.js ================================================ /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict */ /* eslint-disable ft-flow/no-types-missing-file-annotation */ /* eslint-disable no-unused-vars */ declare module '@babel/plugin-syntax-typescript' { declare module.exports: any; } declare module '@babel/plugin-transform-typescript' { declare module.exports: any; } declare module '@babel/plugin-syntax-flow' { declare module.exports: any; } declare module '@babel/plugin-syntax-jsx' { declare module.exports: any; } declare module 'babel-plugin-syntax-hermes-parser' { declare module.exports: any; } ================================================ FILE: flow-typed/environments/bom.js ================================================ /* BOM */ declare class Screen { +availHeight: number; +availWidth: number; +availLeft: number; +availTop: number; +top: number; +left: number; +colorDepth: number; +pixelDepth: number; +width: number; +height: number; +orientation?: { lock(): Promise, unlock(): void, angle: number, onchange: () => mixed, type: | 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary', ... }; // deprecated mozLockOrientation?: (orientation: string | Array) => boolean; mozUnlockOrientation?: () => void; mozOrientation?: string; onmozorientationchange?: (...args: any[]) => mixed; } declare var screen: Screen; declare interface Crypto { // Not using $TypedArray as that would include Float32Array and Float64Array which are not accepted getRandomValues: < T: | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array, >( typedArray: T, ) => T; randomUUID: () => string; } declare var crypto: Crypto; declare var window: any; type GamepadButton = { pressed: boolean, value: number, ... }; type GamepadHapticActuator = { type: 'vibration', pulse(value: number, duration: number): Promise, ... }; type GamepadPose = { angularAcceleration: null | Float32Array, angularVelocity: null | Float32Array, hasOrientation: boolean, hasPosition: boolean, linearAcceleration: null | Float32Array, linearVelocity: null | Float32Array, orientation: null | Float32Array, position: null | Float32Array, ... }; type Gamepad = { axes: number[], buttons: GamepadButton[], connected: boolean, displayId?: number, hapticActuators?: GamepadHapticActuator[], hand?: '' | 'left' | 'right', id: string, index: number, mapping: string, pose?: null | GamepadPose, timestamp: number, ... }; // deprecated type BatteryManager = { +charging: boolean, +chargingTime: number, +dischargingTime: number, +level: number, onchargingchange: ?(event: any) => mixed, onchargingtimechange: ?(event: any) => mixed, ondischargingtimechange: ?(event: any) => mixed, onlevelchange: ?(event: any) => mixed, ... }; // https://wicg.github.io/web-share type ShareData = { title?: string, text?: string, url?: string, ... }; type PermissionName = | 'geolocation' | 'notifications' | 'push' | 'midi' | 'camera' | 'microphone' | 'speaker' | 'usb' | 'device-info' | 'background-sync' | 'bluetooth' | 'persistent-storage' | 'ambient-light-sensor' | 'accelerometer' | 'gyroscope' | 'magnetometer' | 'clipboard-read' | 'clipboard-write'; type PermissionState = 'granted' | 'denied' | 'prompt'; type PermissionDescriptor = {| name: PermissionName, |}; type DevicePermissionDescriptor = {| deviceId?: string, name: 'camera' | 'microphone' | 'speaker', |}; type MidiPermissionDescriptor = {| name: 'midi', sysex?: boolean, |}; type PushPermissionDescriptor = {| name: 'push', userVisibleOnly?: boolean, |}; type ClipboardPermissionDescriptor = {| name: 'clipboard-read' | 'clipboard-write', allowWithoutGesture: boolean, |}; type USBPermissionDescriptor = {| name: 'usb', filters: Array, exclusionFilters: Array, |}; type FileSystemHandlePermissionDescriptor = {| mode: 'read' | 'readwrite', |}; declare class PermissionStatus extends EventTarget { onchange: ?(event: any) => mixed; +state: PermissionState; } declare class Permissions { query( permissionDesc: | DevicePermissionDescriptor | MidiPermissionDescriptor | PushPermissionDescriptor | ClipboardPermissionDescriptor | USBPermissionDescriptor | PermissionDescriptor, ): Promise; } type MIDIPortType = 'input' | 'output'; type MIDIPortDeviceState = 'connected' | 'disconnected'; type MIDIPortConnectionState = 'open' | 'closed' | 'pending'; type MIDIOptions = {| sysex: boolean, software: boolean, |}; type MIDIMessageEvent$Init = Event$Init & { data: Uint8Array, ... }; declare class MIDIMessageEvent extends Event { constructor(type: string, eventInitDict: MIDIMessageEvent$Init): void; +data: Uint8Array; } type MIDIConnectionEvent$Init = Event$Init & { port: MIDIPort, ... }; declare class MIDIConnectionEvent extends Event { constructor(type: string, eventInitDict: MIDIConnectionEvent$Init): void; +port: MIDIPort; } declare class MIDIPort extends EventTarget { +id: string; +manufacturer?: string; +name?: string; +type: MIDIPortType; +version?: string; +state: MIDIPortDeviceState; +connection: MIDIPortConnectionState; onstatechange: ?(ev: MIDIConnectionEvent) => mixed; open(): Promise; close(): Promise; } declare class MIDIInput extends MIDIPort { onmidimessage: ?(ev: MIDIMessageEvent) => mixed; } declare class MIDIOutput extends MIDIPort { send(data: Iterable, timestamp?: number): void; clear(): void; } declare class MIDIInputMap extends $ReadOnlyMap {} declare class MIDIOutputMap extends $ReadOnlyMap {} declare class MIDIAccess extends EventTarget { +inputs: MIDIInputMap; +outputs: MIDIOutputMap; +sysexEnabled: boolean; onstatechange: ?(ev: MIDIConnectionEvent) => mixed; } declare class NavigatorID { appName: 'Netscape'; appCodeName: 'Mozilla'; product: 'Gecko'; appVersion: string; platform: string; userAgent: string; } declare class NavigatorLanguage { +language: string; +languages: $ReadOnlyArray; } declare class NavigatorContentUtils { registerContentHandler(mimeType: string, uri: string, title: string): void; registerProtocolHandler(protocol: string, uri: string, title: string): void; } declare class NavigatorCookies { +cookieEnabled: boolean; } declare class NavigatorPlugins { +plugins: PluginArray; +mimeTypes: MimeTypeArray; javaEnabled(): boolean; } declare class NavigatorOnLine { +onLine: boolean; } declare class NavigatorConcurrentHardware { +hardwareConcurrency: number; } declare class NavigatorStorage { storage?: StorageManager; } declare class StorageManager { persist: () => Promise; persisted: () => Promise; estimate?: () => Promise; getDirectory: () => Promise; } type StorageManagerRegisteredEndpoint = | 'caches' | 'indexedDB' | 'localStorage' | 'serviceWorkerRegistrations' | 'sessionStorage'; type StorageManagerUsageDetails = { [StorageManagerRegisteredEndpoint]: number, }; declare class StorageEstimate { constructor( usage: number, quota: number, usageDetails?: StorageManagerUsageDetails, ): void; +usage: number; +quota: number; // Not a part of the standard +usageDetails?: StorageManagerUsageDetails; } declare class Navigator mixins NavigatorID, NavigatorLanguage, NavigatorOnLine, NavigatorContentUtils, NavigatorCookies, NavigatorPlugins, NavigatorConcurrentHardware, NavigatorStorage { productSub: '20030107' | '20100101'; vendor: '' | 'Google Inc.' | 'Apple Computer, Inc'; vendorSub: ''; activeVRDisplays?: VRDisplay[]; appCodeName: 'Mozilla'; buildID: string; doNotTrack: string | null; geolocation: Geolocation; mediaDevices?: MediaDevices; usb?: USB; maxTouchPoints: number; permissions: Permissions; // serviceWorker?: ServiceWorkerContainer; getGamepads?: () => Array; webkitGetGamepads?: Function; mozGetGamepads?: Function; mozGamepads?: any; gamepads?: any; webkitGamepads?: any; getVRDisplays?: () => Promise; registerContentHandler(mimeType: string, uri: string, title: string): void; registerProtocolHandler(protocol: string, uri: string, title: string): void; requestMIDIAccess?: (options?: MIDIOptions) => Promise; requestMediaKeySystemAccess?: ( keySystem: string, supportedConfigurations: any[], ) => Promise; sendBeacon?: (url: string, data?: BodyInit) => boolean; vibrate?: (pattern: number | number[]) => boolean; mozVibrate?: (pattern: number | number[]) => boolean; webkitVibrate?: (pattern: number | number[]) => boolean; canShare?: (shareData?: ShareData) => boolean; share?: (shareData: ShareData) => Promise; clipboard: Clipboard; credentials?: CredMgmtCredentialsContainer; globalPrivacyControl?: boolean; // deprecated getBattery?: () => Promise; mozGetBattery?: () => Promise; // deprecated getUserMedia?: Function; webkitGetUserMedia?: Function; mozGetUserMedia?: Function; msGetUserMedia?: Function; // Gecko taintEnabled?: () => false; oscpu: string; } declare class Clipboard extends EventTarget { read(): Promise; readText(): Promise; write(data: $ReadOnlyArray): Promise; writeText(data: string): Promise; } declare var navigator: Navigator; declare class MimeType { type: string; description: string; suffixes: string; enabledPlugin: Plugin; } declare class MimeTypeArray { length: number; item(index: number): MimeType; namedItem(name: string): MimeType; [key: number | string]: MimeType; } declare class Plugin { description: string; filename: string; name: string; version?: string; // Gecko only length: number; item(index: number): MimeType; namedItem(name: string): MimeType; [key: number | string]: MimeType; } declare class PluginArray { length: number; item(index: number): Plugin; namedItem(name: string): Plugin; refresh(): void; [key: number | string]: Plugin; } // https://www.w3.org/TR/hr-time-2/#dom-domhighrestimestamp // https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp declare type DOMHighResTimeStamp = number; // https://www.w3.org/TR/navigation-timing-2/ declare class PerformanceTiming { connectEnd: number; connectStart: number; domainLookupEnd: number; domainLookupStart: number; domComplete: number; domContentLoadedEventEnd: number; domContentLoadedEventStart: number; domInteractive: number; domLoading: number; fetchStart: number; loadEventEnd: number; loadEventStart: number; navigationStart: number; redirectEnd: number; redirectStart: number; requestStart: number; responseEnd: number; responseStart: number; secureConnectionStart: number; unloadEventEnd: number; unloadEventStart: number; } declare class PerformanceNavigation { TYPE_NAVIGATE: 0; TYPE_RELOAD: 1; TYPE_BACK_FORWARD: 2; TYPE_RESERVED: 255; type: 0 | 1 | 2 | 255; redirectCount: number; } type PerformanceEntryFilterOptions = { name: string, entryType: string, initiatorType: string, ... }; // https://www.w3.org/TR/performance-timeline-2/ declare class PerformanceEntry { name: string; entryType: string; startTime: DOMHighResTimeStamp; duration: DOMHighResTimeStamp; toJSON(): string; } // https://w3c.github.io/server-timing/#the-performanceservertiming-interface declare class PerformanceServerTiming { description: string; duration: DOMHighResTimeStamp; name: string; toJSON(): string; } // https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming // https://w3c.github.io/server-timing/#extension-to-the-performanceresourcetiming-interface declare class PerformanceResourceTiming extends PerformanceEntry { initiatorType: string; nextHopProtocol: string; workerStart: number; redirectStart: number; redirectEnd: number; fetchStart: number; domainLookupStart: number; domainLookupEnd: number; connectStart: number; connectEnd: number; secureConnectionStart: number; requestStart: number; responseStart: number; responseEnd: number; transferSize: string; encodedBodySize: number; decodedBodySize: number; serverTiming: Array; } // https://w3c.github.io/event-timing/#sec-performance-event-timing declare class PerformanceEventTiming extends PerformanceEntry { processingStart: number; processingEnd: number; cancelable: boolean; target: ?Node; interactionId: number; } // https://w3c.github.io/longtasks/#taskattributiontiming declare class TaskAttributionTiming extends PerformanceEntry { containerType: string; containerSrc: string; containerId: string; containerName: string; } // https://w3c.github.io/longtasks/#sec-PerformanceLongTaskTiming declare class PerformanceLongTaskTiming extends PerformanceEntry { attribution: $ReadOnlyArray; } // https://www.w3.org/TR/navigation-timing-2/ declare class PerformanceNavigationTiming extends PerformanceResourceTiming { unloadEventStart: number; unloadEventEnd: number; domInteractive: number; domContentLoadedEventStart: number; domContentLoadedEventEnd: number; domComplete: number; loadEventStart: number; loadEventEnd: number; type: 'navigate' | 'reload' | 'back_forward' | 'prerender'; redirectCount: number; } // https://www.w3.org/TR/user-timing/#extensions-performance-interface declare type PerformanceMarkOptions = {| detail?: mixed, startTime?: number, |}; declare type PerformanceMeasureOptions = {| detail?: mixed, start?: number | string, end?: number | string, duration?: number, |}; type EventCountsForEachCallbackType = | (() => void) | ((value: number) => void) | ((value: number, key: string) => void) | ((value: number, key: string, map: Map) => void); // https://www.w3.org/TR/event-timing/#eventcounts declare interface EventCounts { size: number; entries(): Iterator<[string, number]>; forEach(callback: EventCountsForEachCallbackType): void; get(key: string): ?number; has(key: string): boolean; keys(): Iterator; values(): Iterator; } declare class Performance { eventCounts: EventCounts; // deprecated navigation: PerformanceNavigation; timing: PerformanceTiming; onresourcetimingbufferfull: (ev: any) => mixed; clearMarks(name?: string): void; clearMeasures(name?: string): void; clearResourceTimings(): void; getEntries(options?: PerformanceEntryFilterOptions): Array; getEntriesByName(name: string, type?: string): Array; getEntriesByType(type: string): Array; mark(name: string, options?: PerformanceMarkOptions): void; measure( name: string, startMarkOrOptions?: string | PerformanceMeasureOptions, endMark?: string, ): void; now(): DOMHighResTimeStamp; setResourceTimingBufferSize(maxSize: number): void; toJSON(): string; } declare var performance: Performance; type PerformanceEntryList = PerformanceEntry[]; declare interface PerformanceObserverEntryList { getEntries(): PerformanceEntryList; getEntriesByType(type: string): PerformanceEntryList; getEntriesByName(name: string, type: ?string): PerformanceEntryList; } type PerformanceObserverInit = { entryTypes?: string[], type?: string, buffered?: boolean, ... }; declare class PerformanceObserver { constructor( callback: ( entries: PerformanceObserverEntryList, observer: PerformanceObserver, ) => mixed, ): void; observe(options: ?PerformanceObserverInit): void; disconnect(): void; takeRecords(): PerformanceEntryList; static supportedEntryTypes: string[]; } declare class History { length: number; scrollRestoration: 'auto' | 'manual'; state: any; back(): void; forward(): void; go(delta?: number): void; pushState(statedata: any, title: string, url?: string): void; replaceState(statedata: any, title: string, url?: string): void; } declare var history: History; declare class Location { ancestorOrigins: string[]; hash: string; host: string; hostname: string; href: string; origin: string; pathname: string; port: string; protocol: string; search: string; assign(url: string): void; reload(flag?: boolean): void; replace(url: string): void; toString(): string; } declare var location: Location; /////////////////////////////////////////////////////////////////////////////// declare class DOMParser { parseFromString(source: string | TrustedHTML, mimeType: string): Document; } type FormDataEntryValue = string | File; declare class FormData { constructor(form?: HTMLFormElement, submitter?: HTMLElement | null): void; has(name: string): boolean; get(name: string): ?FormDataEntryValue; getAll(name: string): Array; set(name: string, value: string): void; set(name: string, value: Blob, filename?: string): void; set(name: string, value: File, filename?: string): void; append(name: string, value: string): void; append(name: string, value: Blob, filename?: string): void; append(name: string, value: File, filename?: string): void; delete(name: string): void; keys(): Iterator; values(): Iterator; entries(): Iterator<[string, FormDataEntryValue]>; } declare type IntersectionObserverEntry = { // boundingClientRect: DOMRectReadOnly, intersectionRatio: number, // intersectionRect: DOMRectReadOnly, isIntersecting: boolean, // rootBounds: DOMRectReadOnly, target: Element, time: DOMHighResTimeStamp, ... }; declare type IntersectionObserverCallback = ( entries: Array, observer: IntersectionObserver, ) => mixed; declare type IntersectionObserverOptions = { root?: Node | null, rootMargin?: string, threshold?: number | Array, ... }; declare class IntersectionObserver { constructor( callback: IntersectionObserverCallback, options?: IntersectionObserverOptions, ): void; root: Element | null; rootMargin: string; scrollMargin: string; thresholds: number[]; observe(target: Element): void; unobserve(target: Element): void; takeRecords(): Array; disconnect(): void; } declare interface ResizeObserverSize { +inlineSize: number; +blockSize: number; } declare interface ResizeObserverEntry { /** * The Element whose size has changed. */ +target: Element; /** * Element's content rect when ResizeObserverCallback is invoked. * * Legacy, may be deprecated in the future. */ // +contentRect: DOMRectReadOnly; /** * An array containing the Element's border box size when * ResizeObserverCallback is invoked. */ +borderBoxSize: $ReadOnlyArray; /** * An array containing the Element's content rect size when * ResizeObserverCallback is invoked. */ +contentBoxSize: $ReadOnlyArray; /** * An array containing the Element's content rect size in integral device * pixels when ResizeObserverCallback is invoked. * * Not implemented in Firefox or Safari as of July 2021 */ +devicePixelContentBoxSize?: $ReadOnlyArray | void; } /** * ResizeObserver can observe different kinds of CSS sizes: * - border-box : size of box border area as defined in CSS2. * - content-box : size of content area as defined in CSS2. * - device-pixel-content-box : size of content area as defined in CSS2, in device * pixels, before applying any CSS transforms on the element or its ancestors. * This size must contain integer values. */ type ResizeObserverBoxOptions = | 'border-box' | 'content-box' | 'device-pixel-content-box'; declare type ResizeObserverOptions = { box?: ResizeObserverBoxOptions, ... }; /** * The ResizeObserver interface is used to observe changes to Element's size. */ declare class ResizeObserver { constructor( callback: ( entries: ResizeObserverEntry[], observer: ResizeObserver, ) => mixed, ): void; /** * Adds target to the list of observed elements. */ observe(target: Element, options?: ResizeObserverOptions): void; /** * Removes target from the list of observed elements. */ unobserve(target: Element): void; disconnect(): void; } declare class CloseEvent extends Event { code: number; reason: string; wasClean: boolean; } declare class WebSocket extends EventTarget { static CONNECTING: 0; static OPEN: 1; static CLOSING: 2; static CLOSED: 3; constructor(url: string, protocols?: string | Array): void; protocol: string; readyState: number; bufferedAmount: number; extensions: string; onopen: (ev: any) => mixed; onmessage: (ev: MessageEvent) => mixed; onclose: (ev: CloseEvent) => mixed; onerror: (ev: any) => mixed; binaryType: 'blob' | 'arraybuffer'; url: string; close(code?: number, reason?: string): void; send(data: string): void; send(data: Blob): void; send(data: ArrayBuffer): void; send(data: $ArrayBufferView): void; CONNECTING: 0; OPEN: 1; CLOSING: 2; CLOSED: 3; } type WorkerOptions = { type?: any, credentials?: CredentialsType, name?: string, ... }; declare class Worker extends EventTarget { constructor( stringUrl: string | TrustedScriptURL, workerOptions?: WorkerOptions, ): void; onerror: null | ((ev: any) => mixed); onmessage: null | ((ev: MessageEvent) => mixed); onmessageerror: null | ((ev: MessageEvent) => mixed); postMessage(message: any, ports?: any): void; terminate(): void; } declare class SharedWorker extends EventTarget { constructor(stringUrl: string | TrustedScriptURL, name?: string): void; constructor( stringUrl: string | TrustedScriptURL, workerOptions?: WorkerOptions, ): void; port: MessagePort; onerror: (ev: any) => mixed; } declare function importScripts(...urls: Array): void; declare class WorkerGlobalScope extends EventTarget { self: this; location: WorkerLocation; navigator: WorkerNavigator; close(): void; importScripts(...urls: Array): void; onerror: (ev: any) => mixed; onlanguagechange: (ev: any) => mixed; onoffline: (ev: any) => mixed; ononline: (ev: any) => mixed; onrejectionhandled: (ev: PromiseRejectionEvent) => mixed; onunhandledrejection: (ev: PromiseRejectionEvent) => mixed; } declare class DedicatedWorkerGlobalScope extends WorkerGlobalScope { onmessage: (ev: MessageEvent) => mixed; onmessageerror: (ev: MessageEvent) => mixed; postMessage(message: any, transfer?: Iterable): void; } declare class SharedWorkerGlobalScope extends WorkerGlobalScope { name: string; onconnect: (ev: MessageEvent) => mixed; } declare class WorkerLocation { origin: string; protocol: string; host: string; hostname: string; port: string; pathname: string; search: string; hash: string; } declare class WorkerNavigator mixins NavigatorID, NavigatorLanguage, NavigatorOnLine, NavigatorConcurrentHardware, NavigatorStorage { permissions: Permissions; } // deprecated declare class XDomainRequest { timeout: number; onerror: () => mixed; onload: () => mixed; onprogress: () => mixed; ontimeout: () => mixed; +responseText: string; +contentType: string; open(method: 'GET' | 'POST', url: string): void; abort(): void; send(data?: string): void; statics: { create(): XDomainRequest, ... }; } declare class XMLHttpRequest extends EventTarget { static LOADING: number; static DONE: number; static UNSENT: number; static OPENED: number; static HEADERS_RECEIVED: number; responseBody: any; status: number; readyState: number; responseText: string; responseXML: any; responseURL: string; ontimeout: ProgressEventHandler; statusText: string; onreadystatechange: (ev: any) => mixed; timeout: number; onload: ProgressEventHandler; response: any; withCredentials: boolean; onprogress: ProgressEventHandler; onabort: ProgressEventHandler; responseType: string; onloadend: ProgressEventHandler; upload: XMLHttpRequestEventTarget; onerror: ProgressEventHandler; onloadstart: ProgressEventHandler; msCaching: string; open( method: string, url: string, async?: boolean, user?: string, password?: string, ): void; send(data?: any): void; abort(): void; getAllResponseHeaders(): string; setRequestHeader(header: string, value: string): void; getResponseHeader(header: string): string; msCachingEnabled(): boolean; overrideMimeType(mime: string): void; LOADING: number; DONE: number; UNSENT: number; OPENED: number; HEADERS_RECEIVED: number; statics: { create(): XMLHttpRequest, ... }; } declare class XMLHttpRequestEventTarget extends EventTarget { onprogress: ProgressEventHandler; onerror: ProgressEventHandler; onload: ProgressEventHandler; ontimeout: ProgressEventHandler; onabort: ProgressEventHandler; onloadstart: ProgressEventHandler; onloadend: ProgressEventHandler; } declare class XMLSerializer { serializeToString(target: Node): string; } declare class Geolocation { getCurrentPosition( success: (position: Position) => mixed, error?: (error: PositionError) => mixed, options?: PositionOptions, ): void; watchPosition( success: (position: Position) => mixed, error?: (error: PositionError) => mixed, options?: PositionOptions, ): number; clearWatch(id: number): void; } declare class Position { coords: Coordinates; timestamp: number; } declare class Coordinates { latitude: number; longitude: number; altitude?: number; accuracy: number; altitudeAccuracy?: number; heading?: number; speed?: number; } declare class PositionError { code: number; message: string; PERMISSION_DENIED: 1; POSITION_UNAVAILABLE: 2; TIMEOUT: 3; } type PositionOptions = { enableHighAccuracy?: boolean, timeout?: number, maximumAge?: number, ... }; type AudioContextState = 'suspended' | 'running' | 'closed'; // deprecated type AudioProcessingEvent$Init = Event$Init & { playbackTime: number, inputBuffer: AudioBuffer, outputBuffer: AudioBuffer, ... }; // deprecated declare class AudioProcessingEvent extends Event { constructor(type: string, eventInitDict: AudioProcessingEvent$Init): void; +playbackTime: number; +inputBuffer: AudioBuffer; +outputBuffer: AudioBuffer; } type OfflineAudioCompletionEvent$Init = Event$Init & { renderedBuffer: AudioBuffer, ... }; declare class OfflineAudioCompletionEvent extends Event { constructor( type: string, eventInitDict: OfflineAudioCompletionEvent$Init, ): void; +renderedBuffer: AudioBuffer; } declare class BaseAudioContext extends EventTarget { currentTime: number; destination: AudioDestinationNode; listener: AudioListener; sampleRate: number; state: AudioContextState; onstatechange: (ev: any) => mixed; createBuffer( numOfChannels: number, length: number, sampleRate: number, ): AudioBuffer; createBufferSource(myMediaElement?: HTMLMediaElement): AudioBufferSourceNode; createMediaElementSource( myMediaElement: HTMLMediaElement, ): MediaElementAudioSourceNode; createMediaStreamSource(stream: MediaStream): MediaStreamAudioSourceNode; createMediaStreamDestination(): MediaStreamAudioDestinationNode; // deprecated createScriptProcessor( bufferSize: number, numberOfInputChannels: number, numberOfOutputChannels: number, ): ScriptProcessorNode; createAnalyser(): AnalyserNode; createBiquadFilter(): BiquadFilterNode; createChannelMerger(numberOfInputs?: number): ChannelMergerNode; createChannelSplitter(numberOfInputs?: number): ChannelSplitterNode; createConstantSource(): ConstantSourceNode; createConvolver(): ConvolverNode; createDelay(maxDelayTime?: number): DelayNode; createDynamicsCompressor(): DynamicsCompressorNode; createGain(): GainNode; createIIRFilter( feedforward: Float32Array, feedback: Float32Array, ): IIRFilterNode; createOscillator(): OscillatorNode; createPanner(): PannerNode; createStereoPanner(): StereoPannerNode; createPeriodicWave( real: Float32Array, img: Float32Array, options?: { disableNormalization: boolean, ... }, ): PeriodicWave; createStereoPanner(): StereoPannerNode; createWaveShaper(): WaveShaperNode; decodeAudioData( arrayBuffer: ArrayBuffer, decodeSuccessCallback: (decodedData: AudioBuffer) => mixed, decodeErrorCallback: (err: DOMError) => mixed, ): void; decodeAudioData(arrayBuffer: ArrayBuffer): Promise; } declare class AudioTimestamp { contextTime: number; performanceTime: number; } declare class AudioContext extends BaseAudioContext { constructor(options?: {| latencyHint?: 'balanced' | 'interactive' | 'playback' | number, sampleRate?: number, |}): AudioContext; baseLatency: number; outputLatency: number; getOutputTimestamp(): AudioTimestamp; resume(): Promise; suspend(): Promise; close(): Promise; createMediaElementSource( myMediaElement: HTMLMediaElement, ): MediaElementAudioSourceNode; createMediaStreamSource( myMediaStream: MediaStream, ): MediaStreamAudioSourceNode; createMediaStreamTrackSource( myMediaStreamTrack: MediaStreamTrack, ): MediaStreamTrackAudioSourceNode; createMediaStreamDestination(): MediaStreamAudioDestinationNode; } declare class OfflineAudioContext extends BaseAudioContext { startRendering(): Promise; suspend(suspendTime: number): Promise; length: number; oncomplete: (ev: OfflineAudioCompletionEvent) => mixed; } declare class AudioNode extends EventTarget { context: AudioContext; numberOfInputs: number; numberOfOutputs: number; channelCount: number; channelCountMode: 'max' | 'clamped-max' | 'explicit'; channelInterpretation: 'speakers' | 'discrete'; connect(audioNode: AudioNode, output?: number, input?: number): AudioNode; connect(destination: AudioParam, output?: number): void; disconnect(destination?: AudioNode, output?: number, input?: number): void; } declare class AudioParam extends AudioNode { value: number; defaultValue: number; setValueAtTime(value: number, startTime: number): this; linearRampToValueAtTime(value: number, endTime: number): this; exponentialRampToValueAtTime(value: number, endTime: number): this; setTargetAtTime( target: number, startTime: number, timeConstant: number, ): this; setValueCurveAtTime( values: Float32Array, startTime: number, duration: number, ): this; cancelScheduledValues(startTime: number): this; } declare class AudioDestinationNode extends AudioNode { maxChannelCount: number; } declare class AudioListener extends AudioNode { positionX: AudioParam; positionY: AudioParam; positionZ: AudioParam; forwardX: AudioParam; forwardY: AudioParam; forwardZ: AudioParam; upX: AudioParam; upY: AudioParam; upZ: AudioParam; setPosition(x: number, y: number, c: number): void; setOrientation( x: number, y: number, z: number, xUp: number, yUp: number, zUp: number, ): void; } declare class AudioBuffer { sampleRate: number; length: number; duration: number; numberOfChannels: number; getChannelData(channel: number): Float32Array; copyFromChannel( destination: Float32Array, channelNumber: number, startInChannel?: number, ): void; copyToChannel( source: Float32Array, channelNumber: number, startInChannel?: number, ): void; } declare class AudioBufferSourceNode extends AudioNode { buffer: AudioBuffer; detune: AudioParam; loop: boolean; loopStart: number; loopEnd: number; playbackRate: AudioParam; onended: (ev: any) => mixed; start(when?: number, offset?: number, duration?: number): void; stop(when?: number): void; } declare class CanvasCaptureMediaStream extends MediaStream { canvas: HTMLCanvasElement; requestFrame(): void; } type DoubleRange = { max?: number, min?: number, ... }; type LongRange = { max?: number, min?: number, ... }; type ConstrainBooleanParameters = { exact?: boolean, ideal?: boolean, ... }; type ConstrainDOMStringParameters = { exact?: string | string[], ideal?: string | string[], ... }; type ConstrainDoubleRange = { ...DoubleRange, exact?: number, ideal?: number, ... }; type ConstrainLongRange = { ...LongRange, exact?: number, ideal?: number, ... }; type MediaTrackSupportedConstraints = {| width: boolean, height: boolean, aspectRatio: boolean, frameRate: boolean, facingMode: boolean, resizeMode: boolean, volume: boolean, sampleRate: boolean, sampleSize: boolean, echoCancellation: boolean, autoGainControl: boolean, noiseSuppression: boolean, latency: boolean, channelCount: boolean, deviceId: boolean, groupId: boolean, |}; type MediaTrackConstraintSet = { width?: number | ConstrainLongRange, height?: number | ConstrainLongRange, aspectRatio?: number | ConstrainDoubleRange, frameRate?: number | ConstrainDoubleRange, facingMode?: string | string[] | ConstrainDOMStringParameters, resizeMode?: string | string[] | ConstrainDOMStringParameters, volume?: number | ConstrainDoubleRange, sampleRate?: number | ConstrainLongRange, sampleSize?: number | ConstrainLongRange, echoCancellation?: boolean | ConstrainBooleanParameters, autoGainControl?: boolean | ConstrainBooleanParameters, noiseSuppression?: boolean | ConstrainBooleanParameters, latency?: number | ConstrainDoubleRange, channelCount?: number | ConstrainLongRange, deviceId?: string | string[] | ConstrainDOMStringParameters, groupId?: string | string[] | ConstrainDOMStringParameters, ... }; type MediaTrackConstraints = { ...MediaTrackConstraintSet, advanced?: Array, ... }; type DisplayMediaStreamConstraints = { video?: boolean | MediaTrackConstraints, audio?: boolean | MediaTrackConstraints, ... }; type MediaStreamConstraints = { audio?: boolean | MediaTrackConstraints, video?: boolean | MediaTrackConstraints, peerIdentity?: string, ... }; type MediaTrackSettings = { aspectRatio?: number, deviceId?: string, displaySurface?: 'application' | 'browser' | 'monitor' | 'window', echoCancellation?: boolean, facingMode?: string, frameRate?: number, groupId?: string, height?: number, logicalSurface?: boolean, sampleRate?: number, sampleSize?: number, volume?: number, width?: number, ... }; type MediaTrackCapabilities = { aspectRatio?: number | DoubleRange, deviceId?: string, echoCancellation?: boolean[], facingMode?: string, frameRate?: number | DoubleRange, groupId?: string, height?: number | LongRange, sampleRate?: number | LongRange, sampleSize?: number | LongRange, volume?: number | DoubleRange, width?: number | LongRange, ... }; declare class MediaDevices extends EventTarget { ondevicechange: (ev: any) => mixed; enumerateDevices: () => Promise>; getSupportedConstraints: () => MediaTrackSupportedConstraints; getDisplayMedia: ( constraints?: DisplayMediaStreamConstraints, ) => Promise; getUserMedia: (constraints: MediaStreamConstraints) => Promise; } declare class MediaDeviceInfo { +deviceId: string; +groupId: string; +kind: 'videoinput' | 'audioinput' | 'audiooutput'; +label: string; } type MediaRecorderOptions = { mimeType?: string, audioBitsPerSecond?: number, videoBitsPerSecond?: number, bitsPerSecond?: number, audioBitrateMode?: 'cbr' | 'vbr', ... }; declare class MediaRecorder extends EventTarget { constructor(stream: MediaStream, options?: MediaRecorderOptions): void; +stream: MediaStream; +mimeType: string; +state: 'inactive' | 'recording' | 'paused'; onstart: (ev: any) => mixed; onstop: (ev: any) => mixed; ondataavailable: (ev: any) => mixed; onpause: (ev: any) => mixed; onresume: (ev: any) => mixed; onerror: (ev: any) => mixed; +videoBitsPerSecond: number; +audioBitsPerSecond: number; +audioBitrateMode: 'cbr' | 'vbr'; start(timeslice?: number): void; stop(): void; pause(): void; resume(): void; requestData(): void; static isTypeSupported(type: string): boolean; } declare class MediaStream extends EventTarget { active: boolean; ended: boolean; id: string; onactive: (ev: any) => mixed; oninactive: (ev: any) => mixed; onended: (ev: any) => mixed; onaddtrack: (ev: MediaStreamTrackEvent) => mixed; onremovetrack: (ev: MediaStreamTrackEvent) => mixed; addTrack(track: MediaStreamTrack): void; clone(): MediaStream; getAudioTracks(): MediaStreamTrack[]; getTrackById(trackid?: string): ?MediaStreamTrack; getTracks(): MediaStreamTrack[]; getVideoTracks(): MediaStreamTrack[]; removeTrack(track: MediaStreamTrack): void; } declare class MediaStreamTrack extends EventTarget { enabled: boolean; id: string; kind: string; label: string; muted: boolean; readonly: boolean; readyState: 'live' | 'ended'; remote: boolean; contentHint?: string; onstarted: (ev: any) => mixed; onmute: (ev: any) => mixed; onunmute: (ev: any) => mixed; onoverconstrained: (ev: any) => mixed; onended: (ev: any) => mixed; getConstraints(): MediaTrackConstraints; applyConstraints(constraints?: MediaTrackConstraints): Promise; getSettings(): MediaTrackSettings; getCapabilities(): MediaTrackCapabilities; clone(): MediaStreamTrack; stop(): void; } declare class MediaStreamTrackEvent extends Event { track: MediaStreamTrack; } declare class MediaElementAudioSourceNode extends AudioNode {} declare class MediaStreamAudioSourceNode extends AudioNode {} declare class MediaStreamTrackAudioSourceNode extends AudioNode {} declare class MediaStreamAudioDestinationNode extends AudioNode { stream: MediaStream; } // deprecated declare class ScriptProcessorNode extends AudioNode { bufferSize: number; onaudioprocess: (ev: AudioProcessingEvent) => mixed; } declare class AnalyserNode extends AudioNode { fftSize: number; frequencyBinCount: number; minDecibels: number; maxDecibels: number; smoothingTimeConstant: number; getFloatFrequencyData(array: Float32Array): Float32Array; getByteFrequencyData(array: Uint8Array): Uint8Array; getFloatTimeDomainData(array: Float32Array): Float32Array; getByteTimeDomainData(array: Uint8Array): Uint8Array; } declare class BiquadFilterNode extends AudioNode { frequency: AudioParam; detune: AudioParam; Q: AudioParam; gain: AudioParam; type: | 'lowpass' | 'highpass' | 'bandpass' | 'lowshelf' | 'highshelf' | 'peaking' | 'notch' | 'allpass'; getFrequencyResponse( frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array, ): void; } declare class ChannelMergerNode extends AudioNode {} declare class ChannelSplitterNode extends AudioNode {} type ConstantSourceOptions = { offset?: number, ... }; declare class ConstantSourceNode extends AudioNode { constructor(context: BaseAudioContext, options?: ConstantSourceOptions): void; offset: AudioParam; onended: (ev: any) => mixed; start(when?: number): void; stop(when?: number): void; } declare class ConvolverNode extends AudioNode { buffer: AudioBuffer; normalize: boolean; } declare class DelayNode extends AudioNode { delayTime: number; } declare class DynamicsCompressorNode extends AudioNode { threshold: AudioParam; knee: AudioParam; ratio: AudioParam; reduction: AudioParam; attack: AudioParam; release: AudioParam; } declare class GainNode extends AudioNode { gain: AudioParam; } declare class IIRFilterNode extends AudioNode { getFrequencyResponse( frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array, ): void; } declare class OscillatorNode extends AudioNode { frequency: AudioParam; detune: AudioParam; type: 'sine' | 'square' | 'sawtooth' | 'triangle' | 'custom'; start(when?: number): void; stop(when?: number): void; setPeriodicWave(periodicWave: PeriodicWave): void; onended: (ev: any) => mixed; } declare class StereoPannerNode extends AudioNode { pan: AudioParam; } declare class PannerNode extends AudioNode { panningModel: 'equalpower' | 'HRTF'; distanceModel: 'linear' | 'inverse' | 'exponential'; refDistance: number; maxDistance: number; rolloffFactor: number; coneInnerAngle: number; coneOuterAngle: number; coneOuterGain: number; setPosition(x: number, y: number, z: number): void; setOrientation(x: number, y: number, z: number): void; } declare class PeriodicWave extends AudioNode {} declare class WaveShaperNode extends AudioNode { curve: Float32Array; oversample: 'none' | '2x' | '4x'; } // this part of spec is not finished yet, apparently // https://stackoverflow.com/questions/35296664/can-fetch-get-object-as-headers type HeadersInit = | Headers | Array<[string, string]> | { [key: string]: string, ... }; // TODO Heades and URLSearchParams are almost the same thing. // Could it somehow be abstracted away? declare class Headers { @@iterator(): Iterator<[string, string]>; constructor(init?: HeadersInit): void; append(name: string, value: string): void; delete(name: string): void; entries(): Iterator<[string, string]>; forEach( callback: ( this: This, value: string, name: string, headers: Headers, ) => mixed, thisArg: This, ): void; get(name: string): null | string; has(name: string): boolean; keys(): Iterator; set(name: string, value: string): void; values(): Iterator; } declare class URLSearchParams { @@iterator(): Iterator<[string, string]>; size: number; constructor( init?: | string | URLSearchParams | Array<[string, string]> | { [string]: string, ... }, ): void; append(name: string, value: string): void; delete(name: string, value?: string): void; entries(): Iterator<[string, string]>; forEach( callback: ( this: This, value: string, name: string, params: URLSearchParams, ) => mixed, thisArg: This, ): void; get(name: string): null | string; getAll(name: string): Array; has(name: string, value?: string): boolean; keys(): Iterator; set(name: string, value: string): void; sort(): void; values(): Iterator; toString(): string; } type CacheType = | 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached'; type CredentialsType = 'omit' | 'same-origin' | 'include'; type ModeType = 'cors' | 'no-cors' | 'same-origin' | 'navigate'; type RedirectType = 'follow' | 'error' | 'manual'; type ReferrerPolicyType = | '' | 'no-referrer' | 'no-referrer-when-downgrade' | 'same-origin' | 'origin' | 'strict-origin' | 'origin-when-cross-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url'; type ResponseType = | 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect'; type BodyInit = | string | URLSearchParams | FormData | Blob | ArrayBuffer | $ArrayBufferView | ReadableStream; type RequestInfo = Request | URL | string; type RequestOptions = { body?: ?BodyInit, cache?: CacheType, credentials?: CredentialsType, headers?: HeadersInit, integrity?: string, keepalive?: boolean, method?: string, mode?: ModeType, redirect?: RedirectType, referrer?: string, referrerPolicy?: ReferrerPolicyType, signal?: ?AbortSignal, window?: any, ... }; type ResponseOptions = { status?: number, statusText?: string, headers?: HeadersInit, ... }; declare class Response { constructor(input?: ?BodyInit, init?: ResponseOptions): void; clone(): Response; static error(): Response; static redirect(url: string, status?: number): Response; redirected: boolean; type: ResponseType; url: string; ok: boolean; status: number; statusText: string; headers: Headers; trailer: Promise; // Body methods and attributes bodyUsed: boolean; body: ?ReadableStream; arrayBuffer(): Promise; blob(): Promise; formData(): Promise; json(): Promise; text(): Promise; } declare class Request { constructor(input: RequestInfo, init?: RequestOptions): void; clone(): Request; url: string; cache: CacheType; credentials: CredentialsType; headers: Headers; integrity: string; method: string; mode: ModeType; redirect: RedirectType; referrer: string; referrerPolicy: ReferrerPolicyType; +signal: AbortSignal; // Body methods and attributes bodyUsed: boolean; arrayBuffer(): Promise; blob(): Promise; formData(): Promise; json(): Promise; text(): Promise; } declare function fetch( input: RequestInfo, init?: RequestOptions, ): Promise; type TextEncoder$availableEncodings = | 'utf-8' | 'utf8' | 'unicode-1-1-utf-8' | 'utf-16be' | 'utf-16' | 'utf-16le'; declare class TextEncoder { constructor(encoding?: TextEncoder$availableEncodings): void; encode(buffer: string, options?: { stream: boolean, ... }): Uint8Array; encoding: TextEncoder$availableEncodings; } type TextDecoder$availableEncodings = | '866' | 'ansi_x3.4-1968' | 'arabic' | 'ascii' | 'asmo-708' | 'big5-hkscs' | 'big5' | 'chinese' | 'cn-big5' | 'cp1250' | 'cp1251' | 'cp1252' | 'cp1253' | 'cp1254' | 'cp1255' | 'cp1256' | 'cp1257' | 'cp1258' | 'cp819' | 'cp866' | 'csbig5' | 'cseuckr' | 'cseucpkdfmtjapanese' | 'csgb2312' | 'csibm866' | 'csiso2022jp' | 'csiso2022kr' | 'csiso58gb231280' | 'csiso88596e' | 'csiso88596i' | 'csiso88598e' | 'csiso88598i' | 'csisolatin1' | 'csisolatin2' | 'csisolatin3' | 'csisolatin4' | 'csisolatin5' | 'csisolatin6' | 'csisolatin9' | 'csisolatinarabic' | 'csisolatincyrillic' | 'csisolatingreek' | 'csisolatinhebrew' | 'cskoi8r' | 'csksc56011987' | 'csmacintosh' | 'csshiftjis' | 'cyrillic' | 'dos-874' | 'ecma-114' | 'ecma-118' | 'elot_928' | 'euc-jp' | 'euc-kr' | 'gb_2312-80' | 'gb_2312' | 'gb18030' | 'gb2312' | 'gbk' | 'greek' | 'greek8' | 'hebrew' | 'hz-gb-2312' | 'ibm819' | 'ibm866' | 'iso_8859-1:1987' | 'iso_8859-1' | 'iso_8859-2:1987' | 'iso_8859-2' | 'iso_8859-3:1988' | 'iso_8859-3' | 'iso_8859-4:1988' | 'iso_8859-4' | 'iso_8859-5:1988' | 'iso_8859-5' | 'iso_8859-6:1987' | 'iso_8859-6' | 'iso_8859-7:1987' | 'iso_8859-7' | 'iso_8859-8:1988' | 'iso_8859-8' | 'iso_8859-9:1989' | 'iso_8859-9' | 'iso-2022-cn-ext' | 'iso-2022-cn' | 'iso-2022-jp' | 'iso-2022-kr' | 'iso-8859-1' | 'iso-8859-10' | 'iso-8859-11' | 'iso-8859-13' | 'iso-8859-14' | 'iso-8859-15' | 'iso-8859-16' | 'iso-8859-2' | 'iso-8859-3' | 'iso-8859-4' | 'iso-8859-5' | 'iso-8859-6-e' | 'iso-8859-6-i' | 'iso-8859-6' | 'iso-8859-7' | 'iso-8859-8-e' | 'iso-8859-8-i' | 'iso-8859-8' | 'iso-8859-9' | 'iso-ir-100' | 'iso-ir-101' | 'iso-ir-109' | 'iso-ir-110' | 'iso-ir-126' | 'iso-ir-127' | 'iso-ir-138' | 'iso-ir-144' | 'iso-ir-148' | 'iso-ir-149' | 'iso-ir-157' | 'iso-ir-58' | 'iso8859-1' | 'iso8859-10' | 'iso8859-11' | 'iso8859-13' | 'iso8859-14' | 'iso8859-15' | 'iso8859-2' | 'iso8859-3' | 'iso8859-4' | 'iso8859-6' | 'iso8859-7' | 'iso8859-8' | 'iso8859-9' | 'iso88591' | 'iso885910' | 'iso885911' | 'iso885913' | 'iso885914' | 'iso885915' | 'iso88592' | 'iso88593' | 'iso88594' | 'iso88595' | 'iso88596' | 'iso88597' | 'iso88598' | 'iso88599' | 'koi' | 'koi8_r' | 'koi8-r' | 'koi8-u' | 'koi8' | 'korean' | 'ks_c_5601-1987' | 'ks_c_5601-1989' | 'ksc_5601' | 'ksc5601' | 'l1' | 'l2' | 'l3' | 'l4' | 'l5' | 'l6' | 'l9' | 'latin1' | 'latin2' | 'latin3' | 'latin4' | 'latin5' | 'latin6' | 'latin9' | 'logical' | 'mac' | 'macintosh' | 'ms_kanji' | 'shift_jis' | 'shift-jis' | 'sjis' | 'sun_eu_greek' | 'tis-620' | 'unicode-1-1-utf-8' | 'us-ascii' | 'utf-16' | 'utf-16be' | 'utf-16le' | 'utf-8' | 'utf8' | 'visual' | 'windows-1250' | 'windows-1251' | 'windows-1252' | 'windows-1253' | 'windows-1254' | 'windows-1255' | 'windows-1256' | 'windows-1257' | 'windows-1258' | 'windows-31j' | 'windows-874' | 'windows-949' | 'x-cp1250' | 'x-cp1251' | 'x-cp1252' | 'x-cp1253' | 'x-cp1254' | 'x-cp1255' | 'x-cp1256' | 'x-cp1257' | 'x-cp1258' | 'x-euc-jp' | 'x-gbk' | 'x-mac-cyrillic' | 'x-mac-roman' | 'x-mac-ukrainian' | 'x-sjis' | 'x-user-defined' | 'x-x-big5'; declare class TextDecoder { constructor( encoding?: TextDecoder$availableEncodings, options?: { fatal: boolean, ... }, ): void; encoding: TextDecoder$availableEncodings; fatal: boolean; ignoreBOM: boolean; decode( buffer?: ArrayBuffer | $ArrayBufferView, options?: { stream: boolean, ... }, ): string; } declare class TextDecoderStream { constructor( encoding?: TextDecoder$availableEncodings, options?: { fatal?: boolean, ignoreBOM?: boolean, ... }, ): void; encoding: TextDecoder$availableEncodings; fatal: boolean; ignoreBOM: boolean; readable: ReadableStream; writable: WritableStream; } declare class MessagePort extends EventTarget { postMessage(message: any, transfer?: Iterable): void; start(): void; close(): void; onmessage: null | ((ev: MessageEvent) => mixed); onmessageerror: null | ((ev: MessageEvent) => mixed); } declare class MessageChannel { port1: MessagePort; port2: MessagePort; } declare class VRDisplay extends EventTarget { capabilities: VRDisplayCapabilities; depthFar: number; depthNear: number; displayId: number; displayName: string; isPresenting: boolean; stageParameters: null | VRStageParameters; cancelAnimationFrame(number): void; exitPresent(): Promise; getEyeParameters(VREye): VREyeParameters; getFrameData(VRFrameData): boolean; getLayers(): VRLayerInit[]; requestAnimationFrame(cb: (number) => mixed): number; requestPresent(VRLayerInit[]): Promise; submitFrame(): void; } type VRSource = HTMLCanvasElement; type VRLayerInit = { leftBounds?: number[], rightBounds?: number[], source?: null | VRSource, ... }; type VRDisplayCapabilities = { canPresent: boolean, hasExternalDisplay: boolean, hasPosition: boolean, maxLayers: number, ... }; type VREye = 'left' | 'right'; type VRPose = { angularAcceleration?: Float32Array, angularVelocity?: Float32Array, linearAcceleration?: Float32Array, linearVelocity?: Float32Array, orientation?: Float32Array, position?: Float32Array, ... }; declare class VRFrameData { leftProjectionMatrix: Float32Array; leftViewMatrix: Float32Array; pose: VRPose; rightProjectionMatrix: Float32Array; rightViewMatrix: Float32Array; timestamp: number; } type VREyeParameters = { offset: Float32Array, renderWidth: number, renderHeight: number, ... }; type VRStageParameters = { sittingToStandingTransform: Float32Array, sizeX: number, sizeZ: number, ... }; type VRDisplayEventReason = | 'mounted' | 'navigation' | 'requested' | 'unmounted'; type VRDisplayEventInit = { display: VRDisplay, reason: VRDisplayEventReason, ... }; declare class VRDisplayEvent extends Event { constructor(type: string, eventInitDict: VRDisplayEventInit): void; display: VRDisplay; reason?: VRDisplayEventReason; } declare class MediaQueryListEvent { matches: boolean; media: string; } declare type MediaQueryListListener = (MediaQueryListEvent) => void; declare class MediaQueryList extends EventTarget { matches: boolean; media: string; addListener: (MediaQueryListListener) => void; removeListener: (MediaQueryListListener) => void; onchange: MediaQueryListListener; } declare var matchMedia: (string) => MediaQueryList; // https://w3c.github.io/webappsec-credential-management/#idl-index declare type CredMgmtCredentialRequestOptions = { mediation?: 'silent' | 'optional' | 'required', signal?: AbortSignal, ... }; declare type CredMgmtCredentialCreationOptions = { signal: AbortSignal, ... }; declare interface CredMgmtCredential { id: string; type: string; } declare interface CredMgmtPasswordCredential extends CredMgmtCredential { password: string; } declare interface CredMgmtCredentialsContainer { get(option?: CredMgmtCredentialRequestOptions): Promise; store(credential: CredMgmtCredential): Promise; create( creationOption?: CredMgmtCredentialCreationOptions, ): Promise; preventSilentAccess(): Promise; } type SpeechSynthesisErrorCode = | 'canceled' | 'interrupted' | 'audio-busy' | 'audio-hardware' | 'network' | 'synthesis-unavailable' | 'synthesis-failed' | 'language-unavailable' | 'voice-unavailable' | 'text-too-long' | 'invalid-argument' | 'not-allowed'; declare class SpeechSynthesis extends EventTarget { +pending: boolean; +speaking: boolean; +paused: boolean; onvoiceschanged: ?(ev: Event) => mixed; speak(utterance: SpeechSynthesisUtterance): void; cancel(): void; pause(): void; resume(): void; getVoices(): Array; } declare var speechSynthesis: SpeechSynthesis; declare class SpeechSynthesisUtterance extends EventTarget { constructor(text?: string): void; text: string; lang: string; voice: SpeechSynthesisVoice | null; volume: number; rate: number; pitch: number; onstart: ?(ev: SpeechSynthesisEvent) => mixed; onend: ?(ev: SpeechSynthesisEvent) => mixed; onerror: ?(ev: SpeechSynthesisErrorEvent) => mixed; onpause: ?(ev: SpeechSynthesisEvent) => mixed; onresume: ?(ev: SpeechSynthesisEvent) => mixed; onmark: ?(ev: SpeechSynthesisEvent) => mixed; onboundary: ?(ev: SpeechSynthesisEvent) => mixed; } type SpeechSynthesisEvent$Init = Event$Init & { utterance: SpeechSynthesisUtterance, charIndex?: number, charLength?: number, elapsedTime?: number, name?: string, ... }; declare class SpeechSynthesisEvent extends Event { constructor(type: string, eventInitDict?: SpeechSynthesisEvent$Init): void; +utterance: SpeechSynthesisUtterance; charIndex: number; charLength: number; elapsedTime: number; name: string; } type SpeechSynthesisErrorEvent$Init = SpeechSynthesisEvent$Init & { error: SpeechSynthesisErrorCode, ... }; declare class SpeechSynthesisErrorEvent extends SpeechSynthesisEvent { constructor( type: string, eventInitDict?: SpeechSynthesisErrorEvent$Init, ): void; +error: SpeechSynthesisErrorCode; } declare class SpeechSynthesisVoice { +voiceURI: string; +name: string; +lang: string; +localService: boolean; +default: boolean; } type SpeechRecognitionErrorCode = | 'no-speech' | 'aborted' | 'audio-capture' | 'not-allowed' | 'service-not-allowed' | 'bad-grammar' | 'language-not-supported'; declare class SpeechGrammar { constructor(): void; src: string; weight?: number; } declare class SpeechGrammarList { +length: number; item(index: number): SpeechGrammar; addFromURI(src: string, weight?: number): void; addFromString(string: string, weight?: number): void; } declare class SpeechRecognitionAlternative { +transcript: string; +confidence: number; } declare class SpeechRecognitionResult { +isFinal: boolean; +length: number; item(index: number): SpeechRecognitionAlternative; } declare class SpeechRecognitionResultList { +length: number; item(index: number): SpeechRecognitionResult; } type SpeechRecognitionEvent$Init = Event$Init & { emma: any, interpretation: any, resultIndex: number, results: SpeechRecognitionResultList, ... }; declare class SpeechRecognitionEvent extends Event { constructor(type: string, eventInitDict?: SpeechRecognitionEvent$Init): void; +emma: any; +interpretation: any; +resultIndex: number; +results: SpeechRecognitionResultList; } type SpeechRecognitionErrorEvent$Init = SpeechRecognitionEvent$Init & { error: SpeechRecognitionErrorCode, ... }; declare class SpeechRecognitionErrorEvent extends SpeechRecognitionEvent { constructor( type: string, eventInitDict?: SpeechRecognitionErrorEvent$Init, ): void; +error: SpeechRecognitionErrorCode; +message: string; } declare class SpeechRecognition extends EventTarget { constructor(): void; +grammars: SpeechGrammar[]; +lang: string; +continuous: boolean; +interimResults: boolean; +maxAlternatives: number; +serviceURI: string; onaudiostart: ?(ev: Event) => mixed; onaudioend: ?(ev: Event) => mixed; onend: ?(ev: Event) => mixed; onerror: ?(ev: Event) => mixed; onnomatch: ?(ev: Event) => mixed; onsoundstart: ?(ev: Event) => mixed; onsoundend: ?(ev: Event) => mixed; onspeechstart: ?(ev: Event) => mixed; onspeechend: ?(ev: Event) => mixed; onstart: ?(ev: Event) => mixed; abort(): void; start(): void; stop(): void; } /* Trusted Types * https://w3c.github.io/trusted-types/dist/spec/#trusted-types */ declare class TrustedHTML { toString(): string; toJSON(): string; } declare class TrustedScript { toString(): string; toJSON(): string; } declare class TrustedScriptURL { toString(): string; toJSON(): string; } declare class TrustedTypePolicy { +name: string; createHTML(input: string, ...args: Array): TrustedHTML; createScript(input: string, ...args: Array): TrustedScript; createScriptURL(input: string, ...args: Array): TrustedScriptURL; } declare type TrustedTypePolicyOptions = {| createHTML?: (string, ...args: Array) => string, createScript?: (string, ...args: Array) => string, createScriptURL?: (string, ...args: Array) => string, |}; // window.trustedTypes?: TrustedTypePolicyFactory declare class TrustedTypePolicyFactory { +emptyHTML: TrustedHTML; +emptyScript: TrustedScript; +defaultPolicy: ?TrustedTypePolicy; +isHTML: (value: mixed) => value is TrustedHTML; +isScript: (value: mixed) => value is TrustedScript; +isScriptURL: (value: mixed) => value is TrustedScriptURL; createPolicy( policyName: string, policyOptions?: TrustedTypePolicyOptions, ): TrustedTypePolicy; getAttributeType( tagName: string, attribute?: string, elementNS?: string, attrNS?: string, ): null | string; getPropertyType( tagName: string, property: string, elementNS?: string, ): null | string; } // https://wicg.github.io/webusb/ // https://developer.mozilla.org/en-US/docs/Web/API/USBDevice declare class USBDevice { configuration: USBConfiguration; configurations: Array; deviceClass: number; deviceProtocol: number; deviceSubclass: number; deviceVersionMajor: number; deviceVersionMinor: number; deviceVersionSubminor: number; manufacturerName: ?string; opened: boolean; productId: number; productName: ?string; serialNumber: ?string; usbVersionMajor: number; usbVersionMinor: number; usbVersionSubminor: number; vendorId: number; claimInterface(interfaceNumber: number): Promise; clearHalt(direction: 'in' | 'out', endpointNumber: number): Promise; close(): Promise; controlTransferIn( setup: SetUpOptions, length: number, ): Promise; controlTransferOut( setup: SetUpOptions, data: ArrayBuffer, ): Promise; forget(): Promise; isochronousTransferIn( endpointNumber: number, packetLengths: Array, ): Promise; isochronousTransferOut( endpointNumber: number, data: ArrayBuffer, packetLengths: Array, ): Promise; open(): Promise; releaseInterface(interfaceNumber: number): Promise; reset(): Promise; selectAlternateInterface( interfaceNumber: number, alternateSetting: number, ): Promise; selectConfiguration(configurationValue: number): Promise; transferIn( endpointNumber: number, length: number, ): Promise; transferOut( endpointNumber: number, data: ArrayBuffer, ): Promise; } declare class USB extends EventTarget { getDevices(): Promise>; requestDevice(options: USBDeviceRequestOptions): Promise; } declare type USBDeviceFilter = {| vendorId?: number, productId?: number, classCode?: number, subclassCode?: number, protocolCode?: number, serialNumber?: string, |}; declare type USBDeviceRequestOptions = {| filters: Array, exclusionFilters?: Array, |}; declare class USBConfiguration { constructor(): void; configurationName: ?string; configurationValue: number; interfaces: $ReadOnlyArray; } declare class USBInterface { constructor(): void; interfaceNumber: number; alternate: USBAlternateInterface; alternates: Array; claimed: boolean; } declare class USBAlternateInterface { constructor(): void; alternateSetting: number; interfaceClass: number; interfaceSubclass: number; interfaceProtocol: number; interfaceName: ?string; endpoints: Array; } declare class USBEndpoint { constructor(): void; endpointNumber: number; direction: 'in' | 'out'; type: 'bulk' | 'interrupt' | 'isochronous'; packetSize: number; } declare class USBOutTransferResult { constructor(): void; bytesWritten: number; status: 'ok' | 'stall'; } declare class USBInTransferResult { constructor(): void; data: DataView; status: 'ok' | 'stall' | 'babble'; } declare class USBIsochronousInTransferResult { constructor(): void; data: DataView; packets: Array; } declare class USBIsochronousInTransferPacket { constructor(): void; data: DataView; status: 'ok' | 'stall' | 'babble'; } declare class USBIsochronousOutTransferResult { constructor(): void; packets: Array; } declare class USBIsochronousOutTransferPacket { constructor(): void; bytesWritten: number; status: 'ok' | 'stall'; } type SetUpOptions = { requestType: string, recipient: string, request: number, value: number, index: number, ... }; declare type FileSystemHandleKind = 'file' | 'directory'; // https://wicg.github.io/file-system-access/#api-filesystemhandle declare class FileSystemHandle { +kind: FileSystemHandleKind; +name: string; isSameEntry: (other: FileSystemHandle) => Promise; queryPermission?: ( descriptor: FileSystemHandlePermissionDescriptor, ) => Promise; requestPermission?: ( descriptor: FileSystemHandlePermissionDescriptor, ) => Promise; } // https://fs.spec.whatwg.org/#api-filesystemfilehandle declare class FileSystemFileHandle extends FileSystemHandle { +kind: 'file'; constructor(name: string): void; getFile(): Promise; createSyncAccessHandle(): Promise; createWritable(options?: {| keepExistingData?: boolean, |}): Promise; } // https://fs.spec.whatwg.org/#api-filesystemdirectoryhandle declare class FileSystemDirectoryHandle extends FileSystemHandle { +kind: 'directory'; constructor(name: string): void; getDirectoryHandle( name: string, options?: {| create?: boolean |}, ): Promise; getFileHandle( name: string, options?: {| create?: boolean |}, ): Promise; removeEntry(name: string, options?: {| recursive?: boolean |}): Promise; resolve(possibleDescendant: FileSystemHandle): Promise | null>; // Async iterator functions @@asyncIterator(): AsyncIterator<[string, FileSystemHandle]>; entries(): AsyncIterator<[string, FileSystemHandle]>; keys(): AsyncIterator; values(): AsyncIterator; } // https://fs.spec.whatwg.org/#api-filesystemsyncaccesshandle declare class FileSystemSyncAccessHandle { close(): void; flush(): void; getSize(): number; read(buffer: ArrayBuffer, options?: {| at: number |}): number; truncate(newSize: number): void; write(buffer: ArrayBuffer, options?: {| at: number |}): number; } // https://streams.spec.whatwg.org/#default-writer-class declare class WritableStreamDefaultWriter { +closed: Promise; +desiredSize: number; +ready: Promise; constructor(): void; abort(reason?: string): Promise; close(): Promise; releaseLock(): void; write(chunk: any): Promise; } // https://streams.spec.whatwg.org/#ws-class declare class WriteableStream { +locked: boolean; constructor(): void; abort(reason: string): Promise; close(): Promise; getWriter(): WritableStreamDefaultWriter; } // https://fs.spec.whatwg.org/#dictdef-writeparams declare type FileSystemWriteableFileStreamDataTypes = | ArrayBuffer | $TypedArray | DataView | Blob | string; // https://fs.spec.whatwg.org/#dictdef-writeparams declare type FileSystemWriteableFileStreamData = | FileSystemWriteableFileStreamDataTypes | {| type: 'write', position?: number, data: FileSystemWriteableFileStreamDataTypes, |} | {| type: 'seek', position: number, data: FileSystemWriteableFileStreamDataTypes, |} | {| type: 'size', size: number, |}; // https://fs.spec.whatwg.org/#api-filesystemwritablefilestream declare class FileSystemWritableFileStream extends WriteableStream { write(data: FileSystemWriteableFileStreamData): Promise; truncate(size: number): Promise; seek(position: number): Promise; } ================================================ FILE: flow-typed/environments/cssom.js ================================================ declare class StyleSheet { disabled: boolean; +href: string; +media: MediaList; +ownerNode: Node; +parentStyleSheet: ?StyleSheet; +title: string; +type: string; } declare class StyleSheetList { @@iterator(): Iterator; length: number; [index: number]: StyleSheet; } declare class MediaList { @@iterator(): Iterator; mediaText: string; length: number; item(index: number): ?string; deleteMedium(oldMedium: string): void; appendMedium(newMedium: string): void; [index: number]: string; } declare class CSSStyleSheet extends StyleSheet { +cssRules: CSSRuleList; +ownerRule: ?CSSRule; deleteRule(index: number): void; insertRule(rule: string, index: number): number; replace(text: string): Promise; replaceSync(text: string): void; } declare class CSSGroupingRule extends CSSRule { +cssRules: CSSRuleList; deleteRule(index: number): void; insertRule(rule: string, index: number): number; } declare class CSSConditionRule extends CSSGroupingRule { conditionText: string; } declare class CSSMediaRule extends CSSConditionRule { +media: MediaList; } declare class CSSStyleRule extends CSSRule { selectorText: string; +style: CSSStyleDeclaration; } declare class CSSSupportsRule extends CSSConditionRule {} declare class CSSRule { cssText: string; +parentRule: ?CSSRule; +parentStyleSheet: ?CSSStyleSheet; +type: number; static STYLE_RULE: number; static MEDIA_RULE: number; static FONT_FACE_RULE: number; static PAGE_RULE: number; static IMPORT_RULE: number; static CHARSET_RULE: number; static UNKNOWN_RULE: number; static KEYFRAMES_RULE: number; static KEYFRAME_RULE: number; static NAMESPACE_RULE: number; static COUNTER_STYLE_RULE: number; static SUPPORTS_RULE: number; static DOCUMENT_RULE: number; static FONT_FEATURE_VALUES_RULE: number; static VIEWPORT_RULE: number; static REGION_STYLE_RULE: number; } declare class CSSKeyframeRule extends CSSRule { keyText: string; +style: CSSStyleDeclaration; } declare class CSSKeyframesRule extends CSSRule { name: string; +cssRules: CSSRuleList; appendRule(rule: string): void; deleteRule(select: string): void; findRule(select: string): CSSKeyframeRule | null; } declare class CSSRuleList { @@iterator(): Iterator; length: number; item(index: number): ?CSSRule; [index: number]: CSSRule; } declare class CSSStyleDeclaration { @@iterator(): Iterator; /* DOM CSS Properties */ alignContent: string; alignItems: string; alignSelf: string; all: string; animation: string; animationDelay: string; animationDirection: string; animationDuration: string; animationFillMode: string; animationIterationCount: string; animationName: string; animationPlayState: string; animationTimingFunction: string; backdropFilter: string; webkitBackdropFilter: string; backfaceVisibility: string; background: string; backgroundAttachment: string; backgroundBlendMode: string; backgroundClip: string; backgroundColor: string; backgroundImage: string; backgroundOrigin: string; backgroundPosition: string; backgroundPositionX: string; backgroundPositionY: string; backgroundRepeat: string; backgroundSize: string; blockSize: string; border: string; borderBlockEnd: string; borderBlockEndColor: string; borderBlockEndStyle: string; borderBlockEndWidth: string; borderBlockStart: string; borderBlockStartColor: string; borderBlockStartStyle: string; borderBlockStartWidth: string; borderBottom: string; borderBottomColor: string; borderBottomLeftRadius: string; borderBottomRightRadius: string; borderBottomStyle: string; borderBottomWidth: string; borderCollapse: string; borderColor: string; borderImage: string; borderImageOutset: string; borderImageRepeat: string; borderImageSlice: string; borderImageSource: string; borderImageWidth: string; borderInlineEnd: string; borderInlineEndColor: string; borderInlineEndStyle: string; borderInlineEndWidth: string; borderInlineStart: string; borderInlineStartColor: string; borderInlineStartStyle: string; borderInlineStartWidth: string; borderLeft: string; borderLeftColor: string; borderLeftStyle: string; borderLeftWidth: string; borderRadius: string; borderRight: string; borderRightColor: string; borderRightStyle: string; borderRightWidth: string; borderSpacing: string; borderStyle: string; borderTop: string; borderTopColor: string; borderTopLeftRadius: string; borderTopRightRadius: string; borderTopStyle: string; borderTopWidth: string; borderWidth: string; bottom: string; boxDecorationBreak: string; boxShadow: string; boxSizing: string; breakAfter: string; breakBefore: string; breakInside: string; captionSide: string; clear: string; clip: string; clipPath: string; color: string; columns: string; columnCount: string; columnFill: string; columnGap: string; columnRule: string; columnRuleColor: string; columnRuleStyle: string; columnRuleWidth: string; columnSpan: string; columnWidth: string; contain: string; content: string; counterIncrement: string; counterReset: string; cursor: string; direction: string; display: string; emptyCells: string; filter: string; flex: string; flexBasis: string; flexDirection: string; flexFlow: string; flexGrow: string; flexShrink: string; flexWrap: string; float: string; font: string; fontFamily: string; fontFeatureSettings: string; fontKerning: string; fontLanguageOverride: string; fontSize: string; fontSizeAdjust: string; fontStretch: string; fontStyle: string; fontSynthesis: string; fontVariant: string; fontVariantAlternates: string; fontVariantCaps: string; fontVariantEastAsian: string; fontVariantLigatures: string; fontVariantNumeric: string; fontVariantPosition: string; fontWeight: string; grad: string; grid: string; gridArea: string; gridAutoColumns: string; gridAutoFlow: string; gridAutoPosition: string; gridAutoRows: string; gridColumn: string; gridColumnStart: string; gridColumnEnd: string; gridRow: string; gridRowStart: string; gridRowEnd: string; gridTemplate: string; gridTemplateAreas: string; gridTemplateRows: string; gridTemplateColumns: string; height: string; hyphens: string; imageRendering: string; imageResolution: string; imageOrientation: string; imeMode: string; inherit: string; initial: string; inlineSize: string; isolation: string; justifyContent: string; left: string; letterSpacing: string; lineBreak: string; lineHeight: string; listStyle: string; listStyleImage: string; listStylePosition: string; listStyleType: string; margin: string; marginBlockEnd: string; marginBlockStart: string; marginBottom: string; marginInlineEnd: string; marginInlineStart: string; marginLeft: string; marginRight: string; marginTop: string; marks: string; mask: string; maskType: string; maxBlockSize: string; maxHeight: string; maxInlineSize: string; maxWidth: string; minBlockSize: string; minHeight: string; minInlineSize: string; minWidth: string; mixBlendMode: string; mozTransform: string; mozTransformOrigin: string; mozTransitionDelay: string; mozTransitionDuration: string; mozTransitionProperty: string; mozTransitionTimingFunction: string; objectFit: string; objectPosition: string; offsetBlockEnd: string; offsetBlockStart: string; offsetInlineEnd: string; offsetInlineStart: string; opacity: string; order: string; orphans: string; outline: string; outlineColor: string; outlineOffset: string; outlineStyle: string; outlineWidth: string; overflow: string; overflowWrap: string; overflowX: string; overflowY: string; padding: string; paddingBlockEnd: string; paddingBlockStart: string; paddingBottom: string; paddingInlineEnd: string; paddingInlineStart: string; paddingLeft: string; paddingRight: string; paddingTop: string; pageBreakAfter: string; pageBreakBefore: string; pageBreakInside: string; perspective: string; perspectiveOrigin: string; pointerEvents: string; position: string; quotes: string; rad: string; resize: string; right: string; rubyAlign: string; rubyMerge: string; rubyPosition: string; scrollBehavior: string; scrollSnapCoordinate: string; scrollSnapDestination: string; scrollSnapPointsX: string; scrollSnapPointsY: string; scrollSnapType: string; shapeImageThreshold: string; shapeMargin: string; shapeOutside: string; tableLayout: string; tabSize: string; textAlign: string; textAlignLast: string; textCombineUpright: string; textDecoration: string; textDecorationColor: string; textDecorationLine: string; textDecorationStyle: string; textIndent: string; textOrientation: string; textOverflow: string; textRendering: string; textShadow: string; textTransform: string; textUnderlinePosition: string; top: string; touchAction: string; transform: string; transformOrigin: string; transformStyle: string; transition: string; transitionDelay: string; transitionDuration: string; transitionProperty: string; transitionTimingFunction: string; turn: string; unicodeBidi: string; unicodeRange: string; userSelect: string; verticalAlign: string; visibility: string; webkitOverflowScrolling: string; webkitTransform: string; webkitTransformOrigin: string; webkitTransitionDelay: string; webkitTransitionDuration: string; webkitTransitionProperty: string; webkitTransitionTimingFunction: string; whiteSpace: string; widows: string; width: string; willChange: string; wordBreak: string; wordSpacing: string; wordWrap: string; writingMode: string; zIndex: string; cssFloat: string; cssText: string; getPropertyPriority(property: string): string; getPropertyValue(property: string): string; item(index: number): string; [index: number]: string; length: number; parentRule: CSSRule; removeProperty(property: string): string; setProperty(property: string, value: ?string, priority: ?string): void; setPropertyPriority(property: string, priority: string): void; } ================================================ FILE: flow-typed/environments/dom.js ================================================ /* Files */ declare class Blob { constructor( blobParts?: Array, options?: { type?: string, endings?: string, ... }, ): void; isClosed: boolean; size: number; type: string; close(): void; slice(start?: number, end?: number, contentType?: string): Blob; arrayBuffer(): Promise; text(): Promise; stream(): ReadableStream; } declare class FileReader extends EventTarget { +EMPTY: 0; +LOADING: 1; +DONE: 2; +error: null | DOMError; +readyState: 0 | 1 | 2; +result: null | string | ArrayBuffer; abort(): void; onabort: null | ((ev: ProgressEvent) => any); onerror: null | ((ev: ProgressEvent) => any); onload: null | ((ev: ProgressEvent) => any); onloadend: null | ((ev: ProgressEvent) => any); onloadstart: null | ((ev: ProgressEvent) => any); onprogress: null | ((ev: ProgressEvent) => any); readAsArrayBuffer(blob: Blob): void; readAsBinaryString(blob: Blob): void; readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; } declare type FilePropertyBag = { type?: string, lastModified?: number, ... }; declare class File extends Blob { constructor( fileBits: $ReadOnlyArray, filename: string, options?: FilePropertyBag, ): void; lastModified: number; name: string; } declare class FileList { @@iterator(): Iterator; length: number; item(index: number): File; [index: number]: File; } declare class DOMError { name: string; } declare interface ShadowRoot extends DocumentFragment { +delegatesFocus: boolean; +host: Element; // flowlint unsafe-getters-setters:off get innerHTML(): string; set innerHTML(value: string | TrustedHTML): void; // flowlint unsafe-getters-setters:error +mode: ShadowRootMode; // From DocumentOrShadowRoot Mixin. +styleSheets: StyleSheetList; adoptedStyleSheets: Array; } declare type ShadowRootMode = 'open' | 'closed'; declare type ShadowRootInit = { delegatesFocus?: boolean, mode: ShadowRootMode, ... }; declare type ScrollToOptions = { top?: number, left?: number, behavior?: 'auto' | 'smooth', ... }; type EventHandler = (event: Event) => mixed; type EventListener = { handleEvent: EventHandler, ... } | EventHandler; type MouseEventHandler = (event: MouseEvent) => mixed; type MouseEventListener = | { handleEvent: MouseEventHandler, ... } | MouseEventHandler; type FocusEventHandler = (event: FocusEvent) => mixed; type FocusEventListener = | { handleEvent: FocusEventHandler, ... } | FocusEventHandler; type KeyboardEventHandler = (event: KeyboardEvent) => mixed; type KeyboardEventListener = | { handleEvent: KeyboardEventHandler, ... } | KeyboardEventHandler; type InputEventHandler = (event: InputEvent) => mixed; type InputEventListener = | { handleEvent: InputEventHandler, ... } | InputEventHandler; type TouchEventHandler = (event: TouchEvent) => mixed; type TouchEventListener = | { handleEvent: TouchEventHandler, ... } | TouchEventHandler; type WheelEventHandler = (event: WheelEvent) => mixed; type WheelEventListener = | { handleEvent: WheelEventHandler, ... } | WheelEventHandler; type AbortProgressEventHandler = (event: ProgressEvent) => mixed; type AbortProgressEventListener = | { handleEvent: AbortProgressEventHandler, ... } | AbortProgressEventHandler; type ProgressEventHandler = (event: ProgressEvent) => mixed; type ProgressEventListener = | { handleEvent: ProgressEventHandler, ... } | ProgressEventHandler; type DragEventHandler = (event: DragEvent) => mixed; type DragEventListener = | { handleEvent: DragEventHandler, ... } | DragEventHandler; type PointerEventHandler = (event: PointerEvent) => mixed; type PointerEventListener = | { handleEvent: PointerEventHandler, ... } | PointerEventHandler; type AnimationEventHandler = (event: AnimationEvent) => mixed; type AnimationEventListener = | { handleEvent: AnimationEventHandler, ... } | AnimationEventHandler; type ClipboardEventHandler = (event: ClipboardEvent) => mixed; type ClipboardEventListener = | { handleEvent: ClipboardEventHandler, ... } | ClipboardEventHandler; type TransitionEventHandler = (event: TransitionEvent) => mixed; type TransitionEventListener = | { handleEvent: TransitionEventHandler, ... } | TransitionEventHandler; type MessageEventHandler = (event: MessageEvent) => mixed; type MessageEventListener = | { handleEvent: MessageEventHandler, ... } | MessageEventHandler; type BeforeUnloadEventHandler = (event: BeforeUnloadEvent) => mixed; type BeforeUnloadEventListener = | { handleEvent: BeforeUnloadEventHandler, ... } | BeforeUnloadEventHandler; type StorageEventHandler = (event: StorageEvent) => mixed; type StorageEventListener = | { handleEvent: StorageEventHandler, ... } | StorageEventHandler; type SecurityPolicyViolationEventHandler = ( event: SecurityPolicyViolationEvent, ) => mixed; type SecurityPolicyViolationEventListener = | { handleEvent: SecurityPolicyViolationEventHandler, ... } | SecurityPolicyViolationEventHandler; type USBConnectionEventHandler = (event: USBConnectionEvent) => mixed; type USBConnectionEventListener = | { handleEvent: USBConnectionEventHandler, ... } | USBConnectionEventHandler; type MediaKeySessionType = 'temporary' | 'persistent-license'; type MediaKeyStatus = | 'usable' | 'expired' | 'released' | 'output-restricted' | 'output-downscaled' | 'status-pending' | 'internal-error'; type MouseEventTypes = | 'contextmenu' | 'mousedown' | 'mouseenter' | 'mouseleave' | 'mousemove' | 'mouseout' | 'mouseover' | 'mouseup' | 'click' | 'dblclick'; type FocusEventTypes = 'blur' | 'focus' | 'focusin' | 'focusout'; type KeyboardEventTypes = 'keydown' | 'keyup' | 'keypress'; type InputEventTypes = 'input' | 'beforeinput'; type TouchEventTypes = 'touchstart' | 'touchmove' | 'touchend' | 'touchcancel'; type WheelEventTypes = 'wheel'; type AbortProgressEventTypes = 'abort'; type ProgressEventTypes = | 'abort' | 'error' | 'load' | 'loadend' | 'loadstart' | 'progress' | 'timeout'; type DragEventTypes = | 'drag' | 'dragend' | 'dragenter' | 'dragexit' | 'dragleave' | 'dragover' | 'dragstart' | 'drop'; type PointerEventTypes = | 'pointerover' | 'pointerenter' | 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel' | 'pointerout' | 'pointerleave' | 'gotpointercapture' | 'lostpointercapture'; type AnimationEventTypes = | 'animationstart' | 'animationend' | 'animationiteration'; type ClipboardEventTypes = 'clipboardchange' | 'cut' | 'copy' | 'paste'; type TransitionEventTypes = | 'transitionrun' | 'transitionstart' | 'transitionend' | 'transitioncancel'; type MessageEventTypes = string; type BeforeUnloadEventTypes = 'beforeunload'; type StorageEventTypes = 'storage'; type SecurityPolicyViolationEventTypes = 'securitypolicyviolation'; type USBConnectionEventTypes = 'connect' | 'disconnect'; type ToggleEventTypes = 'beforetoggle' | 'toggle'; type EventListenerOptionsOrUseCapture = | boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal, ... }; declare class EventTarget { addEventListener( type: MouseEventTypes, listener: MouseEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: FocusEventTypes, listener: FocusEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: KeyboardEventTypes, listener: KeyboardEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: InputEventTypes, listener: InputEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: TouchEventTypes, listener: TouchEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: WheelEventTypes, listener: WheelEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: AbortProgressEventTypes, listener: AbortProgressEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: ProgressEventTypes, listener: ProgressEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: DragEventTypes, listener: DragEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: PointerEventTypes, listener: PointerEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: AnimationEventTypes, listener: AnimationEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: ClipboardEventTypes, listener: ClipboardEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: TransitionEventTypes, listener: TransitionEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: MessageEventTypes, listener: MessageEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: BeforeUnloadEventTypes, listener: BeforeUnloadEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: StorageEventTypes, listener: StorageEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: SecurityPolicyViolationEventTypes, listener: SecurityPolicyViolationEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: USBConnectionEventTypes, listener: USBConnectionEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; addEventListener( type: string, listener: EventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: MouseEventTypes, listener: MouseEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: FocusEventTypes, listener: FocusEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: KeyboardEventTypes, listener: KeyboardEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: InputEventTypes, listener: InputEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: TouchEventTypes, listener: TouchEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: WheelEventTypes, listener: WheelEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: AbortProgressEventTypes, listener: AbortProgressEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: ProgressEventTypes, listener: ProgressEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: DragEventTypes, listener: DragEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: PointerEventTypes, listener: PointerEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: AnimationEventTypes, listener: AnimationEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: ClipboardEventTypes, listener: ClipboardEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: TransitionEventTypes, listener: TransitionEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: MessageEventTypes, listener: MessageEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: BeforeUnloadEventTypes, listener: BeforeUnloadEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: StorageEventTypes, listener: StorageEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: SecurityPolicyViolationEventTypes, listener: SecurityPolicyViolationEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: USBConnectionEventTypes, listener: USBConnectionEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; removeEventListener( type: string, listener: EventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture, ): void; attachEvent?: (type: MouseEventTypes, listener: MouseEventListener) => void; attachEvent?: (type: FocusEventTypes, listener: FocusEventListener) => void; attachEvent?: ( type: KeyboardEventTypes, listener: KeyboardEventListener, ) => void; attachEvent?: (type: InputEventTypes, listener: InputEventListener) => void; attachEvent?: (type: TouchEventTypes, listener: TouchEventListener) => void; attachEvent?: (type: WheelEventTypes, listener: WheelEventListener) => void; attachEvent?: ( type: AbortProgressEventTypes, listener: AbortProgressEventListener, ) => void; attachEvent?: ( type: ProgressEventTypes, listener: ProgressEventListener, ) => void; attachEvent?: (type: DragEventTypes, listener: DragEventListener) => void; attachEvent?: ( type: PointerEventTypes, listener: PointerEventListener, ) => void; attachEvent?: ( type: AnimationEventTypes, listener: AnimationEventListener, ) => void; attachEvent?: ( type: ClipboardEventTypes, listener: ClipboardEventListener, ) => void; attachEvent?: ( type: TransitionEventTypes, listener: TransitionEventListener, ) => void; attachEvent?: ( type: MessageEventTypes, listener: MessageEventListener, ) => void; attachEvent?: ( type: BeforeUnloadEventTypes, listener: BeforeUnloadEventListener, ) => void; attachEvent?: ( type: StorageEventTypes, listener: StorageEventListener, ) => void; attachEvent?: ( type: USBConnectionEventTypes, listener: USBConnectionEventListener, ) => void; attachEvent?: (type: string, listener: EventListener) => void; detachEvent?: (type: MouseEventTypes, listener: MouseEventListener) => void; detachEvent?: (type: FocusEventTypes, listener: FocusEventListener) => void; detachEvent?: ( type: KeyboardEventTypes, listener: KeyboardEventListener, ) => void; detachEvent?: (type: InputEventTypes, listener: InputEventListener) => void; detachEvent?: (type: TouchEventTypes, listener: TouchEventListener) => void; detachEvent?: (type: WheelEventTypes, listener: WheelEventListener) => void; detachEvent?: ( type: AbortProgressEventTypes, listener: AbortProgressEventListener, ) => void; detachEvent?: ( type: ProgressEventTypes, listener: ProgressEventListener, ) => void; detachEvent?: (type: DragEventTypes, listener: DragEventListener) => void; detachEvent?: ( type: PointerEventTypes, listener: PointerEventListener, ) => void; detachEvent?: ( type: AnimationEventTypes, listener: AnimationEventListener, ) => void; detachEvent?: ( type: ClipboardEventTypes, listener: ClipboardEventListener, ) => void; detachEvent?: ( type: TransitionEventTypes, listener: TransitionEventListener, ) => void; detachEvent?: ( type: MessageEventTypes, listener: MessageEventListener, ) => void; detachEvent?: ( type: BeforeUnloadEventTypes, listener: BeforeUnloadEventListener, ) => void; detachEvent?: ( type: StorageEventTypes, listener: StorageEventListener, ) => void; detachEvent?: ( type: USBConnectionEventTypes, listener: USBConnectionEventListener, ) => void; detachEvent?: (type: string, listener: EventListener) => void; dispatchEvent(evt: Event): boolean; // Deprecated cancelBubble: boolean; initEvent( eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean, ): void; } // https://dom.spec.whatwg.org/#dictdef-eventinit type Event$Init = { bubbles?: boolean, cancelable?: boolean, composed?: boolean, /** Non-standard. See `composed` instead. */ scoped?: boolean, ... }; // https://dom.spec.whatwg.org/#interface-event declare class Event { constructor(type: string, eventInitDict?: Event$Init): void; /** * Returns the type of event, e.g. "click", "hashchange", or "submit". */ +type: string; /** * Returns the object to which event is dispatched (its target). */ +target: EventTarget; // TODO: nullable /** @deprecated */ +srcElement: Element; // TODO: nullable /** * Returns the object whose event listener's callback is currently being invoked. */ +currentTarget: EventTarget; // TODO: nullable /** * Returns the invocation target objects of event's path (objects on which * listeners will be invoked), except for any nodes in shadow trees of which * the shadow root's mode is "closed" that are not reachable from event's * currentTarget. */ composedPath(): Array; +NONE: number; +AT_TARGET: number; +BUBBLING_PHASE: number; +CAPTURING_PHASE: number; /** * Returns the event's phase, which is one of NONE, CAPTURING_PHASE, AT_TARGET, * and BUBBLING_PHASE. */ +eventPhase: number; /** * When dispatched in a tree, invoking this method prevents event from reaching * any objects other than the current object. */ stopPropagation(): void; /** * Invoking this method prevents event from reaching any registered event * listeners after the current one finishes running and, when dispatched in a * tree, also prevents event from reaching any other objects. */ stopImmediatePropagation(): void; /** * Returns true or false depending on how event was initialized. True if * event goes through its target's ancestors in reverse tree order, and * false otherwise. */ +bubbles: boolean; /** * Returns true or false depending on how event was initialized. Its * return value does not always carry meaning, but true can indicate * that part of the operation during which event was dispatched, can * be canceled by invoking the preventDefault() method. */ +cancelable: boolean; // returnValue: boolean; // legacy, and some subclasses still define it as a string! /** * If invoked when the cancelable attribute value is true, and while * executing a listener for the event with passive set to false, signals to * the operation that caused event to be dispatched that it needs to be * canceled. */ preventDefault(): void; /** * Returns true if preventDefault() was invoked successfully to indicate * cancelation, and false otherwise. */ +defaultPrevented: boolean; /** * Returns true or false depending on how event was initialized. True if * event invokes listeners past a ShadowRoot node that is the root of its * target, and false otherwise. */ +composed: boolean; /** * Returns true if event was dispatched by the user agent, and false otherwise. */ +isTrusted: boolean; /** * Returns the event's timestamp as the number of milliseconds measured relative * to the time origin. */ +timeStamp: number; /** Non-standard. See Event.prototype.composedPath */ +deepPath?: () => EventTarget[]; /** Non-standard. See Event.prototype.composed */ +scoped: boolean; /** * @deprecated */ initEvent(type: string, bubbles: boolean, cancelable: boolean): void; } type CustomEvent$Init = { ...Event$Init, detail?: any, ... }; declare class CustomEvent extends Event { constructor(type: string, eventInitDict?: CustomEvent$Init): void; detail: any; // deprecated initCustomEvent( type: string, bubbles: boolean, cancelable: boolean, detail: any, ): CustomEvent; } type UIEvent$Init = { ...Event$Init, detail?: number, view?: any, ... }; declare class UIEvent extends Event { constructor(typeArg: string, uiEventInit?: UIEvent$Init): void; detail: number; view: any; } declare class CompositionEvent extends UIEvent { data: string | null; locale: string; } type MouseEvent$MouseEventInit = { screenX?: number, screenY?: number, clientX?: number, clientY?: number, ctrlKey?: boolean, shiftKey?: boolean, altKey?: boolean, metaKey?: boolean, button?: number, buttons?: number, region?: string | null, relatedTarget?: EventTarget | null, ... }; declare class MouseEvent extends UIEvent { constructor( typeArg: string, mouseEventInit?: MouseEvent$MouseEventInit, ): void; altKey: boolean; button: number; buttons: number; clientX: number; clientY: number; ctrlKey: boolean; metaKey: boolean; movementX: number; movementY: number; offsetX: number; offsetY: number; pageX: number; pageY: number; region: string | null; relatedTarget: EventTarget | null; screenX: number; screenY: number; shiftKey: boolean; x: number; y: number; getModifierState(keyArg: string): boolean; } declare class FocusEvent extends UIEvent { relatedTarget: ?EventTarget; } type WheelEvent$Init = { ...MouseEvent$MouseEventInit, deltaX?: number, deltaY?: number, deltaZ?: number, deltaMode?: 0x00 | 0x01 | 0x02, ... }; declare class WheelEvent extends MouseEvent { static +DOM_DELTA_PIXEL: 0x00; static +DOM_DELTA_LINE: 0x01; static +DOM_DELTA_PAGE: 0x02; constructor(type: string, eventInitDict?: WheelEvent$Init): void; +deltaX: number; +deltaY: number; +deltaZ: number; +deltaMode: 0x00 | 0x01 | 0x02; } declare class DragEvent extends MouseEvent { dataTransfer: ?DataTransfer; // readonly } type PointerEvent$PointerEventInit = MouseEvent$MouseEventInit & { pointerId?: number, width?: number, height?: number, pressure?: number, tangentialPressure?: number, tiltX?: number, tiltY?: number, twist?: number, pointerType?: string, isPrimary?: boolean, ... }; declare class PointerEvent extends MouseEvent { constructor( typeArg: string, pointerEventInit?: PointerEvent$PointerEventInit, ): void; pointerId: number; width: number; height: number; pressure: number; tangentialPressure: number; tiltX: number; tiltY: number; twist: number; pointerType: string; isPrimary: boolean; } declare class ProgressEvent extends Event { lengthComputable: boolean; loaded: number; total: number; // Deprecated initProgressEvent( typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, lengthComputableArg: boolean, loadedArg: number, totalArg: number, ): void; } declare class PromiseRejectionEvent extends Event { promise: Promise; reason: any; } type PageTransitionEventInit = { ...Event$Init, persisted: boolean, ... }; // https://html.spec.whatwg.org/multipage/browsing-the-web.html#the-pagetransitionevent-interface declare class PageTransitionEvent extends Event { constructor(type: string, init?: PageTransitionEventInit): void; +persisted: boolean; } // used for websockets and postMessage, for example. See: // https://www.w3.org/TR/2011/WD-websockets-20110419/ // and // https://www.w3.org/TR/2008/WD-html5-20080610/comms.html // and // https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces declare class MessageEvent extends Event { data: mixed; origin: string; lastEventId: string; source: WindowProxy; } // https://w3c.github.io/uievents/#idl-keyboardeventinit type KeyboardEvent$Init = { ...UIEvent$Init, /** * Initializes the `key` attribute of the KeyboardEvent object to the unicode * character string representing the meaning of a key after taking into * account all keyboard modifiers (such as shift-state). This value is the * final effective value of the key. If the key is not a printable character, * then it should be one of the key values defined in [UIEvents-Key](https://www.w3.org/TR/uievents-key/). * * NOTE: not `null`, this results in `evt.key === 'null'`! */ key?: string | void, /** * Initializes the `code` attribute of the KeyboardEvent object to the unicode * character string representing the key that was pressed, ignoring any * keyboard modifications such as keyboard layout. This value should be one * of the code values defined in [UIEvents-Code](https://www.w3.org/TR/uievents-code/). * * NOTE: not `null`, this results in `evt.code === 'null'`! */ code?: string | void, /** * Initializes the `location` attribute of the KeyboardEvent object to one of * the following location numerical constants: * * DOM_KEY_LOCATION_STANDARD (numerical value 0) * DOM_KEY_LOCATION_LEFT (numerical value 1) * DOM_KEY_LOCATION_RIGHT (numerical value 2) * DOM_KEY_LOCATION_NUMPAD (numerical value 3) */ location?: number, /** * Initializes the `ctrlKey` attribute of the KeyboardEvent object to true if * the Control key modifier is to be considered active, false otherwise. */ ctrlKey?: boolean, /** * Initializes the `shiftKey` attribute of the KeyboardEvent object to true if * the Shift key modifier is to be considered active, false otherwise. */ shiftKey?: boolean, /** * Initializes the `altKey` attribute of the KeyboardEvent object to true if * the Alt (alternative) (or Option) key modifier is to be considered active, * false otherwise. */ altKey?: boolean, /** * Initializes the `metaKey` attribute of the KeyboardEvent object to true if * the Meta key modifier is to be considered active, false otherwise. */ metaKey?: boolean, /** * Initializes the `repeat` attribute of the KeyboardEvent object. This * attribute should be set to true if the the current KeyboardEvent is * considered part of a repeating sequence of similar events caused by the * long depression of any single key, false otherwise. */ repeat?: boolean, /** * Initializes the `isComposing` attribute of the KeyboardEvent object. This * attribute should be set to true if the event being constructed occurs as * part of a composition sequence, false otherwise. */ isComposing?: boolean, /** * Initializes the `charCode` attribute of the KeyboardEvent to the Unicode * code point for the event’s character. */ charCode?: number, /** * Initializes the `keyCode` attribute of the KeyboardEvent to the system- * and implementation-dependent numerical code signifying the unmodified * identifier associated with the key pressed. */ keyCode?: number, /** Initializes the `which` attribute */ which?: number, ... }; // https://w3c.github.io/uievents/#idl-keyboardevent declare class KeyboardEvent extends UIEvent { constructor(typeArg: string, init?: KeyboardEvent$Init): void; /** `true` if the Alt (alternative) (or "Option") key modifier was active. */ +altKey: boolean; /** * Holds a string that identifies the physical key being pressed. The value * is not affected by the current keyboard layout or modifier state, so a * particular key will always return the same value. */ +code: string; /** `true` if the Control (control) key modifier was active. */ +ctrlKey: boolean; /** * `true` if the key event occurs as part of a composition session, i.e., * after a `compositionstart` event and before the corresponding * `compositionend` event. */ +isComposing: boolean; /** * Holds a [key attribute value](https://www.w3.org/TR/uievents-key/#key-attribute-value) * corresponding to the key pressed. */ +key: string; /** An indication of the logical location of the key on the device. */ +location: number; /** `true` if the meta (Meta) key (or "Command") modifier was active. */ +metaKey: boolean; /** `true` if the key has been pressed in a sustained manner. */ +repeat: boolean; /** `true` if the shift (Shift) key modifier was active. */ +shiftKey: boolean; /** * Queries the state of a modifier using a key value. * * Returns `true` if it is a modifier key and the modifier is activated, * `false` otherwise. */ getModifierState(keyArg?: string): boolean; /** * Holds a character value, for keypress events which generate character * input. The value is the Unicode reference number (code point) of that * character (e.g. event.charCode = event.key.charCodeAt(0) for printable * characters). For keydown or keyup events, the value of charCode is 0. * * @deprecated You should use KeyboardEvent.key instead, if available. */ +charCode: number; /** * Holds a system- and implementation-dependent numerical code signifying * the unmodified identifier associated with the key pressed. Unlike the * `key` attribute, the set of possible values are not normatively defined. * Typically, these value of the keyCode SHOULD represent the decimal * codepoint in ASCII or Windows 1252, but MAY be drawn from a different * appropriate character set. Implementations that are unable to identify * a key use the key value 0. * * @deprecated You should use KeyboardEvent.key instead, if available. */ +keyCode: number; /** * Holds a system- and implementation-dependent numerical code signifying * the unmodified identifier associated with the key pressed. In most cases, * the value is identical to keyCode. * * @deprecated You should use KeyboardEvent.key instead, if available. */ +which: number; } type InputEvent$Init = { ...UIEvent$Init, inputType?: string, data?: string, dataTransfer?: DataTransfer, isComposing?: boolean, ranges?: Array, // TODO: StaticRange ... }; declare class InputEvent extends UIEvent { constructor(typeArg: string, inputEventInit: InputEvent$Init): void; +data: string | null; +dataTransfer: DataTransfer | null; +inputType: string; +isComposing: boolean; getTargetRanges(): Array; // TODO: StaticRange } declare class AnimationEvent extends Event { animationName: string; elapsedTime: number; pseudoElement: string; // deprecated initAnimationEvent: ( type: 'animationstart' | 'animationend' | 'animationiteration', canBubble: boolean, cancelable: boolean, animationName: string, elapsedTime: number, ) => void; } // https://www.w3.org/TR/touch-events/#idl-def-Touch declare class Touch { clientX: number; clientY: number; identifier: number; pageX: number; pageY: number; screenX: number; screenY: number; target: EventTarget; } // https://www.w3.org/TR/touch-events/#idl-def-TouchList // TouchList#item(index) will return null if n > #length. Should #item's // return type just been Touch? declare class TouchList { @@iterator(): Iterator; length: number; item(index: number): null | Touch; [index: number]: Touch; } // https://www.w3.org/TR/touch-events/#touchevent-interface declare class TouchEvent extends UIEvent { altKey: boolean; changedTouches: TouchList; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean; targetTouches: TouchList; touches: TouchList; } // https://www.w3.org/TR/clipboard-apis/#typedefdef-clipboarditemdata // Raw string | Blob are allowed per https://webidl.spec.whatwg.org/#es-promise type ClipboardItemData = string | Blob | Promise; type PresentationStyle = 'attachment' | 'inline' | 'unspecified'; type ClipboardItemOptions = { presentationStyle?: PresentationStyle, ... }; declare class ClipboardItem { +types: $ReadOnlyArray; getType(type: string): Promise; constructor( items: { [type: string]: ClipboardItemData }, options?: ClipboardItemOptions, ): void; } // https://w3c.github.io/clipboard-apis/ as of 15 May 2018 type ClipboardEvent$Init = { ...Event$Init, clipboardData: DataTransfer | null, ... }; declare class ClipboardEvent extends Event { constructor(type: ClipboardEventTypes, eventInit?: ClipboardEvent$Init): void; +clipboardData: ?DataTransfer; // readonly } // https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#interface-transitionevent type TransitionEvent$Init = { ...Event$Init, propertyName: string, elapsedTime: number, pseudoElement: string, ... }; declare class TransitionEvent extends Event { constructor( type: TransitionEventTypes, eventInit?: TransitionEvent$Init, ): void; +propertyName: string; // readonly +elapsedTime: number; // readonly +pseudoElement: string; // readonly } declare class SecurityPolicyViolationEvent extends Event { +documentURI: string; +referrer: string; +blockedURI: string; +effectiveDirective: string; +violatedDirective: string; +originalPolicy: string; +sourceFile: string; +sample: string; +disposition: 'enforce' | 'report'; +statusCode: number; +lineNumber: number; +columnNumber: number; } // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler declare class TaskSignal extends AbortSignal { +priority: number; } type SchedulerPostTaskOptions = { priority?: 'user-blocking' | 'user-visible' | 'background', signal?: TaskSignal | AbortSignal, delay?: number, }; declare class Scheduler { postTask( callback: () => T, options?: SchedulerPostTaskOptions, ): Promise; yield(): Promise; } // https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone declare function structuredClone( value: T, options?: {| transfer: any[] |}, ): T; // https://developer.mozilla.org/en-US/docs/Web/API/USBConnectionEvent declare class USBConnectionEvent extends Event { device: USBDevice; } // TODO: *Event declare class AbortController { constructor(): void; +signal: AbortSignal; abort(reason?: any): void; } declare class AbortSignal extends EventTarget { +aborted: boolean; +reason: any; abort(reason?: any): AbortSignal; onabort: (event: Event) => mixed; throwIfAborted(): void; timeout(time: number): AbortSignal; } declare class Node extends EventTarget { baseURI: ?string; childNodes: NodeList; firstChild: ?Node; +isConnected: boolean; lastChild: ?Node; nextSibling: ?Node; nodeName: string; nodeType: number; nodeValue: string; ownerDocument: Document; parentElement: ?Element; parentNode: ?Node; previousSibling: ?Node; rootNode: Node; textContent: string; appendChild(newChild: T): T; cloneNode(deep?: boolean): this; compareDocumentPosition(other: Node): number; contains(other: ?Node): boolean; getRootNode(options?: { composed: boolean, ... }): Node; hasChildNodes(): boolean; insertBefore(newChild: T, refChild?: ?Node): T; isDefaultNamespace(namespaceURI: string): boolean; isEqualNode(arg: Node): boolean; isSameNode(other: Node): boolean; lookupNamespaceURI(prefix: string): string; lookupPrefix(namespaceURI: string): string; normalize(): void; removeChild(oldChild: T): T; replaceChild(newChild: Node, oldChild: T): T; replaceChildren(...nodes: $ReadOnlyArray): void; static ATTRIBUTE_NODE: number; static CDATA_SECTION_NODE: number; static COMMENT_NODE: number; static DOCUMENT_FRAGMENT_NODE: number; static DOCUMENT_NODE: number; static DOCUMENT_POSITION_CONTAINED_BY: number; static DOCUMENT_POSITION_CONTAINS: number; static DOCUMENT_POSITION_DISCONNECTED: number; static DOCUMENT_POSITION_FOLLOWING: number; static DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: number; static DOCUMENT_POSITION_PRECEDING: number; static DOCUMENT_TYPE_NODE: number; static ELEMENT_NODE: number; static ENTITY_NODE: number; static ENTITY_REFERENCE_NODE: number; static NOTATION_NODE: number; static PROCESSING_INSTRUCTION_NODE: number; static TEXT_NODE: number; // Non-standard innerText?: string; outerText?: string; } declare class NodeList { @@iterator(): Iterator; length: number; item(index: number): T; [index: number]: T; forEach( callbackfn: (this: This, value: T, index: number, list: NodeList) => any, thisArg: This, ): void; entries(): Iterator<[number, T]>; keys(): Iterator; values(): Iterator; } declare class NamedNodeMap { @@iterator(): Iterator; length: number; removeNamedItemNS(namespaceURI: string, localName: string): Attr; item(index: number): Attr; [index: number | string]: Attr; removeNamedItem(name: string): Attr; getNamedItem(name: string): Attr; setNamedItem(arg: Attr): Attr; getNamedItemNS(namespaceURI: string, localName: string): Attr; setNamedItemNS(arg: Attr): Attr; } declare class Attr extends Node { isId: boolean; specified: boolean; ownerElement: Element | null; value: string; name: string; namespaceURI: string | null; prefix: string | null; localName: string; } declare class HTMLCollection<+Elem: Element> { @@iterator(): Iterator; length: number; item(nameOrIndex?: any, optionalIndex?: any): Elem | null; namedItem(name: string): Elem | null; [index: number | string]: Elem; } // from https://www.w3.org/TR/custom-elements/#extensions-to-document-interface-to-register // See also https://github.com/w3c/webcomponents/ type ElementRegistrationOptions = { +prototype?: { // from https://www.w3.org/TR/custom-elements/#types-of-callbacks // See also https://github.com/w3c/webcomponents/ +createdCallback?: () => mixed, +attachedCallback?: () => mixed, +detachedCallback?: () => mixed, +attributeChangedCallback?: (( // attribute is set attributeLocalName: string, oldAttributeValue: null, newAttributeValue: string, attributeNamespace: string, ) => mixed) & // attribute is changed (( attributeLocalName: string, oldAttributeValue: string, newAttributeValue: string, attributeNamespace: string, ) => mixed) & // attribute is removed (( attributeLocalName: string, oldAttributeValue: string, newAttributeValue: null, attributeNamespace: string, ) => mixed), ... }, +extends?: string, ... }; type ElementCreationOptions = { is: string, ... }; declare class MutationRecord { type: 'attributes' | 'characterData' | 'childList'; target: Node; addedNodes: NodeList; removedNodes: NodeList; previousSibling: ?Node; nextSibling: ?Node; attributeName: ?string; attributeNamespace: ?string; oldValue: ?string; } type MutationObserverInitRequired = | { childList: true, ... } | { attributes: true, ... } | { characterData: true, ... }; declare type MutationObserverInit = MutationObserverInitRequired & { subtree?: boolean, attributeOldValue?: boolean, characterDataOldValue?: boolean, attributeFilter?: Array, ... }; declare class MutationObserver { constructor( callback: (arr: Array, observer: MutationObserver) => mixed, ): void; observe(target: Node, options: MutationObserverInit): void; takeRecords(): Array; disconnect(): void; } declare class Document extends Node { // +timeline: DocumentTimeline; // getAnimations(): Array; +URL: string; adoptNode(source: T): T; anchors: HTMLCollection; applets: HTMLCollection; body: HTMLBodyElement | null; +characterSet: string; /** * Legacy alias of `characterSet` * @deprecated */ +charset: string; close(): void; +contentType: string; cookie: string; createAttribute(name: string): Attr; createAttributeNS(namespaceURI: string | null, qualifiedName: string): Attr; createCDATASection(data: string): Text; createComment(data: string): Comment; createDocumentFragment(): DocumentFragment; createElement>( localName: TName, options?: string | ElementCreationOptions, ): HTMLElementTagNameMap[TName]; createElementNS>( namespaceURI: 'http://www.w3.org/1999/xhtml', qualifiedName: TName, options?: string | ElementCreationOptions, ): HTMLElementTagNameMap[TName]; createElementNS( namespaceURI: string | null, qualifiedName: string, options?: string | ElementCreationOptions, ): Element; createTextNode(data: string): Text; currentScript: HTMLScriptElement | null; dir: 'rtl' | 'ltr'; +doctype: DocumentType | null; +documentElement: HTMLElement | null; documentMode: number; +documentURI: string; domain: string | null; embeds: HTMLCollection; exitFullscreen(): Promise; queryCommandSupported(cmdID: string): boolean; execCommand(cmdID: string, showUI?: boolean, value?: any): boolean; forms: HTMLCollection; fullscreenElement: Element | null; fullscreenEnabled: boolean; getElementsByClassName(classNames: string): HTMLCollection; getElementsByName(elementName: string): HTMLCollection; getElementsByTagName>( qualifiedName: TName, ): HTMLCollection; getElementsByTagNameNS>( namespaceURI: 'http://www.w3.org/1999/xhtml', qualifiedName: TName, ): HTMLCollection; getElementsByTagNameNS( namespaceURI: string | null, qualifiedName: string, ): HTMLCollection; head: HTMLHeadElement | null; images: HTMLCollection; +implementation: DOMImplementation; importNode(importedNode: T, deep: boolean): T; /** * Legacy alias of `characterSet` * @deprecated */ +inputEncoding: string; lastModified: string; links: HTMLCollection; media: string; open(url?: string, name?: string, features?: string, replace?: boolean): any; readyState: string; referrer: string; scripts: HTMLCollection; scrollingElement: HTMLElement | null; title: string; visibilityState: 'visible' | 'hidden' | 'prerender' | 'unloaded'; write(...content: Array): void; writeln(...content: Array): void; xmlEncoding: string; xmlStandalone: boolean; xmlVersion: string; registerElement(type: string, options?: ElementRegistrationOptions): any; getSelection(): Selection | null; // 6.4.6 Focus management APIs activeElement: HTMLElement | null; hasFocus(): boolean; // extension location: Location; createEvent(eventInterface: 'CustomEvent'): CustomEvent; createEvent(eventInterface: string): Event; createRange(): Range; elementFromPoint(x: number, y: number): HTMLElement | null; elementsFromPoint(x: number, y: number): Array; defaultView: any; +compatMode: 'BackCompat' | 'CSS1Compat'; hidden: boolean; // Pointer Lock specification exitPointerLock(): void; pointerLockElement: Element | null; // from ParentNode interface childElementCount: number; children: HTMLCollection; firstElementChild: ?Element; lastElementChild: ?Element; append(...nodes: Array): void; prepend(...nodes: Array): void; querySelector>( selector: TSelector, ): HTMLElementTagNameMap[TSelector] | null; querySelectorAll>( selector: TSelector, ): NodeList; // Interface DocumentTraversal // http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/traversal.html#Traversal-Document // Not all combinations of RootNodeT and whatToShow are logically possible. // The bitmasks NodeFilter.SHOW_CDATA_SECTION, // NodeFilter.SHOW_ENTITY_REFERENCE, NodeFilter.SHOW_ENTITY, and // NodeFilter.SHOW_NOTATION are deprecated and do not correspond to types // that Flow knows about. // NodeFilter.SHOW_ATTRIBUTE is also deprecated, but corresponds to the // type Attr. While there is no reason to prefer it to Node.attributes, // it does have meaning and can be typed: When (whatToShow & // NodeFilter.SHOW_ATTRIBUTE === 1), RootNodeT must be Attr, and when // RootNodeT is Attr, bitmasks other than NodeFilter.SHOW_ATTRIBUTE are // meaningless. createNodeIterator( root: RootNodeT, whatToShow: 2, filter?: NodeFilterInterface, ): NodeIterator; createTreeWalker( root: RootNodeT, whatToShow: 2, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; // NodeFilter.SHOW_PROCESSING_INSTRUCTION is not implemented because Flow // does not currently define a ProcessingInstruction class. // When (whatToShow & NodeFilter.SHOW_DOCUMENT === 1 || whatToShow & // NodeFilter.SHOW_DOCUMENT_TYPE === 1), RootNodeT must be Document. createNodeIterator( root: RootNodeT, whatToShow: 256, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 257, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 260, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 261, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 384, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 385, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 388, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 389, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 512, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 513, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 516, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 517, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 640, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 641, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 644, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 645, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 768, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 769, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 772, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 773, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 896, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 897, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 900, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 901, filter?: NodeFilterInterface, ): NodeIterator< RootNodeT, DocumentType | Document | Element | Text | Comment, >; createTreeWalker( root: RootNodeT, whatToShow: 256, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 257, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 260, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 261, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 384, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 385, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 388, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 389, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 512, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 513, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 516, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 517, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 640, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 641, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 644, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 645, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 768, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 769, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 772, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 773, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 896, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 897, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 900, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 901, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; // When (whatToShow & NodeFilter.SHOW_DOCUMENT_FRAGMENT === 1), RootNodeT // must be a DocumentFragment. createNodeIterator( root: RootNodeT, whatToShow: 1024, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1025, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1028, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1029, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1152, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1153, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1156, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 1157, filter?: NodeFilterInterface, ): NodeIterator; createTreeWalker( root: RootNodeT, whatToShow: 1024, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1025, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1028, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1029, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1152, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1153, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1156, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 1157, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; // In the general case, RootNodeT may be any Node and whatToShow may be // NodeFilter.SHOW_ALL or any combination of NodeFilter.SHOW_ELEMENT, // NodeFilter.SHOW_TEXT and/or NodeFilter.SHOW_COMMENT createNodeIterator( root: RootNodeT, whatToShow: 1, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 4, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 5, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 128, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 129, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 132, filter?: NodeFilterInterface, ): NodeIterator; createNodeIterator( root: RootNodeT, whatToShow: 133, filter?: NodeFilterInterface, ): NodeIterator; createTreeWalker( root: RootNodeT, whatToShow: 1, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 4, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 5, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 128, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 129, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 132, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; createTreeWalker( root: RootNodeT, whatToShow: 133, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; // Catch all for when we don't know the value of `whatToShow` // And for when whatToShow is not provided, it is assumed to be SHOW_ALL createNodeIterator( root: RootNodeT, whatToShow?: number, filter?: NodeFilterInterface, ): NodeIterator; createTreeWalker( root: RootNodeT, whatToShow?: number, filter?: NodeFilterInterface, entityReferenceExpansion?: boolean, ): TreeWalker; // From NonElementParentNode Mixin. getElementById(elementId: string): HTMLElement | null; // From DocumentOrShadowRoot Mixin. +styleSheets: StyleSheetList; adoptedStyleSheets: Array; } declare class DocumentFragment extends Node { // from ParentNode interface childElementCount: number; children: HTMLCollection; firstElementChild: ?Element; lastElementChild: ?Element; append(...nodes: Array): void; prepend(...nodes: Array): void; querySelector(selector: string): HTMLElement | null; querySelectorAll(selector: string): NodeList; // From NonElementParentNode Mixin. getElementById(elementId: string): HTMLElement | null; } declare class Selection { anchorNode: Node | null; anchorOffset: number; focusNode: Node | null; focusOffset: number; isCollapsed: boolean; rangeCount: number; type: string; addRange(range: Range): void; getRangeAt(index: number): Range; removeRange(range: Range): void; removeAllRanges(): void; collapse(parentNode: Node | null, offset?: number): void; collapseToStart(): void; collapseToEnd(): void; containsNode(aNode: Node, aPartlyContained?: boolean): boolean; deleteFromDocument(): void; extend(parentNode: Node, offset?: number): void; empty(): void; selectAllChildren(parentNode: Node): void; setPosition(aNode: Node | null, offset?: number): void; setBaseAndExtent( anchorNode: Node, anchorOffset: number, focusNode: Node, focusOffset: number, ): void; toString(): string; } declare class Range { // extension startOffset: number; collapsed: boolean; endOffset: number; startContainer: Node; endContainer: Node; commonAncestorContainer: Node; setStart(refNode: Node, offset: number): void; setEndBefore(refNode: Node): void; setStartBefore(refNode: Node): void; selectNode(refNode: Node): void; detach(): void; // getBoundingClientRect(): DOMRect; toString(): string; compareBoundaryPoints(how: number, sourceRange: Range): number; insertNode(newNode: Node): void; collapse(toStart: boolean): void; selectNodeContents(refNode: Node): void; cloneContents(): DocumentFragment; setEnd(refNode: Node, offset: number): void; cloneRange(): Range; // getClientRects(): DOMRectList; surroundContents(newParent: Node): void; deleteContents(): void; setStartAfter(refNode: Node): void; extractContents(): DocumentFragment; setEndAfter(refNode: Node): void; createContextualFragment(fragment: string | TrustedHTML): DocumentFragment; intersectsNode(refNode: Node): boolean; isPointInRange(refNode: Node, offset: number): boolean; static END_TO_END: number; static START_TO_START: number; static START_TO_END: number; static END_TO_START: number; } declare var document: Document; declare class DOMTokenList { @@iterator(): Iterator; length: number; item(index: number): string; contains(token: string): boolean; add(...token: Array): void; remove(...token: Array): void; toggle(token: string, force?: boolean): boolean; replace(oldToken: string, newToken: string): boolean; forEach( callbackfn: (value: string, index: number, list: DOMTokenList) => any, thisArg?: any, ): void; entries(): Iterator<[number, string]>; keys(): Iterator; values(): Iterator; [index: number]: string; } declare class Element extends Node { assignedSlot: ?HTMLSlotElement; attachShadow(shadowRootInitDict: ShadowRootInit): ShadowRoot; attributes: NamedNodeMap; classList: DOMTokenList; className: string; clientHeight: number; clientLeft: number; clientTop: number; clientWidth: number; id: string; // flowlint unsafe-getters-setters:off get innerHTML(): string; set innerHTML(value: string | TrustedHTML): void; // flowlint unsafe-getters-setters:error localName: string; namespaceURI: ?string; nextElementSibling: ?Element; // flowlint unsafe-getters-setters:off get outerHTML(): string; set outerHTML(value: string | TrustedHTML): void; // flowlint unsafe-getters-setters:error prefix: string | null; previousElementSibling: ?Element; scrollHeight: number; scrollLeft: number; scrollTop: number; scrollWidth: number; +tagName: string; // TODO: a lot more ARIA properties ariaHidden: void | 'true' | 'false'; closest(selectors: string): ?Element; getAttribute(name?: string): ?string; getAttributeNames(): Array; getAttributeNS(namespaceURI: string | null, localName: string): string | null; getAttributeNode(name: string): Attr | null; getAttributeNodeNS( namespaceURI: string | null, localName: string, ): Attr | null; getBoundingClientRect(): ClientRect; getClientRects(): ClientRectList; getElementsByClassName(names: string): HTMLCollection; getElementsByTagName>( qualifiedName: TName, ): HTMLCollection; getElementsByTagNameNS>( namespaceURI: 'http://www.w3.org/1999/xhtml', qualifiedName: TName, ): HTMLCollection; getElementsByTagNameNS( namespaceURI: string | null, qualifiedName: string, ): HTMLCollection; hasAttribute(name: string): boolean; hasAttributeNS(namespaceURI: string | null, localName: string): boolean; hasAttributes(): boolean; hasPointerCapture(pointerId: number): boolean; insertAdjacentElement( position: 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend', element: Element, ): void; insertAdjacentHTML( position: 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend', html: string | TrustedHTML, ): void; insertAdjacentText( position: 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend', text: string, ): void; matches(selector: string): boolean; releasePointerCapture(pointerId: number): void; removeAttribute(name?: string): void; removeAttributeNode(attributeNode: Attr): Attr; removeAttributeNS(namespaceURI: string | null, localName: string): void; requestFullscreen(options?: { navigationUI: 'auto' | 'show' | 'hide', ... }): Promise; requestPointerLock(): void; scrollIntoView( arg?: | boolean | { behavior?: 'auto' | 'instant' | 'smooth', block?: 'start' | 'center' | 'end' | 'nearest', inline?: 'start' | 'center' | 'end' | 'nearest', ... }, ): void; scroll(x: number, y: number): void; scroll(options: ScrollToOptions): void; scrollTo(x: number, y: number): void; scrollTo(options: ScrollToOptions): void; scrollBy(x: number, y: number): void; scrollBy(options: ScrollToOptions): void; setAttribute(name?: string, value?: string): void; toggleAttribute(name?: string, force?: boolean): void; setAttributeNS( namespaceURI: string | null, qualifiedName: string, value: string, ): void; setAttributeNode(newAttr: Attr): Attr | null; setAttributeNodeNS(newAttr: Attr): Attr | null; setPointerCapture(pointerId: number): void; shadowRoot?: ShadowRoot; slot?: string; // from ParentNode interface childElementCount: number; children: HTMLCollection; firstElementChild: ?Element; lastElementChild: ?Element; append(...nodes: Array): void; prepend(...nodes: Array): void; querySelector>( selector: TSelector, ): HTMLElementTagNameMap[TSelector] | null; querySelectorAll>( selector: TSelector, ): NodeList; // from ChildNode interface after(...nodes: Array): void; before(...nodes: Array): void; replaceWith(...nodes: Array): void; remove(): void; } declare class HitRegionOptions { path?: Path2D; fillRule?: CanvasFillRule; id?: string; parentID?: string; cursor?: string; control?: Element; label: ?string; role: ?string; } declare class SVGMatrix { getComponent(index: number): number; mMultiply(secondMatrix: SVGMatrix): SVGMatrix; inverse(): SVGMatrix; mTranslate(x: number, y: number): SVGMatrix; mScale(scaleFactor: number): SVGMatrix; mRotate(angle: number): SVGMatrix; } // WebGL idl: https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl type WebGLContextAttributes = { alpha: boolean, depth: boolean, stencil: boolean, antialias: boolean, premultipliedAlpha: boolean, preserveDrawingBuffer: boolean, preferLowPowerToHighPerformance: boolean, failIfMajorPerformanceCaveat: boolean, ... }; interface WebGLObject {} interface WebGLBuffer extends WebGLObject {} interface WebGLFramebuffer extends WebGLObject {} interface WebGLProgram extends WebGLObject {} interface WebGLRenderbuffer extends WebGLObject {} interface WebGLShader extends WebGLObject {} interface WebGLTexture extends WebGLObject {} interface WebGLUniformLocation {} interface WebGLActiveInfo { size: number; type: number; name: string; } interface WebGLShaderPrecisionFormat { rangeMin: number; rangeMax: number; precision: number; } type BufferDataSource = ArrayBuffer | $ArrayBufferView; type TexImageSource = | ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement; type VertexAttribFVSource = Float32Array | Array; /* flow */ declare class WebGLRenderingContext { static DEPTH_BUFFER_BIT: 0x00000100; DEPTH_BUFFER_BIT: 0x00000100; static STENCIL_BUFFER_BIT: 0x00000400; STENCIL_BUFFER_BIT: 0x00000400; static COLOR_BUFFER_BIT: 0x00004000; COLOR_BUFFER_BIT: 0x00004000; static POINTS: 0x0000; POINTS: 0x0000; static LINES: 0x0001; LINES: 0x0001; static LINE_LOOP: 0x0002; LINE_LOOP: 0x0002; static LINE_STRIP: 0x0003; LINE_STRIP: 0x0003; static TRIANGLES: 0x0004; TRIANGLES: 0x0004; static TRIANGLE_STRIP: 0x0005; TRIANGLE_STRIP: 0x0005; static TRIANGLE_FAN: 0x0006; TRIANGLE_FAN: 0x0006; static ZERO: 0; ZERO: 0; static ONE: 1; ONE: 1; static SRC_COLOR: 0x0300; SRC_COLOR: 0x0300; static ONE_MINUS_SRC_COLOR: 0x0301; ONE_MINUS_SRC_COLOR: 0x0301; static SRC_ALPHA: 0x0302; SRC_ALPHA: 0x0302; static ONE_MINUS_SRC_ALPHA: 0x0303; ONE_MINUS_SRC_ALPHA: 0x0303; static DST_ALPHA: 0x0304; DST_ALPHA: 0x0304; static ONE_MINUS_DST_ALPHA: 0x0305; ONE_MINUS_DST_ALPHA: 0x0305; static DST_COLOR: 0x0306; DST_COLOR: 0x0306; static ONE_MINUS_DST_COLOR: 0x0307; ONE_MINUS_DST_COLOR: 0x0307; static SRC_ALPHA_SATURATE: 0x0308; SRC_ALPHA_SATURATE: 0x0308; static FUNC_ADD: 0x8006; FUNC_ADD: 0x8006; static BLEND_EQUATION: 0x8009; BLEND_EQUATION: 0x8009; static BLEND_EQUATION_RGB: 0x8009; BLEND_EQUATION_RGB: 0x8009; static BLEND_EQUATION_ALPHA: 0x883d; BLEND_EQUATION_ALPHA: 0x883d; static FUNC_SUBTRACT: 0x800a; FUNC_SUBTRACT: 0x800a; static FUNC_REVERSE_SUBTRACT: 0x800b; FUNC_REVERSE_SUBTRACT: 0x800b; static BLEND_DST_RGB: 0x80c8; BLEND_DST_RGB: 0x80c8; static BLEND_SRC_RGB: 0x80c9; BLEND_SRC_RGB: 0x80c9; static BLEND_DST_ALPHA: 0x80ca; BLEND_DST_ALPHA: 0x80ca; static BLEND_SRC_ALPHA: 0x80cb; BLEND_SRC_ALPHA: 0x80cb; static CONSTANT_COLOR: 0x8001; CONSTANT_COLOR: 0x8001; static ONE_MINUS_CONSTANT_COLOR: 0x8002; ONE_MINUS_CONSTANT_COLOR: 0x8002; static CONSTANT_ALPHA: 0x8003; CONSTANT_ALPHA: 0x8003; static ONE_MINUS_CONSTANT_ALPHA: 0x8004; ONE_MINUS_CONSTANT_ALPHA: 0x8004; static BLEND_COLOR: 0x8005; BLEND_COLOR: 0x8005; static ARRAY_BUFFER: 0x8892; ARRAY_BUFFER: 0x8892; static ELEMENT_ARRAY_BUFFER: 0x8893; ELEMENT_ARRAY_BUFFER: 0x8893; static ARRAY_BUFFER_BINDING: 0x8894; ARRAY_BUFFER_BINDING: 0x8894; static ELEMENT_ARRAY_BUFFER_BINDING: 0x8895; ELEMENT_ARRAY_BUFFER_BINDING: 0x8895; static STREAM_DRAW: 0x88e0; STREAM_DRAW: 0x88e0; static STATIC_DRAW: 0x88e4; STATIC_DRAW: 0x88e4; static DYNAMIC_DRAW: 0x88e8; DYNAMIC_DRAW: 0x88e8; static BUFFER_SIZE: 0x8764; BUFFER_SIZE: 0x8764; static BUFFER_USAGE: 0x8765; BUFFER_USAGE: 0x8765; static CURRENT_VERTEX_ATTRIB: 0x8626; CURRENT_VERTEX_ATTRIB: 0x8626; static FRONT: 0x0404; FRONT: 0x0404; static BACK: 0x0405; BACK: 0x0405; static FRONT_AND_BACK: 0x0408; FRONT_AND_BACK: 0x0408; static CULL_FACE: 0x0b44; CULL_FACE: 0x0b44; static BLEND: 0x0be2; BLEND: 0x0be2; static DITHER: 0x0bd0; DITHER: 0x0bd0; static STENCIL_TEST: 0x0b90; STENCIL_TEST: 0x0b90; static DEPTH_TEST: 0x0b71; DEPTH_TEST: 0x0b71; static SCISSOR_TEST: 0x0c11; SCISSOR_TEST: 0x0c11; static POLYGON_OFFSET_FILL: 0x8037; POLYGON_OFFSET_FILL: 0x8037; static SAMPLE_ALPHA_TO_COVERAGE: 0x809e; SAMPLE_ALPHA_TO_COVERAGE: 0x809e; static SAMPLE_COVERAGE: 0x80a0; SAMPLE_COVERAGE: 0x80a0; static NO_ERROR: 0; NO_ERROR: 0; static INVALID_ENUM: 0x0500; INVALID_ENUM: 0x0500; static INVALID_VALUE: 0x0501; INVALID_VALUE: 0x0501; static INVALID_OPERATION: 0x0502; INVALID_OPERATION: 0x0502; static OUT_OF_MEMORY: 0x0505; OUT_OF_MEMORY: 0x0505; static CW: 0x0900; CW: 0x0900; static CCW: 0x0901; CCW: 0x0901; static LINE_WIDTH: 0x0b21; LINE_WIDTH: 0x0b21; static ALIASED_POINT_SIZE_RANGE: 0x846d; ALIASED_POINT_SIZE_RANGE: 0x846d; static ALIASED_LINE_WIDTH_RANGE: 0x846e; ALIASED_LINE_WIDTH_RANGE: 0x846e; static CULL_FACE_MODE: 0x0b45; CULL_FACE_MODE: 0x0b45; static FRONT_FACE: 0x0b46; FRONT_FACE: 0x0b46; static DEPTH_RANGE: 0x0b70; DEPTH_RANGE: 0x0b70; static DEPTH_WRITEMASK: 0x0b72; DEPTH_WRITEMASK: 0x0b72; static DEPTH_CLEAR_VALUE: 0x0b73; DEPTH_CLEAR_VALUE: 0x0b73; static DEPTH_FUNC: 0x0b74; DEPTH_FUNC: 0x0b74; static STENCIL_CLEAR_VALUE: 0x0b91; STENCIL_CLEAR_VALUE: 0x0b91; static STENCIL_FUNC: 0x0b92; STENCIL_FUNC: 0x0b92; static STENCIL_FAIL: 0x0b94; STENCIL_FAIL: 0x0b94; static STENCIL_PASS_DEPTH_FAIL: 0x0b95; STENCIL_PASS_DEPTH_FAIL: 0x0b95; static STENCIL_PASS_DEPTH_PASS: 0x0b96; STENCIL_PASS_DEPTH_PASS: 0x0b96; static STENCIL_REF: 0x0b97; STENCIL_REF: 0x0b97; static STENCIL_VALUE_MASK: 0x0b93; STENCIL_VALUE_MASK: 0x0b93; static STENCIL_WRITEMASK: 0x0b98; STENCIL_WRITEMASK: 0x0b98; static STENCIL_BACK_FUNC: 0x8800; STENCIL_BACK_FUNC: 0x8800; static STENCIL_BACK_FAIL: 0x8801; STENCIL_BACK_FAIL: 0x8801; static STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802; STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802; static STENCIL_BACK_PASS_DEPTH_PASS: 0x8803; STENCIL_BACK_PASS_DEPTH_PASS: 0x8803; static STENCIL_BACK_REF: 0x8ca3; STENCIL_BACK_REF: 0x8ca3; static STENCIL_BACK_VALUE_MASK: 0x8ca4; STENCIL_BACK_VALUE_MASK: 0x8ca4; static STENCIL_BACK_WRITEMASK: 0x8ca5; STENCIL_BACK_WRITEMASK: 0x8ca5; static VIEWPORT: 0x0ba2; VIEWPORT: 0x0ba2; static SCISSOR_BOX: 0x0c10; SCISSOR_BOX: 0x0c10; static COLOR_CLEAR_VALUE: 0x0c22; COLOR_CLEAR_VALUE: 0x0c22; static COLOR_WRITEMASK: 0x0c23; COLOR_WRITEMASK: 0x0c23; static UNPACK_ALIGNMENT: 0x0cf5; UNPACK_ALIGNMENT: 0x0cf5; static PACK_ALIGNMENT: 0x0d05; PACK_ALIGNMENT: 0x0d05; static MAX_TEXTURE_SIZE: 0x0d33; MAX_TEXTURE_SIZE: 0x0d33; static MAX_VIEWPORT_DIMS: 0x0d3a; MAX_VIEWPORT_DIMS: 0x0d3a; static SUBPIXEL_BITS: 0x0d50; SUBPIXEL_BITS: 0x0d50; static RED_BITS: 0x0d52; RED_BITS: 0x0d52; static GREEN_BITS: 0x0d53; GREEN_BITS: 0x0d53; static BLUE_BITS: 0x0d54; BLUE_BITS: 0x0d54; static ALPHA_BITS: 0x0d55; ALPHA_BITS: 0x0d55; static DEPTH_BITS: 0x0d56; DEPTH_BITS: 0x0d56; static STENCIL_BITS: 0x0d57; STENCIL_BITS: 0x0d57; static POLYGON_OFFSET_UNITS: 0x2a00; POLYGON_OFFSET_UNITS: 0x2a00; static POLYGON_OFFSET_FACTOR: 0x8038; POLYGON_OFFSET_FACTOR: 0x8038; static TEXTURE_BINDING_2D: 0x8069; TEXTURE_BINDING_2D: 0x8069; static SAMPLE_BUFFERS: 0x80a8; SAMPLE_BUFFERS: 0x80a8; static SAMPLES: 0x80a9; SAMPLES: 0x80a9; static SAMPLE_COVERAGE_VALUE: 0x80aa; SAMPLE_COVERAGE_VALUE: 0x80aa; static SAMPLE_COVERAGE_INVERT: 0x80ab; SAMPLE_COVERAGE_INVERT: 0x80ab; static COMPRESSED_TEXTURE_FORMATS: 0x86a3; COMPRESSED_TEXTURE_FORMATS: 0x86a3; static DONT_CARE: 0x1100; DONT_CARE: 0x1100; static FASTEST: 0x1101; FASTEST: 0x1101; static NICEST: 0x1102; NICEST: 0x1102; static GENERATE_MIPMAP_HINT: 0x8192; GENERATE_MIPMAP_HINT: 0x8192; static BYTE: 0x1400; BYTE: 0x1400; static UNSIGNED_BYTE: 0x1401; UNSIGNED_BYTE: 0x1401; static SHORT: 0x1402; SHORT: 0x1402; static UNSIGNED_SHORT: 0x1403; UNSIGNED_SHORT: 0x1403; static INT: 0x1404; INT: 0x1404; static UNSIGNED_INT: 0x1405; UNSIGNED_INT: 0x1405; static FLOAT: 0x1406; FLOAT: 0x1406; static DEPTH_COMPONENT: 0x1902; DEPTH_COMPONENT: 0x1902; static ALPHA: 0x1906; ALPHA: 0x1906; static RGB: 0x1907; RGB: 0x1907; static RGBA: 0x1908; RGBA: 0x1908; static LUMINANCE: 0x1909; LUMINANCE: 0x1909; static LUMINANCE_ALPHA: 0x190a; LUMINANCE_ALPHA: 0x190a; static UNSIGNED_SHORT_4_4_4_4: 0x8033; UNSIGNED_SHORT_4_4_4_4: 0x8033; static UNSIGNED_SHORT_5_5_5_1: 0x8034; UNSIGNED_SHORT_5_5_5_1: 0x8034; static UNSIGNED_SHORT_5_6_5: 0x8363; UNSIGNED_SHORT_5_6_5: 0x8363; static FRAGMENT_SHADER: 0x8b30; FRAGMENT_SHADER: 0x8b30; static VERTEX_SHADER: 0x8b31; VERTEX_SHADER: 0x8b31; static MAX_VERTEX_ATTRIBS: 0x8869; MAX_VERTEX_ATTRIBS: 0x8869; static MAX_VERTEX_UNIFORM_VECTORS: 0x8dfb; MAX_VERTEX_UNIFORM_VECTORS: 0x8dfb; static MAX_VARYING_VECTORS: 0x8dfc; MAX_VARYING_VECTORS: 0x8dfc; static MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8b4d; MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8b4d; static MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8b4c; MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8b4c; static MAX_TEXTURE_IMAGE_UNITS: 0x8872; MAX_TEXTURE_IMAGE_UNITS: 0x8872; static MAX_FRAGMENT_UNIFORM_VECTORS: 0x8dfd; MAX_FRAGMENT_UNIFORM_VECTORS: 0x8dfd; static SHADER_TYPE: 0x8b4f; SHADER_TYPE: 0x8b4f; static DELETE_STATUS: 0x8b80; DELETE_STATUS: 0x8b80; static LINK_STATUS: 0x8b82; LINK_STATUS: 0x8b82; static VALIDATE_STATUS: 0x8b83; VALIDATE_STATUS: 0x8b83; static ATTACHED_SHADERS: 0x8b85; ATTACHED_SHADERS: 0x8b85; static ACTIVE_UNIFORMS: 0x8b86; ACTIVE_UNIFORMS: 0x8b86; static ACTIVE_ATTRIBUTES: 0x8b89; ACTIVE_ATTRIBUTES: 0x8b89; static SHADING_LANGUAGE_VERSION: 0x8b8c; SHADING_LANGUAGE_VERSION: 0x8b8c; static CURRENT_PROGRAM: 0x8b8d; CURRENT_PROGRAM: 0x8b8d; static NEVER: 0x0200; NEVER: 0x0200; static LESS: 0x0201; LESS: 0x0201; static EQUAL: 0x0202; EQUAL: 0x0202; static LEQUAL: 0x0203; LEQUAL: 0x0203; static GREATER: 0x0204; GREATER: 0x0204; static NOTEQUAL: 0x0205; NOTEQUAL: 0x0205; static GEQUAL: 0x0206; GEQUAL: 0x0206; static ALWAYS: 0x0207; ALWAYS: 0x0207; static KEEP: 0x1e00; KEEP: 0x1e00; static REPLACE: 0x1e01; REPLACE: 0x1e01; static INCR: 0x1e02; INCR: 0x1e02; static DECR: 0x1e03; DECR: 0x1e03; static INVERT: 0x150a; INVERT: 0x150a; static INCR_WRAP: 0x8507; INCR_WRAP: 0x8507; static DECR_WRAP: 0x8508; DECR_WRAP: 0x8508; static VENDOR: 0x1f00; VENDOR: 0x1f00; static RENDERER: 0x1f01; RENDERER: 0x1f01; static VERSION: 0x1f02; VERSION: 0x1f02; static NEAREST: 0x2600; NEAREST: 0x2600; static LINEAR: 0x2601; LINEAR: 0x2601; static NEAREST_MIPMAP_NEAREST: 0x2700; NEAREST_MIPMAP_NEAREST: 0x2700; static LINEAR_MIPMAP_NEAREST: 0x2701; LINEAR_MIPMAP_NEAREST: 0x2701; static NEAREST_MIPMAP_LINEAR: 0x2702; NEAREST_MIPMAP_LINEAR: 0x2702; static LINEAR_MIPMAP_LINEAR: 0x2703; LINEAR_MIPMAP_LINEAR: 0x2703; static TEXTURE_MAG_FILTER: 0x2800; TEXTURE_MAG_FILTER: 0x2800; static TEXTURE_MIN_FILTER: 0x2801; TEXTURE_MIN_FILTER: 0x2801; static TEXTURE_WRAP_S: 0x2802; TEXTURE_WRAP_S: 0x2802; static TEXTURE_WRAP_T: 0x2803; TEXTURE_WRAP_T: 0x2803; static TEXTURE_2D: 0x0de1; TEXTURE_2D: 0x0de1; static TEXTURE: 0x1702; TEXTURE: 0x1702; static TEXTURE_CUBE_MAP: 0x8513; TEXTURE_CUBE_MAP: 0x8513; static TEXTURE_BINDING_CUBE_MAP: 0x8514; TEXTURE_BINDING_CUBE_MAP: 0x8514; static TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515; TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515; static TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516; TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516; static TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517; TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517; static TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518; TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518; static TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519; TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519; static TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851a; TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851a; static MAX_CUBE_MAP_TEXTURE_SIZE: 0x851c; MAX_CUBE_MAP_TEXTURE_SIZE: 0x851c; static TEXTURE0: 0x84c0; TEXTURE0: 0x84c0; static TEXTURE1: 0x84c1; TEXTURE1: 0x84c1; static TEXTURE2: 0x84c2; TEXTURE2: 0x84c2; static TEXTURE3: 0x84c3; TEXTURE3: 0x84c3; static TEXTURE4: 0x84c4; TEXTURE4: 0x84c4; static TEXTURE5: 0x84c5; TEXTURE5: 0x84c5; static TEXTURE6: 0x84c6; TEXTURE6: 0x84c6; static TEXTURE7: 0x84c7; TEXTURE7: 0x84c7; static TEXTURE8: 0x84c8; TEXTURE8: 0x84c8; static TEXTURE9: 0x84c9; TEXTURE9: 0x84c9; static TEXTURE10: 0x84ca; TEXTURE10: 0x84ca; static TEXTURE11: 0x84cb; TEXTURE11: 0x84cb; static TEXTURE12: 0x84cc; TEXTURE12: 0x84cc; static TEXTURE13: 0x84cd; TEXTURE13: 0x84cd; static TEXTURE14: 0x84ce; TEXTURE14: 0x84ce; static TEXTURE15: 0x84cf; TEXTURE15: 0x84cf; static TEXTURE16: 0x84d0; TEXTURE16: 0x84d0; static TEXTURE17: 0x84d1; TEXTURE17: 0x84d1; static TEXTURE18: 0x84d2; TEXTURE18: 0x84d2; static TEXTURE19: 0x84d3; TEXTURE19: 0x84d3; static TEXTURE20: 0x84d4; TEXTURE20: 0x84d4; static TEXTURE21: 0x84d5; TEXTURE21: 0x84d5; static TEXTURE22: 0x84d6; TEXTURE22: 0x84d6; static TEXTURE23: 0x84d7; TEXTURE23: 0x84d7; static TEXTURE24: 0x84d8; TEXTURE24: 0x84d8; static TEXTURE25: 0x84d9; TEXTURE25: 0x84d9; static TEXTURE26: 0x84da; TEXTURE26: 0x84da; static TEXTURE27: 0x84db; TEXTURE27: 0x84db; static TEXTURE28: 0x84dc; TEXTURE28: 0x84dc; static TEXTURE29: 0x84dd; TEXTURE29: 0x84dd; static TEXTURE30: 0x84de; TEXTURE30: 0x84de; static TEXTURE31: 0x84df; TEXTURE31: 0x84df; static ACTIVE_TEXTURE: 0x84e0; ACTIVE_TEXTURE: 0x84e0; static REPEAT: 0x2901; REPEAT: 0x2901; static CLAMP_TO_EDGE: 0x812f; CLAMP_TO_EDGE: 0x812f; static MIRRORED_REPEAT: 0x8370; MIRRORED_REPEAT: 0x8370; static FLOAT_VEC2: 0x8b50; FLOAT_VEC2: 0x8b50; static FLOAT_VEC3: 0x8b51; FLOAT_VEC3: 0x8b51; static FLOAT_VEC4: 0x8b52; FLOAT_VEC4: 0x8b52; static INT_VEC2: 0x8b53; INT_VEC2: 0x8b53; static INT_VEC3: 0x8b54; INT_VEC3: 0x8b54; static INT_VEC4: 0x8b55; INT_VEC4: 0x8b55; static BOOL: 0x8b56; BOOL: 0x8b56; static BOOL_VEC2: 0x8b57; BOOL_VEC2: 0x8b57; static BOOL_VEC3: 0x8b58; BOOL_VEC3: 0x8b58; static BOOL_VEC4: 0x8b59; BOOL_VEC4: 0x8b59; static FLOAT_MAT2: 0x8b5a; FLOAT_MAT2: 0x8b5a; static FLOAT_MAT3: 0x8b5b; FLOAT_MAT3: 0x8b5b; static FLOAT_MAT4: 0x8b5c; FLOAT_MAT4: 0x8b5c; static SAMPLER_2D: 0x8b5e; SAMPLER_2D: 0x8b5e; static SAMPLER_CUBE: 0x8b60; SAMPLER_CUBE: 0x8b60; static VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622; VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622; static VERTEX_ATTRIB_ARRAY_SIZE: 0x8623; VERTEX_ATTRIB_ARRAY_SIZE: 0x8623; static VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624; VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624; static VERTEX_ATTRIB_ARRAY_TYPE: 0x8625; VERTEX_ATTRIB_ARRAY_TYPE: 0x8625; static VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886a; VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886a; static VERTEX_ATTRIB_ARRAY_POINTER: 0x8645; VERTEX_ATTRIB_ARRAY_POINTER: 0x8645; static VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889f; VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889f; static IMPLEMENTATION_COLOR_READ_TYPE: 0x8b9a; IMPLEMENTATION_COLOR_READ_TYPE: 0x8b9a; static IMPLEMENTATION_COLOR_READ_FORMAT: 0x8b9b; IMPLEMENTATION_COLOR_READ_FORMAT: 0x8b9b; static COMPILE_STATUS: 0x8b81; COMPILE_STATUS: 0x8b81; static LOW_FLOAT: 0x8df0; LOW_FLOAT: 0x8df0; static MEDIUM_FLOAT: 0x8df1; MEDIUM_FLOAT: 0x8df1; static HIGH_FLOAT: 0x8df2; HIGH_FLOAT: 0x8df2; static LOW_INT: 0x8df3; LOW_INT: 0x8df3; static MEDIUM_INT: 0x8df4; MEDIUM_INT: 0x8df4; static HIGH_INT: 0x8df5; HIGH_INT: 0x8df5; static FRAMEBUFFER: 0x8d40; FRAMEBUFFER: 0x8d40; static RENDERBUFFER: 0x8d41; RENDERBUFFER: 0x8d41; static RGBA4: 0x8056; RGBA4: 0x8056; static RGB5_A1: 0x8057; RGB5_A1: 0x8057; static RGB565: 0x8d62; RGB565: 0x8d62; static DEPTH_COMPONENT16: 0x81a5; DEPTH_COMPONENT16: 0x81a5; static STENCIL_INDEX: 0x1901; STENCIL_INDEX: 0x1901; static STENCIL_INDEX8: 0x8d48; STENCIL_INDEX8: 0x8d48; static DEPTH_STENCIL: 0x84f9; DEPTH_STENCIL: 0x84f9; static RENDERBUFFER_WIDTH: 0x8d42; RENDERBUFFER_WIDTH: 0x8d42; static RENDERBUFFER_HEIGHT: 0x8d43; RENDERBUFFER_HEIGHT: 0x8d43; static RENDERBUFFER_INTERNAL_FORMAT: 0x8d44; RENDERBUFFER_INTERNAL_FORMAT: 0x8d44; static RENDERBUFFER_RED_SIZE: 0x8d50; RENDERBUFFER_RED_SIZE: 0x8d50; static RENDERBUFFER_GREEN_SIZE: 0x8d51; RENDERBUFFER_GREEN_SIZE: 0x8d51; static RENDERBUFFER_BLUE_SIZE: 0x8d52; RENDERBUFFER_BLUE_SIZE: 0x8d52; static RENDERBUFFER_ALPHA_SIZE: 0x8d53; RENDERBUFFER_ALPHA_SIZE: 0x8d53; static RENDERBUFFER_DEPTH_SIZE: 0x8d54; RENDERBUFFER_DEPTH_SIZE: 0x8d54; static RENDERBUFFER_STENCIL_SIZE: 0x8d55; RENDERBUFFER_STENCIL_SIZE: 0x8d55; static FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8cd0; FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8cd0; static FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8cd1; FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8cd1; static FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8cd2; FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8cd2; static FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8cd3; FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8cd3; static COLOR_ATTACHMENT0: 0x8ce0; COLOR_ATTACHMENT0: 0x8ce0; static DEPTH_ATTACHMENT: 0x8d00; DEPTH_ATTACHMENT: 0x8d00; static STENCIL_ATTACHMENT: 0x8d20; STENCIL_ATTACHMENT: 0x8d20; static DEPTH_STENCIL_ATTACHMENT: 0x821a; DEPTH_STENCIL_ATTACHMENT: 0x821a; static NONE: 0; NONE: 0; static FRAMEBUFFER_COMPLETE: 0x8cd5; FRAMEBUFFER_COMPLETE: 0x8cd5; static FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8cd6; FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8cd6; static FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8cd7; FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8cd7; static FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8cd9; FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8cd9; static FRAMEBUFFER_UNSUPPORTED: 0x8cdd; FRAMEBUFFER_UNSUPPORTED: 0x8cdd; static FRAMEBUFFER_BINDING: 0x8ca6; FRAMEBUFFER_BINDING: 0x8ca6; static RENDERBUFFER_BINDING: 0x8ca7; RENDERBUFFER_BINDING: 0x8ca7; static MAX_RENDERBUFFER_SIZE: 0x84e8; MAX_RENDERBUFFER_SIZE: 0x84e8; static INVALID_FRAMEBUFFER_OPERATION: 0x0506; INVALID_FRAMEBUFFER_OPERATION: 0x0506; static UNPACK_FLIP_Y_WEBGL: 0x9240; UNPACK_FLIP_Y_WEBGL: 0x9240; static UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241; UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241; static CONTEXT_LOST_WEBGL: 0x9242; CONTEXT_LOST_WEBGL: 0x9242; static UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243; UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243; static BROWSER_DEFAULT_WEBGL: 0x9244; BROWSER_DEFAULT_WEBGL: 0x9244; canvas: HTMLCanvasElement; drawingBufferWidth: number; drawingBufferHeight: number; getContextAttributes(): ?WebGLContextAttributes; isContextLost(): boolean; getSupportedExtensions(): ?Array; getExtension(name: string): any; activeTexture(texture: number): void; attachShader(program: WebGLProgram, shader: WebGLShader): void; bindAttribLocation(program: WebGLProgram, index: number, name: string): void; bindBuffer(target: number, buffer: ?WebGLBuffer): void; bindFramebuffer(target: number, framebuffer: ?WebGLFramebuffer): void; bindRenderbuffer(target: number, renderbuffer: ?WebGLRenderbuffer): void; bindTexture(target: number, texture: ?WebGLTexture): void; blendColor(red: number, green: number, blue: number, alpha: number): void; blendEquation(mode: number): void; blendEquationSeparate(modeRGB: number, modeAlpha: number): void; blendFunc(sfactor: number, dfactor: number): void; blendFuncSeparate( srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number, ): void; bufferData(target: number, size: number, usage: number): void; bufferData(target: number, data: ?ArrayBuffer, usage: number): void; bufferData(target: number, data: $ArrayBufferView, usage: number): void; bufferSubData(target: number, offset: number, data: BufferDataSource): void; checkFramebufferStatus(target: number): number; clear(mask: number): void; clearColor(red: number, green: number, blue: number, alpha: number): void; clearDepth(depth: number): void; clearStencil(s: number): void; colorMask(red: boolean, green: boolean, blue: boolean, alpha: boolean): void; compileShader(shader: WebGLShader): void; compressedTexImage2D( target: number, level: number, internalformat: number, width: number, height: number, border: number, data: $ArrayBufferView, ): void; compressedTexSubImage2D( target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, data: $ArrayBufferView, ): void; copyTexImage2D( target: number, level: number, internalformat: number, x: number, y: number, width: number, height: number, border: number, ): void; copyTexSubImage2D( target: number, level: number, xoffset: number, yoffset: number, x: number, y: number, width: number, height: number, ): void; createBuffer(): ?WebGLBuffer; createFramebuffer(): ?WebGLFramebuffer; createProgram(): ?WebGLProgram; createRenderbuffer(): ?WebGLRenderbuffer; createShader(type: number): ?WebGLShader; createTexture(): ?WebGLTexture; cullFace(mode: number): void; deleteBuffer(buffer: ?WebGLBuffer): void; deleteFramebuffer(framebuffer: ?WebGLFramebuffer): void; deleteProgram(program: ?WebGLProgram): void; deleteRenderbuffer(renderbuffer: ?WebGLRenderbuffer): void; deleteShader(shader: ?WebGLShader): void; deleteTexture(texture: ?WebGLTexture): void; depthFunc(func: number): void; depthMask(flag: boolean): void; depthRange(zNear: number, zFar: number): void; detachShader(program: WebGLProgram, shader: WebGLShader): void; disable(cap: number): void; disableVertexAttribArray(index: number): void; drawArrays(mode: number, first: number, count: number): void; drawElements(mode: number, count: number, type: number, offset: number): void; enable(cap: number): void; enableVertexAttribArray(index: number): void; finish(): void; flush(): void; framebufferRenderbuffer( target: number, attachment: number, renderbuffertarget: number, renderbuffer: ?WebGLRenderbuffer, ): void; framebufferTexture2D( target: number, attachment: number, textarget: number, texture: ?WebGLTexture, level: number, ): void; frontFace(mode: number): void; generateMipmap(target: number): void; getActiveAttrib(program: WebGLProgram, index: number): ?WebGLActiveInfo; getActiveUniform(program: WebGLProgram, index: number): ?WebGLActiveInfo; getAttachedShaders(program: WebGLProgram): ?Array; getAttribLocation(program: WebGLProgram, name: string): number; getBufferParameter(target: number, pname: number): any; getParameter(pname: number): any; getError(): number; getFramebufferAttachmentParameter( target: number, attachment: number, pname: number, ): any; getProgramParameter(program: WebGLProgram, pname: number): any; getProgramInfoLog(program: WebGLProgram): ?string; getRenderbufferParameter(target: number, pname: number): any; getShaderParameter(shader: WebGLShader, pname: number): any; getShaderPrecisionFormat( shadertype: number, precisiontype: number, ): ?WebGLShaderPrecisionFormat; getShaderInfoLog(shader: WebGLShader): ?string; getShaderSource(shader: WebGLShader): ?string; getTexParameter(target: number, pname: number): any; getUniform(program: WebGLProgram, location: WebGLUniformLocation): any; getUniformLocation( program: WebGLProgram, name: string, ): ?WebGLUniformLocation; getVertexAttrib(index: number, pname: number): any; getVertexAttribOffset(index: number, pname: number): number; hint(target: number, mode: number): void; isBuffer(buffer: ?WebGLBuffer): boolean; isEnabled(cap: number): boolean; isFramebuffer(framebuffer: ?WebGLFramebuffer): boolean; isProgram(program: ?WebGLProgram): boolean; isRenderbuffer(renderbuffer: ?WebGLRenderbuffer): boolean; isShader(shader: ?WebGLShader): boolean; isTexture(texture: ?WebGLTexture): boolean; lineWidth(width: number): void; linkProgram(program: WebGLProgram): void; pixelStorei(pname: number, param: number): void; polygonOffset(factor: number, units: number): void; readPixels( x: number, y: number, width: number, height: number, format: number, type: number, pixels: ?$ArrayBufferView, ): void; renderbufferStorage( target: number, internalformat: number, width: number, height: number, ): void; sampleCoverage(value: number, invert: boolean): void; scissor(x: number, y: number, width: number, height: number): void; shaderSource(shader: WebGLShader, source: string): void; stencilFunc(func: number, ref: number, mask: number): void; stencilFuncSeparate( face: number, func: number, ref: number, mask: number, ): void; stencilMask(mask: number): void; stencilMaskSeparate(face: number, mask: number): void; stencilOp(fail: number, zfail: number, zpass: number): void; stencilOpSeparate( face: number, fail: number, zfail: number, zpass: number, ): void; texImage2D( target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ?$ArrayBufferView, ): void; texImage2D( target: number, level: number, internalformat: number, format: number, type: number, source: TexImageSource, ): void; texParameterf(target: number, pname: number, param: number): void; texParameteri(target: number, pname: number, param: number): void; texSubImage2D( target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ?$ArrayBufferView, ): void; texSubImage2D( target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, source: TexImageSource, ): void; uniform1f(location: ?WebGLUniformLocation, x: number): void; uniform1fv(location: ?WebGLUniformLocation, v: Float32Array): void; uniform1fv(location: ?WebGLUniformLocation, v: Array): void; uniform1fv(location: ?WebGLUniformLocation, v: [number]): void; uniform1i(location: ?WebGLUniformLocation, x: number): void; uniform1iv(location: ?WebGLUniformLocation, v: Int32Array): void; uniform1iv(location: ?WebGLUniformLocation, v: Array): void; uniform1iv(location: ?WebGLUniformLocation, v: [number]): void; uniform2f(location: ?WebGLUniformLocation, x: number, y: number): void; uniform2fv(location: ?WebGLUniformLocation, v: Float32Array): void; uniform2fv(location: ?WebGLUniformLocation, v: Array): void; uniform2fv(location: ?WebGLUniformLocation, v: [number, number]): void; uniform2i(location: ?WebGLUniformLocation, x: number, y: number): void; uniform2iv(location: ?WebGLUniformLocation, v: Int32Array): void; uniform2iv(location: ?WebGLUniformLocation, v: Array): void; uniform2iv(location: ?WebGLUniformLocation, v: [number, number]): void; uniform3f( location: ?WebGLUniformLocation, x: number, y: number, z: number, ): void; uniform3fv(location: ?WebGLUniformLocation, v: Float32Array): void; uniform3fv(location: ?WebGLUniformLocation, v: Array): void; uniform3fv( location: ?WebGLUniformLocation, v: [number, number, number], ): void; uniform3i( location: ?WebGLUniformLocation, x: number, y: number, z: number, ): void; uniform3iv(location: ?WebGLUniformLocation, v: Int32Array): void; uniform3iv(location: ?WebGLUniformLocation, v: Array): void; uniform3iv( location: ?WebGLUniformLocation, v: [number, number, number], ): void; uniform4f( location: ?WebGLUniformLocation, x: number, y: number, z: number, w: number, ): void; uniform4fv(location: ?WebGLUniformLocation, v: Float32Array): void; uniform4fv(location: ?WebGLUniformLocation, v: Array): void; uniform4fv( location: ?WebGLUniformLocation, v: [number, number, number, number], ): void; uniform4i( location: ?WebGLUniformLocation, x: number, y: number, z: number, w: number, ): void; uniform4iv(location: ?WebGLUniformLocation, v: Int32Array): void; uniform4iv(location: ?WebGLUniformLocation, v: Array): void; uniform4iv( location: ?WebGLUniformLocation, v: [number, number, number, number], ): void; uniformMatrix2fv( location: ?WebGLUniformLocation, transpose: boolean, value: Float32Array, ): void; uniformMatrix2fv( location: ?WebGLUniformLocation, transpose: boolean, value: Array, ): void; uniformMatrix3fv( location: ?WebGLUniformLocation, transpose: boolean, value: Float32Array, ): void; uniformMatrix3fv( location: ?WebGLUniformLocation, transpose: boolean, value: Array, ): void; uniformMatrix4fv( location: ?WebGLUniformLocation, transpose: boolean, value: Float32Array, ): void; uniformMatrix4fv( location: ?WebGLUniformLocation, transpose: boolean, value: Array, ): void; useProgram(program: ?WebGLProgram): void; validateProgram(program: WebGLProgram): void; vertexAttrib1f(index: number, x: number): void; vertexAttrib1fv(index: number, values: VertexAttribFVSource): void; vertexAttrib2f(index: number, x: number, y: number): void; vertexAttrib2fv(index: number, values: VertexAttribFVSource): void; vertexAttrib3f(index: number, x: number, y: number, z: number): void; vertexAttrib3fv(index: number, values: VertexAttribFVSource): void; vertexAttrib4f( index: number, x: number, y: number, z: number, w: number, ): void; vertexAttrib4fv(index: number, values: VertexAttribFVSource): void; vertexAttribPointer( index: number, size: number, type: number, normalized: boolean, stride: number, offset: number, ): void; viewport(x: number, y: number, width: number, height: number): void; } declare class WebGLContextEvent extends Event { statusMessage: string; } declare class MediaKeyStatusMap { @@iterator(): Iterator<[BufferDataSource, MediaKeyStatus]>; size: number; entries(): Iterator<[BufferDataSource, MediaKeyStatus]>; forEach( callbackfn: ( value: MediaKeyStatus, key: BufferDataSource, map: MediaKeyStatusMap, ) => any, thisArg?: any, ): void; get(key: BufferDataSource): MediaKeyStatus; has(key: BufferDataSource): boolean; keys(): Iterator; values(): Iterator; } declare class MediaKeySession extends EventTarget { sessionId: string; expiration: number; closed: Promise; keyStatuses: MediaKeyStatusMap; generateRequest( initDataType: string, initData: BufferDataSource, ): Promise; load(sessionId: string): Promise; update(response: BufferDataSource): Promise; close(): Promise; remove(): Promise; onkeystatuschange: (ev: any) => any; onmessage: (ev: any) => any; } declare class MediaKeys { createSession(mediaKeySessionType: MediaKeySessionType): MediaKeySession; setServerCertificate(serverCertificate: BufferDataSource): Promise; } declare class TextRange { boundingLeft: number; htmlText: string; offsetLeft: number; boundingWidth: number; boundingHeight: number; boundingTop: number; text: string; offsetTop: number; moveToPoint(x: number, y: number): void; queryCommandValue(cmdID: string): any; getBookmark(): string; move(unit: string, count?: number): number; queryCommandIndeterm(cmdID: string): boolean; scrollIntoView(fStart?: boolean): void; findText(string: string, count?: number, flags?: number): boolean; execCommand(cmdID: string, showUI?: boolean, value?: any): boolean; // getBoundingClientRect(): DOMRect; moveToBookmark(bookmark: string): boolean; isEqual(range: TextRange): boolean; duplicate(): TextRange; collapse(start?: boolean): void; queryCommandText(cmdID: string): string; select(): void; pasteHTML(html: string): void; inRange(range: TextRange): boolean; moveEnd(unit: string, count?: number): number; // getClientRects(): DOMRectList; moveStart(unit: string, count?: number): number; parentElement(): Element; queryCommandState(cmdID: string): boolean; compareEndPoints(how: string, sourceRange: TextRange): number; execCommandShowHelp(cmdID: string): boolean; moveToElementText(element: Element): void; expand(Unit: string): boolean; queryCommandSupported(cmdID: string): boolean; setEndPoint(how: string, SourceRange: TextRange): void; queryCommandEnabled(cmdID: string): boolean; } // These types used to exist as a copy of DOMRect/DOMRectList, which is // incorrect because there are no ClientRect/ClientRectList globals on the DOM. // Keep these as type aliases for backwards compatibility. declare type ClientRect = any; declare type ClientRectList = any; // TODO: HTML*Element declare class DOMImplementation { createDocumentType( qualifiedName: string, publicId: string, systemId: string, ): DocumentType; createDocument( namespaceURI: string | null, qualifiedName: string, doctype?: DocumentType | null, ): Document; hasFeature(feature: string, version?: string): boolean; // non-standard createHTMLDocument(title?: string): Document; } declare class DocumentType extends Node { name: string; notations: NamedNodeMap; systemId: string; internalSubset: string; entities: NamedNodeMap; publicId: string; // from ChildNode interface after(...nodes: Array): void; before(...nodes: Array): void; replaceWith(...nodes: Array): void; remove(): void; } declare class CharacterData extends Node { length: number; data: string; deleteData(offset: number, count: number): void; replaceData(offset: number, count: number, arg: string): void; appendData(arg: string): void; insertData(offset: number, arg: string): void; substringData(offset: number, count: number): string; // from ChildNode interface after(...nodes: Array): void; before(...nodes: Array): void; replaceWith(...nodes: Array): void; remove(): void; } declare class Text extends CharacterData { assignedSlot?: HTMLSlotElement; wholeText: string; splitText(offset: number): Text; replaceWholeText(content: string): Text; } declare class Comment extends CharacterData { text: string; } declare class URL { static canParse(url: string, base?: string): boolean; static createObjectURL(blob: Blob): string; static createObjectURL(mediaSource: MediaSource): string; static revokeObjectURL(url: string): void; static parse(url: string, base?: string): URL | null; constructor(url: string, base?: string | URL): void; hash: string; host: string; hostname: string; href: string; +origin: string; password: string; pathname: string; port: string; protocol: string; search: string; +searchParams: URLSearchParams; username: string; toString(): string; toJSON(): string; } declare interface MediaSourceHandle {} declare class MediaSource extends EventTarget { sourceBuffers: SourceBufferList; activeSourceBuffers: SourceBufferList; // https://w3c.github.io/media-source/#dom-readystate readyState: 'closed' | 'open' | 'ended'; duration: number; handle: MediaSourceHandle; addSourceBuffer(type: string): SourceBuffer; removeSourceBuffer(sourceBuffer: SourceBuffer): void; endOfStream(error?: string): void; static isTypeSupported(type: string): boolean; } declare class SourceBuffer extends EventTarget { mode: 'segments' | 'sequence'; updating: boolean; buffered: TimeRanges; timestampOffset: number; audioTracks: AudioTrackList; videoTracks: VideoTrackList; textTracks: TextTrackList; appendWindowStart: number; appendWindowEnd: number; appendBuffer(data: ArrayBuffer | $ArrayBufferView): void; // TODO: Add ReadableStream // appendStream(stream: ReadableStream, maxSize?: number): void; abort(): void; remove(start: number, end: number): void; trackDefaults: TrackDefaultList; } declare class SourceBufferList extends EventTarget { @@iterator(): Iterator; [index: number]: SourceBuffer; length: number; } declare class TrackDefaultList { [index: number]: TrackDefault; length: number; } declare class TrackDefault { type: 'audio' | 'video' | 'text'; byteStreamTrackID: string; language: string; label: string; kinds: Array; } // TODO: The use of `typeof` makes this function signature effectively // (node: Node) => number, but it should be (node: Node) => 1|2|3 type NodeFilterCallback = ( node: Node, ) => | typeof NodeFilter.FILTER_ACCEPT | typeof NodeFilter.FILTER_REJECT | typeof NodeFilter.FILTER_SKIP; type NodeFilterInterface = | NodeFilterCallback | { acceptNode: NodeFilterCallback, ... }; // TODO: window.NodeFilter exists at runtime and behaves as a constructor // as far as `instanceof` is concerned, but it is not callable. declare class NodeFilter { static SHOW_ALL: -1; static SHOW_ELEMENT: 1; static SHOW_ATTRIBUTE: 2; // deprecated static SHOW_TEXT: 4; static SHOW_CDATA_SECTION: 8; // deprecated static SHOW_ENTITY_REFERENCE: 16; // deprecated static SHOW_ENTITY: 32; // deprecated static SHOW_PROCESSING_INSTRUCTION: 64; static SHOW_COMMENT: 128; static SHOW_DOCUMENT: 256; static SHOW_DOCUMENT_TYPE: 512; static SHOW_DOCUMENT_FRAGMENT: 1024; static SHOW_NOTATION: 2048; // deprecated static FILTER_ACCEPT: 1; static FILTER_REJECT: 2; static FILTER_SKIP: 3; acceptNode: NodeFilterCallback; } // TODO: window.NodeIterator exists at runtime and behaves as a constructor // as far as `instanceof` is concerned, but it is not callable. declare class NodeIterator { root: RootNodeT; whatToShow: number; filter: NodeFilter; expandEntityReferences: boolean; referenceNode: RootNodeT | WhatToShowT; pointerBeforeReferenceNode: boolean; detach(): void; previousNode(): WhatToShowT | null; nextNode(): WhatToShowT | null; } // TODO: window.TreeWalker exists at runtime and behaves as a constructor // as far as `instanceof` is concerned, but it is not callable. declare class TreeWalker { root: RootNodeT; whatToShow: number; filter: NodeFilter; expandEntityReferences: boolean; currentNode: RootNodeT | WhatToShowT; parentNode(): WhatToShowT | null; firstChild(): WhatToShowT | null; lastChild(): WhatToShowT | null; previousSibling(): WhatToShowT | null; nextSibling(): WhatToShowT | null; previousNode(): WhatToShowT | null; nextNode(): WhatToShowT | null; } /* Window file picker */ type WindowFileSystemPickerFileType = {| description?: string, /* * An Object with the keys set to the MIME type * and the values an Array of file extensions * Example: * accept: { * "image/*": [".png", ".gif", ".jpeg", ".jpg"], * }, */ accept: { [string]: Array, }, |}; type WindowBaseFilePickerOptions = {| id?: number, startIn?: | FileSystemHandle | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos', |}; type WindowFilePickerOptions = WindowBaseFilePickerOptions & {| excludeAcceptAllOption?: boolean, types?: Array, |}; type WindowOpenFilePickerOptions = WindowFilePickerOptions & {| multiple?: boolean, |}; type WindowSaveFilePickerOptions = WindowFilePickerOptions & {| suggestedName?: string, |}; type WindowDirectoryFilePickerOptions = WindowBaseFilePickerOptions & {| mode?: 'read' | 'readwrite', |}; // https://wicg.github.io/file-system-access/#api-showopenfilepicker declare function showOpenFilePicker( options?: WindowOpenFilePickerOptions, ): Promise>; // https://wicg.github.io/file-system-access/#api-showsavefilepicker declare function showSaveFilePicker( options?: WindowSaveFilePickerOptions, ): Promise; // https://wicg.github.io/file-system-access/#api-showdirectorypicker declare function showDirectoryPicker( options?: WindowDirectoryFilePickerOptions, ): Promise; /* Notification */ type NotificationPermission = 'default' | 'denied' | 'granted'; type NotificationDirection = 'auto' | 'ltr' | 'rtl'; type VibratePattern = number | Array; type NotificationAction = { action: string, title: string, icon?: string, ... }; type NotificationOptions = { dir?: NotificationDirection, lang?: string, body?: string, tag?: string, image?: string, icon?: string, badge?: string, sound?: string, vibrate?: VibratePattern, timestamp?: number, renotify?: boolean, silent?: boolean, requireInteraction?: boolean, data?: ?any, actions?: Array, ... }; declare class Notification extends EventTarget { constructor(title: string, options?: NotificationOptions): void; static +permission: NotificationPermission; static requestPermission( callback?: (perm: NotificationPermission) => mixed, ): Promise; static +maxActions: number; onclick: ?(evt: Event) => mixed; onclose: ?(evt: Event) => mixed; onerror: ?(evt: Event) => mixed; onshow: ?(evt: Event) => mixed; +title: string; +dir: NotificationDirection; +lang: string; +body: string; +tag: string; +image?: string; +icon?: string; +badge?: string; +vibrate?: Array; +timestamp: number; +renotify: boolean; +silent: boolean; +requireInteraction: boolean; +data: any; +actions: Array; close(): void; } ================================================ FILE: flow-typed/environments/html.js ================================================ /* DataTransfer */ declare class DataTransfer { clearData(format?: string): void; getData(format: string): string; setData(format: string, data: string): void; setDragImage(image: Element, x: number, y: number): void; dropEffect: string; effectAllowed: string; files: FileList; // readonly items: DataTransferItemList; // readonly types: Array; // readonly } declare class DataTransferItemList { @@iterator(): Iterator; length: number; // readonly [index: number]: DataTransferItem; add(data: string, type: string): ?DataTransferItem; add(data: File): ?DataTransferItem; remove(index: number): void; clear(): void; } // https://wicg.github.io/file-system-access/#drag-and-drop declare class DataTransferItem { kind: string; // readonly type: string; // readonly getAsString(_callback: ?(data: string) => mixed): void; getAsFile(): ?File; /* * This is not supported by all browsers, please have a fallback plan for it. * For more information, please checkout * https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry */ webkitGetAsEntry(): void | (() => any); /* * Not supported in all browsers * For up to date compatibility information, please visit * https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/getAsFileSystemHandle */ getAsFileSystemHandle?: () => Promise; } declare type DOMStringMap = { [key: string]: string, ... }; declare class DOMStringList { @@iterator(): Iterator; +[key: number]: string; +length: number; item(number): string | null; contains(string): boolean; } declare type ElementDefinitionOptions = {| extends?: string |}; declare interface CustomElementRegistry { define( name: string, ctor: Class, options?: ElementDefinitionOptions, ): void; get(name: string): any; whenDefined(name: string): Promise; } // https://www.w3.org/TR/eventsource/ declare class EventSource extends EventTarget { constructor( url: string, configuration?: { withCredentials: boolean, ... }, ): void; +CLOSED: 2; +CONNECTING: 0; +OPEN: 1; +readyState: 0 | 1 | 2; +url: string; +withCredentials: boolean; onerror: () => void; onmessage: MessageEventListener; onopen: () => void; close: () => void; } // https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface declare class ErrorEvent extends Event { constructor( type: string, eventInitDict?: { ...Event$Init, message?: string, filename?: string, lineno?: number, colno?: number, error?: any, ... }, ): void; +message: string; +filename: string; +lineno: number; +colno: number; +error: any; } // https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts declare class BroadcastChannel extends EventTarget { name: string; onmessage: ?(event: MessageEvent) => void; onmessageerror: ?(event: MessageEvent) => void; constructor(name: string): void; postMessage(msg: mixed): void; close(): void; } // https://www.w3.org/TR/webstorage/#the-storageevent-interface declare class StorageEvent extends Event { key: ?string; oldValue: ?string; newValue: ?string; url: string; storageArea: ?Storage; } // https://www.w3.org/TR/html50/browsers.html#beforeunloadevent declare class BeforeUnloadEvent extends Event { returnValue: string; } type ToggleEvent$Init = { ...Event$Init, oldState: string, newState: string, ... }; declare class ToggleEvent extends Event { constructor(type: ToggleEventTypes, eventInit?: ToggleEvent$Init): void; +oldState: string; +newState: string; } // TODO: HTMLDocument type FocusOptions = { preventScroll?: boolean, ... }; declare class HTMLElement extends Element { blur(): void; click(): void; focus(options?: FocusOptions): void; // getBoundingClientRect(): DOMRect; forceSpellcheck(): void; showPopover(options?: {| source?: HTMLElement |}): void; hidePopover(): void; togglePopover( options?: boolean | {| force?: boolean, source?: HTMLElement |}, ): boolean; accessKey: string; accessKeyLabel: string; contentEditable: string; contextMenu: ?HTMLMenuElement; dataset: DOMStringMap; dir: 'ltr' | 'rtl' | 'auto'; draggable: boolean; dropzone: any; hidden: boolean; inert: boolean; isContentEditable: boolean; itemProp: any; itemScope: boolean; itemType: any; itemValue: Object; lang: string; offsetHeight: number; offsetLeft: number; offsetParent: ?Element; offsetTop: number; offsetWidth: number; onabort: ?Function; onblur: ?Function; oncancel: ?Function; oncanplay: ?Function; oncanplaythrough: ?Function; onchange: ?Function; onclick: ?Function; oncontextmenu: ?Function; oncuechange: ?Function; ondblclick: ?Function; ondurationchange: ?Function; onemptied: ?Function; onended: ?Function; onerror: ?Function; onfocus: ?Function; onfullscreenchange: ?Function; onfullscreenerror: ?Function; ongotpointercapture: ?Function; oninput: ?Function; oninvalid: ?Function; onkeydown: ?Function; onkeypress: ?Function; onkeyup: ?Function; onload: ?Function; onloadeddata: ?Function; onloadedmetadata: ?Function; onloadstart: ?Function; onlostpointercapture: ?Function; onmousedown: ?Function; onmouseenter: ?Function; onmouseleave: ?Function; onmousemove: ?Function; onmouseout: ?Function; onmouseover: ?Function; onmouseup: ?Function; onmousewheel: ?Function; onpause: ?Function; onplay: ?Function; onplaying: ?Function; onpointercancel: ?Function; onpointerdown: ?Function; onpointerenter: ?Function; onpointerleave: ?Function; onpointermove: ?Function; onpointerout: ?Function; onpointerover: ?Function; onpointerup: ?Function; onprogress: ?Function; onratechange: ?Function; onreadystatechange: ?Function; onreset: ?Function; onresize: ?Function; onscroll: ?Function; onseeked: ?Function; onseeking: ?Function; onselect: ?Function; onshow: ?Function; onstalled: ?Function; onsubmit: ?Function; onsuspend: ?Function; ontimeupdate: ?Function; ontoggle: ?Function; onbeforetoggle: ?Function; onvolumechange: ?Function; onwaiting: ?Function; properties: any; spellcheck: boolean; style: CSSStyleDeclaration; tabIndex: number; title: string; translate: boolean; popover: '' | 'auto' | 'manual' | 'hint'; +popoverVisibilityState: 'hidden' | 'showing'; +popoverInvoker: HTMLElement | null; } declare class HTMLSlotElement extends HTMLElement { name: string; assignedNodes(options?: { flatten: boolean, ... }): Node[]; } declare class HTMLTableElement extends HTMLElement { tagName: 'TABLE'; caption: HTMLTableCaptionElement | null; tHead: HTMLTableSectionElement | null; tFoot: HTMLTableSectionElement | null; +tBodies: HTMLCollection; +rows: HTMLCollection; createTHead(): HTMLTableSectionElement; deleteTHead(): void; createTFoot(): HTMLTableSectionElement; deleteTFoot(): void; createCaption(): HTMLTableCaptionElement; deleteCaption(): void; insertRow(index?: number): HTMLTableRowElement; deleteRow(index: number): void; } declare class HTMLTableCaptionElement extends HTMLElement { tagName: 'CAPTION'; } declare class HTMLTableColElement extends HTMLElement { tagName: 'COL' | 'COLGROUP'; span: number; } declare class HTMLTableSectionElement extends HTMLElement { tagName: 'THEAD' | 'TFOOT' | 'TBODY'; +rows: HTMLCollection; insertRow(index?: number): HTMLTableRowElement; deleteRow(index: number): void; } declare class HTMLTableCellElement extends HTMLElement { tagName: 'TD' | 'TH'; colSpan: number; rowSpan: number; +cellIndex: number; } declare class HTMLTableRowElement extends HTMLElement { tagName: 'TR'; align: 'left' | 'right' | 'center'; +rowIndex: number; +sectionRowIndex: number; +cells: HTMLCollection; deleteCell(index: number): void; insertCell(index?: number): HTMLTableCellElement; } declare class HTMLMenuElement extends HTMLElement { getCompact(): boolean; setCompact(compact: boolean): void; } declare class HTMLBaseElement extends HTMLElement { href: string; target: string; } declare class HTMLTemplateElement extends HTMLElement { content: DocumentFragment; } declare class CanvasGradient { addColorStop(offset: number, color: string): void; } declare class CanvasPattern { setTransform(matrix: SVGMatrix): void; } declare class ImageBitmap { close(): void; width: number; height: number; } type CanvasFillRule = string; type CanvasImageSource = | HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | CanvasRenderingContext2D | ImageBitmap; declare class TextMetrics { // x-direction width: number; actualBoundingBoxLeft: number; actualBoundingBoxRight: number; // y-direction fontBoundingBoxAscent: number; fontBoundingBoxDescent: number; actualBoundingBoxAscent: number; actualBoundingBoxDescent: number; emHeightAscent: number; emHeightDescent: number; hangingBaseline: number; alphabeticBaseline: number; ideographicBaseline: number; } declare class CanvasDrawingStyles { width: number; actualBoundingBoxLeft: number; actualBoundingBoxRight: number; // y-direction fontBoundingBoxAscent: number; fontBoundingBoxDescent: number; actualBoundingBoxAscent: number; actualBoundingBoxDescent: number; emHeightAscent: number; emHeightDescent: number; hangingBaseline: number; alphabeticBaseline: number; ideographicBaseline: number; } declare class Path2D { constructor(path?: Path2D | string): void; addPath(path: Path2D, transformation?: ?SVGMatrix): void; addPathByStrokingPath( path: Path2D, styles: CanvasDrawingStyles, transformation?: ?SVGMatrix, ): void; addText( text: string, styles: CanvasDrawingStyles, transformation: ?SVGMatrix, x: number, y: number, maxWidth?: number, ): void; addPathByStrokingText( text: string, styles: CanvasDrawingStyles, transformation: ?SVGMatrix, x: number, y: number, maxWidth?: number, ): void; addText( text: string, styles: CanvasDrawingStyles, transformation: ?SVGMatrix, path: Path2D, maxWidth?: number, ): void; addPathByStrokingText( text: string, styles: CanvasDrawingStyles, transformation: ?SVGMatrix, path: Path2D, maxWidth?: number, ): void; // CanvasPathMethods // shared path API methods arc( x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, ): void; arcTo( x1: number, y1: number, x2: number, y2: number, radius: number, _: void, _: void, ): void; arcTo( x1: number, y1: number, x2: number, y2: number, radiusX: number, radiusY: number, rotation: number, ): void; bezierCurveTo( cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number, ): void; closePath(): void; ellipse( x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean, ): void; lineTo(x: number, y: number): void; moveTo(x: number, y: number): void; quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void; rect(x: number, y: number, w: number, h: number): void; } declare class ImageData { width: number; height: number; data: Uint8ClampedArray; // constructor methods are used in Worker where CanvasRenderingContext2D // is unavailable. // https://html.spec.whatwg.org/multipage/scripting.html#dom-imagedata constructor(data: Uint8ClampedArray, width: number, height: number): void; constructor(width: number, height: number): void; } declare class CanvasRenderingContext2D { canvas: HTMLCanvasElement; // canvas dimensions width: number; height: number; // for contexts that aren't directly fixed to a specific canvas commit(): void; // state save(): void; restore(): void; // transformations currentTransform: SVGMatrix; scale(x: number, y: number): void; rotate(angle: number): void; translate(x: number, y: number): void; transform( a: number, b: number, c: number, d: number, e: number, f: number, ): void; setTransform( a: number, b: number, c: number, d: number, e: number, f: number, ): void; resetTransform(): void; // compositing globalAlpha: number; globalCompositeOperation: string; // image smoothing imageSmoothingEnabled: boolean; imageSmoothingQuality: 'low' | 'medium' | 'high'; // filters filter: string; // colours and styles strokeStyle: string | CanvasGradient | CanvasPattern; fillStyle: string | CanvasGradient | CanvasPattern; createLinearGradient( x0: number, y0: number, x1: number, y1: number, ): CanvasGradient; createRadialGradient( x0: number, y0: number, r0: number, x1: number, y1: number, r1: number, ): CanvasGradient; createPattern(image: CanvasImageSource, repetition: ?string): CanvasPattern; // shadows shadowOffsetX: number; shadowOffsetY: number; shadowBlur: number; shadowColor: string; // rects clearRect(x: number, y: number, w: number, h: number): void; fillRect(x: number, y: number, w: number, h: number): void; // roundRect( // x: number, // y: number, // w: number, // h: number, // radii?: number | DOMPointInit | $ReadOnlyArray // ): void; strokeRect(x: number, y: number, w: number, h: number): void; // path API beginPath(): void; fill(fillRule?: CanvasFillRule): void; fill(path: Path2D, fillRule?: CanvasFillRule): void; stroke(): void; stroke(path: Path2D): void; drawFocusIfNeeded(element: Element): void; drawFocusIfNeeded(path: Path2D, element: Element): void; scrollPathIntoView(): void; scrollPathIntoView(path: Path2D): void; clip(fillRule?: CanvasFillRule): void; clip(path: Path2D, fillRule?: CanvasFillRule): void; resetClip(): void; isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean; isPointInPath( path: Path2D, x: number, y: number, fillRule?: CanvasFillRule, ): boolean; isPointInStroke(x: number, y: number): boolean; isPointInStroke(path: Path2D, x: number, y: number): boolean; // text (see also the CanvasDrawingStyles interface) fillText(text: string, x: number, y: number, maxWidth?: number): void; strokeText(text: string, x: number, y: number, maxWidth?: number): void; measureText(text: string): TextMetrics; // drawing images drawImage(image: CanvasImageSource, dx: number, dy: number): void; drawImage( image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number, ): void; drawImage( image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number, ): void; // hit regions addHitRegion(options?: HitRegionOptions): void; removeHitRegion(id: string): void; clearHitRegions(): void; // pixel manipulation createImageData(sw: number, sh: number): ImageData; createImageData(imagedata: ImageData): ImageData; getImageData(sx: number, sy: number, sw: number, sh: number): ImageData; putImageData(imagedata: ImageData, dx: number, dy: number): void; putImageData( imagedata: ImageData, dx: number, dy: number, dirtyX: number, dirtyY: number, dirtyWidth: number, dirtyHeight: number, ): void; // CanvasDrawingStyles // line caps/joins lineWidth: number; lineCap: string; lineJoin: string; miterLimit: number; // dashed lines setLineDash(segments: Array): void; getLineDash(): Array; lineDashOffset: number; // text font: string; textAlign: string; textBaseline: string; direction: string; // CanvasPathMethods // shared path API methods closePath(): void; moveTo(x: number, y: number): void; lineTo(x: number, y: number): void; quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void; bezierCurveTo( cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number, ): void; arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void; arcTo( x1: number, y1: number, x2: number, y2: number, radiusX: number, radiusY: number, rotation: number, ): void; rect(x: number, y: number, w: number, h: number): void; arc( x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, ): void; ellipse( x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean, ): void; } // http://www.w3.org/TR/html5/scripting-1.html#renderingcontext type RenderingContext = CanvasRenderingContext2D | WebGLRenderingContext; // https://www.w3.org/TR/html5/scripting-1.html#htmlcanvaselement declare class HTMLCanvasElement extends HTMLElement { tagName: 'CANVAS'; width: number; height: number; getContext(contextId: '2d', ...args: any): CanvasRenderingContext2D; getContext( contextId: 'webgl', contextAttributes?: Partial, ): ?WebGLRenderingContext; // IE currently only supports "experimental-webgl" getContext( contextId: 'experimental-webgl', contextAttributes?: Partial, ): ?WebGLRenderingContext; getContext(contextId: string, ...args: any): ?RenderingContext; // fallback toDataURL(type?: string, ...args: any): string; toBlob(callback: (v: File) => void, type?: string, ...args: any): void; captureStream(frameRate?: number): CanvasCaptureMediaStream; } // https://html.spec.whatwg.org/multipage/forms.html#the-details-element declare class HTMLDetailsElement extends HTMLElement { tagName: 'DETAILS'; open: boolean; } declare class HTMLFormElement extends HTMLElement { tagName: 'FORM'; @@iterator(): Iterator; [index: number | string]: HTMLElement | null; acceptCharset: string; action: string; elements: HTMLCollection; encoding: string; enctype: string; length: number; method: string; name: string; rel: string; target: string; checkValidity(): boolean; reportValidity(): boolean; reset(): void; submit(): void; } // https://www.w3.org/TR/html5/forms.html#the-fieldset-element declare class HTMLFieldSetElement extends HTMLElement { tagName: 'FIELDSET'; disabled: boolean; elements: HTMLCollection; // readonly form: HTMLFormElement | null; // readonly name: string; type: string; // readonly checkValidity(): boolean; setCustomValidity(error: string): void; } declare class HTMLLegendElement extends HTMLElement { tagName: 'LEGEND'; form: HTMLFormElement | null; // readonly } declare class HTMLIFrameElement extends HTMLElement { tagName: 'IFRAME'; allowFullScreen: boolean; contentDocument: Document; contentWindow: any; frameBorder: string; height: string; marginHeight: string; marginWidth: string; name: string; scrolling: string; sandbox: DOMTokenList; src: string; // flowlint unsafe-getters-setters:off get srcdoc(): string; set srcdoc(value: string | TrustedHTML): void; // flowlint unsafe-getters-setters:error width: string; } declare class HTMLImageElement extends HTMLElement { tagName: 'IMG'; alt: string; complete: boolean; // readonly crossOrigin: ?string; currentSrc: string; // readonly height: number; decode(): Promise; isMap: boolean; naturalHeight: number; // readonly naturalWidth: number; // readonly sizes: string; src: string; srcset: string; useMap: string; width: number; } declare class Image extends HTMLImageElement { constructor(width?: number, height?: number): void; } declare class MediaError { MEDIA_ERR_ABORTED: number; MEDIA_ERR_NETWORK: number; MEDIA_ERR_DECODE: number; MEDIA_ERR_SRC_NOT_SUPPORTED: number; code: number; message: ?string; } declare class TimeRanges { length: number; start(index: number): number; end(index: number): number; } declare class Audio extends HTMLAudioElement { constructor(URLString?: string): void; } declare class AudioTrack { id: string; kind: string; label: string; language: string; enabled: boolean; } declare class AudioTrackList extends EventTarget { length: number; [index: number]: AudioTrack; getTrackById(id: string): ?AudioTrack; onchange: (ev: any) => any; onaddtrack: (ev: any) => any; onremovetrack: (ev: any) => any; } declare class VideoTrack { id: string; kind: string; label: string; language: string; selected: boolean; } declare class VideoTrackList extends EventTarget { length: number; [index: number]: VideoTrack; getTrackById(id: string): ?VideoTrack; selectedIndex: number; onchange: (ev: any) => any; onaddtrack: (ev: any) => any; onremovetrack: (ev: any) => any; } declare class TextTrackCue extends EventTarget { constructor(startTime: number, endTime: number, text: string): void; track: TextTrack; id: string; startTime: number; endTime: number; pauseOnExit: boolean; vertical: string; snapToLines: boolean; lines: number; position: number; size: number; align: string; text: string; getCueAsHTML(): Node; onenter: (ev: any) => any; onexit: (ev: any) => any; } declare class TextTrackCueList { @@iterator(): Iterator; length: number; [index: number]: TextTrackCue; getCueById(id: string): ?TextTrackCue; } declare class TextTrack extends EventTarget { kind: string; label: string; language: string; mode: string; cues: TextTrackCueList; activeCues: TextTrackCueList; addCue(cue: TextTrackCue): void; removeCue(cue: TextTrackCue): void; oncuechange: (ev: any) => any; } declare class TextTrackList extends EventTarget { length: number; [index: number]: TextTrack; onaddtrack: (ev: any) => any; onremovetrack: (ev: any) => any; } declare class HTMLMediaElement extends HTMLElement { // error state error: ?MediaError; // network state src: string; srcObject: ?any; currentSrc: string; crossOrigin: ?string; NETWORK_EMPTY: number; NETWORK_IDLE: number; NETWORK_LOADING: number; NETWORK_NO_SOURCE: number; networkState: number; preload: string; buffered: TimeRanges; load(): void; canPlayType(type: string): string; // ready state HAVE_NOTHING: number; HAVE_METADATA: number; HAVE_CURRENT_DATA: number; HAVE_FUTURE_DATA: number; HAVE_ENOUGH_DATA: number; readyState: number; seeking: boolean; // playback state currentTime: number; duration: number; startDate: Date; paused: boolean; defaultPlaybackRate: number; playbackRate: number; played: TimeRanges; seekable: TimeRanges; ended: boolean; autoplay: boolean; loop: boolean; play(): Promise; pause(): void; fastSeek(): void; captureStream(): MediaStream; // media controller mediaGroup: string; controller: ?any; // controls controls: boolean; volume: number; muted: boolean; defaultMuted: boolean; controlsList?: DOMTokenList; // tracks audioTracks: AudioTrackList; videoTracks: VideoTrackList; textTracks: TextTrackList; addTextTrack(kind: string, label?: string, language?: string): TextTrack; // media keys mediaKeys?: ?MediaKeys; setMediakeys?: (mediakeys: ?MediaKeys) => Promise; } declare class HTMLAudioElement extends HTMLMediaElement { tagName: 'AUDIO'; } declare class HTMLVideoElement extends HTMLMediaElement { tagName: 'VIDEO'; width: number; height: number; videoWidth: number; videoHeight: number; poster: string; } declare class HTMLSourceElement extends HTMLElement { tagName: 'SOURCE'; src: string; type: string; //when used with the picture element srcset: string; sizes: string; media: string; } declare class ValidityState { badInput: boolean; customError: boolean; patternMismatch: boolean; rangeOverflow: boolean; rangeUnderflow: boolean; stepMismatch: boolean; tooLong: boolean; tooShort: boolean; typeMismatch: boolean; valueMissing: boolean; valid: boolean; } // https://w3c.github.io/html/sec-forms.html#dom-selectionapielements-setselectionrange type SelectionDirection = 'backward' | 'forward' | 'none'; type SelectionMode = 'select' | 'start' | 'end' | 'preserve'; declare class HTMLInputElement extends HTMLElement { tagName: 'INPUT'; accept: string; align: string; alt: string; autocomplete: string; autofocus: boolean; border: string; checked: boolean; complete: boolean; defaultChecked: boolean; defaultValue: string; dirname: string; disabled: boolean; dynsrc: string; files: FileList; form: HTMLFormElement | null; formAction: string; formEncType: string; formMethod: string; formNoValidate: boolean; formTarget: string; height: string; hspace: number; indeterminate: boolean; labels: NodeList; list: HTMLElement | null; loop: number; lowsrc: string; max: string; maxLength: number; min: string; multiple: boolean; name: string; pattern: string; placeholder: string; readOnly: boolean; required: boolean; selectionDirection: SelectionDirection; selectionEnd: number; selectionStart: number; size: number; src: string; start: string; status: boolean; step: string; type: string; useMap: string; validationMessage: string; validity: ValidityState; value: string; valueAsDate: Date; valueAsNumber: number; vrml: string; vspace: number; width: string; willValidate: boolean; popoverTargetElement: Element | null; popoverTargetAction: 'toggle' | 'show' | 'hide'; checkValidity(): boolean; reportValidity(): boolean; setCustomValidity(error: string): void; createTextRange(): TextRange; select(): void; setRangeText( replacement: string, start?: void, end?: void, selectMode?: void, ): void; setRangeText( replacement: string, start: number, end: number, selectMode?: SelectionMode, ): void; setSelectionRange( start: number, end: number, direction?: SelectionDirection, ): void; showPicker(): void; stepDown(stepDecrement?: number): void; stepUp(stepIncrement?: number): void; } declare class HTMLButtonElement extends HTMLElement { tagName: 'BUTTON'; autofocus: boolean; disabled: boolean; form: HTMLFormElement | null; labels: NodeList | null; name: string; type: string; validationMessage: string; validity: ValidityState; value: string; willValidate: boolean; checkValidity(): boolean; reportValidity(): boolean; setCustomValidity(error: string): void; popoverTargetElement: Element | null; popoverTargetAction: 'toggle' | 'show' | 'hide'; } // https://w3c.github.io/html/sec-forms.html#the-textarea-element declare class HTMLTextAreaElement extends HTMLElement { tagName: 'TEXTAREA'; autofocus: boolean; cols: number; dirName: string; disabled: boolean; form: HTMLFormElement | null; maxLength: number; name: string; placeholder: string; readOnly: boolean; required: boolean; rows: number; wrap: string; type: string; defaultValue: string; value: string; textLength: number; willValidate: boolean; validity: ValidityState; validationMessage: string; checkValidity(): boolean; setCustomValidity(error: string): void; labels: NodeList; select(): void; selectionStart: number; selectionEnd: number; selectionDirection: SelectionDirection; setSelectionRange( start: number, end: number, direction?: SelectionDirection, ): void; } declare class HTMLSelectElement extends HTMLElement { tagName: 'SELECT'; autocomplete: string; autofocus: boolean; disabled: boolean; form: HTMLFormElement | null; labels: NodeList; length: number; multiple: boolean; name: string; options: HTMLOptionsCollection; required: boolean; selectedIndex: number; selectedOptions: HTMLCollection; size: number; type: string; validationMessage: string; validity: ValidityState; value: string; willValidate: boolean; add(element: HTMLElement, before?: HTMLElement): void; checkValidity(): boolean; item(index: number): HTMLOptionElement | null; namedItem(name: string): HTMLOptionElement | null; remove(index?: number): void; setCustomValidity(error: string): void; } declare class HTMLOptionsCollection extends HTMLCollection { selectedIndex: number; add( element: HTMLOptionElement | HTMLOptGroupElement, before?: HTMLElement | number, ): void; remove(index: number): void; } declare class HTMLOptionElement extends HTMLElement { tagName: 'OPTION'; defaultSelected: boolean; disabled: boolean; form: HTMLFormElement | null; index: number; label: string; selected: boolean; text: string; value: string; } declare class HTMLOptGroupElement extends HTMLElement { tagName: 'OPTGROUP'; disabled: boolean; label: string; } declare class HTMLAnchorElement extends HTMLElement { tagName: 'A'; charset: string; coords: string; download: string; hash: string; host: string; hostname: string; href: string; hreflang: string; media: string; name: string; origin: string; password: string; pathname: string; port: string; protocol: string; rel: string; rev: string; search: string; shape: string; target: string; text: string; type: string; username: string; } // https://w3c.github.io/html/sec-forms.html#the-label-element declare class HTMLLabelElement extends HTMLElement { tagName: 'LABEL'; form: HTMLFormElement | null; htmlFor: string; control: HTMLElement | null; } declare class HTMLLinkElement extends HTMLElement { tagName: 'LINK'; crossOrigin: ?('anonymous' | 'use-credentials'); href: string; hreflang: string; media: string; rel: string; sizes: DOMTokenList; type: string; as: string; } declare class HTMLScriptElement extends HTMLElement { tagName: 'SCRIPT'; async: boolean; charset: string; crossOrigin?: string; defer: boolean; // flowlint unsafe-getters-setters:off get src(): string; set src(value: string | TrustedScriptURL): void; get text(): string; set text(value: string | TrustedScript): void; // flowlint unsafe-getters-setters:error type: string; } declare class HTMLStyleElement extends HTMLElement { tagName: 'STYLE'; disabled: boolean; media: string; scoped: boolean; sheet: ?CSSStyleSheet; type: string; } declare class HTMLParagraphElement extends HTMLElement { tagName: 'P'; align: 'left' | 'center' | 'right' | 'justify'; // deprecated in HTML 4.01 } declare class HTMLHtmlElement extends HTMLElement { tagName: 'HTML'; } declare class HTMLBodyElement extends HTMLElement { tagName: 'BODY'; } declare class HTMLHeadElement extends HTMLElement { tagName: 'HEAD'; } declare class HTMLDivElement extends HTMLElement { tagName: 'DIV'; } declare class HTMLSpanElement extends HTMLElement { tagName: 'SPAN'; } declare class HTMLAppletElement extends HTMLElement {} declare class HTMLHeadingElement extends HTMLElement { tagName: 'H1' | 'H2' | 'H3' | 'H4' | 'H5' | 'H6'; } declare class HTMLHRElement extends HTMLElement { tagName: 'HR'; } declare class HTMLBRElement extends HTMLElement { tagName: 'BR'; } declare class HTMLDListElement extends HTMLElement { tagName: 'DL'; } declare class HTMLAreaElement extends HTMLElement { tagName: 'AREA'; alt: string; coords: string; shape: string; target: string; download: string; ping: string; rel: string; relList: DOMTokenList; referrerPolicy: string; } declare class HTMLDataElement extends HTMLElement { tagName: 'DATA'; value: string; } declare class HTMLDataListElement extends HTMLElement { tagName: 'DATALIST'; options: HTMLCollection; } declare class HTMLDialogElement extends HTMLElement { tagName: 'DIALOG'; open: boolean; returnValue: string; show(): void; showModal(): void; close(returnValue: ?string): void; } declare class HTMLEmbedElement extends HTMLElement { tagName: 'EMBED'; src: string; type: string; width: string; height: string; getSVGDocument(): ?Document; } declare class HTMLMapElement extends HTMLElement { tagName: 'MAP'; areas: HTMLCollection; images: HTMLCollection; name: string; } declare class HTMLMeterElement extends HTMLElement { tagName: 'METER'; high: number; low: number; max: number; min: number; optimum: number; value: number; labels: NodeList; } declare class HTMLModElement extends HTMLElement { tagName: 'DEL' | 'INS'; cite: string; dateTime: string; } declare class HTMLObjectElement extends HTMLElement { tagName: 'OBJECT'; contentDocument: ?Document; contentWindow: ?WindowProxy; data: string; form: ?HTMLFormElement; height: string; name: string; type: string; typeMustMatch: boolean; useMap: string; validationMessage: string; validity: ValidityState; width: string; willValidate: boolean; checkValidity(): boolean; getSVGDocument(): ?Document; reportValidity(): boolean; setCustomValidity(error: string): void; } declare class HTMLOutputElement extends HTMLElement { defaultValue: string; form: ?HTMLFormElement; htmlFor: DOMTokenList; labels: NodeList; name: string; type: string; validationMessage: string; validity: ValidityState; value: string; willValidate: boolean; checkValidity(): boolean; reportValidity(): boolean; setCustomValidity(error: string): void; } declare class HTMLParamElement extends HTMLElement { tagName: 'PARAM'; name: string; value: string; } declare class HTMLProgressElement extends HTMLElement { tagName: 'PROGRESS'; labels: NodeList; max: number; position: number; value: number; } declare class HTMLPictureElement extends HTMLElement { tagName: 'PICTURE'; } declare class HTMLTimeElement extends HTMLElement { tagName: 'TIME'; dateTime: string; } declare class HTMLTitleElement extends HTMLElement { tagName: 'TITLE'; text: string; } declare class HTMLTrackElement extends HTMLElement { tagName: 'TRACK'; static NONE: 0; static LOADING: 1; static LOADED: 2; static ERROR: 3; default: boolean; kind: string; label: string; readyState: 0 | 1 | 2 | 3; src: string; srclang: string; track: TextTrack; } declare class HTMLQuoteElement extends HTMLElement { tagName: 'BLOCKQUOTE' | 'Q'; cite: string; } declare class HTMLOListElement extends HTMLElement { tagName: 'OL'; reversed: boolean; start: number; type: string; } declare class HTMLUListElement extends HTMLElement { tagName: 'UL'; } declare class HTMLLIElement extends HTMLElement { tagName: 'LI'; value: number; } declare class HTMLPreElement extends HTMLElement { tagName: 'PRE'; } declare class HTMLMetaElement extends HTMLElement { tagName: 'META'; content: string; httpEquiv: string; name: string; } declare class HTMLUnknownElement extends HTMLElement {} declare class Storage { length: number; getItem(key: string): ?string; setItem(key: string, data: string): void; clear(): void; removeItem(key: string): void; key(index: number): ?string; [name: string]: ?string; } /* window */ declare type WindowProxy = any; declare function alert(message?: any): void; declare function prompt(message?: any, value?: any): string; declare function close(): void; declare function confirm(message?: string): boolean; declare function getComputedStyle( elt: Element, pseudoElt?: string, ): CSSStyleDeclaration; declare opaque type AnimationFrameID; declare function requestAnimationFrame( callback: (timestamp: number) => void, ): AnimationFrameID; declare function cancelAnimationFrame(requestId: AnimationFrameID): void; declare opaque type IdleCallbackID; declare function requestIdleCallback( cb: (deadline: { didTimeout: boolean, timeRemaining: () => number, ... }) => void, opts?: { timeout: number, ... }, ): IdleCallbackID; declare function cancelIdleCallback(id: IdleCallbackID): void; declare var localStorage: Storage; declare var devicePixelRatio: number; declare function focus(): void; declare function onfocus(ev: Event): any; declare function open( url?: string, target?: string, features?: string, replace?: boolean, ): any; declare var parent: WindowProxy; declare function print(): void; declare var self: any; declare var sessionStorage: Storage; declare var top: WindowProxy; declare function getSelection(): Selection | null; declare var customElements: CustomElementRegistry; declare function scroll(x: number, y: number): void; declare function scroll(options: ScrollToOptions): void; declare function scrollTo(x: number, y: number): void; declare function scrollTo(options: ScrollToOptions): void; declare function scrollBy(x: number, y: number): void; declare function scrollBy(options: ScrollToOptions): void; type HTMLElementTagNameMap = { a: HTMLAnchorElement, abbr: HTMLElement, address: HTMLElement, area: HTMLAreaElement, article: HTMLElement, aside: HTMLElement, audio: HTMLAudioElement, b: HTMLElement, base: HTMLBaseElement, bdi: HTMLElement, bdo: HTMLElement, blockquote: HTMLQuoteElement, body: HTMLBodyElement, br: HTMLBRElement, button: HTMLButtonElement, canvas: HTMLCanvasElement, caption: HTMLTableCaptionElement, cite: HTMLElement, code: HTMLElement, col: HTMLTableColElement, colgroup: HTMLTableColElement, data: HTMLDataElement, datalist: HTMLDataListElement, dd: HTMLElement, del: HTMLModElement, details: HTMLDetailsElement, dfn: HTMLElement, dialog: HTMLDialogElement, div: HTMLDivElement, dl: HTMLDListElement, dt: HTMLElement, em: HTMLElement, embed: HTMLEmbedElement, fieldset: HTMLFieldSetElement, figcaption: HTMLElement, figure: HTMLElement, footer: HTMLElement, form: HTMLFormElement, h1: HTMLHeadingElement, h2: HTMLHeadingElement, h3: HTMLHeadingElement, h4: HTMLHeadingElement, h5: HTMLHeadingElement, h6: HTMLHeadingElement, head: HTMLHeadElement, header: HTMLElement, hgroup: HTMLElement, hr: HTMLHRElement, html: HTMLHtmlElement, i: HTMLElement, iframe: HTMLIFrameElement, img: HTMLImageElement, input: HTMLInputElement, ins: HTMLModElement, kbd: HTMLElement, label: HTMLLabelElement, legend: HTMLLegendElement, li: HTMLLIElement, link: HTMLLinkElement, main: HTMLElement, map: HTMLMapElement, mark: HTMLElement, menu: HTMLMenuElement, meta: HTMLMetaElement, meter: HTMLMeterElement, nav: HTMLElement, noscript: HTMLElement, object: HTMLObjectElement, ol: HTMLOListElement, optgroup: HTMLOptGroupElement, option: HTMLOptionElement, output: HTMLOutputElement, p: HTMLParagraphElement, picture: HTMLPictureElement, pre: HTMLPreElement, progress: HTMLProgressElement, q: HTMLQuoteElement, rp: HTMLElement, rt: HTMLElement, ruby: HTMLElement, s: HTMLElement, samp: HTMLElement, script: HTMLScriptElement, search: HTMLElement, section: HTMLElement, select: HTMLSelectElement, slot: HTMLSlotElement, small: HTMLElement, source: HTMLSourceElement, span: HTMLSpanElement, strong: HTMLElement, style: HTMLStyleElement, sub: HTMLElement, summary: HTMLElement, sup: HTMLElement, table: HTMLTableElement, tbody: HTMLTableSectionElement, td: HTMLTableCellElement, template: HTMLTemplateElement, textarea: HTMLTextAreaElement, tfoot: HTMLTableSectionElement, th: HTMLTableCellElement, thead: HTMLTableSectionElement, time: HTMLTimeElement, title: HTMLTitleElement, tr: HTMLTableRowElement, track: HTMLTrackElement, u: HTMLElement, ul: HTMLUListElement, var: HTMLElement, video: HTMLVideoElement, wbr: HTMLElement, [string]: Element, }; ================================================ FILE: flow-typed/environments/jsx.js ================================================ // flow-typed signature: 740504cb8176bc8734d2a62895c6d35d // flow-typed version: a6edf4ac0b/jsx/flow_>=v0.83.x /** * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#list_of_global_attributes */ declare type jsx$HTMLElement = { /** * Specifies a shortcut key to activate/focus an element */ accessKey?: string, /** * Specifies one or more classnames for an element (refers to a class in a style sheet) */ className?: string, /** * Specifies whether the content of an element is editable or not */ contentEditable?: string, /** * Specifies meta tag for application testing or querying */ 'data-testid'?: string, /** * Specifies the text direction for the content in an element */ dir?: string, /** * Specifies whether an element is draggable or not */ draggable?: string, /** * Specifies that an element is not yet, or is no longer, relevant */ hidden?: boolean | '' | 'hidden' | 'until-found', /** * Specifies a unique id for an element */ id?: string, /** * Specify that a standard HTML element should behave like a defined custom * built-in element * @see https://html.spec.whatwg.org/multipage/custom-elements.html#attr-is */ is?: string, /** * Specifies the language of the element's content */ lang?: string, /* * Roles define the semantic meaning of content, allowing screen readers and * other tools to present and support interaction with an object in a way that * is consistent with user expectations of that type of object. */ role?: string, /* * Assigns a slot in a shadow DOM shadow tree to an element: An element with a * slot attribute is assigned to the slot created by the element whose * name attribute's value matches that slot attribute's value. */ slot?: string, /** * Specifies whether the element is to have its spelling and grammar checked or not */ spellCheck?: string, /* * Contains CSS styling declarations to be applied to the element. */ style?: { +[string]: string | number, ... }, /** * Specifies the tabbing order of an element */ tabIndex?: string, /** * Specifies extra information about an element */ title?: string, /** * Specifies whether the content of an element should be translated or not */ translate?: string, ... }; /** * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types */ declare type jsx$HTMLInputElement$Type = | 'button' | 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'reset' | 'search' | 'submit' | 'tel' | 'text' | 'time' | 'url' | 'week'; /** * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes */ declare type jsx$HTMLInputElement = { ...jsx$HTMLElement, value?: string, type?: jsx$HTMLInputElement$Type, ... }; /** * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attributes */ declare type jsx$HTMLTextAreaElement = { ...jsx$HTMLElement, /** * This attribute indicates whether the value of the control can be automatically completed by the browser. Possible values are: * * off: The user must explicitly enter a value into this field for every use, or the document provides its own auto-completion method; the browser does not automatically complete the entry. * on: The browser can automatically complete the value based on values that the user has entered during previous uses. */ autoComplete?: 'on' | 'off', /** * A string which indicates whether or not to activate automatic spelling correction and processing of text substitutions (if any are configured) while the user is editing this textarea. Permitted values are: * * off: Disable automatic spelling correction and text substitutions. * on: Enable automatic spelling correction and text substitutions. */ autoCorrect?: 'on' | 'off', /** * This Boolean attribute lets you specify that a form control should have input focus when the page loads. Only one form-associated element in a document can have this attribute specified. */ autoFocus?: boolean, /** * The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20. */ cols?: number, /** * This Boolean attribute indicates that the user cannot interact with the control. If this attribute is not specified, the control inherits its setting from the containing element, for example
; if there is no containing element when the disabled attribute is set, the control is enabled. */ disabled?: boolean, /** * The form element that the