Full Code of u-wave/react-vimeo for AI

default 9c8d277d1b45 cached
27 files
49.1 KB
13.5k tokens
39 symbols
1 requests
Download .txt
Repository: u-wave/react-vimeo
Branch: default
Commit: 9c8d277d1b45
Files: 27
Total size: 49.1 KB

Directory structure:
gitextract_ty8zbuxn/

├── .babelrc.js
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       └── deploy.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── example/
│   ├── .babelrc.js
│   ├── app.js
│   ├── index.html
│   └── package.json
├── index.d.ts
├── index.test-d.tsx
├── package.json
├── rollup.config.mjs
├── src/
│   ├── eventNames.js
│   └── index.js
└── test/
    ├── .eslintrc.js
    ├── test.js
    └── util/
        ├── createVimeo.js
        └── render.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc.js
================================================
const TEST = process.env.BABEL_ENV === 'test';
const CJS = process.env.BABEL_ENV === 'cjs';

module.exports = {
  presets: [
    ['@babel/env', {
      modules: TEST || CJS ? 'commonjs' : false,
      loose: true,
      targets: TEST ? { node: 'current' } : {},
    }],
    '@babel/react',
  ],
  plugins: TEST ? [
    'dynamic-import-node',
  ] : [],
};


================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2


[*.js]
indent_style = space
indent_size = 2


[*.md]
trim_trailing_whitespace = false


================================================
FILE: .eslintignore
================================================
node_modules
example/bundle.js
dist


================================================
FILE: .eslintrc.js
================================================
module.exports = {
  extends: 'airbnb',
  parserOptions: {
    ecmaVersion: 2022,
    sourceType: 'module',
  },
  rules: {
    // I disagree
    'react/jsx-filename-extension': 'off',
    // I disagree
    'react/require-default-props': 'off',
    // Our babel config doesn't support class properties
    'react/state-in-constructor': 'off',
    'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
    'jsx-a11y/label-has-for': ['error', {
      components: [],
      required: {
        some: ['nesting', 'id'],
      },
      allowChildren: false,
    }],
  },
};


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: npm
  directory: "/"
  schedule:
    interval: weekly
  open-pull-requests-limit: 10
- package-ecosystem: github-actions
  directory: "/"
  schedule:
    interval: weekly


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on: [push, pull_request]

jobs:
  types:
    name: Types
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: npm install
      - name: Check types
        run: npm run tsd

  lint:
    name: Code style
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: npm install
      - name: Check code style
        run: npm run lint

  test:
    name: Tests
    strategy:
      fail-fast: false
      matrix:
        node-version: [16.x, 18.x, 20.x]
        react-version: [17.x, 18.x, 19.x]
        include:
          - node-version: 14.x
            react-version: 16.0.0
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4
      - name: Install Node.js ${{matrix.node-version}}
        uses: actions/setup-node@v4
        with:
          node-version: ${{matrix.node-version}}
      - name: Install dependencies
        run: npm install
      - name: Install React ${{matrix.react-version}}
        if: matrix.react-version != '18.x'
        run: |
          npm install --save-dev \
            react@${{matrix.react-version}} \
            react-dom@${{matrix.react-version}}
      - name: Run tests
        run: npm run tests-only


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy

on:
  push:
    branches:
      - default

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build example
        run: |
          npm run example
          mkdir _deploy
          cp example/bundle.js example/index.html _deploy
      - name: Publish site
        if: success()
        uses: crazy-max/ghaction-github-pages@v4
        with:
          target_branch: gh-pages
          build_dir: _deploy
          keep_history: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .gitignore
================================================
node_modules
/dist
/example/bundle.js
/generated-docs.md
.eslintcache
package-lock.json


================================================
FILE: .npmignore
================================================
.eslintcache
node_modules
/tools
/example
/generated-docs.md


================================================
FILE: .npmrc
================================================
package-lock=false


================================================
FILE: CHANGELOG.md
================================================
# @u-wave/react-vimeo change log

All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](http://semver.org/).

## 0.9.12
 * Add React 19 to supported `peerDependencies` range. (#282)

## 0.9.11
 * Fix type bug. (d0d38a84d4b5f3f94d6aaad681d0f90492c8ef4c)

## 0.9.10
 * Fix npm package keywords. (bb944df)

## 0.9.9
 * Bump minimum `@vimeo/player` version. (@k-p-jones in #191)
 * Document `controls` as pro-account-only. (fd61877)
 * Add `onPlaying` event, fix documentation for `onPlay`. (@Aliath in #212)
 * Add `playbackRate` prop. (@chidimi in #220)
 * Support changing the `quality` prop during playback. (941b68b)
 * Add support for passing a URL to the `video` prop, eg. for embedding private videos. (e7128b6)

## 0.9.8
 * Fix a warning about workspaces when installing with yarn. (#190)

## 0.9.7
 * Add React 18 to supported `peerDependencies` range. (@dockwarder in #189)
 * Accept typings from React 17 and 18 … hopefully npm picks the correct version for you :)

## 0.9.6
 * Add `textTrack`, `playsInline`, `pip`, `keyboard`, `quality` props. (@thanhsonng in #178)

## 0.9.5
 * Add the `dnt` prop to the typescript definitions. (@k-p-jones in #140)

## 0.9.4
 * Add prop for the `speed` player option. (@warrenmcquinn in #128)

   This option enables speed controls so the user can select speeds in the Vimeo frame UI,
   it does not itself control the playback rate.

## 0.9.3
 * Add prop for the `dnt` player option. (@k-p-jones in #125)

## 0.9.2
 * Add prop for the `onPlaybackRateChange` event. (@houmark in #120)

## 0.9.1
 * Add React 17 to allowed peerDependency range. (#114)

## 0.9.0
 * Add typescript typings. (#103)

## 0.8.3
 * Set `sideEffects: false` in package.json.
 * Add `style` pass-through property to set CSS properties on the container element. (@Authchirion in #100)

## 0.8.2
 * Call `onError()` prop if initial load fails (#96).
 * Call `setCurrentTime()` after a new video has loaded. (#95)

## 0.8.1
 * Add color string example to docs. (@ivoilic in #82)
 * Fix documentation for union prop types.

## 0.8.0
 * Add `controls` prop, set to `controls={false}` to disable UI on videos uploaded by pro accounts. (@ljmsouza in #81)

## 0.7.0
 * Add `responsive` prop that automatically fills the parent element. (@deJong in #80)

## 0.6.0
 * Add working `onReady` callback. You can use it to get access to the raw [@vimeo/player](https://github.com/vimeo/player.js) instance.

## 0.5.0
 * Clean up the `@vimeo/player` instance when unmounting.

## 0.4.0
 * Add `muted` and `background` props from new Vimeo player. (@pgib in #5)


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 Renée Kooi

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
================================================
# @u-wave/react-vimeo

Vimeo player component for React.

[Install][] - [Usage][] - [Demo][] - [Props][]

## Install

```
npm install --save @u-wave/react-vimeo
```

## Usage

[Demo][] - [Demo source code][]

```js
import Vimeo from '@u-wave/react-vimeo';

<Vimeo
  video="x2to0hs"
  autoplay
/>
```

## Props
| Name | Type | Default | Description |
|:-----|:-----|:-----|:-----|
| video | number, string |  | A Vimeo video ID or URL. |
| id | string |  | DOM ID for the player element. |
| className | string |  | CSS className for the player element. |
| style | object |  | Inline style for container element. |
| width | number, string |  | Width of the player element. |
| height | number, string |  | Height of the player element. |
| paused | bool |  | Pause the video. |
| volume | number |  | The playback volume as a number between 0 and 1. |
| start | number |  | The time in seconds at which to start playing the video. |
| autopause | bool | true | Pause this video automatically when another one plays. |
| autoplay | bool | false | Automatically start playback of the video. Note that this won’t work on some devices. |
| showByline | bool | true | Show the byline on the video. |
| color | string |  | Specify the color of the video controls. Colors may be overridden by the embed settings of the video. _(Ex: "ef2f9f")_ |
| dnt | bool | false | Blocks the player from tracking any session data, including all cookies and analytics. |
| controls | bool | true | Hide all elements in the player, such as the progress bar, sharing buttons, etc. (requires Vimeo PRO / Business account) |
| loop | bool | false | Play the video again when it reaches the end. |
| showPortrait | bool | true | Show the portrait on the video. |
| showTitle | bool | true | Show the title on the video. |
| muted | bool | false | Starts in a muted state to help with autoplay |
| background | bool | false | Starts in a background state with no controls to help with autoplay |
| responsive | bool | false | Enable responsive mode and resize according to parent element (experimental) |
| playbackRate | number | | Specify playback rate (requires Vimeo PRO / Business account)
| speed | bool | false | Enable playback rate controls (requires Vimeo PRO / Business account) |
| keyboard | bool | true | Allows for keyboard input to trigger player events. |
| pip | bool | false | Show the picture-in-picture button in the controlbar and enable the picture-in-picture API. |
| playsInline | bool | true | Play video inline on mobile devices, to automatically go fullscreen on playback set this parameter to false. |
| quality | string |  | Vimeo Plus, PRO, and Business members can default an embedded video to a specific quality on desktop. |
| textTrack | string |  | Turn captions/subtitles on for a specific language by default. |
| transparent | bool | true | The responsive player and transparent background are enabled by default, to disable set this parameter to false. |
| onReady | function |  | Sent when the Vimeo player API has loaded. Receives the Vimeo player object in the first parameter. |
| onError | function |  | Sent when the player triggers an error. |
| onPlay | function |  | Triggered when video playback is initiated. |
| onPlaying | function |  | Triggered when the video starts playing. |
| onPause | function |  | Triggered when the video pauses. |
| onEnd | function |  | Triggered any time the video playback reaches the end. Note: when `loop` is turned on, the ended event will not fire. |
| onTimeUpdate | function |  | Triggered as the `currentTime` of the video updates. It generally fires every 250ms, but it may vary depending on the browser. |
| onProgress | function |  | Triggered as the video is loaded. Reports back the amount of the video that has been buffered. |
| onSeeked | function |  | Triggered when the player seeks to a specific time. An `onTimeUpdate` event will also be fired at the same time. |
| onTextTrackChange | function |  | Triggered when the active text track (captions/subtitles) changes. The values will be `null` if text tracks are turned off. |
| onCueChange | function |  | Triggered when the active cue for the current text track changes. It also fires when the active text track changes. There may be multiple cues active. |
| onCuePoint | function |  | Triggered when the current time hits a registered cue point. |
| onVolumeChange | function |  | Triggered when the volume in the player changes. Some devices do not support setting the volume of the video independently from the system volume, so this event will never fire on those devices. |
| onPlaybackRateChange | function |  | Triggered when the playback rate changes. |
| onLoaded | function |  | Triggered when a new video is loaded in the player. |

## Related

 - [@u-wave/react-youtube][] - A YouTube component with a similar declarative API.
 - [react-dailymotion][] - A Dailymotion component with a similar declarative API.

## License

[MIT]

[Install]: #install
[Usage]: #usage
[Props]: #props
[Demo]: https://u-wave.github.io/react-vimeo
[Demo source code]: ./example
[MIT]: ./LICENSE
[@u-wave/react-youtube]: https://github.com/u-wave/react-youtube
[react-dailymotion]: https://github.com/u-wave/react-dailymotion


================================================
FILE: example/.babelrc.js
================================================
module.exports = require('../.babelrc');


================================================
FILE: example/app.js
================================================
/* global document */
import React from 'react';
import ReactDOM from 'react-dom';
import Vimeo from '@u-wave/react-vimeo'; // eslint-disable-line import/no-unresolved

const videos = [
  { id: 115783408, name: 'Jambinai - Connection' },
  { id: 162959050, name: 'Jambinai - They Keep Silence' },
  { id: 169408731, name: 'Hoody - Like You' },
];

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      videoIndex: 0,
      volume: 1,
      paused: false,
    };

    this.handlePause = this.handlePause.bind(this);
    this.handlePlayerPause = this.handlePlayerPause.bind(this);
    this.handlePlayerPlay = this.handlePlayerPlay.bind(this);
    this.handleVolume = this.handleVolume.bind(this);
  }

  handlePause(event) {
    this.setState({
      paused: event.target.checked,
    });
  }

  handlePlayerPause() {
    this.setState({ paused: true });
  }

  handlePlayerPlay() {
    this.setState({ paused: false });
  }

  handleVolume(event) {
    this.setState({
      volume: parseFloat(event.target.value),
    });
  }

  selectVideo(index) {
    this.setState({ videoIndex: index });
  }

  render() {
    const { videoIndex, paused, volume } = this.state;

    const video = videos[videoIndex];
    return (
      <div className="row">
        <div className="col s4">
          <h5>
            Video
          </h5>
          <div className="collection">
            {videos.map((choice, index) => (
              <a
                href={`#!/video/${index}`}
                className={`collection-item ${video === choice ? 'active' : ''}`}
                onClick={() => this.selectVideo(index)}
              >
                {choice.name}
              </a>
            ))}
          </div>
          <h5>
            Paused
          </h5>
          <p>
            <label htmlFor="paused">
              <input
                type="checkbox"
                id="paused"
                checked={paused}
                onChange={this.handlePause}
              />
              <span>Paused</span>
            </label>
          </p>
          <h5>
            Volume
          </h5>
          <input
            type="range"
            value={volume}
            min={0}
            max={1}
            step={0.01}
            onChange={this.handleVolume}
          />
        </div>
        <div className="col s8 center-align">
          <Vimeo
            video={video.id}
            width={640}
            height={480}
            autoplay
            volume={volume}
            paused={paused}
            onPause={this.handlePlayerPause}
            onPlay={this.handlePlayerPlay}
          />
        </div>
      </div>
    );
  }
}

// eslint-disable-next-line react/no-deprecated
ReactDOM.render(<App />, document.getElementById('example'));


================================================
FILE: example/index.html
================================================
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>@u-wave/react-vimeo example</title>
    <link rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
    <style>
      .primary { background-color: #9d2053 }
      .nav-wrapper {
        padding: 0 24px;
        display: flex;
        align-items: center;
      }
      .logo-wrapper { height: 48px; line-height: 48px; margin-right: 24px; }
      .logo { height: 48px; }
    </style>
  </head>
  <body>
    <nav class="primary">
      <div class="nav-wrapper">
        <a href="https://u-wave.net" class="logo-wrapper">
          <img src="https://u-wave.net/static/images/logo-white.png" alt="" class="logo">
        </a>
        <ul id="nav-mobile" class="right hide-on-med-and-down">
          <li><a href="https://hub.u-wave.net/" class="white-text btn-flat">Join</a></li>
          <li><a href="https://u-wave.net/install" class="white-text btn-flat">Install</a></li>
          <li><a href="https://u-wave.net/react-vimeo" class="white-text btn-flat">react-vimeo</a></li>
        </ul>
      </div>
    </nav>
    <div class="container">
      <div class="row">
        <div class="col s12">
          <h1>@u-wave/react-vimeo example</h1>
          <p>
            An example Vimeo player using <a href="https://facebook.github.io/react">React</a>
            and <a href="https://github.com/u-wave/react-vimeo">@u-wave/react-vimeo</a>.
            <a href="https://github.com/u-wave/react-vimeo/tree/default/example">view source</a>
          </p>
        </div>
      </div>
    </div>
    <div class="container" id="example"></div>
    <script src="bundle.js"></script>
  </body>
</html>


================================================
FILE: example/package.json
================================================
{
  "private": true,
  "name": "@u-wave/react-vimeo-example",
  "description": "@u-wave/react-vimeo example.",
  "version": "0.0.0-example",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "esbuild --bundle app.js --loader:.js=jsx --sourcemap=inline --minify > bundle.js",
    "start": "serve ."
  },
  "dependencies": {
    "@u-wave/react-vimeo": "file:..",
    "esbuild": "^0.14.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "serve": "^13.0.2"
  }
}


================================================
FILE: index.d.ts
================================================
import * as React from 'react'
import Player, { Error } from '@vimeo/player'

export type PlayEvent = {
  /**
   * The length of the video in seconds.
   */
  duration: number
  /**
   * The amount of the video, in seconds, that has played.
   */
  seconds: number
  /**
   * The amount of the video that has played in comparison to the length of the video;
   * multiply by 100 to obtain the percentage.
   */
  percent: number
}

export type PlayingEvent = PlayEvent;

export type PauseEvent = {
  /**
   * The length of the video in seconds.
   */
  duration: number
  /**
   * The amount of the video, in seconds, that has played to the pause position.
   */
  seconds: number
  /**
   * The amount of the video that has played to the pause position in comparison to the length of the video; multiply by 100 to obtain the percentage.
   */
  percent: number
}

export type EndEvent = PauseEvent

export type TimeUpdateEvent = {
  /**
   * The length of the video in seconds.
   */
  duration: number
  /**
   * The amount of the video, in seconds, that has played from the current playback position.
   */
  seconds: number
  /**
   * The amount of the video that has played from the current playback position in comparison to the length of the video; multiply by 100 to obtain the percentage.
   */
  percent: number
}

export type ProgressEvent = {
  /**
   * The length of the video in seconds.
   */
  duration: number
  /**
   * The amount of the video, in seconds, that has buffered.
   */
  seconds: number
  /**
   * The amount of the video that has buffered in comparison to the length of the video;
   * multiply by 100 to obtain the percentage.
   */
  percent: number
}

export type SeekedEvent = {
  /**
   * The length of the video in seconds.
   */
  duration: number
  /**
   * The amount of the video, in seconds, that has played from the new seek position.
   */
  seconds: number
  /**
  * The amount of the video that has played from the new seek position in comparison to the length of the video; multiply by 100 to obtain the percentage.
   */
  percent: number
}

export type TextTrackEvent = {
  kind: 'captions' | 'subtitles'
  label: string
  language: string
}

export type Cue = {
  html: string
  text: string
}

export type CueChangeEvent = {
  cues: Cue[]
  kind: 'captions' | 'subtitles'
  label: string
  language: string
}

export type CuePointEvent = {
  /**
   * The location of the cue point in seconds.
   */
  time: number
  /**
   * The ID of the cue point.
   */
  id: string
  /**
   * The custom data from the `addCuePoint()` call, or an empty object.
   */
  data: object
}

export type VolumeEvent = {
  /**
   * The new volume level.
   */
  volume: number
}

export type PlaybackRateEvent = {
  /**
   * The new playback rate.
   */
  playbackRate: number
}

export type LoadEvent = {
  /**
   * The ID of the new video.
   */
  id: number
}

export interface VimeoProps {
  /**
   * A Vimeo video ID or URL.
   */
  video: number | string
  /**
   * DOM ID for the player element.
   */
  id?: string
  /**
   * CSS className for the player element.
   */
  className?: string
  /**
   * Inline style for container element.
   */
  style?: React.CSSProperties
  /**
   * Width of the player element.
   */
  width?: number | string
  /**
   * Height of the player element.
   */
  height?: number | string

  /**
   * Pause the video.
   */
  paused?: boolean

  /**
   * The playback volume as a number between 0 and 1.
   */
  volume?: number

  /**
   * The time in seconds at which to start playing the video.
   */
  start?: number

  /**
   * Pause this video automatically when another one plays.
   */
  autopause?: boolean

  /**
   * Automatically start playback of the video. Note that this won’t work on
   * some devices.
   */
  autoplay?: boolean

  /**
   * Show the byline on the video.
   */
  showByline?: boolean

  /**
   * Specify the color of the video controls. Colors may be overridden by the
   * embed settings of the video. _(Ex: "ef2f9f")_
   */
  color?: string

  /**
   * Hide all elements in the player, such as the progress bar, sharing buttons, etc.
   * (requires Vimeo PRO / Business account)
   */
  controls?: boolean

  /**
   * Play the video again when it reaches the end.
   */
  loop?: boolean

  /**
   * Show the portrait on the video.
   */
  showPortrait?: boolean

  /**
   * Show the title on the video.
   */
  showTitle?: boolean

  /**
   * Starts in a muted state to help with autoplay
   */
  muted?: boolean

  /**
   * Starts in a background state with no controls to help with autoplay
   */
  background?: boolean

  /**
   * Enable responsive mode and resize according to parent element (experimental)
   */
  responsive?: boolean

  /**
   * Specify playback rate (requires Vimeo PRO / Business account)
   */
  playbackRate?: number

  /**
   * Enable playback rate controls (requires Vimeo PRO / Business account)
   */
  speed?: boolean

  /**
   * Blocks the player from tracking any session data, including all cookies and analytics
   */
  dnt?: boolean

  /**
   * Allows for keyboard input to trigger player events.
   */
  keyboard?: boolean

  /**
   * Show the picture-in-picture button in the controlbar
   * and enable the picture-in-picture API.
   */
  pip?: boolean

  /**
   * Play video inline on mobile devices, to automatically
   * go fullscreen on playback set this parameter to false.
   */
  playsInline?: boolean

  /**
   * Vimeo Plus, PRO, and Business members can default
   * an embedded video to a specific quality on desktop.
   */
  quality?: string

  /**
   * Turn captions/subtitles on for a specific language by default.
   */
  textTrack?: string

  /**
   * The responsive player and transparent background are enabled
   * by default, to disable set this parameter to false.
   */
  transparent?: boolean

  /**
   * Sent when the Vimeo player API has loaded.
   * Receives the Vimeo player object in the first parameter.
   */
  onReady?: (player: Player) => void
  /**
   * Sent when the player triggers an error.
   */
  onError?: (error: Error) => void
  /**
   * Triggered when video playback is initiated.
   */
  onPlay?: (event: PlayEvent) => void
  /**
   * Triggered when the video starts playing.
   */
  onPlaying?: (event: PlayingEvent) => void
  /**
   * Triggered when the video pauses.
   */
  onPause?: (event: PauseEvent) => void
  /**
   * Triggered any time the video playback reaches the end.
   * Note: when `loop` is turned on, the ended event will not fire.
   */
  onEnd?: (event: EndEvent) => void
  /**
   * Triggered as the `currentTime` of the video updates. It generally fires
   * every 250ms, but it may vary depending on the browser.
   */
  onTimeUpdate?: (event: TimeUpdateEvent) => void
  /**
   * Triggered as the video is loaded. Reports back the amount of the video
   * that has been buffered.
   */
  onProgress?: (event: ProgressEvent) => void
  /**
   * Triggered when the player seeks to a specific time. An `onTimeUpdate`
   * event will also be fired at the same time.
   */
  onSeeked?: (event: SeekedEvent) => void
  /**
   * Triggered when the active text track (captions/subtitles) changes. The
   * values will be `null` if text tracks are turned off.
   */
  onTextTrackChange?: (event: TextTrackEvent) => void
  /**
   * Triggered when the active cue for the current text track changes. It also
   * fires when the active text track changes. There may be multiple cues
   * active.
   */
  onCueChange?: (event: CueChangeEvent) => void
  /**
   * Triggered when the current time hits a registered cue point.
   */
  onCuePoint?: (event: CuePointEvent) => void
  /**
   * Triggered when the volume in the player changes. Some devices do not
   * support setting the volume of the video independently from the system
   * volume, so this event will never fire on those devices.
   */
  onVolumeChange?: (event: VolumeEvent) => void
  /**
   * Triggered when the playback rate in the player changes.
   */
  onPlaybackRateChange?: (event: PlaybackRateEvent) => void
  /**
   * Triggered when a new video is loaded in the player.
   */
  onLoaded?: (event: LoadEvent) => void
}

/**
 * Vimeo player component for React.
 */
export default class Vimeo extends React.Component<VimeoProps> {}


================================================
FILE: index.test-d.tsx
================================================
import { expectError, expectType } from 'tsd'
import * as React from 'react'
import Vimeo from '.'

// Missing required prop `video`.
expectError(<Vimeo />)

{
  const element = (
    <Vimeo
      video={654321}
      onPlay={(event) => {
        expectType<number>(event.seconds)
        expectType<number>(event.duration)
        expectType<number>(event.percent)
      }}
    />
  )
}

{
  const element = <Vimeo video={123456} width={600} height="300px" />
}

{
  const element = (
    <Vimeo
      video={654321}
      onReady={(player) => {
        player.getCurrentTime()
      }}
    />
  )
}

{
  const element = (
    <Vimeo
      video={654321}
      autoplay
    />
  )
}


================================================
FILE: package.json
================================================
{
  "name": "@u-wave/react-vimeo",
  "version": "0.9.12",
  "description": "Vimeo player component for React.",
  "main": "dist/react-vimeo.js",
  "module": "dist/react-vimeo.es.js",
  "types": "index.d.ts",
  "scripts": {
    "prepare": "npm run build",
    "build": "rollup -c",
    "lint": "eslint --cache .",
    "test": "npm run lint && npm run tests-only && npm run tsd",
    "tests-only": "cross-env BABEL_ENV=test mocha --require @babel/register test/*.js",
    "tsd": "tsd",
    "docs": "prop-types-table src/index.js | md-insert README.md --header Props -i",
    "example": "npm run --prefix example build"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/u-wave/react-vimeo.git"
  },
  "keywords": [
    "vimeo",
    "react",
    "player",
    "react-component",
    "video"
  ],
  "author": "Renée Kooi <renee@kooi.me>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/u-wave/react-vimeo/issues"
  },
  "homepage": "https://github.com/u-wave/react-vimeo#readme",
  "dependencies": {
    "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
    "@types/vimeo__player": "^2.10.0",
    "@vimeo/player": "^2.16.4",
    "prop-types": "^15.7.2"
  },
  "peerDependencies": {
    "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.10",
    "@babel/preset-env": "^7.12.10",
    "@babel/preset-react": "^7.12.10",
    "@babel/register": "^7.12.10",
    "@rollup/plugin-babel": "^6.0.0",
    "@u-wave/react-vimeo-example": "file:example",
    "babel-plugin-dynamic-import-node": "^2.3.3",
    "cross-env": "^7.0.3",
    "eslint": "^8.2.0",
    "eslint-config-airbnb": "^19.0.0",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.27.0",
    "eslint-plugin-react-hooks": "^4.3.0",
    "expect": "^1.20.2",
    "md-insert": "^2.0.0",
    "min-react-env": "^2.0.0",
    "mocha": "^10.0.0",
    "prop-types-table": "^1.0.0",
    "proxyquire": "^2.1.3",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "rollup": "^3.1.0",
    "tsd": "^0.32.0"
  },
  "sideEffects": false
}


================================================
FILE: rollup.config.mjs
================================================
import fs from 'fs';
import babel from '@rollup/plugin-babel';

const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'));

process.env.BABEL_ENV = 'rollup';

export default {
  input: './src/index.js',
  output: [
    { format: 'cjs', file: pkg.main, exports: 'named' },
    { format: 'es', file: pkg.module },
  ],

  external: Object.keys(pkg.dependencies)
    .concat(Object.keys(pkg.peerDependencies)),
  plugins: [
    babel({
      babelHelpers: 'bundled',
    }),
  ],
};


================================================
FILE: src/eventNames.js
================================================
export default {
  play: 'onPlay',
  playing: 'onPlaying',
  pause: 'onPause',
  ended: 'onEnd',
  timeupdate: 'onTimeUpdate',
  progress: 'onProgress',
  seeked: 'onSeeked',
  texttrackchange: 'onTextTrackChange',
  cuechange: 'onCueChange',
  cuepoint: 'onCuePoint',
  volumechange: 'onVolumeChange',
  playbackratechange: 'onPlaybackRateChange',
  error: 'onError',
  loaded: 'onLoaded',
};


================================================
FILE: src/index.js
================================================
import React from 'react';
import PropTypes from 'prop-types';
import Player from '@vimeo/player';
import eventNames from './eventNames';

class Vimeo extends React.Component {
  constructor(props) {
    super(props);

    this.refContainer = this.refContainer.bind(this);
  }

  componentDidMount() {
    this.createPlayer();
  }

  componentDidUpdate(prevProps) {
    // eslint-disable-next-line react/destructuring-assignment
    const changes = Object.keys(this.props).filter((name) => this.props[name] !== prevProps[name]);

    this.updateProps(changes);
  }

  componentWillUnmount() {
    this.player.destroy();
  }

  /**
   * @private
   */
  getInitialOptions() {
    const { video } = this.props;
    const videoType = /^https?:/i.test(video) ? 'url' : 'id';
    /* eslint-disable react/destructuring-assignment */
    return {
      [videoType]: video,
      width: this.props.width,
      height: this.props.height,
      autopause: this.props.autopause,
      autoplay: this.props.autoplay,
      byline: this.props.showByline,
      color: this.props.color,
      controls: this.props.controls,
      loop: this.props.loop,
      portrait: this.props.showPortrait,
      title: this.props.showTitle,
      muted: this.props.muted,
      background: this.props.background,
      responsive: this.props.responsive,
      dnt: this.props.dnt,
      speed: this.props.speed,
      keyboard: this.props.keyboard,
      pip: this.props.pip,
      playsinline: this.props.playsInline,
      quality: this.props.quality,
      texttrack: this.props.textTrack,
      transparent: this.props.transparent,
    };
    /* eslint-enable react/destructuring-assignment */
  }

  /**
   * @private
   */
  updateProps(propNames) {
    const { player } = this;
    propNames.forEach((name) => {
      // eslint-disable-next-line react/destructuring-assignment
      const value = this.props[name];
      switch (name) {
        case 'autopause':
          player.setAutopause(value);
          break;
        case 'color':
          player.setColor(value);
          break;
        case 'loop':
          player.setLoop(value);
          break;
        case 'volume':
          player.setVolume(value);
          break;
        case 'paused':
          player.getPaused().then((paused) => {
            if (value && !paused) {
              return player.pause();
            }
            if (!value && paused) {
              return player.play();
            }
            return null;
          });
          break;
        case 'width':
        case 'height':
          player.element[name] = value;
          break;
        case 'video':
          if (value) {
            const { start } = this.props;
            const loaded = player.loadVideo(value);
            // Set the start time only when loading a new video.
            // It seems like this has to be done after the video has loaded, else it just starts at
            // the beginning!
            if (typeof start === 'number') {
              loaded.then(() => {
                player.setCurrentTime(start);
              });
            }
          } else {
            player.unload();
          }
          break;
        case 'playbackRate':
          player.setPlaybackRate(value);
          break;
        case 'quality':
          player.setQuality(value);
          break;
        default:
          // Nothing
      }
    });
  }

  /**
   * @private
   */
  createPlayer() {
    const { start, volume, playbackRate } = this.props;

    this.player = new Player(this.container, this.getInitialOptions());

    Object.keys(eventNames).forEach((dmName) => {
      const reactName = eventNames[dmName];
      this.player.on(dmName, (event) => {
        // eslint-disable-next-line react/destructuring-assignment
        const handler = this.props[reactName];
        if (handler) {
          handler(event);
        }
      });
    });

    const { onError, onReady } = this.props;
    this.player.ready().then(() => {
      if (onReady) {
        onReady(this.player);
      }
    }, (err) => {
      if (onError) {
        onError(err);
      } else {
        throw err;
      }
    });

    if (typeof start === 'number') {
      this.player.setCurrentTime(start);
    }

    if (typeof volume === 'number') {
      this.updateProps(['volume']);
    }

    if (typeof playbackRate === 'number') {
      this.updateProps(['playbackRate']);
    }
  }

  /**
   * @private
   */
  refContainer(container) {
    this.container = container;
  }

  render() {
    const { id, className, style } = this.props;

    return (
      <div
        id={id}
        className={className}
        style={style}
        ref={this.refContainer}
      />
    );
  }
}

if (process.env.NODE_ENV !== 'production') {
  Vimeo.propTypes = {
    /**
     * A Vimeo video ID or URL.
     */
    video: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.string,
    ]),
    /**
     * DOM ID for the player element.
     */
    id: PropTypes.string,
    /**
     * CSS className for the player element.
     */
    className: PropTypes.string,
    /**
     * Inline style for container element.
     */
    style: PropTypes.object, // eslint-disable-line react/forbid-prop-types
    /**
     * Width of the player element.
     */
    width: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.string,
    ]),
    /**
     * Height of the player element.
     */
    height: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.string,
    ]),

    /**
     * Pause the video.
     */
    paused: PropTypes.bool, // eslint-disable-line react/no-unused-prop-types

    /**
     * The playback volume as a number between 0 and 1.
     */
    volume: PropTypes.number,

    /**
     * The time in seconds at which to start playing the video.
     */
    start: PropTypes.number,

    // Player parameters
    /**
     * Pause this video automatically when another one plays.
     */
    autopause: PropTypes.bool,

    /**
     * Automatically start playback of the video. Note that this won’t work on
     * some devices.
     */
    autoplay: PropTypes.bool,

    /**
     * Show the byline on the video.
     */
    showByline: PropTypes.bool,

    /**
     * Specify the color of the video controls. Colors may be overridden by the
     * embed settings of the video. _(Ex: "ef2f9f")_
     */
    color: PropTypes.string,

    /**
     * Blocks the player from tracking any session data, including all cookies and analytics.
     */
    dnt: PropTypes.bool,

    // Player controls
    /**
     * Hide all elements in the player, such as the progress bar, sharing buttons, etc.
     * (requires Vimeo PRO / Business account)
     */
    controls: PropTypes.bool,

    /**
     * Play the video again when it reaches the end.
     */
    loop: PropTypes.bool,

    /**
     * Show the portrait on the video.
     */
    showPortrait: PropTypes.bool,

    /**
     * Show the title on the video.
     */
    showTitle: PropTypes.bool,

    /**
     * Starts in a muted state to help with autoplay
     */
    muted: PropTypes.bool,

    /**
     * Starts in a background state with no controls to help with autoplay
     */
    background: PropTypes.bool,

    /**
     * Enable responsive mode and resize according to parent element (experimental)
     */
    responsive: PropTypes.bool,

    /**
     * Specify playback rate (requires Vimeo PRO / Business account)
     */
    playbackRate: PropTypes.number,

    /**
     * Enable playback rate controls (requires Vimeo PRO / Business account)
     */
    speed: PropTypes.bool,

    /**
     * Allows for keyboard input to trigger player events.
     */
    keyboard: PropTypes.bool,

    /**
     * Show the picture-in-picture button in the controlbar
     * and enable the picture-in-picture API.
     */
    pip: PropTypes.bool,

    /**
     * Play video inline on mobile devices, to automatically
     * go fullscreen on playback set this parameter to false.
     */
    playsInline: PropTypes.bool,

    /**
     * Vimeo Plus, PRO, and Business members can default
     * an embedded video to a specific quality on desktop.
     */
    quality: PropTypes.string,

    /**
     * Turn captions/subtitles on for a specific language by default.
     */
    textTrack: PropTypes.string,

    /**
     * The responsive player and transparent background are enabled
     * by default, to disable set this parameter to false.
     */
    transparent: PropTypes.bool,

    // Events
    /* eslint-disable react/no-unused-prop-types */

    /**
     * Sent when the Vimeo player API has loaded.
     * Receives the Vimeo player object in the first parameter.
     */
    onReady: PropTypes.func,
    /**
     * Sent when the player triggers an error.
     */
    onError: PropTypes.func,
    /**
     * Triggered when video playback is initiated.
     */
    onPlay: PropTypes.func,
    /**
     * Triggered when the video starts playing.
     */
    onPlaying: PropTypes.func,
    /**
     * Triggered when the video pauses.
     */
    onPause: PropTypes.func,
    /**
     * Triggered any time the video playback reaches the end.
     * Note: when `loop` is turned on, the ended event will not fire.
     */
    onEnd: PropTypes.func,
    /**
     * Triggered as the `currentTime` of the video updates. It generally fires
     * every 250ms, but it may vary depending on the browser.
     */
    onTimeUpdate: PropTypes.func,
    /**
     * Triggered as the video is loaded. Reports back the amount of the video
     * that has been buffered.
     */
    onProgress: PropTypes.func,
    /**
     * Triggered when the player seeks to a specific time. An `onTimeUpdate`
     * event will also be fired at the same time.
     */
    onSeeked: PropTypes.func,
    /**
     * Triggered when the active text track (captions/subtitles) changes. The
     * values will be `null` if text tracks are turned off.
     */
    onTextTrackChange: PropTypes.func,
    /**
     * Triggered when the active cue for the current text track changes. It also
     * fires when the active text track changes. There may be multiple cues
     * active.
     */
    onCueChange: PropTypes.func,
    /**
     * Triggered when the current time hits a registered cue point.
     */
    onCuePoint: PropTypes.func,
    /**
     * Triggered when the volume in the player changes. Some devices do not
     * support setting the volume of the video independently from the system
     * volume, so this event will never fire on those devices.
     */
    onVolumeChange: PropTypes.func,
    /**
     * Triggered when the playback rate changes.
     */
    onPlaybackRateChange: PropTypes.func,
    /**
     * Triggered when a new video is loaded in the player.
     */
    onLoaded: PropTypes.func,

    /* eslint-enable react/no-unused-prop-types */
  };
}

Vimeo.defaultProps = {
  autopause: true,
  autoplay: false,
  showByline: true,
  controls: true,
  loop: false,
  showPortrait: true,
  showTitle: true,
  muted: false,
  background: false,
  responsive: false,
  dnt: false,
  speed: false,
  keyboard: true,
  pip: false,
  playsInline: true,
  transparent: true,
};

export default Vimeo;


================================================
FILE: test/.eslintrc.js
================================================
module.exports = {
  extends: '../.eslintrc.js',
  env: {
    mocha: true,
  },
  rules: {
    // We have good reasons
    'react/jsx-props-no-spreading': 'off',
  },
};


================================================
FILE: test/test.js
================================================
import expect, { createSpy } from 'expect';
import render from './util/render';

describe('Vimeo', () => {
  it('should create a Vimeo player when mounted', async () => {
    const onReady = createSpy();
    const { sdkMock, playerMock } = await render({
      video: 169408731,
      onReady,
    });
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ id: 169408731 });
    await playerMock.ready();
    expect(onReady).toHaveBeenCalled();
    expect(onReady.calls[0].arguments[0]).toBe(playerMock);
  });

  it('should use `url` prop for full vimeo URLs', async () => {
    const { sdkMock } = await render({ video: 'https://vimeo.com/179290396' });
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ url: 'https://vimeo.com/179290396' });
  });

  it('should all onError when `ready()` fails', async () => {
    const onError = createSpy();
    const { sdkMock } = await render({
      video: 404,
      shouldFail: true,
      onError,
    });
    await Promise.resolve();
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ id: 404 });
    expect(onError).toHaveBeenCalled();
    expect(onError.calls[0].arguments[0]).toEqual(new Error('artificial failure'));
  });

  it('should load a different video when "video" prop changes', async () => {
    const { sdkMock, playerMock, rerender } = await render({
      video: 169408731,
    });
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ id: 169408731 });

    await rerender({ video: 162959050 });

    expect(playerMock.loadVideo).toHaveBeenCalled();
    expect(playerMock.loadVideo.calls[0].arguments[0]).toEqual(162959050);
  });

  it('should pause the video using the "paused" prop', async () => {
    const { playerMock, rerender } = await render({
      video: 169408731,
      autoplay: true,
    });

    // Don't call `play` again when we were already playing
    await rerender({ paused: false });
    expect(playerMock.play).toNotHaveBeenCalled();

    await rerender({ paused: true });
    expect(playerMock.pause).toHaveBeenCalled();

    await rerender({ paused: false });
    expect(playerMock.play).toHaveBeenCalled();
  });

  it('should set the volume using the "volume" prop', async () => {
    const { playerMock, rerender } = await render({
      video: 169408731,
      volume: 0.5,
    });
    expect(playerMock.setVolume).toHaveBeenCalledWith(0.5);

    await rerender({ volume: 1 });

    expect(playerMock.setVolume).toHaveBeenCalledWith(1);
  });

  it('should set the start time using the "start" prop', async () => {
    const { playerMock, rerender } = await render({
      video: 169408731,
      start: 60,
    });
    expect(playerMock.setCurrentTime).toHaveBeenCalledWith(60);

    playerMock.setCurrentTime.reset();
    await rerender({ start: 90 });
    expect(playerMock.setCurrentTime).toNotHaveBeenCalled();

    await rerender({ video: 169408732, start: 120 });
    expect(playerMock.setCurrentTime).toHaveBeenCalledWith(120);
  });

  it('should set the player color using the "color" prop', async () => {
    const { playerMock, sdkMock, rerender } = await render({
      video: 169408731,
      color: '#0000ff',
    });
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ color: '#0000ff' });

    await rerender({ color: '#ff0000' });
    expect(playerMock.setColor).toHaveBeenCalledWith('#ff0000');
    await rerender({ color: '#00ff00' });
    expect(playerMock.setColor).toHaveBeenCalledWith('#00ff00');
  });

  it('should set the looping flag using the "loop" prop', async () => {
    const { playerMock, sdkMock, rerender } = await render({
      video: 169408731,
      loop: false,
    });
    expect(sdkMock).toHaveBeenCalled();
    expect(sdkMock.calls[0].arguments[1]).toMatch({ loop: false });

    await rerender({ loop: true });
    expect(playerMock.setLoop).toHaveBeenCalledWith(true);
    await rerender({ loop: false });
    expect(playerMock.setLoop).toHaveBeenCalledWith(false);
  });

  it('should set the iframe width/height using the width/height props', async () => {
    const { sdkMock, playerMock, rerender } = await render({
      video: 169408731,
      width: 640,
      height: 320,
    });
    expect(sdkMock.calls[0].arguments[1]).toMatch({
      width: 640,
      height: 320,
    });

    await rerender({
      width: '100%',
      height: 800,
    });

    expect(playerMock.setWidth).toHaveBeenCalledWith('100%');
    expect(playerMock.setHeight).toHaveBeenCalledWith(800);
  });

  it('should set the playback rate using the "playbackRate" props', async () => {
    const { playerMock, rerender } = await render({
      video: 169408731,
      playbackRate: 0.5,
    });

    expect(playerMock.setPlaybackRate).toHaveBeenCalledWith(0.5);

    await rerender({ playbackRate: 2 });

    expect(playerMock.setPlaybackRate).toHaveBeenCalledWith(2);
  });

  it('should destroy player when unmounting', async () => {
    const { playerMock, unmount } = await render({
      video: 169408731,
      width: 640,
      height: 320,
    });

    unmount();

    expect(playerMock.destroy).toHaveBeenCalled();
  });
});


================================================
FILE: test/util/createVimeo.js
================================================
import { createSpy } from 'expect';
import proxyquire from 'proxyquire';

export default function createVimeo({ shouldFail = false } = {}) {
  let isPaused = true;

  const createPromiseSpy = () => createSpy().andCall(() => Promise.resolve());

  const playerMock = {
    on: createSpy(),
    ready() {
      return shouldFail
        ? Promise.reject(new Error('artificial failure'))
        : Promise.resolve();
    },
    setVolume: createPromiseSpy(),
    setPlaybackRate: createPromiseSpy(),
    setCurrentTime: createPromiseSpy(),
    setAutopause: createPromiseSpy(),
    setColor: createPromiseSpy(),
    setLoop: createPromiseSpy(),
    loadVideo: createPromiseSpy(),
    playing: createPromiseSpy(),
    unload: createPromiseSpy(),
    play: createSpy().andCall(() => {
      isPaused = false;
    }),
    pause: createSpy().andCall(() => {
      isPaused = true;
    }),
    getPaused() {
      return Promise.resolve(isPaused);
    },
    destroy: createSpy(),
    setWidth: createSpy(),
    setHeight: createSpy(),
    element: {
      set width(value) {
        playerMock.setWidth(value);
      },
      set height(value) {
        playerMock.setHeight(value);
      },
    },
  };

  const sdkMock = createSpy().andCall((container, options) => {
    isPaused = !options.autoplay;
    return playerMock;
  });

  const Vimeo = proxyquire.noCallThru().load('../../src/index.js', {
    '@vimeo/player': function Player(...args) {
      return sdkMock(...args);
    },
  }).default;

  return { Vimeo, sdkMock, playerMock };
}


================================================
FILE: test/util/render.js
================================================
/**
 * Taken from react-youtube's tests at
 * https://github.com/troybetz/react-youtube
 */

import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
// Doing this after React is loaded makes React do a bit less DOM work
import 'min-react-env/install';
import env from 'min-react-env';
import createVimeo from './createVimeo';

const reactMajor = parseInt((ReactDOM.version || '16').split('.')[0], 10);

function noAct(fn) {
  return fn();
}

async function render(initialProps) {
  const { Vimeo, sdkMock, playerMock } = createVimeo({
    shouldFail: initialProps.shouldFail,
  });

  let component;
  // Emulate changes to component.props using a container component's state
  class Container extends React.Component {
    constructor(ytProps) {
      super(ytProps);

      this.state = { props: ytProps };
    }

    render() {
      const { props } = this.state;

      return (
        <Vimeo
          ref={(vimeo) => { component = vimeo; }}
          {...props}
        />
      );
    }
  }

  const div = env.document.createElement('div');
  let root;
  if (reactMajor >= 18) {
    const { createRoot } = await import('react-dom/client');
    root = createRoot(div);
  } else {
    root = {
      render(element) {
        // eslint-disable-next-line react/no-deprecated
        ReactDOM.render(element, div);
      },
      unmount() {
        // eslint-disable-next-line react/no-deprecated
        ReactDOM.unmountComponentAtNode(div);
      },
    };
  }
  const container = await new Promise((resolve) => {
    root.render(<Container {...initialProps} ref={resolve} />);
  });

  function rerender(newProps) {
    return (act || noAct)(async () => {
      container.setState({ props: newProps });
    });
  }

  function unmount() {
    root.unmount();
  }

  return {
    sdkMock,
    playerMock,
    component,
    rerender,
    unmount,
  };
}

export default render;
Download .txt
gitextract_ty8zbuxn/

├── .babelrc.js
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       └── deploy.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── example/
│   ├── .babelrc.js
│   ├── app.js
│   ├── index.html
│   └── package.json
├── index.d.ts
├── index.test-d.tsx
├── package.json
├── rollup.config.mjs
├── src/
│   ├── eventNames.js
│   └── index.js
└── test/
    ├── .eslintrc.js
    ├── test.js
    └── util/
        ├── createVimeo.js
        └── render.js
Download .txt
SYMBOL INDEX (39 symbols across 6 files)

FILE: .babelrc.js
  constant TEST (line 1) | const TEST = process.env.BABEL_ENV === 'test';
  constant CJS (line 2) | const CJS = process.env.BABEL_ENV === 'cjs';

FILE: example/app.js
  class App (line 12) | class App extends React.Component {
    method constructor (line 13) | constructor(props) {
    method handlePause (line 28) | handlePause(event) {
    method handlePlayerPause (line 34) | handlePlayerPause() {
    method handlePlayerPlay (line 38) | handlePlayerPlay() {
    method handleVolume (line 42) | handleVolume(event) {
    method selectVideo (line 48) | selectVideo(index) {
    method render (line 52) | render() {

FILE: index.d.ts
  type PlayEvent (line 4) | type PlayEvent = {
  type PlayingEvent (line 20) | type PlayingEvent = PlayEvent;
  type PauseEvent (line 22) | type PauseEvent = {
  type EndEvent (line 37) | type EndEvent = PauseEvent
  type TimeUpdateEvent (line 39) | type TimeUpdateEvent = {
  type ProgressEvent (line 54) | type ProgressEvent = {
  type SeekedEvent (line 70) | type SeekedEvent = {
  type TextTrackEvent (line 85) | type TextTrackEvent = {
  type Cue (line 91) | type Cue = {
  type CueChangeEvent (line 96) | type CueChangeEvent = {
  type CuePointEvent (line 103) | type CuePointEvent = {
  type VolumeEvent (line 118) | type VolumeEvent = {
  type PlaybackRateEvent (line 125) | type PlaybackRateEvent = {
  type LoadEvent (line 132) | type LoadEvent = {
  type VimeoProps (line 139) | interface VimeoProps {
  class Vimeo (line 362) | class Vimeo extends React.Component<VimeoProps> {}

FILE: src/index.js
  class Vimeo (line 6) | class Vimeo extends React.Component {
    method constructor (line 7) | constructor(props) {
    method componentDidMount (line 13) | componentDidMount() {
    method componentDidUpdate (line 17) | componentDidUpdate(prevProps) {
    method componentWillUnmount (line 24) | componentWillUnmount() {
    method getInitialOptions (line 31) | getInitialOptions() {
    method updateProps (line 65) | updateProps(propNames) {
    method createPlayer (line 129) | createPlayer() {
    method refContainer (line 174) | refContainer(container) {
    method render (line 178) | render() {

FILE: test/util/createVimeo.js
  function createVimeo (line 4) | function createVimeo({ shouldFail = false } = {}) {

FILE: test/util/render.js
  function noAct (line 16) | function noAct(fn) {
  function render (line 20) | async function render(initialProps) {
Condensed preview — 27 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (54K chars).
[
  {
    "path": ".babelrc.js",
    "chars": 355,
    "preview": "const TEST = process.env.BABEL_ENV === 'test';\nconst CJS = process.env.BABEL_ENV === 'cjs';\n\nmodule.exports = {\n  preset"
  },
  {
    "path": ".editorconfig",
    "chars": 370,
    "preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
  },
  {
    "path": ".eslintignore",
    "chars": 36,
    "preview": "node_modules\nexample/bundle.js\ndist\n"
  },
  {
    "path": ".eslintrc.js",
    "chars": 590,
    "preview": "module.exports = {\n  extends: 'airbnb',\n  parserOptions: {\n    ecmaVersion: 2022,\n    sourceType: 'module',\n  },\n  rules"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 212,
    "preview": "version: 2\nupdates:\n- package-ecosystem: npm\n  directory: \"/\"\n  schedule:\n    interval: weekly\n  open-pull-requests-limi"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1606,
    "preview": "name: CI\n\non: [push, pull_request]\n\njobs:\n  types:\n    name: Types\n    runs-on: ubuntu-latest\n    steps:\n      - name: C"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 739,
    "preview": "name: Deploy\n\non:\n  push:\n    branches:\n      - default\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - "
  },
  {
    "path": ".gitignore",
    "chars": 88,
    "preview": "node_modules\n/dist\n/example/bundle.js\n/generated-docs.md\n.eslintcache\npackage-lock.json\n"
  },
  {
    "path": ".npmignore",
    "chars": 61,
    "preview": ".eslintcache\nnode_modules\n/tools\n/example\n/generated-docs.md\n"
  },
  {
    "path": ".npmrc",
    "chars": 19,
    "preview": "package-lock=false\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 2626,
    "preview": "# @u-wave/react-vimeo change log\n\nAll notable changes to this project will be documented in this file.\n\nThis project adh"
  },
  {
    "path": "LICENSE",
    "chars": 1077,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Renée Kooi\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "README.md",
    "chars": 5244,
    "preview": "# @u-wave/react-vimeo\n\nVimeo player component for React.\n\n[Install][] - [Usage][] - [Demo][] - [Props][]\n\n## Install\n\n``"
  },
  {
    "path": "example/.babelrc.js",
    "chars": 41,
    "preview": "module.exports = require('../.babelrc');\n"
  },
  {
    "path": "example/app.js",
    "chars": 2825,
    "preview": "/* global document */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport Vimeo from '@u-wave/react-vime"
  },
  {
    "path": "example/index.html",
    "chars": 1732,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <title>@u-wave/react-vimeo example</title>\n    <link rel="
  },
  {
    "path": "example/package.json",
    "chars": 505,
    "preview": "{\n  \"private\": true,\n  \"name\": \"@u-wave/react-vimeo-example\",\n  \"description\": \"@u-wave/react-vimeo example.\",\n  \"versio"
  },
  {
    "path": "index.d.ts",
    "chars": 8291,
    "preview": "import * as React from 'react'\nimport Player, { Error } from '@vimeo/player'\n\nexport type PlayEvent = {\n  /**\n   * The l"
  },
  {
    "path": "index.test-d.tsx",
    "chars": 684,
    "preview": "import { expectError, expectType } from 'tsd'\nimport * as React from 'react'\nimport Vimeo from '.'\n\n// Missing required "
  },
  {
    "path": "package.json",
    "chars": 2152,
    "preview": "{\n  \"name\": \"@u-wave/react-vimeo\",\n  \"version\": \"0.9.12\",\n  \"description\": \"Vimeo player component for React.\",\n  \"main\""
  },
  {
    "path": "rollup.config.mjs",
    "chars": 488,
    "preview": "import fs from 'fs';\nimport babel from '@rollup/plugin-babel';\n\nconst pkg = JSON.parse(fs.readFileSync('./package.json',"
  },
  {
    "path": "src/eventNames.js",
    "chars": 394,
    "preview": "export default {\n  play: 'onPlay',\n  playing: 'onPlaying',\n  pause: 'onPause',\n  ended: 'onEnd',\n  timeupdate: 'onTimeUp"
  },
  {
    "path": "src/index.js",
    "chars": 11207,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Player from '@vimeo/player';\nimport eventNames fro"
  },
  {
    "path": "test/.eslintrc.js",
    "chars": 170,
    "preview": "module.exports = {\n  extends: '../.eslintrc.js',\n  env: {\n    mocha: true,\n  },\n  rules: {\n    // We have good reasons\n "
  },
  {
    "path": "test/test.js",
    "chars": 5255,
    "preview": "import expect, { createSpy } from 'expect';\nimport render from './util/render';\n\ndescribe('Vimeo', () => {\n  it('should "
  },
  {
    "path": "test/util/createVimeo.js",
    "chars": 1539,
    "preview": "import { createSpy } from 'expect';\nimport proxyquire from 'proxyquire';\n\nexport default function createVimeo({ shouldFa"
  },
  {
    "path": "test/util/render.js",
    "chars": 1934,
    "preview": "/**\n * Taken from react-youtube's tests at\n * https://github.com/troybetz/react-youtube\n */\n\nimport React from 'react';\n"
  }
]

About this extraction

This page contains the full source code of the u-wave/react-vimeo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 27 files (49.1 KB), approximately 13.5k tokens, and a symbol index with 39 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!