├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Feature_request.md │ └── Questions_answers.md ├── dependabot.yml └── workflows │ ├── main.yml │ └── pull_request.yml ├── .gitignore ├── .npmrc ├── CHANGELOG.md ├── CNAME ├── LICENSE.md ├── README.md ├── lerna.json ├── package.json ├── packages ├── hover-react │ ├── .babelrc │ ├── .npmrc │ ├── .storybook │ │ ├── main.js │ │ ├── manager.js │ │ └── theme.js │ ├── CHANGELOG.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ └── index.js │ └── stories │ │ ├── index.js │ │ └── index.test.js ├── hover-vanilla │ ├── .npmrc │ ├── CHANGELOG.md │ ├── docs │ │ ├── assets │ │ │ └── video │ │ │ │ └── demo.mp4 │ │ ├── bootstrap.html │ │ ├── collectednotes.html │ │ ├── dealflow.html │ │ ├── index.html │ │ └── joshwcomeau.html │ ├── package.json │ ├── preact.html │ ├── rollup.config.js │ └── src │ │ └── index.js ├── react │ ├── .babelrc │ ├── .npmrc │ ├── .storybook │ │ ├── main.js │ │ └── preview.js │ ├── CHANGELOG.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── components │ │ │ └── Card │ │ │ │ ├── CardAnimation.js │ │ │ │ ├── CardContent.js │ │ │ │ ├── CardEmpty.js │ │ │ │ ├── CardMedia │ │ │ │ ├── Audio.js │ │ │ │ ├── Controls │ │ │ │ │ ├── FooterControls.js │ │ │ │ │ ├── MediaButton.js │ │ │ │ │ ├── PlaybackButton.js │ │ │ │ │ ├── ProgressBar │ │ │ │ │ │ ├── Scrubber.js │ │ │ │ │ │ ├── Tooltip.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── SeekButton.js │ │ │ │ │ ├── Spinner.js │ │ │ │ │ └── index.js │ │ │ │ ├── Image.js │ │ │ │ ├── Video.js │ │ │ │ ├── Wrap.js │ │ │ │ ├── index.js │ │ │ │ └── loader.js │ │ │ │ ├── CardText.js │ │ │ │ ├── CardWrap.js │ │ │ │ └── index.js │ │ ├── context │ │ │ └── GlobalState.js │ │ ├── index.js │ │ ├── theme.js │ │ └── utils │ │ │ ├── hooks.js │ │ │ └── index.js │ ├── stories │ │ ├── media.stories.js │ │ ├── props.stories.js │ │ ├── set-data.stories.js │ │ ├── style.stories.js │ │ └── util │ │ │ ├── data.js │ │ │ └── story.js │ └── test │ │ ├── build.mjs │ │ └── snapshots │ │ ├── build.mjs.md │ │ └── build.mjs.snap └── vanilla │ ├── .npmrc │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── preact.html │ ├── rollup.config.js │ └── src │ └── index.js ├── pnpm-lock.yaml └── pnpm-workspace.yaml /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | max_line_length = 80 13 | indent_brace_style = 1TBS 14 | spaces_around_operators = true 15 | quote_type = auto 16 | 17 | [package.json] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [*.md] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: If something isn't working as expected. 4 | 5 | --- 6 | 7 | ## Bug Report 8 | 9 | > You can use live code at Codesandbox: [React](https://codesandbox.io/s/n5w839zm4m) | [Vanilla](https://codesandbox.io/s/o92r2y4q9z) 10 | 11 | **Current Behavior** 12 | 13 | A clear and concise description of the behavior. 14 | 15 | **Expected behavior/code** 16 | 17 | A clear and concise description of what you expected to happen (or code). 18 | 19 | **Possible Solution** 20 | 21 | 22 | 23 | **Additional context/Screenshots** 24 | 25 | Add any other context about the problem here. If applicable, add screenshots to help explain. 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Request 3 | about: If you have a suggestion. 4 | 5 | --- 6 | 7 | ## Feature Request 8 | 9 | > You can use live code at Codesandbox: [React](https://codesandbox.io/s/qqr6knpvp6) | [Vanilla](https://codesandbox.io/s/264799kkj) 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | A clear and concise description of what the problem is. Ex. I have an issue when [...] 13 | 14 | **Describe the solution you'd like** 15 | A clear and concise description of what you want to happen. Add any considered drawbacks. 16 | 17 | **Describe alternatives you've considered** 18 | A clear and concise description of any alternative solutions or features you've considered. 19 | 20 | **Teachability, Documentation, Adoption, Migration Strategy** 21 | If you can, explain how users will be able to use this and possibly write out a version the docs. 22 | Maybe a screenshot or design? 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Questions_answers.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🤔 Questions & Answers 3 | about: Ask anything you want to know 4 | 5 | --- 6 | 7 | ## Questions & Answers 8 | 9 | > You can use live code at Codesandbox: [React](https://codesandbox.io/s/qqr6knpvp6) | [Vanilla](https://codesandbox.io/s/264799kkj) 10 | 11 | **Context of your question** 12 | Help us to understand the mental roadmap we need to follow to reach the same question. 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | # Check for updates to GitHub Actions every weekday 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: main 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | contributors: 10 | if: "${{ github.event.head_commit.message != 'build: contributors' }}" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | token: ${{ secrets.GITHUB_TOKEN }} 18 | - name: Setup Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: lts/* 22 | - name: Contributors 23 | run: | 24 | git config --global user.email ${{ secrets.GIT_EMAIL }} 25 | git config --global user.name ${{ secrets.GIT_USERNAME }} 26 | npm run contributors 27 | - name: Push changes 28 | run: | 29 | git push origin ${{ github.head_ref }} 30 | 31 | test: 32 | if: | 33 | !startsWith(github.event.head_commit.message, 'chore(release):') && 34 | !startsWith(github.event.head_commit.message, 'docs:') && 35 | !startsWith(github.event.head_commit.message, 'ci:') 36 | needs: [contributors] 37 | runs-on: ubuntu-latest 38 | steps: 39 | - name: Checkout 40 | uses: actions/checkout@v4 41 | with: 42 | token: ${{ secrets.GITHUB_TOKEN }} 43 | - name: Setup Node.js 44 | uses: actions/setup-node@v4 45 | with: 46 | node-version: lts/* 47 | - name: Setup PNPM 48 | uses: pnpm/action-setup@v4 49 | with: 50 | version: latest 51 | run_install: true 52 | - name: Test 53 | run: pnpm test 54 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: pull_request 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | test: 13 | if: github.ref != 'refs/heads/master' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | - name: Setup Node.js 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: lts/* 24 | - name: Setup PNPM 25 | uses: pnpm/action-setup@v4 26 | with: 27 | version: latest 28 | run_install: true 29 | - name: Test 30 | run: pnpm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | packages/*/dist/** 11 | /build 12 | storybook-static 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .envrc 21 | 22 | # dependency locks 23 | yarn.lock 24 | package-lock.json 25 | npm-shrinkwrap.json 26 | 27 | # logs 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | 32 | # others 33 | packages/*/stats.html 34 | packages/hover-vanilla/docs/dist 35 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | save-prefix=~ 3 | save=false 4 | strict-peer-dependencies=false 5 | unsafe-perm=true 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [5.5.23](https://github.com/microlinkhq/sdk/compare/v5.5.22...v5.5.23) (2025-02-15) 7 | 8 | **Note:** Version bump only for package @microlink/root 9 | 10 | ## [5.5.22](https://github.com/microlinkhq/sdk/compare/v5.5.21...v5.5.22) (2024-07-18) 11 | 12 | **Note:** Version bump only for package @microlink/root 13 | 14 | ## [5.5.21](https://github.com/microlinkhq/sdk/compare/v5.5.20...v5.5.21) (2024-07-18) 15 | 16 | **Note:** Version bump only for package @microlink/root 17 | 18 | ## [5.5.20](https://github.com/microlinkhq/sdk/compare/v5.5.19...v5.5.20) (2024-07-18) 19 | 20 | **Note:** Version bump only for package @microlink/root 21 | 22 | ## [5.5.19](https://github.com/microlinkhq/sdk/compare/v5.5.18...v5.5.19) (2024-02-29) 23 | 24 | ### Bug Fixes 25 | 26 | * **vanilla:** disable mangle ([abfdc45](https://github.com/microlinkhq/sdk/commit/abfdc45a404df4a491f28db2713ddfe9e2a95aa4)) 27 | 28 | ## [5.5.18](https://github.com/microlinkhq/sdk/compare/v5.5.17...v5.5.18) (2024-01-09) 29 | 30 | **Note:** Version bump only for package @microlink/root 31 | 32 | ## [5.5.17](https://github.com/microlinkhq/sdk/compare/v5.5.16...v5.5.17) (2023-12-10) 33 | 34 | ### Bug Fixes 35 | 36 | * script ([12c45c5](https://github.com/microlinkhq/sdk/commit/12c45c5f31cdb33d99871573466c240cb966284f)) 37 | * vanilla build alias ([7e004ec](https://github.com/microlinkhq/sdk/commit/7e004ecaa493c4f667fd54b91c5811f994c5ed18)) 38 | 39 | ## [5.5.16](https://github.com/microlinkhq/sdk/compare/v5.5.15...v5.5.16) (2023-12-02) 40 | 41 | ### Bug Fixes 42 | 43 | * linter warnings related with transient props ([#330](https://github.com/microlinkhq/sdk/issues/330)) ([cebb363](https://github.com/microlinkhq/sdk/commit/cebb363a31c699d85a78b0dff55b5694465fed43)) 44 | * replace __VERSION__ ([#300](https://github.com/microlinkhq/sdk/issues/300)) ([c2789a4](https://github.com/microlinkhq/sdk/commit/c2789a47f8a4c3bf5c793de53f9a5a5aa2fccba5)) 45 | 46 | ## [5.5.15](https://github.com/microlinkhq/sdk/compare/v5.5.14...v5.5.15) (2023-03-29) 47 | 48 | **Note:** Version bump only for package @microlink/root 49 | 50 | ## [5.5.14](https://github.com/microlinkhq/sdk/compare/v5.5.13...v5.5.14) (2023-03-22) 51 | 52 | ### Bug Fixes 53 | 54 | * infinite loading ([#298](https://github.com/microlinkhq/sdk/issues/298)) ([159f1d5](https://github.com/microlinkhq/sdk/commit/159f1d55b4170f4660318f74c03fd119ad495f37)) 55 | 56 | ## [5.5.13](https://github.com/microlinkhq/sdk/compare/v5.5.12...v5.5.13) (2023-03-15) 57 | 58 | ### Bug Fixes 59 | 60 | * linter warnings ([#296](https://github.com/microlinkhq/sdk/issues/296)) ([4222c9c](https://github.com/microlinkhq/sdk/commit/4222c9c593ce8ac42737d6129b83eec12aeeb074)) 61 | * **linter:** glob pattern ([#297](https://github.com/microlinkhq/sdk/issues/297)) ([41db186](https://github.com/microlinkhq/sdk/commit/41db1866a282096688a54fd7a00fd3618bbfcf49)) 62 | 63 | ## [5.5.12](https://github.com/microlinkhq/sdk/compare/v5.5.11...v5.5.12) (2023-01-02) 64 | 65 | ### Bug Fixes 66 | 67 | * **image-proxy:** add image fallback ([#294](https://github.com/microlinkhq/sdk/issues/294)) ([4098f23](https://github.com/microlinkhq/sdk/commit/4098f23cb6c3b2fc09906e03ded0682808cdf1c7)) 68 | 69 | ## [5.5.11](https://github.com/microlinkhq/sdk/compare/v5.5.10...v5.5.11) (2022-11-18) 70 | 71 | **Note:** Version bump only for package @microlink/root 72 | 73 | ## [5.5.10](https://github.com/microlinkhq/sdk/compare/v5.5.9...v5.5.10) (2022-11-13) 74 | 75 | **Note:** Version bump only for package @microlink/root 76 | 77 | ## [5.5.9](https://github.com/microlinkhq/sdk/compare/v5.5.8...v5.5.9) (2022-07-01) 78 | 79 | **Note:** Version bump only for package @microlink/root 80 | 81 | ## [5.5.8](https://github.com/microlinkhq/sdk/compare/v5.5.7...v5.5.8) (2022-03-13) 82 | 83 | ### Bug Fixes 84 | 85 | * avoid to pass apikey ([#277](https://github.com/microlinkhq/sdk/issues/277)) ([747243f](https://github.com/microlinkhq/sdk/commit/747243f7711b8a7f84d7ea22743bddd04b14b582)) 86 | * duplicate line ([431f291](https://github.com/microlinkhq/sdk/commit/431f291385248e72c163d6e89a6a60fdb1b49bb2)) 87 | 88 | ### Performance Improvements 89 | 90 | * prefer mutation instead of Object.assign ([e9e8b42](https://github.com/microlinkhq/sdk/commit/e9e8b42b3f42591f66469226a1c0db0ec1a061c8)) 91 | 92 | ## [5.5.7](https://github.com/microlinkhq/sdk/compare/v5.5.6...v5.5.7) (2021-10-04) 93 | 94 | **Note:** Version bump only for package @microlink/root 95 | 96 | ## [5.5.6](https://github.com/microlinkhq/sdk/compare/v5.5.5...v5.5.6) (2021-06-05) 97 | 98 | **Note:** Version bump only for package @microlink/root 99 | 100 | ## [5.5.5](https://github.com/microlinkhq/sdk/compare/v5.5.4...v5.5.5) (2021-03-22) 101 | 102 | **Note:** Version bump only for package @microlink/root 103 | 104 | ## [5.5.4](https://github.com/microlinkhq/sdk/compare/v5.5.3...v5.5.4) (2021-01-17) 105 | 106 | ### Bug Fixes 107 | 108 | * add missing peer dependency ([034d469](https://github.com/microlinkhq/sdk/commit/034d46994b568963228e9a676ff0238c706c0fec)) 109 | 110 | ## [5.5.3](https://github.com/microlinkhq/sdk/compare/v5.5.2...v5.5.3) (2020-12-20) 111 | 112 | **Note:** Version bump only for package @microlink/root 113 | 114 | ## [5.5.2](https://github.com/microlinkhq/sdk/compare/v5.5.1...v5.5.2) (2020-12-12) 115 | 116 | **Note:** Version bump only for package @microlink/root 117 | 118 | ## [5.5.1](https://github.com/microlinkhq/sdk/compare/v5.5.0...v5.5.1) (2020-11-20) 119 | 120 | ### Bug Fixes 121 | 122 | * typo ([aab3a06](https://github.com/microlinkhq/sdk/commit/aab3a063644212f53a96fb487f9b1fbef91b4dbd)) 123 | 124 | # [5.5.0](https://github.com/microlinkhq/sdk/compare/v5.4.6...v5.5.0) (2020-11-20) 125 | 126 | ### Bug Fixes 127 | 128 | * array from null ([2a105be](https://github.com/microlinkhq/sdk/commit/2a105be0e6e603b4d77a0297fc6118a238283d22)) 129 | 130 | ## [5.4.6](https://github.com/microlinkhq/sdk/compare/v5.4.5...v5.4.6) (2020-07-19) 131 | 132 | **Note:** Version bump only for package @microlink/root 133 | 134 | ## [5.4.5](https://github.com/microlinkhq/sdk/compare/v5.4.4...v5.4.5) (2020-07-15) 135 | 136 | **Note:** Version bump only for package @microlink/root 137 | 138 | ## [5.4.4](https://github.com/microlinkhq/sdk/compare/v5.4.3...v5.4.4) (2020-06-20) 139 | 140 | **Note:** Version bump only for package @microlink/root 141 | 142 | ## [5.4.3](https://github.com/microlinkhq/sdk/compare/v5.4.2...v5.4.3) (2020-06-20) 143 | 144 | **Note:** Version bump only for package @microlink/root 145 | 146 | ## [5.4.2](https://github.com/microlinkhq/sdk/compare/v5.4.0...v5.4.2) (2020-06-18) 147 | 148 | ### Bug Fixes 149 | 150 | * bug with transition ([#236](https://github.com/microlinkhq/sdk/issues/236)) ([1f17041](https://github.com/microlinkhq/sdk/commit/1f170417c3af18bc227034d76da8213f3ece00eb)) 151 | * rollback change ([ac6a5d1](https://github.com/microlinkhq/sdk/commit/ac6a5d1ee4e4432b3167ba346b5cccaa72421018)) 152 | 153 | # [5.4.0](https://github.com/microlinkhq/sdk/compare/v5.3.5...v5.4.0) (2020-06-18) 154 | 155 | ### Bug Fixes 156 | 157 | * build reference ([40f8a7d](https://github.com/microlinkhq/sdk/commit/40f8a7d2e9936b823ea1e2cfdabf0df7ee2fcb44)) 158 | 159 | ### Features 160 | 161 | * allow customization via CSS variables ([ca5e43d](https://github.com/microlinkhq/sdk/commit/ca5e43dce9937804ad9096c2277c430ebaa60043)), closes [#235](https://github.com/microlinkhq/sdk/issues/235) 162 | 163 | ## [5.3.5](https://github.com/microlinkhq/sdk/compare/v5.3.4...v5.3.5) (2020-06-15) 164 | 165 | ### Bug Fixes 166 | 167 | * convert collection into an array ([771496c](https://github.com/microlinkhq/sdk/commit/771496c2455e77e57ac3e14937c74ca719b8468c)) 168 | * convert relative to absolute urls ([ef8e221](https://github.com/microlinkhq/sdk/commit/ef8e221f0e1a9b74bc3d72e79d87a71d347f8e5b)) 169 | 170 | ## [5.3.4](https://github.com/microlinkhq/sdk/compare/v5.3.3...v5.3.4) (2020-06-14) 171 | 172 | **Note:** Version bump only for package @microlink/root 173 | 174 | ## [5.3.3](https://github.com/microlinkhq/sdk/compare/v5.3.2...v5.3.3) (2020-06-14) 175 | 176 | ### Bug Fixes 177 | 178 | * generate all the assets ([fbb5a85](https://github.com/microlinkhq/sdk/commit/fbb5a85ad9d56d59ca8d0cea314124999a0905b7)) 179 | 180 | ## [5.3.2](https://github.com/microlinkhq/sdk/compare/v5.3.1...v5.3.2) (2020-06-14) 181 | 182 | ### Bug Fixes 183 | 184 | * cjs bundle name ([c08cc2a](https://github.com/microlinkhq/sdk/commit/c08cc2a57d821abc8179301f86d55e55b0bd7b07)) 185 | * filename ([00165c7](https://github.com/microlinkhq/sdk/commit/00165c72f087911e52c07c4f061abcb5149a58fa)) 186 | * linter ([67f75ed](https://github.com/microlinkhq/sdk/commit/67f75ed5123856f0dd17e91b5c1d4b897994e1e1)) 187 | 188 | ## [5.3.1](https://github.com/microlinkhq/sdk/compare/v5.3.0...v5.3.1) (2020-06-14) 189 | 190 | ### Bug Fixes 191 | 192 | * trim final space ([e9d4b0c](https://github.com/microlinkhq/sdk/commit/e9d4b0ce30c103c6acbd28b219ed5d5e73bad8a1)) 193 | 194 | # [5.3.0](https://github.com/microlinkhq/sdk/compare/v5.2.2...v5.3.0) (2020-05-27) 195 | 196 | **Note:** Version bump only for package @microlink/root 197 | 198 | ## [5.2.2](https://github.com/microlinkhq/sdk/compare/v5.2.1...v5.2.2) (2020-05-19) 199 | 200 | **Note:** Version bump only for package @microlink/root 201 | 202 | ## [5.2.1](https://github.com/microlinkhq/sdk/compare/v5.2.0...v5.2.1) (2020-05-17) 203 | 204 | **Note:** Version bump only for package @microlink/root 205 | 206 | # [5.2.0](https://github.com/microlinkhq/sdk/compare/v5.1.5...v5.2.0) (2020-05-13) 207 | 208 | ### Features 209 | 210 | * add fetchData parameter ([#223](https://github.com/microlinkhq/sdk/issues/223)) ([8dcdea4](https://github.com/microlinkhq/sdk/commit/8dcdea46397c630733a8c6a08857db8ddf952605)) 211 | 212 | ## [5.1.5](https://github.com/microlinkhq/sdk/compare/v5.1.4...v5.1.5) (2020-04-25) 213 | 214 | **Note:** Version bump only for package @microlink/root 215 | 216 | ## [5.1.4](https://github.com/microlinkhq/sdk/compare/v5.1.3...v5.1.4) (2020-04-03) 217 | 218 | **Note:** Version bump only for package @microlink/root 219 | 220 | ## [5.1.3](https://github.com/microlinkhq/sdk/compare/v5.1.2...v5.1.3) (2020-03-09) 221 | 222 | **Note:** Version bump only for package @microlink/root 223 | 224 | ## [5.1.2](https://github.com/microlinkhq/sdk/compare/v5.1.1...v5.1.2) (2020-03-03) 225 | 226 | ### Bug Fixes 227 | 228 | * fetchFromApi interface ([c5f010e](https://github.com/microlinkhq/sdk/commit/c5f010e83c2ec0d29b1a1258ea3facf61a2e4ad7)) 229 | 230 | ## [5.1.1](https://github.com/microlinkhq/sdk/compare/v5.1.0...v5.1.1) (2020-03-03) 231 | 232 | **Note:** Version bump only for package @microlink/root 233 | 234 | # [5.1.0](https://github.com/microlinkhq/sdk/compare/v5.0.12...v5.1.0) (2020-02-22) 235 | 236 | ### Bug Fixes 237 | 238 | * add `as` prop to vue/angular integrations ([#200](https://github.com/microlinkhq/sdk/issues/200)) ([873ad9a](https://github.com/microlinkhq/sdk/commit/873ad9ac0cfbc670aa3e4b53d11ab2d1684ea1ca)) 239 | 240 | ## [5.0.12](https://github.com/microlinkhq/sdk/compare/v5.0.11...v5.0.12) (2020-02-12) 241 | 242 | ### Bug Fixes 243 | 244 | * markup ([e7a6caa](https://github.com/microlinkhq/sdk/commit/e7a6caace102b41ea506a34797e274d3490a0a8e)) 245 | 246 | ## [5.0.11](https://github.com/microlinkhq/sdk/compare/v5.0.10...v5.0.11) (2020-02-11) 247 | 248 | ### Bug Fixes 249 | 250 | * mount div by default ([9d8a792](https://github.com/microlinkhq/sdk/commit/9d8a79286e313ed219e0f4b3fd65d9a63ba415cd)) 251 | 252 | ## [5.0.10](https://github.com/microlinkhq/sdk/compare/v5.0.9...v5.0.10) (2020-02-09) 253 | 254 | **Note:** Version bump only for package @microlink/root 255 | 256 | ## [5.0.9](https://github.com/microlinkhq/sdk/compare/v5.0.8...v5.0.9) (2020-02-07) 257 | 258 | ### Bug Fixes 259 | 260 | * avoid create element dynamically ([#190](https://github.com/microlinkhq/sdk/issues/190)) ([9849db7](https://github.com/microlinkhq/sdk/commit/9849db7c04eef1f2ec46c2c1870eb809993e3734)) 261 | 262 | ## [5.0.8](https://github.com/microlinkhq/sdk/compare/v5.0.7...v5.0.8) (2020-02-07) 263 | 264 | **Note:** Version bump only for package @microlink/root 265 | 266 | ## [5.0.7](https://github.com/microlinkhq/sdk/compare/v5.0.6...v5.0.7) (2020-02-05) 267 | 268 | **Note:** Version bump only for package @microlink/root 269 | 270 | ## [5.0.6](https://github.com/microlinkhq/sdk/compare/v5.0.5...v5.0.6) (2020-02-05) 271 | 272 | **Note:** Version bump only for package @microlink/root 273 | 274 | ## [5.0.5](https://github.com/microlinkhq/sdk/compare/v5.0.4...v5.0.5) (2020-02-04) 275 | 276 | **Note:** Version bump only for package @microlink/root 277 | 278 | ## [5.0.4](https://github.com/microlinkhq/sdk/compare/v5.0.3...v5.0.4) (2020-02-04) 279 | 280 | **Note:** Version bump only for package @microlink/root 281 | 282 | ## [5.0.3](https://github.com/microlinkhq/sdk/compare/v5.0.2...v5.0.3) (2020-02-01) 283 | 284 | **Note:** Version bump only for package @microlink/root 285 | 286 | ## [5.0.2](https://github.com/microlinkhq/sdk/compare/v5.0.1...v5.0.2) (2020-01-31) 287 | 288 | **Note:** Version bump only for package @microlink/root 289 | 290 | ## [5.0.1](https://github.com/microlinkhq/sdk/compare/v5.0.0...v5.0.1) (2020-01-31) 291 | 292 | ### Performance Improvements 293 | 294 | * optimize animation with will-change ([#177](https://github.com/microlinkhq/sdk/issues/177)) ([dde1aff](https://github.com/microlinkhq/sdk/commit/dde1aff857f7e3a4790a2bd71f69b0f6d9976dbb)) 295 | 296 | # [5.0.0](https://github.com/microlinkhq/sdk/compare/v4.5.1...v5.0.0) (2020-01-17) 297 | 298 | **Note:** Version bump only for package @microlink/root 299 | 300 | ## [4.5.1](https://github.com/microlinkhq/sdk/compare/v4.5.0...v4.5.1) (2019-12-29) 301 | 302 | ### Bug Fixes 303 | 304 | * pass rest of props to iframe ([c4d87f3](https://github.com/microlinkhq/sdk/commit/c4d87f30fc8753ece38b64f69eeb18c0596091d6)) 305 | 306 | # [4.5.0](https://github.com/microlinkhq/sdk/compare/v4.4.9...v4.5.0) (2019-12-26) 307 | 308 | ### Features 309 | 310 | * add iframe support ([#173](https://github.com/microlinkhq/sdk/issues/173)) ([e73ad1a](https://github.com/microlinkhq/sdk/commit/e73ad1a6ccfe2fb3d1603a069bcb008c9b0f38cb)) 311 | 312 | ## [4.4.9](https://github.com/microlinkhq/sdk/compare/v4.4.8...v4.4.9) (2019-12-21) 313 | 314 | ### Bug Fixes 315 | 316 | * ensure props.media is an array ([435f570](https://github.com/microlinkhq/sdk/commit/435f570a722d740c91529c2026a4c0ddb106654d)) 317 | 318 | ## [4.4.8](https://github.com/microlinkhq/sdk/compare/v4.4.7...v4.4.8) (2019-12-13) 319 | 320 | ### Bug Fixes 321 | 322 | * respect media priorities ([#170](https://github.com/microlinkhq/sdk/issues/170)) ([5de299c](https://github.com/microlinkhq/sdk/commit/5de299c160031ac1383fb8127cd40a612122f0b8)) 323 | 324 | ## [4.4.7](https://github.com/microlinkhq/sdk/compare/v4.4.6...v4.4.7) (2019-12-01) 325 | 326 | ### Bug Fixes 327 | 328 | * optimize gif properly ([3b31ed5](https://github.com/microlinkhq/sdk/commit/3b31ed5a9a699f3b2964bc8f66b9032db7c237a2)) 329 | 330 | ## [4.4.6](https://github.com/microlinkhq/sdk/compare/v4.4.5...v4.4.6) (2019-11-26) 331 | 332 | ### Bug Fixes 333 | 334 | * use encodeURIComponent instead of encodeURI ([03fb267](https://github.com/microlinkhq/sdk/commit/03fb2675ab2b6066f83d000f4a8ca3c789b019a7)) 335 | 336 | ## [4.4.5](https://github.com/microlinkhq/sdk/compare/v4.4.4...v4.4.5) (2019-11-25) 337 | 338 | ### Bug Fixes 339 | 340 | * prevent to proxify local urls ([060d38a](https://github.com/microlinkhq/sdk/commit/060d38a9e877d9d28d610a8fb928063d1536d4f7)) 341 | 342 | ## [4.4.4](https://github.com/microlinkhq/sdk/compare/v4.4.3...v4.4.4) (2019-11-21) 343 | 344 | **Note:** Version bump only for package @microlink/root 345 | 346 | ## [4.4.3](https://github.com/microlinkhq/sdk/compare/v4.4.2...v4.4.3) (2019-11-18) 347 | 348 | **Note:** Version bump only for package @microlink/root 349 | 350 | ## [4.4.2](https://github.com/microlinkhq/sdk/compare/v4.4.1...v4.4.2) (2019-11-18) 351 | 352 | **Note:** Version bump only for package @microlink/root 353 | 354 | ## [4.4.1](https://github.com/microlinkhq/sdk/compare/v4.4.0...v4.4.1) (2019-11-11) 355 | 356 | ### Bug Fixes 357 | 358 | * prevent pass cardSize as DOM property ([#166](https://github.com/microlinkhq/sdk/issues/166)) ([6b4848b](https://github.com/microlinkhq/sdk/commit/6b4848b23aef66bd4058e311657122a487030435)) 359 | 360 | # [4.4.0](https://github.com/microlinkhq/sdk/compare/v4.3.2...v4.4.0) (2019-11-10) 361 | 362 | **Note:** Version bump only for package @microlink/root 363 | 364 | ## [4.3.2](https://github.com/microlinkhq/sdk/compare/v4.3.1...v4.3.2) (2019-10-23) 365 | 366 | **Note:** Version bump only for package @microlink/root 367 | 368 | ## [4.3.1](https://github.com/microlinkhq/sdk/compare/v4.3.0...v4.3.1) (2019-10-16) 369 | 370 | **Note:** Version bump only for package @microlink/root 371 | 372 | # [4.3.0](https://github.com/microlinkhq/sdk/compare/v4.2.2...v4.3.0) (2019-10-14) 373 | 374 | ### Features 375 | 376 | * use mql as fetcher ([#162](https://github.com/microlinkhq/sdk/issues/162)) ([b7eac46](https://github.com/microlinkhq/sdk/commit/b7eac46312e0148d4a422bb671086cf21a6f4616)) 377 | 378 | ## [4.2.2](https://github.com/microlinkhq/sdk/compare/v4.2.1...v4.2.2) (2019-09-12) 379 | 380 | **Note:** Version bump only for package @microlink/root 381 | 382 | ## [4.2.1](https://github.com/microlinkhq/sdk/compare/v4.2.0...v4.2.1) (2019-09-12) 383 | 384 | ### Bug Fixes 385 | 386 | * main loading flag and mini optimizations ([#159](https://github.com/microlinkhq/sdk/issues/159)) ([08396ec](https://github.com/microlinkhq/sdk/commit/08396ec)) 387 | 388 | # [4.2.0](https://github.com/microlinkhq/sdk/compare/v4.1.3...v4.2.0) (2019-09-11) 389 | 390 | **Note:** Version bump only for package @microlink/root 391 | 392 | ## [4.1.3](https://github.com/microlinkhq/sdk/compare/v4.1.2...v4.1.3) (2019-09-04) 393 | 394 | **Note:** Version bump only for package @microlink/root 395 | 396 | ## [4.1.2](https://github.com/microlinkhq/sdk/compare/v4.1.1...v4.1.2) (2019-08-22) 397 | 398 | ### Bug Fixes 399 | 400 | * fix server side detection ([b452aeb](https://github.com/microlinkhq/sdk/commit/b452aeb)) 401 | 402 | ## [4.1.1](https://github.com/microlinkhq/sdk/compare/v4.1.0...v4.1.1) (2019-08-21) 403 | 404 | ### Bug Fixes 405 | 406 | * ensure window is accesible ([#155](https://github.com/microlinkhq/sdk/issues/155)) ([1001bd5](https://github.com/microlinkhq/sdk/commit/1001bd5)) 407 | 408 | # [4.1.0](https://github.com/microlinkhq/sdk/compare/v4.0.2...v4.1.0) (2019-08-20) 409 | 410 | **Note:** Version bump only for package @microlink/root 411 | 412 | ## [4.0.2](https://github.com/microlinkhq/sdk/compare/v4.0.1...v4.0.2) (2019-08-10) 413 | 414 | **Note:** Version bump only for package @microlink/root 415 | 416 | ## [4.0.1](https://github.com/microlinkhq/sdk/compare/v4.0.0...v4.0.1) (2019-05-07) 417 | 418 | ### Bug Fixes 419 | 420 | * use transparent background for png images ([#145](https://github.com/microlinkhq/sdk/issues/145)) ([b877967](https://github.com/microlinkhq/sdk/commit/b877967)) 421 | 422 | # [4.0.0](https://github.com/microlinkhq/sdk/compare/v4.0.0-alpha.3...v4.0.0) (2019-04-30) 423 | 424 | **Note:** Version bump only for package @microlink/root 425 | 426 | ## [3.0.5](https://github.com/microlinkhq/sdk/compare/v3.0.4...v3.0.5) (2018-12-24) 427 | 428 | ### Bug Fixes 429 | 430 | * add empty url case ([e8d2d94](https://github.com/microlinkhq/sdk/commit/e8d2d94)) 431 | * data → setData ([48a4d12](https://github.com/microlinkhq/sdk/commit/48a4d12)) 432 | * rename is → as ([88c8ecd](https://github.com/microlinkhq/sdk/commit/88c8ecd)) 433 | * serialize properly ([1e48307](https://github.com/microlinkhq/sdk/commit/1e48307)) 434 | 435 | ### Performance Improvements 436 | 437 | * cached compiled templates ([e76b0c6](https://github.com/microlinkhq/sdk/commit/e76b0c6)) 438 | 439 | ## [3.0.4](https://github.com/microlinkhq/sdk/compare/v3.0.3...v3.0.4) (2018-12-23) 440 | 441 | ### Bug Fixes 442 | 443 | * ensure encode url properly ([#138](https://github.com/microlinkhq/sdk/issues/138)) ([3e8c590](https://github.com/microlinkhq/sdk/commit/3e8c590)) 444 | 445 | ## [3.0.3](https://github.com/microlinkhq/sdk/compare/v3.0.2...v3.0.3) (2018-11-23) 446 | 447 | ### Bug Fixes 448 | 449 | * remove log ([cd40aa2](https://github.com/microlinkhq/sdk/commit/cd40aa2)) 450 | 451 | ## [3.0.2](https://github.com/microlinkhq/sdk/compare/v3.0.1...v3.0.2) (2018-11-23) 452 | 453 | **Note:** Version bump only for package @microlink/root 454 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | microlink.js.org 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2019 Microlink (microlink.io) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | microlink sdk 3 | microlink sdk 4 |
5 | 6 | ###### [Documentation](https://microlink.io/sdk) | [Storybook](https://sdk-react.microlink.io) | [Vanilla](https://sdk-vanilla.microlink.io/) 7 | 8 | ## Installation 9 | 10 | ### React 11 | 12 | ``` 13 | npm install @microlink/react styled-components --save 14 | ``` 15 | 16 | ### Vanilla 17 | 18 | ``` 19 | npm install @microlink/vanilla --save 20 | ``` 21 | 22 | ## License 23 | 24 | **microlink** © [Microlink](https://microlink.io), Released under the [MIT](https://github.com/microlinkhq/sdk/blob/master/LICENSE.md) License.
25 | Authored and maintained by [Kiko Beats](https://kikobeats.com) with help from [contributors](https://github.com/microlinkhq/sdk/contributors). 26 | 27 | > [microlink.io](https://microlink.io) · GitHub [@MicrolinkHQ](https://github.com/microlinkhq) · X [@microlinkhq](https://x.com/microlinkhq) 28 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.5.1", 3 | "packages": [ 4 | "packages/*" 5 | ], 6 | "version": "5.5.23" 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microlink/root", 3 | "description": "Turns links into a beautiful previews", 4 | "homepage": "https://microlink.io/sdk", 5 | "version": "", 6 | "author": { 7 | "email": "josefrancisco.verdu@gmail.com", 8 | "name": "Kiko Beats", 9 | "url": "https://github.com/Kikobeats" 10 | }, 11 | "contributors": [ 12 | { 13 | "name": "Brad Adams", 14 | "email": "hi@breadadams.com" 15 | }, 16 | { 17 | "name": "Pierre Lebrun", 18 | "email": "anthonylebrun@gmail.com" 19 | }, 20 | { 21 | "name": "Germán Rodríguez", 22 | "email": "36035218+GermanRodrickson@users.noreply.github.com" 23 | } 24 | ], 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/microlinkhq/sdk.git" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/microlinkhq/sdk/issues" 31 | }, 32 | "devDependencies": { 33 | "@commitlint/cli": "latest", 34 | "@commitlint/config-conventional": "latest", 35 | "@ksmithut/prettier-standard": "latest", 36 | "@lerna-lite/cli": "latest", 37 | "@lerna-lite/publish": "latest", 38 | "eslint": "8", 39 | "eslint-config-next": "latest", 40 | "finepack": "latest", 41 | "git-authors-cli": "latest", 42 | "nano-staged": "latest", 43 | "next": "latest", 44 | "simple-git-hooks": "latest", 45 | "standard": "latest", 46 | "standard-markdown": "latest", 47 | "standard-version": "latest" 48 | }, 49 | "engines": { 50 | "node": ">= 12" 51 | }, 52 | "scripts": { 53 | "build": "pnpm run -r build", 54 | "clean": "pnpm run clean:node && pnpm run clean:build", 55 | "clean:build": "pnpm -r exec -- rm -rf dist", 56 | "clean:node": "pnpm -r exec -- rm -rf node_modules", 57 | "contributors": "(npx git-authors-cli && npx finepack && git add package.json && git commit -m 'build: contributors' --no-verify) || true", 58 | "lint": "eslint \"packages/*/src/**/*\" && standard-markdown README.md --fix && standard --fix", 59 | "prepublishOnly": "pnpm run build", 60 | "pretest": "pnpm run lint", 61 | "release": "lerna publish --sort --conventional-commits -m \"chore(release): %s\" --create-release github", 62 | "test": "pnpm -r run test" 63 | }, 64 | "private": true, 65 | "license": "MIT", 66 | "commitlint": { 67 | "extends": [ 68 | "@commitlint/config-conventional" 69 | ], 70 | "rules": { 71 | "body-max-line-length": [ 72 | 0 73 | ] 74 | } 75 | }, 76 | "eslintConfig": { 77 | "extends": "eslint-config-next", 78 | "rules": { 79 | "@next/next/no-html-link-for-pages": "off" 80 | } 81 | }, 82 | "nano-staged": { 83 | "*.js": [ 84 | "prettier-standard", 85 | "standard --fix" 86 | ], 87 | "*.md": [ 88 | "standard-markdown" 89 | ], 90 | "package.json": [ 91 | "finepack" 92 | ] 93 | }, 94 | "simple-git-hooks": { 95 | "commit-msg": "npx commitlint --edit", 96 | "pre-commit": "npx nano-staged" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /packages/hover-react/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | ">0.25%", 9 | "not ie 11", 10 | "not op_mini all" 11 | ] 12 | } 13 | } 14 | ], 15 | "@babel/preset-react" 16 | ], 17 | "plugins": [ 18 | "@babel/plugin-proposal-class-properties", 19 | "@babel/plugin-proposal-object-rest-spread" 20 | ], 21 | "env": { 22 | "production": { 23 | "plugins": [ 24 | [ 25 | "transform-react-remove-prop-types", 26 | { 27 | "removeImport": true 28 | } 29 | ], 30 | "transform-react-pure-class-to-function", 31 | "@babel/plugin-transform-react-constant-elements", 32 | "@babel/plugin-transform-runtime" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/hover-react/.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | save-prefix=~ 3 | shrinkwrap=false 4 | save=false 5 | -------------------------------------------------------------------------------- /packages/hover-react/.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../stories/index.js'], 3 | core: { builder: 'webpack5' } 4 | } 5 | -------------------------------------------------------------------------------- /packages/hover-react/.storybook/manager.js: -------------------------------------------------------------------------------- 1 | import { addons } from '@storybook/addons' 2 | import theme from './theme' 3 | 4 | addons.setConfig({ theme }) 5 | -------------------------------------------------------------------------------- /packages/hover-react/.storybook/theme.js: -------------------------------------------------------------------------------- 1 | import { create } from '@storybook/theming/create' 2 | 3 | export default create({ 4 | base: 'light', 5 | brandTitle: 'Microlink SDK', 6 | brandUrl: 'https://github.com/microlinkhq/sdk', 7 | brandImage: 'https://cdn.microlink.io/logo/large.png' 8 | }) 9 | -------------------------------------------------------------------------------- /packages/hover-react/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [5.5.23](https://github.com/microlinkhq/sdk/compare/v5.5.22...v5.5.23) (2025-02-15) 7 | 8 | **Note:** Version bump only for package @microlink/hover-react 9 | 10 | ## [5.5.22](https://github.com/microlinkhq/sdk/compare/v5.5.21...v5.5.22) (2024-07-18) 11 | 12 | **Note:** Version bump only for package @microlink/hover-react 13 | 14 | ## [5.5.21](https://github.com/microlinkhq/sdk/compare/v5.5.20...v5.5.21) (2024-07-18) 15 | 16 | **Note:** Version bump only for package @microlink/hover-react 17 | 18 | ## [5.5.20](https://github.com/microlinkhq/sdk/compare/v5.5.19...v5.5.20) (2024-07-18) 19 | 20 | **Note:** Version bump only for package @microlink/hover-react 21 | 22 | ## [5.5.18](https://github.com/microlinkhq/sdk/compare/v5.5.17...v5.5.18) (2024-01-09) 23 | 24 | **Note:** Version bump only for package @microlink/hover-react 25 | 26 | ## [5.5.17](https://github.com/microlinkhq/sdk/compare/v5.5.16...v5.5.17) (2023-12-10) 27 | 28 | **Note:** Version bump only for package @microlink/hover-react 29 | 30 | ## [5.5.16](https://github.com/microlinkhq/sdk/compare/v5.5.15...v5.5.16) (2023-12-02) 31 | 32 | ### Bug Fixes 33 | 34 | * replace __VERSION__ ([#300](https://github.com/microlinkhq/sdk/issues/300)) ([c2789a4](https://github.com/microlinkhq/sdk/commit/c2789a47f8a4c3bf5c793de53f9a5a5aa2fccba5)) 35 | 36 | ## [5.5.15](https://github.com/microlinkhq/sdk/compare/v5.5.14...v5.5.15) (2023-03-29) 37 | 38 | **Note:** Version bump only for package @microlink/hover-react 39 | 40 | ## [5.5.14](https://github.com/microlinkhq/sdk/compare/v5.5.13...v5.5.14) (2023-03-22) 41 | 42 | **Note:** Version bump only for package @microlink/hover-react 43 | 44 | ## [5.5.13](https://github.com/microlinkhq/sdk/compare/v5.5.12...v5.5.13) (2023-03-15) 45 | 46 | **Note:** Version bump only for package @microlink/hover-react 47 | 48 | ## [5.5.12](https://github.com/microlinkhq/sdk/compare/v5.5.11...v5.5.12) (2023-01-02) 49 | 50 | **Note:** Version bump only for package @microlink/hover-react 51 | 52 | ## [5.5.11](https://github.com/microlinkhq/sdk/compare/v5.5.10...v5.5.11) (2022-11-18) 53 | 54 | **Note:** Version bump only for package @microlink/hover-react 55 | 56 | ## [5.5.10](https://github.com/microlinkhq/sdk/compare/v5.5.9...v5.5.10) (2022-11-13) 57 | 58 | **Note:** Version bump only for package @microlink/hover-react 59 | 60 | ## [5.5.9](https://github.com/microlinkhq/sdk/compare/v5.5.8...v5.5.9) (2022-07-01) 61 | 62 | **Note:** Version bump only for package @microlink/hover-react 63 | 64 | ## [5.5.8](https://github.com/microlinkhq/sdk/compare/v5.5.7...v5.5.8) (2022-03-13) 65 | 66 | **Note:** Version bump only for package @microlink/hover-react 67 | 68 | ## [5.5.7](https://github.com/microlinkhq/sdk/compare/v5.5.6...v5.5.7) (2021-10-04) 69 | 70 | **Note:** Version bump only for package @microlink/hover-react 71 | 72 | ## [5.5.6](https://github.com/microlinkhq/sdk/compare/v5.5.5...v5.5.6) (2021-06-05) 73 | 74 | **Note:** Version bump only for package @microlink/hover-react 75 | 76 | ## [5.5.5](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.5.4...v5.5.5) (2021-03-22) 77 | 78 | **Note:** Version bump only for package @microlink/hover-react 79 | 80 | ## [5.5.4](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.5.3...v5.5.4) (2021-01-17) 81 | 82 | ### Bug Fixes 83 | 84 | * add missing peer dependency ([034d469](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/commit/034d46994b568963228e9a676ff0238c706c0fec)) 85 | 86 | ## [5.5.3](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.5.2...v5.5.3) (2020-12-20) 87 | 88 | **Note:** Version bump only for package @microlink/hover-react 89 | 90 | ## [5.5.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.5.1...v5.5.2) (2020-12-12) 91 | 92 | **Note:** Version bump only for package @microlink/hover-react 93 | 94 | ## [5.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.5.0...v5.5.1) (2020-11-20) 95 | 96 | **Note:** Version bump only for package @microlink/hover-react 97 | 98 | # [5.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.4.6...v5.5.0) (2020-11-20) 99 | 100 | **Note:** Version bump only for package @microlink/hover-react 101 | 102 | ## [5.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.4.5...v5.4.6) (2020-07-19) 103 | 104 | **Note:** Version bump only for package @microlink/hover-react 105 | 106 | ## [5.4.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.4.0...v5.4.2) (2020-06-18) 107 | 108 | ### Bug Fixes 109 | 110 | * bug with transition ([#236](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/issues/236)) ([1f17041](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/commit/1f170417c3af18bc227034d76da8213f3ece00eb)) 111 | * rollback change ([ac6a5d1](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/commit/ac6a5d1ee4e4432b3167ba346b5cccaa72421018)) 112 | 113 | # [5.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.3.5...v5.4.0) (2020-06-18) 114 | 115 | ### Features 116 | 117 | * allow customization via CSS variables ([ca5e43d](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/commit/ca5e43dce9937804ad9096c2277c430ebaa60043)), closes [#235](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/issues/235) 118 | 119 | ## [5.3.5](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.3.4...v5.3.5) (2020-06-15) 120 | 121 | **Note:** Version bump only for package @microlink/hover-react 122 | 123 | ## [5.3.4](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.3.3...v5.3.4) (2020-06-14) 124 | 125 | **Note:** Version bump only for package @microlink/hover-react 126 | 127 | ## [5.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.3.1...v5.3.2) (2020-06-14) 128 | 129 | ### Bug Fixes 130 | 131 | * filename ([00165c7](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/commit/00165c72f087911e52c07c4f061abcb5149a58fa)) 132 | 133 | ## [5.3.1](http://github.com/microlinkhq/sdk/tree/master/packages/hover-react/compare/v5.3.0...v5.3.1) (2020-06-14) 134 | 135 | **Note:** Version bump only for package @microlink/hover-react 136 | -------------------------------------------------------------------------------- /packages/hover-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microlink/hover-react", 3 | "description": "Turn links into beautiful previews.", 4 | "homepage": "https://microlink.io/sdk", 5 | "version": "5.5.23", 6 | "main": "dist/microlink.cjs", 7 | "module": "dist/microlink.mjs", 8 | "jsnext:main": "dist/microlink.mjs", 9 | "repository": { 10 | "directory": "packages/hover-react", 11 | "type": "git", 12 | "url": "git+https://github.com/microlinkhq/sdk.git#master" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/microlinkhq/sdk/issues" 16 | }, 17 | "keywords": [ 18 | "data", 19 | "extraction", 20 | "hover", 21 | "link", 22 | "microlink", 23 | "preview", 24 | "previsualization", 25 | "react" 26 | ], 27 | "dependencies": { 28 | "@microlink/react": "^5.5.23" 29 | }, 30 | "devDependencies": { 31 | "@babel/core": "latest", 32 | "@babel/plugin-proposal-class-properties": "latest", 33 | "@babel/plugin-proposal-object-rest-spread": "latest", 34 | "@babel/plugin-transform-react-constant-elements": "latest", 35 | "@babel/plugin-transform-runtime": "latest", 36 | "@babel/preset-env": "latest", 37 | "@babel/preset-react": "latest", 38 | "@babel/runtime": "latest", 39 | "@microlink/demo-links": "latest", 40 | "@rollup/plugin-babel": "latest", 41 | "@rollup/plugin-commonjs": "latest", 42 | "@rollup/plugin-node-resolve": "latest", 43 | "@rollup/plugin-replace": "latest", 44 | "@rollup/plugin-terser": "latest", 45 | "@storybook/addon-storyshots": "~6.5.16", 46 | "@storybook/addons": "~6.5.16", 47 | "@storybook/builder-webpack5": "~6.5.16", 48 | "@storybook/manager-webpack5": "~6.5.16", 49 | "@storybook/react": "~6.5.16", 50 | "@storybook/theming": "~6.5.16", 51 | "babel-eslint": "latest", 52 | "babel-loader": "latest", 53 | "babel-plugin-transform-react-pure-class-to-function": "latest", 54 | "babel-plugin-transform-react-remove-prop-types": "latest", 55 | "enzyme": "latest", 56 | "eslint-plugin-jsx-a11y": "latest", 57 | "jest": "26", 58 | "jest-environment-enzyme": "latest", 59 | "jest-enzyme": "latest", 60 | "jest-styled-components": "latest", 61 | "lodash": "latest", 62 | "prop-types": "latest", 63 | "react": "18", 64 | "react-dom": "18", 65 | "rollup": "latest", 66 | "rollup-plugin-filesize": "latest", 67 | "rollup-plugin-visualizer": "latest", 68 | "styled-components": "latest", 69 | "unfetch": "latest" 70 | }, 71 | "engines": { 72 | "node": ">= 10" 73 | }, 74 | "files": [ 75 | "dist" 76 | ], 77 | "scripts": { 78 | "build": "NODE_ENV=production rollup -c rollup.config.js --bundleConfigAsCjs", 79 | "build-storybook": "NODE_ENV=production build-storybook --quiet", 80 | "dev": "start-storybook -p 6006", 81 | "start": "node scripts/start.js", 82 | "test": "exit 0 || NODE_ENV=test jest --detectOpenHandles" 83 | }, 84 | "license": "MIT", 85 | "jest": { 86 | "setupFilesAfterEnv": [ 87 | "jest-enzyme" 88 | ], 89 | "testEnvironment": "enzyme", 90 | "testURL": "http://localhost/", 91 | "verbose": true 92 | }, 93 | "peerDependencies": { 94 | "react": ">= 17", 95 | "react-dom": ">= 17", 96 | "styled-components": "^5" 97 | }, 98 | "publishConfig": { 99 | "access": "public" 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /packages/hover-react/rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from '@rollup/plugin-node-resolve' 2 | import { visualizer } from 'rollup-plugin-visualizer' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import filesize from 'rollup-plugin-filesize' 5 | import replace from '@rollup/plugin-replace' 6 | import terser from '@rollup/plugin-terser' 7 | import babel from '@rollup/plugin-babel' 8 | import fs from 'fs' 9 | 10 | const babelRc = JSON.parse(fs.readFileSync('./.babelrc')) 11 | 12 | const globals = { 13 | react: 'React', 14 | 'react-dom': 'ReactDOM', 15 | 'styled-components': 'styled', 16 | '@microlink/mql': 'mql' 17 | } 18 | 19 | const plugins = ({ compress }) => [ 20 | nodeResolve(), 21 | babel({ 22 | babelrc: false, 23 | ...babelRc, 24 | babelHelpers: 'runtime' 25 | }), 26 | commonjs(), 27 | compress && terser(), 28 | filesize(), 29 | visualizer({ template: 'treemap' }), 30 | replace({ 31 | preventAssignment: true, 32 | values: { 33 | 'process.env.NODE_ENV': JSON.stringify('production') 34 | } 35 | }) 36 | ] 37 | 38 | const build = ({ file, format, name, exports }) => { 39 | const compress = file.includes('.min.') 40 | return { 41 | input: './src/index.js', 42 | output: { 43 | sourcemap: compress, 44 | file, 45 | format, 46 | exports, 47 | name, 48 | globals 49 | }, 50 | external: [/@babel\/runtime/].concat(Object.keys(globals)), 51 | plugins: plugins({ compress }) 52 | } 53 | } 54 | 55 | const builds = [ 56 | build({ 57 | format: 'esm', 58 | file: 'dist/microlink.mjs', 59 | exports: 'named' 60 | }), 61 | build({ 62 | format: 'esm', 63 | file: 'dist/microlink.min.mjs', 64 | exports: 'named' 65 | }), 66 | build({ 67 | format: 'cjs', 68 | file: 'dist/microlink.cjs', 69 | exports: 'named' 70 | }), 71 | build({ 72 | format: 'cjs', 73 | file: 'dist/microlink.min.cjs', 74 | exports: 'named' 75 | }) 76 | ] 77 | 78 | export default builds 79 | -------------------------------------------------------------------------------- /packages/hover-react/src/index.js: -------------------------------------------------------------------------------- 1 | import Microlink from '@microlink/react' 2 | import styled from 'styled-components' 3 | import React from 'react' 4 | 5 | const PopOver = styled.div` 6 | --microlink-hover-background-color: var(--microlink-background-color, white); 7 | 8 | position: absolute; 9 | overflow: hidden; 10 | visibility: hidden; 11 | transition: 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); 12 | opacity: 0; 13 | right: 50%; 14 | transform: translate(50%, 0); 15 | bottom: 100%; 16 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.12); 17 | width: 500px; 18 | padding: 0.5rem; 19 | border-radius: 4px; 20 | 21 | .microlink_card { 22 | border: 0; 23 | } 24 | 25 | border: 1px solid var(--microlink-border-color, #e1e8ed); 26 | background-color: var(--microlink-hover-background-color); 27 | 28 | &:hover { 29 | box-shadow: rgba(0, 0, 0, 0.12) 0px 30px 60px; 30 | border-color: var(--microlink-hover-border-color, #f5f8fa); 31 | } 32 | ` 33 | 34 | const Wrapper = styled.span` 35 | text-decoration: inherit; 36 | position: relative; 37 | display: inline-block; 38 | 39 | &:hover ${PopOver} { 40 | margin-bottom: var(--microlink-gap, 15px); 41 | visibility: visible; 42 | opacity: 1; 43 | } 44 | ` 45 | 46 | const withHover = ({ LinkComponent, ...props }) => ( 47 | 48 | 49 | 50 | 51 | 52 | 53 | ) 54 | 55 | const MicrolinkHover = (LinkComponent, microlinkProps) => props => 56 | withHover({ LinkComponent, ...microlinkProps, ...props }) 57 | 58 | MicrolinkHover.withHover = withHover 59 | 60 | export default MicrolinkHover 61 | -------------------------------------------------------------------------------- /packages/hover-react/stories/index.js: -------------------------------------------------------------------------------- 1 | import 'unfetch/polyfill' 2 | import React from 'react' 3 | import styled from 'styled-components' 4 | 5 | import { storiesOf } from '@storybook/react' 6 | 7 | import withMicrolinkHover from '../src' 8 | 9 | const setData = () => ({ 10 | title: 'Browser as API', 11 | description: 12 | 'Turns websites into data: Enter a URL, receive information. Make any URL embeddable. Capture any website as a snapshot. Generate PDF from any website. Automate web performance.', 13 | lang: 'en', 14 | author: null, 15 | publisher: 'Microlink', 16 | image: { 17 | url: 'https://cdn.microlink.io/www/home.png', 18 | type: 'png', 19 | size: 97629, 20 | height: 882, 21 | width: 1686, 22 | size_pretty: '97.6 kB' 23 | }, 24 | url: 'https://microlink.io', 25 | date: '2020-05-07T15:10:41.692Z', 26 | logo: { 27 | url: 'https://cdn.microlink.io/logo/trim.png', 28 | type: 'png', 29 | size: 5050, 30 | height: 500, 31 | width: 500, 32 | size_pretty: '5.05 kB' 33 | } 34 | }) 35 | 36 | const Paraph = styled.div` 37 | font-size: 16px; 38 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, 39 | sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 40 | ` 41 | 42 | const Center = styled.div` 43 | height: 100vh; 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | ` 48 | 49 | const Link = styled.a` 50 | text-decoration: none; 51 | color: rgb(6, 125, 247); 52 | ` 53 | 54 | const Button = styled.button` 55 | cursor: pointer; 56 | text-decoration: none; 57 | background: rgb(6, 125, 247); 58 | color: white; 59 | border: 0; 60 | padding: 0.25rem 0.5rem; 61 | border-radius: 12px; 62 | ` 63 | 64 | storiesOf('decorator', module) 65 | .add('as link', () => { 66 | const MicrolinkHoverLink = withMicrolinkHover(Link) 67 | 68 | return ( 69 |
70 | 71 | Check my{' '} 72 | 73 | link 74 | 75 | 76 |
77 | ) 78 | }) 79 | .add('as button', () => { 80 | const MicrolinkHoverButton = withMicrolinkHover(Button) 81 | 82 | return ( 83 |
84 | 85 | Check my{' '} 86 | 87 | button 88 | 89 | 90 |
91 | ) 92 | }) 93 | .add('as element', () => { 94 | const MicrolinkHoverText = withMicrolinkHover( 95 | styled(Paraph)` 96 | color: gray; 97 | ` 98 | ) 99 | 100 | return ( 101 |
102 | 103 | Check my{' '} 104 | 105 | word 106 | 107 | 108 |
109 | ) 110 | }) 111 | .add('custom style', () => { 112 | const MicrolinkHoverLink = withMicrolinkHover(Link) 113 | 114 | const CustomCenter = styled(Center)` 115 | --microlink-border-color: #666; 116 | --microlink-hover-border-color: #999; 117 | color: white; 118 | background: #1a1a1a; 119 | ` 120 | 121 | return ( 122 | 123 | 124 | Check my{' '} 125 | 134 | link 135 | 136 | 137 | 138 | ) 139 | }) 140 | -------------------------------------------------------------------------------- /packages/hover-react/stories/index.test.js: -------------------------------------------------------------------------------- 1 | import initStoryshots from '@storybook/addon-storyshots' 2 | import 'jest-styled-components' 3 | 4 | initStoryshots() 5 | -------------------------------------------------------------------------------- /packages/hover-vanilla/.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | save-prefix=~ 3 | shrinkwrap=false 4 | save=false 5 | -------------------------------------------------------------------------------- /packages/hover-vanilla/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [5.5.23](https://github.com/microlinkhq/sdk/compare/v5.5.22...v5.5.23) (2025-02-15) 7 | 8 | **Note:** Version bump only for package @microlink/hover-vanilla 9 | 10 | ## [5.5.22](https://github.com/microlinkhq/sdk/compare/v5.5.21...v5.5.22) (2024-07-18) 11 | 12 | **Note:** Version bump only for package @microlink/hover-vanilla 13 | 14 | ## [5.5.21](https://github.com/microlinkhq/sdk/compare/v5.5.20...v5.5.21) (2024-07-18) 15 | 16 | **Note:** Version bump only for package @microlink/hover-vanilla 17 | 18 | ## [5.5.20](https://github.com/microlinkhq/sdk/compare/v5.5.19...v5.5.20) (2024-07-18) 19 | 20 | **Note:** Version bump only for package @microlink/hover-vanilla 21 | 22 | ## [5.5.19](https://github.com/microlinkhq/sdk/compare/v5.5.18...v5.5.19) (2024-02-29) 23 | 24 | ### Bug Fixes 25 | 26 | * **vanilla:** disable mangle ([abfdc45](https://github.com/microlinkhq/sdk/commit/abfdc45a404df4a491f28db2713ddfe9e2a95aa4)) 27 | 28 | ## [5.5.18](https://github.com/microlinkhq/sdk/compare/v5.5.17...v5.5.18) (2024-01-09) 29 | 30 | **Note:** Version bump only for package @microlink/hover-vanilla 31 | 32 | ## [5.5.17](https://github.com/microlinkhq/sdk/compare/v5.5.16...v5.5.17) (2023-12-10) 33 | 34 | ### Bug Fixes 35 | 36 | * vanilla build alias ([7e004ec](https://github.com/microlinkhq/sdk/commit/7e004ecaa493c4f667fd54b91c5811f994c5ed18)) 37 | 38 | ## [5.5.16](https://github.com/microlinkhq/sdk/compare/v5.5.15...v5.5.16) (2023-12-02) 39 | 40 | ### Bug Fixes 41 | 42 | * replace __VERSION__ ([#300](https://github.com/microlinkhq/sdk/issues/300)) ([c2789a4](https://github.com/microlinkhq/sdk/commit/c2789a47f8a4c3bf5c793de53f9a5a5aa2fccba5)) 43 | 44 | ## [5.5.15](https://github.com/microlinkhq/sdk/compare/v5.5.14...v5.5.15) (2023-03-29) 45 | 46 | **Note:** Version bump only for package @microlink/hover-vanilla 47 | 48 | ## [5.5.14](https://github.com/microlinkhq/sdk/compare/v5.5.13...v5.5.14) (2023-03-22) 49 | 50 | **Note:** Version bump only for package @microlink/hover-vanilla 51 | 52 | ## [5.5.13](https://github.com/microlinkhq/sdk/compare/v5.5.12...v5.5.13) (2023-03-15) 53 | 54 | **Note:** Version bump only for package @microlink/hover-vanilla 55 | 56 | ## [5.5.12](https://github.com/microlinkhq/sdk/compare/v5.5.11...v5.5.12) (2023-01-02) 57 | 58 | **Note:** Version bump only for package @microlink/hover-vanilla 59 | 60 | ## [5.5.11](https://github.com/microlinkhq/sdk/compare/v5.5.10...v5.5.11) (2022-11-18) 61 | 62 | **Note:** Version bump only for package @microlink/hover-vanilla 63 | 64 | ## [5.5.10](https://github.com/microlinkhq/sdk/compare/v5.5.9...v5.5.10) (2022-11-13) 65 | 66 | **Note:** Version bump only for package @microlink/hover-vanilla 67 | 68 | ## [5.5.9](https://github.com/microlinkhq/sdk/compare/v5.5.8...v5.5.9) (2022-07-01) 69 | 70 | **Note:** Version bump only for package @microlink/hover-vanilla 71 | 72 | ## [5.5.8](https://github.com/microlinkhq/sdk/compare/v5.5.7...v5.5.8) (2022-03-13) 73 | 74 | ### Bug Fixes 75 | 76 | * duplicate line ([431f291](https://github.com/microlinkhq/sdk/commit/431f291385248e72c163d6e89a6a60fdb1b49bb2)) 77 | 78 | ### Performance Improvements 79 | 80 | * prefer mutation instead of Object.assign ([e9e8b42](https://github.com/microlinkhq/sdk/commit/e9e8b42b3f42591f66469226a1c0db0ec1a061c8)) 81 | 82 | ## [5.5.7](https://github.com/microlinkhq/sdk/compare/v5.5.6...v5.5.7) (2021-10-04) 83 | 84 | **Note:** Version bump only for package @microlink/hover-vanilla 85 | 86 | ## [5.5.6](https://github.com/microlinkhq/sdk/compare/v5.5.5...v5.5.6) (2021-06-05) 87 | 88 | **Note:** Version bump only for package @microlink/hover-vanilla 89 | 90 | ## [5.5.5](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.5.4...v5.5.5) (2021-03-22) 91 | 92 | **Note:** Version bump only for package @microlink/hover-vanilla 93 | 94 | ## [5.5.4](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.5.3...v5.5.4) (2021-01-17) 95 | 96 | **Note:** Version bump only for package @microlink/hover-vanilla 97 | 98 | ## [5.5.3](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.5.2...v5.5.3) (2020-12-20) 99 | 100 | **Note:** Version bump only for package @microlink/hover-vanilla 101 | 102 | ## [5.5.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.5.1...v5.5.2) (2020-12-12) 103 | 104 | **Note:** Version bump only for package @microlink/hover-vanilla 105 | 106 | ## [5.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.5.0...v5.5.1) (2020-11-20) 107 | 108 | **Note:** Version bump only for package @microlink/hover-vanilla 109 | 110 | # [5.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.4.6...v5.5.0) (2020-11-20) 111 | 112 | **Note:** Version bump only for package @microlink/hover-vanilla 113 | 114 | ## [5.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.4.5...v5.4.6) (2020-07-19) 115 | 116 | **Note:** Version bump only for package @microlink/hover-vanilla 117 | 118 | ## [5.4.4](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.4.3...v5.4.4) (2020-06-20) 119 | 120 | **Note:** Version bump only for package @microlink/hover-vanilla 121 | 122 | ## [5.4.3](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.4.2...v5.4.3) (2020-06-20) 123 | 124 | **Note:** Version bump only for package @microlink/hover-vanilla 125 | 126 | ## [5.4.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.4.0...v5.4.2) (2020-06-18) 127 | 128 | **Note:** Version bump only for package @microlink/hover-vanilla 129 | 130 | # [5.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.3.5...v5.4.0) (2020-06-18) 131 | 132 | ### Bug Fixes 133 | 134 | * build reference ([40f8a7d](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/commit/40f8a7d2e9936b823ea1e2cfdabf0df7ee2fcb44)) 135 | 136 | ### Features 137 | 138 | * allow customization via CSS variables ([ca5e43d](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/commit/ca5e43dce9937804ad9096c2277c430ebaa60043)), closes [#235](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/issues/235) 139 | 140 | ## [5.3.5](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.3.4...v5.3.5) (2020-06-15) 141 | 142 | ### Bug Fixes 143 | 144 | * convert collection into an array ([771496c](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/commit/771496c2455e77e57ac3e14937c74ca719b8468c)) 145 | * convert relative to absolute urls ([ef8e221](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/commit/ef8e221f0e1a9b74bc3d72e79d87a71d347f8e5b)) 146 | 147 | ## [5.3.4](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.3.3...v5.3.4) (2020-06-14) 148 | 149 | **Note:** Version bump only for package @microlink/hover-vanilla 150 | 151 | ## [5.3.3](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.3.2...v5.3.3) (2020-06-14) 152 | 153 | ### Bug Fixes 154 | 155 | * generate all the assets ([fbb5a85](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/commit/fbb5a85ad9d56d59ca8d0cea314124999a0905b7)) 156 | 157 | ## [5.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/hover-vanilla/compare/v5.3.1...v5.3.2) (2020-06-14) 158 | 159 | **Note:** Version bump only for package @microlink/hover-vanilla 160 | -------------------------------------------------------------------------------- /packages/hover-vanilla/docs/assets/video/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microlinkhq/sdk/5c7e097b8b2474cc4145a7c9521ab064d1fad654/packages/hover-vanilla/docs/assets/video/demo.mp4 -------------------------------------------------------------------------------- /packages/hover-vanilla/docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | @microlink/hover-vanilla 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 100 | 101 | 102 |
103 |

@microlink/hover-vanilla

104 |

Turns any URL into instant hover preview ✨

105 |
106 | 107 |
108 | React version 109 | | 110 | See on GitHub 111 |
112 | 113 |
114 | 115 |
116 | 117 |
118 |

Usage

119 | 120 |
121 |
122 |   <!-- https://microlink.io/docs/sdk/getting-started/styling -->
123 |   <style>
124 |     :root {
125 |       --microlink-background-color: #1A1A1A;
126 |       --microlink-color: white;
127 |       --microlink-border-color: #666;
128 |       --microlink-hover-border-color: #999;
129 |     }
130 |   </style>
131 | 
132 |   <!-- load @microlink/hover-vanilla -->
133 |   <script src="https://cdn.jsdelivr.net/combine/npm/react@16/umd/react.production.min.js,npm/react-dom@16/umd/react-dom.production.min.js,npm/react-is@16/umd/react-is.production.min.js,npm/styled-components@5/dist/styled-components.min.js,npm/@microlink/mql@latest/dist/mql.min.js,npm/@microlink/hover-vanilla@latest/dist/microlink.min.js"></script>
134 | 
135 |   <!-- intialize `microlinkHover` -->
136 |   <script>
137 |     document.addEventListener('DOMContentLoaded', function (event) {
138 |       microlinkHover('a')
139 |     })
140 |   </script>
141 |
142 |
Just add the above to your main markup before the closing </body> tag.
143 |
144 |
145 |

See in action

146 |

147 | kikobeats.com 148 | collectednotes.com 149 | joshwcomeau.com 150 | getbootstrap.com 151 | dealflow.es 152 |

153 |
154 | 155 | 156 | 157 | 162 | 163 | -------------------------------------------------------------------------------- /packages/hover-vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microlink/hover-vanilla", 3 | "description": "Turn links into beautiful previews.", 4 | "homepage": "https://microlink.io/sdk", 5 | "version": "5.5.23", 6 | "main": "dist/microlink.cjs", 7 | "module": "dist/microlink.mjs", 8 | "jsnext:main": "dist/microlink.mjs", 9 | "repository": { 10 | "directory": "packages/hover-vanilla", 11 | "type": "git", 12 | "url": "git+https://github.com/microlinkhq/sdk.git#master" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/microlinkhq/sdk/issues" 16 | }, 17 | "keywords": [ 18 | "data", 19 | "extraction", 20 | "hover", 21 | "javascript", 22 | "link", 23 | "microlink", 24 | "preview", 25 | "previsualization", 26 | "vanilla" 27 | ], 28 | "dependencies": { 29 | "@microlink/hover-react": "^5.5.23", 30 | "is-local-address": "~2.0.0" 31 | }, 32 | "devDependencies": { 33 | "@rollup/plugin-commonjs": "latest", 34 | "@rollup/plugin-node-resolve": "latest", 35 | "@rollup/plugin-replace": "latest", 36 | "@rollup/plugin-terser": "latest", 37 | "rollup": "latest", 38 | "rollup-plugin-copy": "latest", 39 | "rollup-plugin-filesize": "latest", 40 | "rollup-plugin-visualizer": "latest" 41 | }, 42 | "engines": { 43 | "node": ">= 10" 44 | }, 45 | "files": [ 46 | "dist" 47 | ], 48 | "scripts": { 49 | "build": "NODE_ENV=production npm run rollup", 50 | "dev": "NODE_ENV=development npm run rollup -- -w", 51 | "rollup": "rollup -c rollup.config.js --bundleConfigAsCjs" 52 | }, 53 | "license": "MIT", 54 | "publishConfig": { 55 | "access": "public" 56 | }, 57 | "umd:main": "dist/microlink.js", 58 | "unpkg": "dist/microlink.js" 59 | } 60 | -------------------------------------------------------------------------------- /packages/hover-vanilla/preact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @microlink/preact 8 | 9 | 10 | 11 | 53 | 54 | 55 | 56 |
57 |
58 |

default

59 |
<a class="link" href="https://microlink.io">microlink.io</a>
61 |
microlink.io
62 |
63 | 64 |
65 |

data-media='logo'

66 |
<a class="link" href="https://microlink.io">microlink.io data-media='logo'</a>
68 |
microlink.io 69 |
70 |
71 | 72 |
73 |

data-media='video'

74 |
<a class="link" href="https://www.facebook.com/natgeo/videos/10156364216738951" data-media="video">facebook.com/natgeo/videos/10156364216738951</a>
76 |
facebook.com/natgeo/videos/10156364216738951
78 |
79 | 80 |
81 |

data-media='audio'

82 |
<a class="link" href="https://open.spotify.com/track/1W2919zs8SBCLTrOB1ftQT?si=4PcqgjH5RlWCvB5q4ukdnw" data-media='audio'</a>
 83 |       
84 |
microlink.io
87 |
88 | 89 |
90 |

data-media='screenshot'

91 |
<a class="link" href="https://example.com">example.com data-media='screenshot'</a>
93 |
example.com
94 |
95 | 96 |
97 |

data-contrast='true'

98 |
<a class="link" href="https://microlink.io">microlink.io data-contrast='true'</a>
100 |
microlink.io
101 |
102 | 103 |
104 |

data-size='large'

105 |
<a class="link" href="https://microlink.io">microlink.io data-size='large'</a>
107 |
microlink.io
108 |
109 | 110 |
111 |

custom

112 |
<a class="link" href="https://microlink.io">microlink.io data-setData='{"title": "hello world"}'</a>
114 |
microlink.io
116 |
117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /packages/hover-vanilla/rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from '@rollup/plugin-node-resolve' 2 | import { visualizer } from 'rollup-plugin-visualizer' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import filesize from 'rollup-plugin-filesize' 5 | import replace from '@rollup/plugin-replace' 6 | import terser from '@rollup/plugin-terser' 7 | import copy from 'rollup-plugin-copy' 8 | 9 | const isProduction = process.env.NODE_ENV === 'production' 10 | 11 | const plugins = ({ compress }) => 12 | [ 13 | commonjs(), 14 | nodeResolve(), 15 | compress && terser({ mangle: false }), 16 | filesize(), 17 | visualizer({ template: 'treemap' }), 18 | replace({ 19 | preventAssignment: true, 20 | values: { 21 | 'process.env.NODE_ENV': JSON.stringify('production'), 22 | 'styled$1.styled': 'styled$1', 23 | __VERSION__: require('./package').version 24 | } 25 | }), 26 | !isProduction && 27 | copy({ 28 | targets: [{ src: 'dist', dest: 'docs' }] 29 | }) 30 | ].filter(Boolean) 31 | 32 | const globals = { 33 | react: 'React', 34 | 'react-dom': 'ReactDOM', 35 | 'styled-components': 'styled', 36 | '@microlink/mql': 'mql' 37 | } 38 | 39 | const build = ({ file, format, name, exports }) => { 40 | const compress = file.includes('.min.') 41 | return { 42 | input: './src/index.js', 43 | output: { 44 | sourcemap: compress, 45 | file, 46 | format, 47 | exports, 48 | name, 49 | globals 50 | }, 51 | external: Object.keys(globals), 52 | plugins: plugins({ compress }) 53 | } 54 | } 55 | 56 | const builds = [ 57 | build({ 58 | format: 'umd', 59 | file: 'dist/microlink.js', 60 | name: 'microlinkHover' 61 | }), 62 | build({ 63 | format: 'umd', 64 | file: 'dist/microlink.min.js', 65 | name: 'microlinkHover' 66 | }), 67 | build({ 68 | format: 'esm', 69 | file: 'dist/microlink.mjs', 70 | exports: 'named' 71 | }), 72 | build({ 73 | format: 'esm', 74 | file: 'dist/microlink.min.mjs', 75 | exports: 'named' 76 | }), 77 | build({ 78 | format: 'cjs', 79 | file: 'dist/microlink.cjs', 80 | exports: 'named' 81 | }), 82 | build({ 83 | format: 'cjs', 84 | file: 'dist/microlink.min.cjs', 85 | exports: 'named' 86 | }) 87 | ] 88 | 89 | export default builds 90 | -------------------------------------------------------------------------------- /packages/hover-vanilla/src/index.js: -------------------------------------------------------------------------------- 1 | import MicrolinkHover from '@microlink/hover-react' 2 | import isLocalAddress from 'is-local-address' 3 | import { createRoot } from 'react-dom' 4 | import styled from 'styled-components' 5 | import React from 'react' 6 | 7 | function toArray (input) { 8 | const collection = ( 9 | typeof input === 'string' 10 | ? Array.from(document.querySelectorAll(input)) 11 | : [].concat(input) 12 | ).filter(Boolean) 13 | 14 | return collection 15 | .map(el => { 16 | el.href = new URL(el.href).toString() 17 | return el 18 | }) 19 | .filter(el => { 20 | const { protocol, hostname } = new URL(el.href) 21 | return protocol === 'http:' && !isLocalAddress(hostname) 22 | }) 23 | } 24 | 25 | function parseJSON (value) { 26 | try { 27 | return JSON.parse(value) 28 | } catch (err) { 29 | return value 30 | } 31 | } 32 | 33 | function parseObject (obj) { 34 | return Object.keys(obj).reduce(function (acc, key) { 35 | acc[key] = parseJSON(obj[key]) 36 | return acc 37 | }, {}) 38 | } 39 | 40 | function microlink (selector, opts, rootNode) { 41 | return toArray(selector).forEach(function (el) { 42 | createRoot(rootNode || el).render( 43 | React.createElement( 44 | MicrolinkHover.withHover, 45 | Object.assign( 46 | { 47 | LinkComponent: styled('a')``, 48 | as: 'div', 49 | children: el.text, 50 | url: el.getAttribute('href') 51 | }, 52 | opts, 53 | parseObject(el.dataset) 54 | ) 55 | ) 56 | ) 57 | }) 58 | } 59 | 60 | microlink.version = '__VERSION__' 61 | 62 | export default microlink 63 | -------------------------------------------------------------------------------- /packages/react/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | ">0.25%", 9 | "not ie 11", 10 | "not op_mini all" 11 | ] 12 | } 13 | } 14 | ], 15 | "@babel/preset-react" 16 | ], 17 | "plugins": [ 18 | "@babel/plugin-proposal-class-properties", 19 | "@babel/plugin-proposal-object-rest-spread" 20 | ], 21 | "env": { 22 | "production": { 23 | "plugins": [ 24 | [ 25 | "transform-react-remove-prop-types", 26 | { 27 | "removeImport": true 28 | } 29 | ], 30 | "transform-react-pure-class-to-function", 31 | "@babel/plugin-transform-react-constant-elements", 32 | "@babel/plugin-transform-runtime" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/react/.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | save-prefix=~ 3 | shrinkwrap=false 4 | save=false 5 | -------------------------------------------------------------------------------- /packages/react/.storybook/main.js: -------------------------------------------------------------------------------- 1 | /** @type { import('@storybook/react-webpack5').StorybookConfig } */ 2 | const config = { 3 | stories: [ 4 | '../stories/**/*.mdx', 5 | '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)' 6 | ], 7 | addons: [ 8 | '@storybook/addon-essentials', 9 | '@storybook/addon-interactions', 10 | '@storybook/addon-a11y' 11 | ], 12 | framework: { 13 | name: '@storybook/react-webpack5', 14 | options: { 15 | builder: { 16 | useSWC: true 17 | } 18 | } 19 | } 20 | } 21 | export default config 22 | -------------------------------------------------------------------------------- /packages/react/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | /** @type { import('@storybook/react').Preview } */ 2 | const preview = { 3 | parameters: { 4 | actions: { argTypesRegex: '^on[A-Z].*' }, 5 | controls: { 6 | matchers: { 7 | color: /(background|color)$/i, 8 | date: /Date$/i 9 | } 10 | } 11 | } 12 | } 13 | 14 | export default preview 15 | -------------------------------------------------------------------------------- /packages/react/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [5.5.23](https://github.com/microlinkhq/sdk/compare/v5.5.22...v5.5.23) (2025-02-15) 7 | 8 | **Note:** Version bump only for package @microlink/react 9 | 10 | ## [5.5.22](https://github.com/microlinkhq/sdk/compare/v5.5.21...v5.5.22) (2024-07-18) 11 | 12 | **Note:** Version bump only for package @microlink/react 13 | 14 | ## [5.5.21](https://github.com/microlinkhq/sdk/compare/v5.5.20...v5.5.21) (2024-07-18) 15 | 16 | **Note:** Version bump only for package @microlink/react 17 | 18 | ## [5.5.20](https://github.com/microlinkhq/sdk/compare/v5.5.19...v5.5.20) (2024-07-18) 19 | 20 | **Note:** Version bump only for package @microlink/react 21 | 22 | ## [5.5.18](https://github.com/microlinkhq/sdk/compare/v5.5.17...v5.5.18) (2024-01-09) 23 | 24 | **Note:** Version bump only for package @microlink/react 25 | 26 | ## [5.5.16](https://github.com/microlinkhq/sdk/compare/v5.5.15...v5.5.16) (2023-12-02) 27 | 28 | ### Bug Fixes 29 | 30 | * linter warnings related with transient props ([#330](https://github.com/microlinkhq/sdk/issues/330)) ([cebb363](https://github.com/microlinkhq/sdk/commit/cebb363a31c699d85a78b0dff55b5694465fed43)) 31 | * replace __VERSION__ ([#300](https://github.com/microlinkhq/sdk/issues/300)) ([c2789a4](https://github.com/microlinkhq/sdk/commit/c2789a47f8a4c3bf5c793de53f9a5a5aa2fccba5)) 32 | 33 | ## [5.5.15](https://github.com/microlinkhq/sdk/compare/v5.5.14...v5.5.15) (2023-03-29) 34 | 35 | **Note:** Version bump only for package @microlink/react 36 | 37 | ## [5.5.14](https://github.com/microlinkhq/sdk/compare/v5.5.13...v5.5.14) (2023-03-22) 38 | 39 | ### Bug Fixes 40 | 41 | * infinite loading ([#298](https://github.com/microlinkhq/sdk/issues/298)) ([159f1d5](https://github.com/microlinkhq/sdk/commit/159f1d55b4170f4660318f74c03fd119ad495f37)) 42 | 43 | ## [5.5.13](https://github.com/microlinkhq/sdk/compare/v5.5.12...v5.5.13) (2023-03-15) 44 | 45 | ### Bug Fixes 46 | 47 | * linter warnings ([#296](https://github.com/microlinkhq/sdk/issues/296)) ([4222c9c](https://github.com/microlinkhq/sdk/commit/4222c9c593ce8ac42737d6129b83eec12aeeb074)) 48 | 49 | ## [5.5.12](https://github.com/microlinkhq/sdk/compare/v5.5.11...v5.5.12) (2023-01-02) 50 | 51 | ### Bug Fixes 52 | 53 | * **image-proxy:** add image fallback ([#294](https://github.com/microlinkhq/sdk/issues/294)) ([4098f23](https://github.com/microlinkhq/sdk/commit/4098f23cb6c3b2fc09906e03ded0682808cdf1c7)) 54 | 55 | ## [5.5.11](https://github.com/microlinkhq/sdk/compare/v5.5.10...v5.5.11) (2022-11-18) 56 | 57 | **Note:** Version bump only for package @microlink/react 58 | 59 | ## [5.5.10](https://github.com/microlinkhq/sdk/compare/v5.5.9...v5.5.10) (2022-11-13) 60 | 61 | **Note:** Version bump only for package @microlink/react 62 | 63 | ## [5.5.9](https://github.com/microlinkhq/sdk/compare/v5.5.8...v5.5.9) (2022-07-01) 64 | 65 | **Note:** Version bump only for package @microlink/react 66 | 67 | ## [5.5.8](https://github.com/microlinkhq/sdk/compare/v5.5.7...v5.5.8) (2022-03-13) 68 | 69 | ### Bug Fixes 70 | 71 | * avoid to pass apikey ([#277](https://github.com/microlinkhq/sdk/issues/277)) ([747243f](https://github.com/microlinkhq/sdk/commit/747243f7711b8a7f84d7ea22743bddd04b14b582)) 72 | 73 | ## [5.5.7](https://github.com/microlinkhq/sdk/compare/v5.5.6...v5.5.7) (2021-10-04) 74 | 75 | **Note:** Version bump only for package @microlink/react 76 | 77 | ## [5.5.6](https://github.com/microlinkhq/sdk/compare/v5.5.5...v5.5.6) (2021-06-05) 78 | 79 | **Note:** Version bump only for package @microlink/react 80 | 81 | ## [5.5.5](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.5.4...v5.5.5) (2021-03-22) 82 | 83 | **Note:** Version bump only for package @microlink/react 84 | 85 | ## [5.5.4](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.5.3...v5.5.4) (2021-01-17) 86 | 87 | **Note:** Version bump only for package @microlink/react 88 | 89 | ## [5.5.3](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.5.2...v5.5.3) (2020-12-20) 90 | 91 | **Note:** Version bump only for package @microlink/react 92 | 93 | ## [5.5.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.5.1...v5.5.2) (2020-12-12) 94 | 95 | **Note:** Version bump only for package @microlink/react 96 | 97 | ## [5.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.5.0...v5.5.1) (2020-11-20) 98 | 99 | ### Bug Fixes 100 | 101 | * typo ([aab3a06](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/aab3a063644212f53a96fb487f9b1fbef91b4dbd)) 102 | 103 | # [5.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.4.6...v5.5.0) (2020-11-20) 104 | 105 | **Note:** Version bump only for package @microlink/react 106 | 107 | ## [5.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.4.5...v5.4.6) (2020-07-19) 108 | 109 | **Note:** Version bump only for package @microlink/react 110 | 111 | ## [5.4.5](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.4.4...v5.4.5) (2020-07-15) 112 | 113 | **Note:** Version bump only for package @microlink/react 114 | 115 | # [5.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.3.5...v5.4.0) (2020-06-18) 116 | 117 | ### Features 118 | 119 | * allow customization via CSS variables ([ca5e43d](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/ca5e43dce9937804ad9096c2277c430ebaa60043)), closes [#235](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/235) 120 | 121 | ## [5.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.3.1...v5.3.2) (2020-06-14) 122 | 123 | ### Bug Fixes 124 | 125 | * linter ([67f75ed](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/67f75ed5123856f0dd17e91b5c1d4b897994e1e1)) 126 | 127 | ## [5.3.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.3.0...v5.3.1) (2020-06-14) 128 | 129 | ### Bug Fixes 130 | 131 | * trim final space ([e9d4b0c](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/e9d4b0ce30c103c6acbd28b219ed5d5e73bad8a1)) 132 | 133 | # [5.3.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.2.2...v5.3.0) (2020-05-27) 134 | 135 | **Note:** Version bump only for package @microlink/react 136 | 137 | ## [5.2.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.2.1...v5.2.2) (2020-05-19) 138 | 139 | **Note:** Version bump only for package @microlink/react 140 | 141 | ## [5.2.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.2.0...v5.2.1) (2020-05-17) 142 | 143 | **Note:** Version bump only for package @microlink/react 144 | 145 | # [5.2.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.5...v5.2.0) (2020-05-13) 146 | 147 | ### Features 148 | 149 | * add fetchData parameter ([#223](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/223)) ([8dcdea4](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/8dcdea46397c630733a8c6a08857db8ddf952605)) 150 | 151 | ## [5.1.5](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.4...v5.1.5) (2020-04-25) 152 | 153 | **Note:** Version bump only for package @microlink/react 154 | 155 | ## [5.1.4](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.3...v5.1.4) (2020-04-03) 156 | 157 | **Note:** Version bump only for package @microlink/react 158 | 159 | ## [5.1.3](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.2...v5.1.3) (2020-03-09) 160 | 161 | **Note:** Version bump only for package @microlink/react 162 | 163 | ## [5.1.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.1...v5.1.2) (2020-03-03) 164 | 165 | ### Bug Fixes 166 | 167 | * fetchFromApi interface ([c5f010e](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/c5f010e83c2ec0d29b1a1258ea3facf61a2e4ad7)) 168 | 169 | ## [5.1.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.1.0...v5.1.1) (2020-03-03) 170 | 171 | **Note:** Version bump only for package @microlink/react 172 | 173 | # [5.1.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.12...v5.1.0) (2020-02-22) 174 | 175 | **Note:** Version bump only for package @microlink/react 176 | 177 | ## [5.0.12](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.11...v5.0.12) (2020-02-12) 178 | 179 | **Note:** Version bump only for package @microlink/react 180 | 181 | ## [5.0.11](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.10...v5.0.11) (2020-02-11) 182 | 183 | **Note:** Version bump only for package @microlink/react 184 | 185 | ## [5.0.10](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.9...v5.0.10) (2020-02-09) 186 | 187 | **Note:** Version bump only for package @microlink/react 188 | 189 | ## [5.0.9](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.8...v5.0.9) (2020-02-07) 190 | 191 | ### Bug Fixes 192 | 193 | * avoid create element dynamically ([#190](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/190)) ([9849db7](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/9849db7c04eef1f2ec46c2c1870eb809993e3734)) 194 | 195 | ## [5.0.8](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.7...v5.0.8) (2020-02-07) 196 | 197 | **Note:** Version bump only for package @microlink/react 198 | 199 | ## [5.0.7](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.6...v5.0.7) (2020-02-05) 200 | 201 | **Note:** Version bump only for package @microlink/react 202 | 203 | ## [5.0.6](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.5...v5.0.6) (2020-02-05) 204 | 205 | **Note:** Version bump only for package @microlink/react 206 | 207 | ## [5.0.4](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.3...v5.0.4) (2020-02-04) 208 | 209 | **Note:** Version bump only for package @microlink/react 210 | 211 | ## [5.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.1...v5.0.2) (2020-01-31) 212 | 213 | **Note:** Version bump only for package @microlink/react 214 | 215 | ## [5.0.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v5.0.0...v5.0.1) (2020-01-31) 216 | 217 | ### Performance Improvements 218 | 219 | * optimize animation with will-change ([#177](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/177)) ([dde1aff](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/dde1aff857f7e3a4790a2bd71f69b0f6d9976dbb)) 220 | 221 | # [5.0.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.5.1...v5.0.0) (2020-01-17) 222 | 223 | **Note:** Version bump only for package @microlink/react 224 | 225 | ## [4.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.5.0...v4.5.1) (2019-12-29) 226 | 227 | ### Bug Fixes 228 | 229 | * pass rest of props to iframe ([c4d87f3](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/c4d87f30fc8753ece38b64f69eeb18c0596091d6)) 230 | 231 | # [4.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.9...v4.5.0) (2019-12-26) 232 | 233 | ### Features 234 | 235 | * add iframe support ([#173](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/173)) ([e73ad1a](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/e73ad1a6ccfe2fb3d1603a069bcb008c9b0f38cb)) 236 | 237 | ## [4.4.9](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.8...v4.4.9) (2019-12-21) 238 | 239 | ### Bug Fixes 240 | 241 | * ensure props.media is an array ([435f570](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/435f570a722d740c91529c2026a4c0ddb106654d)) 242 | 243 | ## [4.4.8](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.7...v4.4.8) (2019-12-13) 244 | 245 | ### Bug Fixes 246 | 247 | * respect media priorities ([#170](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/170)) ([5de299c](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/5de299c160031ac1383fb8127cd40a612122f0b8)) 248 | 249 | ## [4.4.7](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.6...v4.4.7) (2019-12-01) 250 | 251 | ### Bug Fixes 252 | 253 | * optimize gif properly ([3b31ed5](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/3b31ed5a9a699f3b2964bc8f66b9032db7c237a2)) 254 | 255 | ## [4.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.5...v4.4.6) (2019-11-26) 256 | 257 | ### Bug Fixes 258 | 259 | * use encodeURIComponent instead of encodeURI ([03fb267](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/03fb2675ab2b6066f83d000f4a8ca3c789b019a7)) 260 | 261 | ## [4.4.5](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.4...v4.4.5) (2019-11-25) 262 | 263 | ### Bug Fixes 264 | 265 | * prevent to proxify local urls ([060d38a](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/060d38a9e877d9d28d610a8fb928063d1536d4f7)) 266 | 267 | ## [4.4.4](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.3...v4.4.4) (2019-11-21) 268 | 269 | **Note:** Version bump only for package @microlink/react 270 | 271 | ## [4.4.3](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.2...v4.4.3) (2019-11-18) 272 | 273 | **Note:** Version bump only for package @microlink/react 274 | 275 | ## [4.4.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.1...v4.4.2) (2019-11-18) 276 | 277 | **Note:** Version bump only for package @microlink/react 278 | 279 | ## [4.4.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.4.0...v4.4.1) (2019-11-11) 280 | 281 | ### Bug Fixes 282 | 283 | * prevent pass cardSize as DOM property ([#166](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/166)) ([6b4848b](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/6b4848b23aef66bd4058e311657122a487030435)) 284 | 285 | # [4.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.3.2...v4.4.0) (2019-11-10) 286 | 287 | **Note:** Version bump only for package @microlink/react 288 | 289 | ## [4.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.3.1...v4.3.2) (2019-10-23) 290 | 291 | **Note:** Version bump only for package @microlink/react 292 | 293 | ## [4.3.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.3.0...v4.3.1) (2019-10-16) 294 | 295 | **Note:** Version bump only for package @microlink/react 296 | 297 | # [4.3.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.2.2...v4.3.0) (2019-10-14) 298 | 299 | ### Features 300 | 301 | * use mql as fetcher ([#162](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/162)) ([b7eac46](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/b7eac46312e0148d4a422bb671086cf21a6f4616)) 302 | 303 | ## [4.2.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.2.1...v4.2.2) (2019-09-12) 304 | 305 | **Note:** Version bump only for package @microlink/react 306 | 307 | ## [4.2.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.2.0...v4.2.1) (2019-09-12) 308 | 309 | ### Bug Fixes 310 | 311 | * main loading flag and mini optimizations ([#159](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/159)) ([08396ec](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/08396ec)) 312 | 313 | # [4.2.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.1.3...v4.2.0) (2019-09-11) 314 | 315 | **Note:** Version bump only for package @microlink/react 316 | 317 | ## [4.1.3](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.1.2...v4.1.3) (2019-09-04) 318 | 319 | **Note:** Version bump only for package @microlink/react 320 | 321 | ## [4.1.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.1.1...v4.1.2) (2019-08-22) 322 | 323 | ### Bug Fixes 324 | 325 | * fix server side detection ([b452aeb](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/b452aeb)) 326 | 327 | ## [4.1.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.1.0...v4.1.1) (2019-08-21) 328 | 329 | ### Bug Fixes 330 | 331 | * ensure window is accesible ([#155](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/155)) ([1001bd5](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/1001bd5)) 332 | 333 | # [4.1.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.0.2...v4.1.0) (2019-08-20) 334 | 335 | **Note:** Version bump only for package @microlink/react 336 | 337 | ## [4.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.0.1...v4.0.2) (2019-08-10) 338 | 339 | **Note:** Version bump only for package @microlink/react 340 | 341 | ## [4.0.1](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.0.0...v4.0.1) (2019-05-07) 342 | 343 | ### Bug Fixes 344 | 345 | * use transparent background for png images ([#145](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/145)) ([b877967](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/b877967)) 346 | 347 | # [4.0.0](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v4.0.0-alpha.3...v4.0.0) (2019-04-30) 348 | 349 | **Note:** Version bump only for package @microlink/react 350 | 351 | ## [3.0.5](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v3.0.4...v3.0.5) (2018-12-24) 352 | 353 | ### Bug Fixes 354 | 355 | * add empty url case ([e8d2d94](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/e8d2d94)) 356 | * data → setData ([48a4d12](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/48a4d12)) 357 | * serialize properly ([1e48307](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/1e48307)) 358 | 359 | ### Performance Improvements 360 | 361 | * cached compiled templates ([e76b0c6](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/e76b0c6)) 362 | 363 | ## [3.0.4](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v3.0.3...v3.0.4) (2018-12-23) 364 | 365 | ### Bug Fixes 366 | 367 | * ensure encode url properly ([#138](http://github.com/microlinkhq/sdk/tree/master/packages/react/issues/138)) ([3e8c590](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/3e8c590)) 368 | 369 | ## [3.0.3](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v3.0.2...v3.0.3) (2018-11-23) 370 | 371 | ### Bug Fixes 372 | 373 | * remove log ([cd40aa2](http://github.com/microlinkhq/sdk/tree/master/packages/react/commit/cd40aa2)) 374 | 375 | ## [3.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/react/compare/v3.0.1...v3.0.2) (2018-11-23) 376 | 377 | **Note:** Version bump only for package @microlink/react 378 | -------------------------------------------------------------------------------- /packages/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microlink/react", 3 | "description": "Turn links into beautiful previews.", 4 | "homepage": "https://microlink.io/sdk", 5 | "version": "5.5.23", 6 | "main": "dist/microlink.cjs", 7 | "module": "dist/microlink.mjs", 8 | "jsnext:main": "dist/microlink.mjs", 9 | "repository": { 10 | "directory": "packages/react", 11 | "type": "git", 12 | "url": "git+https://github.com/microlinkhq/sdk.git#master" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/microlinkhq/sdk/issues" 16 | }, 17 | "keywords": [ 18 | "data", 19 | "extraction", 20 | "link", 21 | "microlink", 22 | "preview", 23 | "previsualization", 24 | "react" 25 | ], 26 | "dependencies": { 27 | "@microlink/mql": "~0.13.4", 28 | "is-local-address": "~2.0.0", 29 | "nanoclamp": "~2.0.4" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "latest", 33 | "@babel/plugin-proposal-class-properties": "latest", 34 | "@babel/plugin-proposal-object-rest-spread": "latest", 35 | "@babel/plugin-transform-react-constant-elements": "latest", 36 | "@babel/plugin-transform-runtime": "latest", 37 | "@babel/preset-env": "latest", 38 | "@babel/preset-react": "latest", 39 | "@babel/runtime": "latest", 40 | "@microlink/demo-links": "latest", 41 | "@rollup/plugin-babel": "latest", 42 | "@rollup/plugin-commonjs": "latest", 43 | "@rollup/plugin-node-resolve": "latest", 44 | "@rollup/plugin-replace": "latest", 45 | "@rollup/plugin-terser": "latest", 46 | "@storybook/addon-a11y": "7", 47 | "@storybook/addon-essentials": "7", 48 | "@storybook/addon-interactions": "7", 49 | "@storybook/blocks": "7", 50 | "@storybook/react": "7", 51 | "@storybook/react-webpack5": "7", 52 | "@storybook/test": "7", 53 | "ava": "latest", 54 | "babel-plugin-transform-react-pure-class-to-function": "latest", 55 | "babel-plugin-transform-react-remove-prop-types": "latest", 56 | "lodash": "latest", 57 | "prop-types": "latest", 58 | "react": "18", 59 | "react-dom": "18", 60 | "rollup": "latest", 61 | "rollup-plugin-filesize": "latest", 62 | "rollup-plugin-visualizer": "latest", 63 | "storybook": "7", 64 | "styled-components": "latest", 65 | "tinyspawn": "latest" 66 | }, 67 | "engines": { 68 | "node": ">= 10" 69 | }, 70 | "files": [ 71 | "dist" 72 | ], 73 | "scripts": { 74 | "build": "NODE_ENV=production rollup -c rollup.config.js --bundleConfigAsCjs", 75 | "build-storybook": "storybook build", 76 | "pretest": "npm run build", 77 | "storybook": "storybook dev -p 6006", 78 | "test": "ava" 79 | }, 80 | "license": "MIT", 81 | "peerDependencies": { 82 | "react": ">= 17", 83 | "react-dom": ">= 17", 84 | "styled-components": " >= 5" 85 | }, 86 | "publishConfig": { 87 | "access": "public" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/react/rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from '@rollup/plugin-node-resolve' 2 | import { visualizer } from 'rollup-plugin-visualizer' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import filesize from 'rollup-plugin-filesize' 5 | import replace from '@rollup/plugin-replace' 6 | import terser from '@rollup/plugin-terser' 7 | import babel from '@rollup/plugin-babel' 8 | import fs from 'fs' 9 | 10 | const babelRc = JSON.parse(fs.readFileSync('./.babelrc')) 11 | 12 | const globals = { 13 | react: 'React', 14 | 'react-dom': 'ReactDOM', 15 | 'styled-components': 'styled', 16 | '@microlink/mql': 'mql' 17 | } 18 | 19 | const plugins = ({ compress }) => [ 20 | nodeResolve(), 21 | babel({ 22 | babelrc: false, 23 | ...babelRc, 24 | babelHelpers: 'runtime' 25 | }), 26 | commonjs(), 27 | compress && terser(), 28 | filesize(), 29 | visualizer({ template: 'treemap' }), 30 | replace({ 31 | preventAssignment: true, 32 | values: { 33 | 'process.env.NODE_ENV': JSON.stringify('production') 34 | } 35 | }) 36 | ] 37 | 38 | const build = ({ file, format, name, exports }) => { 39 | const compress = file.includes('.min.') 40 | return { 41 | input: './src/index.js', 42 | output: { 43 | interop: id => (id === 'styled-components' ? 'esModule' : 'default'), 44 | sourcemap: compress, 45 | file, 46 | format, 47 | exports, 48 | name, 49 | globals 50 | }, 51 | external: [/@babel\/runtime/].concat(Object.keys(globals)), 52 | plugins: plugins({ compress }) 53 | } 54 | } 55 | 56 | const builds = [ 57 | build({ 58 | format: 'esm', 59 | file: 'dist/microlink.mjs', 60 | exports: 'named' 61 | }), 62 | build({ 63 | format: 'esm', 64 | file: 'dist/microlink.min.mjs', 65 | exports: 'named' 66 | }), 67 | build({ 68 | format: 'cjs', 69 | file: 'dist/microlink.cjs', 70 | exports: 'named' 71 | }), 72 | build({ 73 | format: 'cjs', 74 | file: 'dist/microlink.min.cjs', 75 | exports: 'named' 76 | }) 77 | ] 78 | 79 | export default builds 80 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardAnimation.js: -------------------------------------------------------------------------------- 1 | import { css, keyframes } from 'styled-components' 2 | 3 | const emptyStatePulse = keyframes` 4 | 0% { 5 | background: #e1e8ed; 6 | } 7 | 70% { 8 | background: #cdd4d8; 9 | } 10 | 100% { 11 | background: #e1e8ed; 12 | } 13 | ` 14 | const emptyStateImagePulse = keyframes` 15 | 0% { 16 | background: #e1e8ed; 17 | } 18 | 70% { 19 | background: #dce3e8; 20 | } 21 | 100% { 22 | background: #e1e8ed; 23 | } 24 | ` 25 | 26 | export const emptyStateAnimation = css` 27 | animation: ${emptyStatePulse} .75s linear infinite; 28 | ` 29 | 30 | export const emptyStateImageAnimation = css` 31 | animation: ${emptyStateImagePulse} 1.25s linear infinite; 32 | ` 33 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardContent.js: -------------------------------------------------------------------------------- 1 | /* global URL */ 2 | 3 | import React, { useCallback, useMemo, useContext } from 'react' 4 | import { styled, css } from 'styled-components' 5 | import CardText from './CardText' 6 | 7 | import { transition } from '../../theme' 8 | import { classNames, media, isLarge, isSmall, isNil } from '../../utils' 9 | import { GlobalContext } from '../../context/GlobalState' 10 | 11 | const REGEX_STRIP_WWW = /^www\./ 12 | const BADGE_WIDTH = '16px' 13 | const BADGE_HEIGHT = '12px' 14 | 15 | const getHostname = href => { 16 | if (isNil(href)) return '' 17 | const { hostname } = new URL(href) 18 | return hostname.replace(REGEX_STRIP_WWW, '') 19 | } 20 | 21 | const mobileDescriptionStyle = css` 22 | ${media.mobile` 23 | > p { 24 | overflow: hidden; 25 | text-overflow: ellipsis; 26 | white-space: nowrap; 27 | } 28 | `}; 29 | ` 30 | 31 | export const Content = styled('div').attrs({ className: classNames.content })` 32 | display: flex; 33 | padding: 10px 15px; 34 | min-width: 0; 35 | box-sizing: border-box; 36 | ${({ $cardSize }) => css` 37 | flex: ${!isLarge($cardSize) ? 1 : '0 0 125px'}; 38 | justify-content: ${!isSmall($cardSize) ? 'space-around' : 'space-between'}; 39 | flex-direction: ${!isSmall($cardSize) ? 'column' : 'row'}; 40 | align-items: ${!isSmall($cardSize) ? 'stretch' : 'center'}; 41 | `}; 42 | ` 43 | 44 | const Header = styled('header').attrs({ className: classNames.title })` 45 | text-align: left; 46 | font-weight: bold; 47 | margin: 0; 48 | width: 100%; 49 | ${({ $cardSize }) => css` 50 | flex-grow: ${!isSmall($cardSize) ? 1.2 : 0.8}; 51 | font-size: ${!isSmall($cardSize) ? '16px' : '15px'}; 52 | 53 | ${isSmall($cardSize) && 54 | css` 55 | min-width: 0; 56 | padding-right: 14px; 57 | `} 58 | `} 59 | ` 60 | 61 | const Description = styled('div').attrs({ className: classNames.description })` 62 | text-align: left; 63 | font-size: 14px; 64 | flex-grow: 2; 65 | margin: auto 0; 66 | line-height: 18px; 67 | font-weight: normal; 68 | ${({ $cardSize }) => !isLarge($cardSize) && mobileDescriptionStyle}; 69 | ` 70 | 71 | const Footer = styled('footer').attrs({ className: classNames.url })` 72 | display: flex; 73 | align-items: center; 74 | justify-content: space-between; 75 | text-align: left; 76 | margin: 0; 77 | flex-grow: 0; 78 | font-weight: normal; 79 | ${({ $cardSize }) => css` 80 | font-size: ${!isSmall($cardSize) ? '12px' : '10px'}; 81 | ${!isSmall($cardSize) && 'width: 100%;'} 82 | `}; 83 | ` 84 | 85 | const Author = styled(CardText)` 86 | opacity: 0.75; 87 | transition: ${transition.medium('opacity')}; 88 | will-change: opacity; 89 | 90 | .${classNames.main}:hover & { 91 | opacity: 1; 92 | } 93 | ` 94 | 95 | const PoweredBy = styled('span').attrs({ title: 'microlink.io' })` 96 | background: url('https://cdn.microlink.io/logo/logo.svg') no-repeat center 97 | center; 98 | display: block; 99 | margin-left: 15px; 100 | transition: ${transition.medium('filter', 'opacity')}; 101 | will-change: filter, opacity; 102 | &:not(:hover) { 103 | filter: grayscale(100%); 104 | opacity: 0.75; 105 | } 106 | 107 | min-width: ${BADGE_WIDTH}; 108 | width: ${BADGE_WIDTH}; 109 | background-size: ${BADGE_WIDTH}; 110 | height: ${BADGE_HEIGHT}; 111 | ` 112 | 113 | const CardContent = () => { 114 | const { 115 | state: { description, title, url }, 116 | props: { size } 117 | } = useContext(GlobalContext) 118 | const isSmallCard = isSmall(size) 119 | const formattedUrl = useMemo(() => getHostname(url), [url]) 120 | const handleOnClick = useCallback(e => { 121 | e.preventDefault() 122 | window.open('https://www.microlink.io', '_blank') 123 | }, []) 124 | 125 | return ( 126 | 127 |
128 | {title} 129 |
130 | {!isSmallCard && ( 131 | 132 | {description} 133 | 134 | )} 135 |
136 | {formattedUrl} 137 | 138 |
139 |
140 | ) 141 | } 142 | 143 | export default CardContent 144 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardEmpty.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable multiline-ternary */ 2 | 3 | import React, { useContext } from 'react' 4 | import { styled } from 'styled-components' 5 | 6 | import { emptyStateAnimation, emptyStateImageAnimation } from './CardAnimation' 7 | import CardImage from './CardMedia/Image' 8 | import { Content } from './CardContent' 9 | import { GlobalContext } from '../../context/GlobalState' 10 | import { isLarge, isSmall } from '../../utils' 11 | 12 | const MediaEmpty = styled(CardImage)` 13 | ${emptyStateImageAnimation}; 14 | ` 15 | 16 | const HeaderEmpty = styled('span')` 17 | opacity: 0.8; 18 | height: 16px; 19 | width: ${({ $cardSize }) => (!isSmall($cardSize) ? '60%' : '75%')}; 20 | display: block; 21 | background: #e1e8ed; 22 | margin: ${({ $cardSize }) => 23 | !isSmall($cardSize) ? '2px 0 8px' : '0 20px 0 0'}; 24 | ${emptyStateAnimation}; 25 | 26 | ${({ $cardSize }) => 27 | !isLarge($cardSize) && 28 | ` 29 | height: 15px; 30 | `}; 31 | ` 32 | 33 | const DescriptionEmpty = styled('span')` 34 | opacity: 0.8; 35 | height: 14px; 36 | width: 95%; 37 | display: block; 38 | position: relative; 39 | ${emptyStateAnimation}; 40 | animation-delay: 0.125s; 41 | ` 42 | 43 | const FooterEmpty = styled('span')` 44 | opacity: 0.8; 45 | height: 12px; 46 | width: 30%; 47 | display: block; 48 | ${emptyStateAnimation} animation-delay: .25s; 49 | 50 | ${({ $cardSize }) => 51 | !isLarge($cardSize) && 52 | ` 53 | height: 10px; 54 | `}; 55 | ` 56 | 57 | const CardEmptyState = () => { 58 | const { 59 | props: { size } 60 | } = useContext(GlobalContext) 61 | const isSmallCard = isSmall(size) 62 | 63 | return ( 64 | <> 65 | 66 | 67 | 68 | {!isSmallCard ? ( 69 | <> 70 | 71 | 75 | 76 | ) : null} 77 | 78 | 79 | 80 | ) 81 | } 82 | 83 | export default CardEmptyState 84 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Audio.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useMemo } from 'react' 2 | 3 | import Image from './Image' 4 | import Controls from './Controls' 5 | import { GlobalContext } from '../../../context/GlobalState' 6 | import { classNames } from '../../../utils' 7 | 8 | const Audio = props => { 9 | const { 10 | state: { audioUrl } 11 | } = useContext(GlobalContext) 12 | 13 | const mediaProps = useMemo( 14 | () => ({ 15 | className: `${classNames.media} ${classNames.audio}`, 16 | src: audioUrl 17 | }), 18 | [audioUrl] 19 | ) 20 | 21 | return ( 22 | // eslint-disable-next-line 23 | 27 | 28 | 29 | ) 30 | } 31 | 32 | export default Audio 33 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/FooterControls.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import MediaButton from './MediaButton' 5 | import { classNames, media, isLarge } from '../../../../utils' 6 | import { font, transition } from '../../../../theme' 7 | 8 | const VolumeMute = props => ( 9 | 10 | 18 | 19 | ) 20 | 21 | const VolumeUp = props => ( 22 | 23 | 31 | 32 | ) 33 | 34 | const BottomControls = styled('div')` 35 | z-index: 2; 36 | position: absolute; 37 | bottom: ${({ $cardSize }) => (isLarge($cardSize) ? 18 : 14)}px; 38 | left: 0; 39 | right: 0; 40 | display: flex; 41 | justify-content: center; 42 | align-items: center; 43 | transition: ${transition.medium('opacity')}; 44 | will-change: opacity; 45 | ` 46 | 47 | const VolumeIcon = styled('svg')` 48 | stroke: #fff; 49 | ` 50 | 51 | const VolumeButton = styled(MediaButton).attrs({ 52 | className: classNames.volumeControl 53 | })` 54 | ${VolumeIcon} { 55 | width: ${({ $cardSize }) => (isLarge($cardSize) ? 16 : 14)}px; 56 | height: ${({ $cardSize }) => (isLarge($cardSize) ? 16 : 14)}px; 57 | 58 | ${({ $cardSize }) => 59 | !isLarge($cardSize) && 60 | media.mobile` 61 | width: 12px; 62 | height: 12px; 63 | `} 64 | } 65 | ` 66 | 67 | const PlaybackRateButton = styled(MediaButton).attrs({ 68 | className: classNames.rateControl 69 | })` 70 | font-size: ${({ $cardSize }) => (isLarge($cardSize) ? 12 : 10)}px; 71 | min-width: ${({ $cardSize }) => (isLarge($cardSize) ? 33 : 28)}px; 72 | line-height: 1; 73 | font-weight: bold; 74 | border: 1.5px solid #fff; 75 | border-radius: 9999px; 76 | padding: 1px 5px; 77 | text-align: center; 78 | color: #fff; 79 | margin-left: 10px; 80 | 81 | ${({ $cardSize }) => 82 | !isLarge($cardSize) && 83 | media.mobile` 84 | font-size: 8px; 85 | margin-left: 8px; 86 | min-width: 23px; 87 | `} 88 | ` 89 | 90 | const TimeLabel = styled('span').attrs({ className: classNames.progressTime })` 91 | margin: ${({ $right }) => (!$right ? '0 auto 0 0' : '0 0 0 auto')}; 92 | font-family: ${font.mono}; 93 | font-size: 12px; 94 | padding: 0 16px; 95 | color: #fff; 96 | text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); 97 | ` 98 | 99 | const FooterControls = ({ 100 | $cardSize, 101 | currentTime, 102 | endTime, 103 | isMuted, 104 | onMuteClick, 105 | onPlaybackRateClick, 106 | playbackRate 107 | }) => { 108 | const VolumeComponent = useMemo( 109 | () => (isMuted ? VolumeMute : VolumeUp), 110 | [isMuted] 111 | ) 112 | const isLargeCard = useMemo(() => isLarge($cardSize), [$cardSize]) 113 | 114 | return ( 115 | 116 | {isLargeCard && {currentTime}} 117 | 118 | 123 | 124 | 125 | 126 | 131 | {playbackRate}x 132 | 133 | 134 | {isLargeCard && {endTime}} 135 | 136 | ) 137 | } 138 | 139 | export default FooterControls 140 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/MediaButton.js: -------------------------------------------------------------------------------- 1 | import { styled } from 'styled-components' 2 | import { transition } from '../../../../theme' 3 | 4 | const MediaButton = styled('div')` 5 | backface-visibility: hidden; 6 | filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); 7 | transition: ${transition.short('transform')}; 8 | will-change: transform; 9 | 10 | > svg { 11 | display: block; 12 | } 13 | 14 | &:active:not(:focus) { 15 | transform: scale(0.9); 16 | } 17 | ` 18 | 19 | export default MediaButton 20 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/PlaybackButton.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | import { styled, css } from 'styled-components' 3 | 4 | import MediaButton from './MediaButton' 5 | import { classNames, isSmall, isLarge, media } from '../../../../utils' 6 | 7 | const Pause = props => ( 8 | 9 | 17 | 18 | ) 19 | 20 | const Play = props => ( 21 | 22 | 30 | 31 | ) 32 | 33 | const iconSizes = { 34 | large: '50px', 35 | normal: '35px', 36 | small: '20px' 37 | } 38 | 39 | const PlaybackIcon = styled('svg')` 40 | stroke: #fff; 41 | ` 42 | 43 | const PlaybackButtonWrap = styled(MediaButton).attrs({ 44 | className: classNames.playbackControl 45 | })` 46 | ${PlaybackIcon} { 47 | ${({ $cardSize }) => css` 48 | width: ${iconSizes[$cardSize]}; 49 | height: ${iconSizes[$cardSize]}; 50 | padding: ${isLarge($cardSize) ? 0 : '8px'}; 51 | 52 | ${!isLarge($cardSize) && 53 | !isSmall($cardSize) && 54 | media.mobile` 55 | width: calc(${iconSizes.small} * 1.2); 56 | height: calc(${iconSizes.small} * 1.2); 57 | `} 58 | `} 59 | } 60 | ` 61 | 62 | const PlaybackButton = ({ $isPlaying, ...props }) => { 63 | const PlaybackComponent = useMemo( 64 | () => ($isPlaying ? Pause : Play), 65 | [$isPlaying] 66 | ) 67 | 68 | return ( 69 | 70 | 71 | 72 | ) 73 | } 74 | 75 | export default PlaybackButton 76 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/ProgressBar/Scrubber.js: -------------------------------------------------------------------------------- 1 | import { styled, css } from 'styled-components' 2 | 3 | import { transition } from '../../../../../theme' 4 | 5 | const SCRUBBER_SIZE = 12 6 | 7 | const scrubberSizeScales = { normal: 0.8, small: 0.9 } 8 | 9 | const getScrubberSize = size => 10 | Math.floor(SCRUBBER_SIZE * (scrubberSizeScales[size] || 1)) 11 | 12 | const Scrubber = styled('div').attrs(({ $isVisible, $positionX }) => ({ 13 | style: { 14 | left: $positionX, 15 | transform: `scale(${$isVisible ? 1 : 0.5}) translate(-50%, -50%)`, 16 | opacity: $isVisible ? 1 : 0, 17 | visibility: $isVisible ? '$visible' : 'hidden' 18 | } 19 | }))` 20 | position: absolute; 21 | top: 50%; 22 | background: #ffffff; 23 | border-radius: 50%; 24 | transform-origin: center center; 25 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1); 26 | transition: ${transition.short('transform', 'opacity', 'visibility')}; 27 | will-change: left, transform, opacity, visibility; 28 | backface-visibility: hidden; 29 | z-index: 3; 30 | 31 | ${({ $cardSize }) => { 32 | const scrubberSize = getScrubberSize($cardSize) 33 | return css` 34 | height: ${scrubberSize}px; 35 | width: ${scrubberSize}px; 36 | ` 37 | }} 38 | ` 39 | 40 | export default Scrubber 41 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/ProgressBar/Tooltip.js: -------------------------------------------------------------------------------- 1 | import React, { forwardRef } from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import { font, transition } from '../../../../../theme' 5 | 6 | const BASE_FONT_SIZE = 11 7 | 8 | const sizeScales = { normal: 0.8 } 9 | const getMarkerFontSize = size => BASE_FONT_SIZE * (sizeScales[size] || 1) 10 | 11 | const TooltipBase = styled('span').attrs( 12 | ({ $position, $isDragging, $visible }) => ({ 13 | style: { 14 | left: `${$position}px`, 15 | top: $visible ? '-4px' : '0px', 16 | visibility: $visible ? '$visible' : 'hidden', 17 | opacity: $visible ? 1 : 0, 18 | transform: `translate(-50%, ${!$isDragging ? -100 : -110}%)` 19 | } 20 | }) 21 | )` 22 | position: absolute; 23 | background: rgba(24, 25, 25, 0.75); 24 | color: #fff; 25 | text-shadow: 0 1px 2px rgba(24, 25, 25, 0.15); 26 | padding: 2px 3px; 27 | border-radius: 4px; 28 | font-family: ${font.mono}; 29 | font-size: ${({ $cardSize }) => getMarkerFontSize($cardSize)}px; 30 | line-height: 1; 31 | transition: ${transition.medium('opacity', 'visibility', 'transform')}, 32 | ${transition.long('top')}; 33 | will-change: top, left, visibility, opacity, transform; 34 | backface-visibility: hidden; 35 | ` 36 | 37 | const Tooltip = forwardRef( 38 | ({ $isDragging, $isVisible, label, $positionX, size, ...props }, ref) => ( 39 | <> 40 | 48 | {label} 49 | 50 | 51 | ) 52 | ) 53 | 54 | Tooltip.displayName = 'Tooltip' 55 | 56 | export default Tooltip 57 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/ProgressBar/index.js: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useContext, useMemo, useRef } from 'react' 2 | import { styled, css } from 'styled-components' 3 | 4 | import { transition } from '../../../../../theme' 5 | import { 6 | clampNumber, 7 | classNames, 8 | formatSeconds, 9 | isSmall 10 | } from '../../../../../utils' 11 | import { GlobalContext } from '../../../../../context/GlobalState' 12 | 13 | import Scrubber from './Scrubber' 14 | import Tooltip from './Tooltip' 15 | 16 | const HEIGHT = 6 17 | const PADDING = 6 18 | 19 | const heightScales = { normal: 0.7, small: 0.6 } 20 | const activeHeightScales = { small: 0.9, large: 1.4 } 21 | 22 | const getProgressBarHeight = size => 23 | Math.floor(HEIGHT * (heightScales[size] || 1)) 24 | 25 | const getProgressBarActiveHeight = size => 26 | Math.floor(HEIGHT * (activeHeightScales[size] || 1)) 27 | 28 | const OuterWrap = styled('div').attrs(() => ({ 29 | className: classNames.progressBar 30 | }))` 31 | position: relative; 32 | padding: ${PADDING}px ${PADDING / 2}px ${PADDING / 2}px; 33 | z-index: 2; 34 | backface-visibility: hidden; 35 | ` 36 | 37 | const BarsWrap = styled('div').attrs(({ $cardSize, $isDragging }) => { 38 | if ($isDragging) { 39 | const activeHeight = getProgressBarActiveHeight($cardSize) 40 | 41 | return { 42 | style: { 43 | height: `${activeHeight}px` 44 | } 45 | } 46 | } 47 | 48 | return {} 49 | })` 50 | background: transparent; 51 | border-radius: 9999px; 52 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); 53 | background: rgba(255, 255, 255, 0.15); 54 | transition: ${transition.short('height')}; 55 | will-change: height; 56 | pointer-events: none; 57 | position: relative; 58 | 59 | ${({ $cardSize }) => { 60 | const height = getProgressBarHeight($cardSize) 61 | const activeHeight = getProgressBarActiveHeight($cardSize) 62 | 63 | return css` 64 | height: ${height}px; 65 | 66 | ${OuterWrap}:hover & { 67 | height: ${activeHeight}px; 68 | } 69 | ` 70 | }} 71 | ` 72 | 73 | const ProgressLine = styled('div')` 74 | border-radius: inherit; 75 | height: 100%; 76 | position: relative; 77 | overflow: hidden; 78 | ` 79 | 80 | const ProgressMask = styled('div').attrs(({ $maskScale }) => ({ 81 | style: { 82 | transform: `scaleX(${$maskScale})` 83 | } 84 | }))` 85 | position: absolute; 86 | left: 0; 87 | top: -50%; 88 | height: 200%; 89 | width: 100%; 90 | background: #ffffff; 91 | transform-origin: left center; 92 | will-change: transform; 93 | ` 94 | 95 | const ProgressHover = styled('div').attrs( 96 | ({ $cursorRatio, $isHovering, $progressPercent }) => ({ 97 | style: { 98 | left: $progressPercent, 99 | transform: `scaleX(${$cursorRatio})`, 100 | opacity: $isHovering ? 1 : 0, 101 | visibility: $isHovering ? '$visible' : 'hidden' 102 | } 103 | }) 104 | )` 105 | position: absolute; 106 | top: 0; 107 | right: 0; 108 | bottom: 0; 109 | background: rgba(255, 255, 255, 0.4); 110 | transform-origin: left center; 111 | transition: ${transition.short('opacity', 'visibility')}; 112 | will-change: left, transform, opacity, $visible; 113 | ` 114 | 115 | const BufferedChunk = styled('div').attrs(({ start, end }) => ({ 116 | style: { 117 | left: `${start}px`, 118 | right: `${end}px` 119 | } 120 | }))` 121 | background: rgba(255, 255, 255, 0.35); 122 | position: absolute; 123 | top: 0; 124 | bottom: 0; 125 | ` 126 | 127 | const ProgressBar = ({ 128 | bufferedMedia, 129 | cursorX, 130 | duration, 131 | hoveredTime, 132 | $isDragging, 133 | $isHovering, 134 | onClick, 135 | onMouseDown, 136 | onMouseOver, 137 | progress, 138 | showTooltip 139 | }) => { 140 | const { 141 | props: { size } 142 | } = useContext(GlobalContext) 143 | const wrapRef = useRef() 144 | const tooltipRef = useRef() 145 | 146 | const isSmallCard = useMemo(() => isSmall(size), [size]) 147 | 148 | const getWrapWidth = useCallback(() => { 149 | if (wrapRef.current) { 150 | return wrapRef.current.getBoundingClientRect().width - PADDING 151 | } 152 | 153 | return 0 154 | }, []) 155 | 156 | const progressRatio = useMemo( 157 | () => clampNumber(progress / duration, 0, 1), 158 | [duration, progress] 159 | ) 160 | 161 | const $progressPercent = useMemo( 162 | () => `${clampNumber(progressRatio * 100, 1, 99)}%`, 163 | [progressRatio] 164 | ) 165 | 166 | const $cursorRatio = useMemo(() => { 167 | if (wrapRef.current) { 168 | const wrapWidth = getWrapWidth() 169 | const startPoint = progressRatio * wrapWidth 170 | const cursorPosition = cursorX - startPoint 171 | const width = wrapWidth - startPoint 172 | 173 | if (cursorPosition > 0) { 174 | return clampNumber((cursorPosition / width).toFixed(3), 0, 0.99) 175 | } 176 | } 177 | 178 | return 0 179 | }, [cursorX, getWrapWidth, progressRatio]) 180 | 181 | const bufferedMediaChunks = useMemo(() => { 182 | const wrapWidth = getWrapWidth() 183 | 184 | return bufferedMedia.map((chunk, key) => { 185 | const start = chunk.start * wrapWidth 186 | const end = wrapWidth - chunk.end * wrapWidth 187 | 188 | return { key, start, end } 189 | }) 190 | }, [bufferedMedia, getWrapWidth]) 191 | 192 | const tooltipLabel = useMemo(() => formatSeconds(hoveredTime), [hoveredTime]) 193 | 194 | const tooltipPositionX = useMemo(() => { 195 | if (wrapRef.current && tooltipRef.current) { 196 | const wrapWidth = getWrapWidth() 197 | const tooltipWidth = tooltipRef.current.getBoundingClientRect().width 198 | const tooltipHalf = tooltipWidth / 2 199 | 200 | return clampNumber(cursorX, tooltipHalf, wrapWidth - tooltipHalf) 201 | } 202 | 203 | return 0 204 | }, [cursorX, getWrapWidth]) 205 | 206 | const mouseEvents = useMemo( 207 | () => ({ 208 | onClick, 209 | onMouseDown, 210 | onMouseOver 211 | }), 212 | [onClick, onMouseDown, onMouseOver] 213 | ) 214 | 215 | const showAccessories = useMemo( 216 | () => $isDragging || $isHovering, 217 | [$isDragging, $isHovering] 218 | ) 219 | 220 | return ( 221 | 222 | 223 | 224 | 229 | 230 | {bufferedMediaChunks.map(({ key, ...chunk }) => ( 231 | 232 | ))} 233 | 234 | 235 | 236 | 237 | 242 | 243 | {!isSmallCard && ( 244 | 252 | )} 253 | 254 | 255 | ) 256 | } 257 | 258 | export default ProgressBar 259 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/SeekButton.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import MediaButton from './MediaButton' 5 | import { media, isLarge } from '../../../../utils' 6 | 7 | const Backward = ({ $cardSize, ...props }) => ( 8 | 9 | 17 | 18 | ) 19 | 20 | const Forward = ({ $cardSize, ...props }) => ( 21 | 22 | 30 | 31 | ) 32 | 33 | const SeekIcon = styled('svg')` 34 | stroke: #fff; 35 | width: ${({ $cardSize }) => (isLarge($cardSize) ? 30 : 24)}px; 36 | height: ${({ $cardSize }) => (isLarge($cardSize) ? 30 : 24)}px; 37 | 38 | ${({ $cardSize }) => 39 | !isLarge($cardSize) && 40 | media.mobile` 41 | width: 0; 42 | height: 0; 43 | `} 44 | ` 45 | 46 | const SeekButtonWrap = styled(MediaButton)` 47 | margin: 0 ${({ $cardSize }) => (isLarge($cardSize) ? '28px' : '3px')}; 48 | ` 49 | 50 | const SeekButton = ({ type = 'rewind', $cardSize, ...props }) => { 51 | const IconComponent = useMemo( 52 | () => (type === 'rewind' ? Backward : Forward), 53 | [type] 54 | ) 55 | 56 | return ( 57 | 62 | 63 | 64 | ) 65 | } 66 | 67 | export default SeekButton 68 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/Spinner.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { styled, css, keyframes } from 'styled-components' 3 | 4 | import { transition } from '../../../../theme' 5 | import { classNames } from '../../../../utils' 6 | 7 | import MediaButton from './MediaButton' 8 | 9 | const BASE_SIZE = 12 10 | const BASE_OFFSET = 6 11 | 12 | const offsetScales = { normal: 0.8, small: 0.6 } 13 | const sizeScales = { normal: 0.9, small: 0.8 } 14 | 15 | const getSpinnerOffset = size => 16 | Math.floor(BASE_OFFSET * (offsetScales[size] || 1)) 17 | 18 | const getSpinnerSize = size => Math.floor(BASE_SIZE * (sizeScales[size] || 1)) 19 | 20 | const rotate = keyframes` 21 | 100% { 22 | transform: rotate(360deg); 23 | } 24 | ` 25 | 26 | const dash = keyframes` 27 | 0% { 28 | stroke-dasharray: 1, 150; 29 | stroke-dashoffset: 0; 30 | } 31 | 50% { 32 | stroke-dasharray: 90, 150; 33 | stroke-dashoffset: -35; 34 | } 35 | 100% { 36 | stroke-dasharray: 90, 150; 37 | stroke-dashoffset: -124; 38 | } 39 | ` 40 | 41 | const Wrap = styled(MediaButton).attrs(({ $isVisible }) => ({ 42 | style: { 43 | opacity: $isVisible ? 1 : 0, 44 | visibility: $isVisible ? '$visible' : 'hidden' 45 | } 46 | }))(({ $cardSize }) => { 47 | const size = `${getSpinnerSize($cardSize)}px` 48 | const offset = `${getSpinnerOffset($cardSize)}px` 49 | 50 | return css` 51 | position: absolute; 52 | width: ${size}; 53 | right: ${offset}; 54 | top: ${offset}; 55 | transition: ${transition.medium('opacity', 'visibility')}; 56 | will-change: opacity, visibility; 57 | pointer-events: none; 58 | ` 59 | }) 60 | 61 | const Svg = styled('svg')` 62 | width: 100%; 63 | animation: ${rotate} 2s linear infinite; 64 | will-change: transform; 65 | ` 66 | 67 | const Circle = styled('circle')` 68 | stroke: #fff; 69 | stroke-linecap: round; 70 | stroke-width: 7; 71 | fill: none; 72 | animation: ${dash} 1.5s ease-in-out infinite; 73 | will-change: stroke-dasharray, stroke-dashoffset; 74 | ` 75 | 76 | const Spinner = ({ size, $isVisible }) => ( 77 | 78 | 79 | 80 | 81 | 82 | ) 83 | 84 | export default Spinner 85 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Controls/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable multiline-ternary */ 2 | 3 | import React, { 4 | useCallback, 5 | useContext, 6 | useEffect, 7 | useMemo, 8 | useRef, 9 | useState 10 | } from 'react' 11 | 12 | import { styled, css } from 'styled-components' 13 | 14 | import FooterControls from './FooterControls' 15 | import PlaybackButton from './PlaybackButton' 16 | import ProgressBar from './ProgressBar' 17 | import SeekButton from './SeekButton' 18 | import Spinner from './Spinner' 19 | import { transition } from '../../../../theme' 20 | 21 | import { 22 | classNames, 23 | formatSeconds, 24 | isSmall, 25 | isFunction, 26 | clampNumber 27 | } from '../../../../utils' 28 | 29 | import { GlobalContext } from '../../../../context/GlobalState' 30 | 31 | const SPACE_KEY = 32 32 | const L_ARROW_KEY = 37 33 | const R_ARROW_KEY = 39 34 | const M_KEY = 77 35 | 36 | const OuterWrap = styled('div').attrs({ className: classNames.mediaControls })` 37 | position: absolute; 38 | left: 0; 39 | top: 0; 40 | right: 0; 41 | bottom: 0; 42 | transition: ${transition.long('background')}, ${transition.medium('opacity')}; 43 | will-change: background; 44 | display: flex; 45 | flex-direction: column; 46 | pointer-events: auto; 47 | 48 | ${({ $hasInteracted, $isDragging, $isPlaying }) => { 49 | const bg = 'rgba(0, 0, 0, 0.35)' 50 | const dragBg = 'rgba(0, 0, 0, 0.2)' 51 | const isPaused = $hasInteracted && !$isPlaying 52 | 53 | return css` 54 | .${classNames.main}:hover & { 55 | background: ${!$isDragging ? bg : dragBg}; 56 | } 57 | 58 | .${classNames.main}:not(:hover) & { 59 | opacity: ${!$hasInteracted || isPaused ? 1 : 0}; 60 | ${isPaused && `background: ${bg}`}; 61 | } 62 | ` 63 | }} 64 | ` 65 | 66 | const InnerWrap = styled('div')` 67 | position: absolute; 68 | left: 0; 69 | top: 0; 70 | right: 0; 71 | bottom: 0; 72 | display: flex; 73 | align-items: center; 74 | justify-content: center; 75 | z-index: 2; 76 | ` 77 | 78 | const ControlsTop = styled('div')` 79 | flex: 1; 80 | 81 | ${({ $isVisible }) => 82 | !$isVisible && 83 | css` 84 | *[class*='${classNames.mediaControls}']:not(.${classNames.progressTime}) { 85 | transition: ${transition.medium('opacity', 'visibility')}; 86 | opacity: 0; 87 | visibility: hidden; 88 | } 89 | `} 90 | ` 91 | 92 | const getNextPlaybackRate = rate => { 93 | switch (rate) { 94 | case 1: 95 | return 1.25 96 | case 1.25: 97 | return 1.5 98 | case 1.5: 99 | return 2 100 | default: 101 | return 1 102 | } 103 | } 104 | 105 | const Controls = ({ MediaComponent, mediaProps }) => { 106 | const { 107 | props: { autoPlay, controls, mediaRef: propRef, muted, loop, size } 108 | } = useContext(GlobalContext) 109 | const [duration, setDuration] = useState(0) 110 | const [progress, setProgress] = useState(0) 111 | const [buffered, setBuffered] = useState([]) 112 | const [cursorX, setCursorX] = useState(0) 113 | const [hoveredTime, setHoveredTime] = useState(0) 114 | const [$isPlaying, setIsPlaying] = useState(autoPlay) 115 | const [isMuted, setIsMuted] = useState(muted) 116 | const [isBuffering, setIsBuffering] = useState(false) 117 | const [$isHovering, setIsHovering] = useState(false) 118 | const [$isDragging, setIsDragging] = useState(false) 119 | const [playbackRate, setPlaybackRate] = useState(1) 120 | const [$hasInteracted, setHasInteracted] = useState(autoPlay) 121 | const [pausedByDrag, setPausedByDrag] = useState(false) 122 | 123 | const mediaRef = useRef() 124 | const setRefs = useCallback( 125 | node => { 126 | mediaRef.current = node 127 | 128 | if (propRef) { 129 | if (isFunction(propRef)) { 130 | propRef(node) 131 | } else { 132 | propRef.current = node 133 | } 134 | } 135 | }, 136 | [propRef] 137 | ) 138 | 139 | const isNotSmall = useMemo(() => !isSmall(size), [size]) 140 | 141 | const mediaEvents = useMemo( 142 | () => ({ 143 | onCanPlay: () => setIsBuffering(false), 144 | onLoadedMetadata: e => setDuration(e.currentTarget.duration), 145 | onPause: () => setIsPlaying(false), 146 | onPlay: () => setIsPlaying(true), 147 | onPlaying: () => setIsBuffering(false), 148 | onProgress: e => setBuffered(e.currentTarget.buffered), 149 | onRateChange: e => setPlaybackRate(e.currentTarget.playbackRate), 150 | onTimeUpdate: e => setProgress(e.currentTarget.currentTime), 151 | onVolumeChange: e => setIsMuted(e.currentTarget.muted), 152 | onWaiting: e => setIsBuffering(true) 153 | }), 154 | [] 155 | ) 156 | 157 | const evaluateCursorPosition = useCallback(event => { 158 | if (mediaRef.current) { 159 | const bounds = event.currentTarget.getBoundingClientRect() 160 | const cursor = clampNumber( 161 | Math.floor(event.clientX - bounds.left), 162 | 0, 163 | bounds.width 164 | ) 165 | const time = (cursor / bounds.width) * mediaRef.current.duration 166 | 167 | return { cursor, time } 168 | } 169 | 170 | return { cursor: 0, time: 0 } 171 | }, []) 172 | 173 | const togglePlayback = useCallback(() => { 174 | if (mediaRef.current) { 175 | if (mediaRef.current.paused) { 176 | if (!$hasInteracted) { 177 | setHasInteracted(true) 178 | } 179 | 180 | mediaRef.current.play() 181 | } else { 182 | mediaRef.current.pause() 183 | } 184 | } 185 | }, [$hasInteracted]) 186 | 187 | const jumpTo = useCallback(time => { 188 | if (mediaRef.current) { 189 | const t = clampNumber(time, 0, mediaRef.current.duration) 190 | 191 | mediaRef.current.currentTime = t 192 | setProgress(t) 193 | } 194 | }, []) 195 | 196 | const onSeekClick = useCallback( 197 | (event, type) => { 198 | event.preventDefault() 199 | event.stopPropagation() 200 | 201 | if (mediaRef.current) { 202 | const { currentTime } = mediaRef.current 203 | 204 | jumpTo(type === 'rewind' ? currentTime - 10 : currentTime + 30) 205 | } 206 | }, 207 | [jumpTo] 208 | ) 209 | 210 | const onMuteClick = useCallback(event => { 211 | event.preventDefault() 212 | event.stopPropagation() 213 | 214 | if (mediaRef.current) { 215 | mediaRef.current.muted = !mediaRef.current.muted 216 | } 217 | }, []) 218 | 219 | const onPlaybackRateClick = useCallback(event => { 220 | event.preventDefault() 221 | event.stopPropagation() 222 | 223 | if (mediaRef.current) { 224 | mediaRef.current.playbackRate = getNextPlaybackRate( 225 | mediaRef.current.playbackRate 226 | ) 227 | } 228 | }, []) 229 | 230 | const onProgressBarClick = useCallback(event => { 231 | event.preventDefault() 232 | event.stopPropagation() 233 | setIsDragging(false) 234 | }, []) 235 | 236 | const onProgressBarMouseDown = useCallback( 237 | event => { 238 | event.preventDefault() 239 | event.stopPropagation() 240 | setIsDragging(true) 241 | 242 | const { time } = evaluateCursorPosition(event) 243 | jumpTo(time) 244 | }, 245 | [evaluateCursorPosition, jumpTo] 246 | ) 247 | 248 | const onProgressBarMouseOver = useCallback(() => setIsHovering(true), []) 249 | 250 | const onWrapClick = useCallback( 251 | event => { 252 | event.preventDefault() 253 | event.stopPropagation() 254 | 255 | if ($isDragging) { 256 | setIsDragging(false) 257 | } else { 258 | togglePlayback() 259 | } 260 | }, 261 | [$isDragging, togglePlayback] 262 | ) 263 | 264 | const onWrapMouseMove = useCallback( 265 | event => { 266 | if (($isDragging || $isHovering) && mediaRef.current) { 267 | event.preventDefault() 268 | const { cursor, time } = evaluateCursorPosition(event) 269 | 270 | setHoveredTime(time) 271 | setCursorX(cursor) 272 | 273 | if ($isDragging) { 274 | if (!mediaRef.current.paused) { 275 | mediaRef.current.pause() 276 | setPausedByDrag(true) 277 | } 278 | 279 | jumpTo(time) 280 | } 281 | } 282 | }, 283 | [evaluateCursorPosition, $isDragging, $isHovering, jumpTo] 284 | ) 285 | 286 | const onWrapMouseOver = useCallback( 287 | event => { 288 | if ($isDragging && event.buttons === 0) { 289 | setIsDragging(false) 290 | } 291 | }, 292 | [$isDragging] 293 | ) 294 | 295 | const onWrapKeyDown = useCallback( 296 | event => { 297 | if ($isDragging) { 298 | return 299 | } 300 | 301 | const { keyCode } = event 302 | 303 | if ( 304 | [SPACE_KEY, L_ARROW_KEY, R_ARROW_KEY, M_KEY].includes(keyCode) && 305 | mediaRef.current 306 | ) { 307 | event.preventDefault() 308 | 309 | switch (keyCode) { 310 | case SPACE_KEY: 311 | togglePlayback() 312 | break 313 | case L_ARROW_KEY: 314 | jumpTo(mediaRef.current.currentTime - 5) 315 | break 316 | case R_ARROW_KEY: 317 | jumpTo(mediaRef.current.currentTime + 5) 318 | break 319 | case M_KEY: 320 | mediaRef.current.muted = !mediaRef.current.muted 321 | break 322 | } 323 | } 324 | }, 325 | [$isDragging, jumpTo, togglePlayback] 326 | ) 327 | 328 | const outerWrapEvents = useMemo( 329 | () => ({ 330 | onClick: onWrapClick, 331 | onKeyDown: onWrapKeyDown, 332 | onMouseMove: onWrapMouseMove, 333 | onMouseOut: () => setIsHovering(false), 334 | onMouseOver: onWrapMouseOver 335 | }), 336 | [onWrapClick, onWrapKeyDown, onWrapMouseMove, onWrapMouseOver] 337 | ) 338 | 339 | const outerWrapTitle = useMemo( 340 | () => ($hasInteracted ? { title: '' } : {}), 341 | [$hasInteracted] 342 | ) 343 | 344 | const bufferedMedia = useMemo(() => { 345 | if (buffered && buffered.length && mediaRef.current) { 346 | return [...Array(buffered.length).keys()].map(index => { 347 | return { 348 | start: buffered.start(index) / mediaRef.current.duration, 349 | end: buffered.end(index) / mediaRef.current.duration 350 | } 351 | }) 352 | } 353 | 354 | return [] 355 | }, [buffered]) 356 | 357 | const currentTime = useMemo(() => formatSeconds(progress || 0), [progress]) 358 | const endTime = useMemo(() => formatSeconds(duration || 0), [duration]) 359 | 360 | const footerControlsProps = useMemo( 361 | () => ({ 362 | $cardSize: size, 363 | currentTime, 364 | endTime, 365 | isMuted, 366 | onMuteClick, 367 | onPlaybackRateClick, 368 | playbackRate 369 | }), 370 | [ 371 | currentTime, 372 | endTime, 373 | isMuted, 374 | onMuteClick, 375 | onPlaybackRateClick, 376 | playbackRate, 377 | size 378 | ] 379 | ) 380 | 381 | const progressBarProps = useMemo( 382 | () => ({ 383 | bufferedMedia, 384 | cursorX, 385 | duration, 386 | hoveredTime, 387 | $isDragging, 388 | $isHovering, 389 | onClick: onProgressBarClick, 390 | onMouseDown: onProgressBarMouseDown, 391 | onMouseOver: onProgressBarMouseOver, 392 | progress, 393 | showTooltip: $isDragging || $isHovering 394 | }), 395 | [ 396 | bufferedMedia, 397 | cursorX, 398 | duration, 399 | hoveredTime, 400 | $isDragging, 401 | $isHovering, 402 | onProgressBarClick, 403 | onProgressBarMouseDown, 404 | onProgressBarMouseOver, 405 | progress 406 | ] 407 | ) 408 | 409 | useEffect(() => { 410 | if ( 411 | !$isDragging && 412 | pausedByDrag && 413 | mediaRef.current && 414 | mediaRef.current.paused 415 | ) { 416 | mediaRef.current.play() 417 | setPausedByDrag(false) 418 | } 419 | }, [pausedByDrag, $isDragging]) 420 | 421 | return ( 422 | <> 423 | 431 | 432 | {controls && ( 433 | 441 | 442 | 443 | {!$hasInteracted ? ( 444 | 445 | 446 | 447 | ) : ( 448 | <> 449 | 450 | 451 | {isNotSmall && ( 452 | onSeekClick(event, 'rewind')} 457 | /> 458 | )} 459 | 460 | 461 | 462 | {isNotSmall && ( 463 | onSeekClick(event, 'fastforward')} 468 | /> 469 | )} 470 | 471 | 472 | {isNotSmall && } 473 | 474 | 475 | 476 | 477 | )} 478 | 479 | )} 480 | 481 | ) 482 | } 483 | 484 | export default Controls 485 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Image.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import Wrap from './Wrap' 5 | import { GlobalContext } from '../../../context/GlobalState' 6 | import { classNames, imageProxy } from '../../../utils' 7 | 8 | const ImageWrap = styled(Wrap).attrs({ 9 | className: `${classNames.media} ${classNames.image}` 10 | })` 11 | background-image: ${({ url }) => (url ? `url('${imageProxy(url)}')` : '')}; 12 | ` 13 | 14 | const ImageComponent = props => { 15 | const { 16 | state: { imageUrl } 17 | } = useContext(GlobalContext) 18 | 19 | return 20 | } 21 | 22 | export default ImageComponent 23 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Video.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useMemo } from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import Wrap from './Wrap' 5 | import Controls from './Controls' 6 | import { GlobalContext } from '../../../context/GlobalState' 7 | import { classNames, imageProxy } from '../../../utils' 8 | 9 | const VideoDOM = styled('video')` 10 | width: 100%; 11 | height: 100%; 12 | object-fit: cover; 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | bottom: 0; 17 | left: 0; 18 | 19 | &::media-controls-start-playback-button { 20 | display: none; 21 | appearance: none; 22 | } 23 | ` 24 | 25 | const Video = props => { 26 | const { 27 | state: { imageUrl, playsInline, videoUrl } 28 | } = useContext(GlobalContext) 29 | 30 | const mediaProps = useMemo(() => { 31 | const mediaProps = { 32 | className: `${classNames.media} ${classNames.video}`, 33 | src: videoUrl, 34 | playsInline 35 | } 36 | if (imageUrl) mediaProps.poster = imageProxy(imageUrl) 37 | return mediaProps 38 | }, [imageUrl, playsInline, videoUrl]) 39 | 40 | return ( 41 | 45 | 46 | 47 | ) 48 | } 49 | 50 | export default Video 51 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/Wrap.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import { styled, css } from 'styled-components' 3 | 4 | import { GlobalContext } from '../../../context/GlobalState' 5 | import { media } from '../../../utils' 6 | import { loadingOverlay } from './loader' 7 | 8 | const mediaSizeStyles = { 9 | small: css` 10 | flex: 0 0 48px; 11 | `, 12 | normal: css` 13 | flex: 0 0 125px; 14 | 15 | ${media.mobile` 16 | flex: 0 0 92px; 17 | `} 18 | `, 19 | large: css` 20 | flex: 1; 21 | 22 | &::before { 23 | padding-bottom: 0; 24 | } 25 | ` 26 | } 27 | 28 | const StyledWrap = styled('div')` 29 | background: transparent no-repeat center center / cover; 30 | display: block; 31 | overflow: hidden; 32 | height: auto; 33 | position: relative; 34 | 35 | &::before { 36 | content: ''; 37 | padding-bottom: 100%; 38 | display: block; 39 | } 40 | 41 | ${({ $cardSize }) => mediaSizeStyles[$cardSize]}; 42 | 43 | ${loadingOverlay}; 44 | ` 45 | 46 | const Wrap = props => { 47 | const { 48 | props: { size } 49 | } = useContext(GlobalContext) 50 | 51 | return 52 | } 53 | 54 | export default Wrap 55 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/index.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from 'react' 2 | 3 | import { GlobalContext } from '../../../context/GlobalState' 4 | import { getUrlPath } from '../../../utils' 5 | import { ImageLoadCatcher } from './loader' 6 | import Image from './Image' 7 | import Video from './Video' 8 | import Audio from './Audio' 9 | 10 | const isUrl = url => getUrlPath(url) !== null 11 | 12 | const MEDIA_COMPONENT = { 13 | video: Video, 14 | image: Image, 15 | audio: Audio 16 | } 17 | 18 | const getMediaType = (isAudio, isVideo) => { 19 | if (isAudio) return 'audio' 20 | if (isVideo) return 'video' 21 | return 'image' 22 | } 23 | 24 | const CardMedia = () => { 25 | const { 26 | state: { imageUrl, isAudio, isVideo } 27 | } = useContext(GlobalContext) 28 | const [isLoading, setIsLoading] = useState(isUrl(imageUrl)) 29 | const mediaType = getMediaType(isAudio, isVideo) 30 | const MediaComponent = MEDIA_COMPONENT[mediaType] 31 | 32 | return ( 33 | <> 34 | 35 | {isLoading && ( 36 | setIsLoading(false)} /> 37 | )} 38 | 39 | ) 40 | } 41 | 42 | export default CardMedia 43 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardMedia/loader.js: -------------------------------------------------------------------------------- 1 | import { styled, css } from 'styled-components' 2 | import { transition } from '../../../theme' 3 | 4 | export const ImageLoadCatcher = styled('img')` 5 | height: 1px; 6 | width: 1px; 7 | position: absolute; 8 | z-index: -1; 9 | ` 10 | 11 | export const loadingOverlay = css` 12 | &::after { 13 | content: ''; 14 | position: absolute; 15 | left: 0; 16 | top: 0; 17 | right: 0; 18 | bottom: 0; 19 | background: #e1e8ed; 20 | z-index: 1; 21 | transition: ${transition.medium('opacity', 'visibility')}; 22 | will-change: opacity; 23 | 24 | ${({ $isLoading }) => css` 25 | opacity: ${$isLoading ? 1 : 0}; 26 | visibility: ${$isLoading ? '$visible' : 'hidden'}; 27 | `}; 28 | } 29 | ` 30 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardText.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable multiline-ternary */ 2 | 3 | import React from 'react' 4 | import { styled, css } from 'styled-components' 5 | import NanoClamp from 'nanoclamp' 6 | 7 | import { isNil } from '../../utils' 8 | 9 | const Clamp = ({ children, className, lines }) => 10 | isNil(children) ? null : ( 11 | 12 | ) 13 | 14 | const StyledClamp = styled(Clamp)` 15 | &&& { 16 | text-align: inherit; 17 | font-weight: inherit; 18 | font-family: inherit; 19 | color: inherit; 20 | margin: 0; 21 | 22 | ${({ $useNanoClamp }) => 23 | !$useNanoClamp && 24 | css` 25 | overflow: hidden; 26 | white-space: nowrap; 27 | text-overflow: ellipsis; 28 | `} 29 | } 30 | ` 31 | 32 | const CardText = ({ useNanoClamp = true, children, ...props }) => { 33 | const textProps = useNanoClamp 34 | ? props 35 | : { ...props, as: 'p', title: children } 36 | 37 | return ( 38 | 39 | {children} 40 | 41 | ) 42 | } 43 | 44 | export default CardText 45 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/CardWrap.js: -------------------------------------------------------------------------------- 1 | import { createElement, forwardRef, useContext } from 'react' 2 | import { styled, css } from 'styled-components' 3 | 4 | import { GlobalContext } from '../../context/GlobalState' 5 | import { font, animation, speed } from '../../theme' 6 | import { media, isLarge } from '../../utils' 7 | 8 | const HEIGHT = '382px' 9 | 10 | const contrastStyle = ({ $backgroundColor, color }) => css` 11 | background-color: ${$backgroundColor}; 12 | border-color: ${color}; 13 | transition-property: filter; 14 | will-change: filter; 15 | 16 | &&& { 17 | color: ${color}; 18 | } 19 | 20 | &:hover { 21 | filter: brightness(90%); 22 | } 23 | ` 24 | 25 | const largeStyle = css` 26 | flex-direction: column; 27 | height: ${HEIGHT}; 28 | ${media.mobile` 29 | height: calc(${HEIGHT} * 7/9); 30 | `}; 31 | ` 32 | 33 | const hoverStyle = css` 34 | transition-property: background, border-color; 35 | will-change: background, border-color; 36 | &:hover { 37 | background-color: var(--microlink-hover-background-color, #f5f8fa); 38 | border-color: var(--microlink-hover-border-color, #8899a680); 39 | } 40 | ` 41 | 42 | const rtlStyle = ({ $cardSize }) => css` 43 | flex-direction: ${isLarge($cardSize) ? 'column-reverse' : 'row-reverse'}; 44 | ` 45 | 46 | const baseStyle = css( 47 | () => ` 48 | max-width: var(--microlink-max-width, 500px); 49 | background-color: var(--microlink-background-color, #fff); 50 | border-width: var(--microlink-border-width, 1px); 51 | border-style: var(--microlink-border-style, solid); 52 | border-color: var(--microlink-border-color, #e1e8ed); 53 | color: var(--microlink-color, #181919); 54 | overflow: hidden; 55 | font-family: ${font.sans}; 56 | display: flex; 57 | text-decoration: none; 58 | opacity: 1; 59 | position: relative; 60 | transition-duration: ${speed.medium}; 61 | transition-timing-function: ${animation.medium}; 62 | 63 | &:active, 64 | &:hover { 65 | outline: 0; 66 | } 67 | ` 68 | ) 69 | 70 | const Element = styled('a')( 71 | baseStyle, 72 | ({ $isLoading, contrast }) => !$isLoading && !contrast && hoverStyle, 73 | ({ $cardSize }) => isLarge($cardSize) && largeStyle, 74 | ({ direction }) => direction === 'rtl' && rtlStyle, 75 | ({ $backgroundColor, color, contrast }) => 76 | contrast && color && $backgroundColor && contrastStyle, 77 | ({ $backgroundColor, color, contrast }) => 78 | contrast && (!color || !$backgroundColor) && hoverStyle 79 | ) 80 | 81 | const CardWrap = forwardRef( 82 | ( 83 | { 84 | href, 85 | rel = 'noopener noreferrer', 86 | target = '_blank', 87 | as = 'a', 88 | ...restProps 89 | }, 90 | ref 91 | ) => { 92 | const { 93 | state: { $backgroundColor, color, title }, 94 | props: { size: $cardSize } 95 | } = useContext(GlobalContext) 96 | 97 | return createElement(Element, { 98 | ...(as === 'a' ? { href, rel, target } : undefined), 99 | ...restProps, 100 | $backgroundColor, 101 | $cardSize, 102 | color, 103 | ref, 104 | title 105 | }) 106 | } 107 | ) 108 | 109 | CardWrap.displayName = 'CardWrap' 110 | 111 | export default CardWrap 112 | -------------------------------------------------------------------------------- /packages/react/src/components/Card/index.js: -------------------------------------------------------------------------------- 1 | export { default as CardContent } from './CardContent' 2 | export { default as CardEmpty } from './CardEmpty' 3 | export { default as CardMedia } from './CardMedia' 4 | export { default as CardWrap } from './CardWrap' 5 | -------------------------------------------------------------------------------- /packages/react/src/context/GlobalState.js: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useMemo, useState } from 'react' 2 | 3 | const initialState = {} 4 | 5 | export const GlobalContext = React.createContext(initialState) 6 | 7 | const GlobalState = ({ 8 | autoPlay, 9 | children, 10 | controls, 11 | loop, 12 | mediaRef, 13 | muted, 14 | playsInline, 15 | size, 16 | ...rest 17 | }) => { 18 | const [state, setState] = useState(initialState) 19 | 20 | const updateState = useCallback( 21 | newState => setState(currentState => ({ ...currentState, ...newState })), 22 | [] 23 | ) 24 | 25 | const props = useMemo( 26 | () => ({ 27 | autoPlay, 28 | controls, 29 | loop, 30 | mediaRef, 31 | muted, 32 | playsInline, 33 | size 34 | }), 35 | [autoPlay, controls, loop, mediaRef, muted, playsInline, size] 36 | ) 37 | 38 | const values = useMemo( 39 | () => ({ 40 | props, 41 | state, 42 | updateState 43 | }), 44 | [props, state, updateState] 45 | ) 46 | 47 | return ( 48 | 49 | {children(rest)} 50 | 51 | ) 52 | } 53 | 54 | export default GlobalState 55 | -------------------------------------------------------------------------------- /packages/react/src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable multiline-ternary */ 2 | 3 | import React, { 4 | useState, 5 | useEffect, 6 | useCallback, 7 | useMemo, 8 | useContext 9 | } from 'react' 10 | 11 | import PropTypes from 'prop-types' 12 | 13 | import { CardWrap, CardMedia, CardContent, CardEmpty } from './components/Card' 14 | import GlobalState, { GlobalContext } from './context/GlobalState' 15 | import { 16 | castArray, 17 | classNames, 18 | fetchFromApi, 19 | getApiUrl, 20 | getUrlPath, 21 | getPreferredMedia, 22 | imageProxy, 23 | isFunction, 24 | isLazySupported, 25 | isObject, 26 | isSSR, 27 | someProp 28 | } from './utils' 29 | 30 | import { useIntersectionObserver } from './utils/hooks' 31 | 32 | const Card = props => { 33 | const { 34 | className, 35 | fetchData, 36 | lazy, 37 | loading, 38 | media: mediaProp, 39 | setData, 40 | url, 41 | apiKey, // destructuring to avoid pass it 42 | ...restProps 43 | } = props 44 | 45 | const mediaProps = useMemo(() => castArray(mediaProp), [mediaProp]) 46 | const { updateState } = useContext(GlobalContext) 47 | const [loadingState, setLoading] = useState(true) 48 | const [iframeMedia, setIframeMedia] = useState(null) 49 | const [isError, setIsError] = useState(false) 50 | const isLoadingUndefined = useMemo(() => loading === undefined, [loading]) 51 | const [apiUrl, apiUrlProps] = useMemo( 52 | () => getApiUrl({ ...props, media: mediaProps }), 53 | [mediaProps, props] 54 | ) 55 | 56 | const isLazyEnabled = useMemo( 57 | () => isLazySupported && (lazy === true || isObject(lazy)), 58 | [lazy] 59 | ) 60 | const lazyOptions = useMemo(() => (isObject(lazy) ? lazy : undefined), [lazy]) 61 | const [hasIntersected, cardRef] = useIntersectionObserver( 62 | isLazyEnabled, 63 | lazyOptions 64 | ) 65 | 66 | const canFetchData = useMemo( 67 | () => !isLazyEnabled || (isLazyEnabled && hasIntersected), 68 | [isLazyEnabled, hasIntersected] 69 | ) 70 | 71 | const mergeData = useCallback( 72 | fetchedData => { 73 | const payload = isFunction(setData) 74 | ? setData(fetchedData) 75 | : { ...fetchedData, ...setData } 76 | 77 | const { title, description, url, video, audio, image, logo, iframe } = 78 | payload 79 | 80 | const mediaFallback = image || logo || {} 81 | let media = mediaFallback 82 | let videoUrl 83 | let audioUrl 84 | let isVideo = false 85 | let isAudio = false 86 | 87 | const preferredMedia = getPreferredMedia(payload, mediaProps) 88 | 89 | switch (preferredMedia) { 90 | case 'audio': 91 | isAudio = true 92 | audioUrl = getUrlPath(audio) 93 | break 94 | case 'video': 95 | isVideo = true 96 | videoUrl = getUrlPath(video) 97 | break 98 | case 'iframe': 99 | setIframeMedia(iframe) 100 | break 101 | default: 102 | media = someProp(payload, mediaProps) || mediaFallback 103 | break 104 | } 105 | 106 | const imageUrl = getUrlPath(media) 107 | const { color, background_color: $backgroundColor } = media 108 | 109 | updateState({ 110 | url, 111 | color, 112 | title, 113 | description, 114 | imageUrl, 115 | videoUrl, 116 | audioUrl, 117 | isVideo, 118 | isAudio, 119 | $backgroundColor 120 | }) 121 | 122 | setLoading(false) 123 | }, 124 | [updateState, mediaProps, setData] 125 | ) 126 | 127 | const toFetchData = useCallback(() => { 128 | if (canFetchData) { 129 | setLoading(true) 130 | 131 | const fetch = fetchData 132 | ? fetchFromApi(apiUrl, apiUrlProps) 133 | : Promise.resolve({}) 134 | 135 | fetch 136 | .then(({ data }) => mergeData(data)) 137 | .catch(error => { 138 | setLoading(false) 139 | setIsError(true) 140 | console.error(` 141 | ┌───────────────┐ 142 | │ Microlink SDK │ 143 | └───────────────┘ 144 | 145 | ${error.description} 146 | 147 | ${JSON.stringify(error.data)} 148 | 149 | id ${error.headers['x-request-id']} 150 | uri ${error.url} 151 | code ${error.code} (${error.statusCode}) 152 | 153 | microlink.io/${error.code.toLowerCase()} 154 | `) 155 | }) 156 | } 157 | }, [apiUrlProps, fetchData, apiUrl, mergeData, canFetchData]) 158 | 159 | useEffect(toFetchData, [url, setData, hasIntersected]) 160 | 161 | const isLoading = isLoadingUndefined ? loadingState : loading 162 | 163 | if (isError) { 164 | return ( 165 | 166 | {url} 167 | 168 | ) 169 | } 170 | 171 | if (iframeMedia) { 172 | if (!isSSR) { 173 | iframeMedia.scripts.forEach(attrs => { 174 | const hasScript = document.querySelector(`script[src="${attrs.src}"]`) 175 | if (!hasScript) { 176 | const script = document.createElement('script') 177 | Object.keys(attrs).forEach(key => (script[key] = attrs[key])) 178 | document.body.appendChild(script) 179 | } 180 | }) 181 | } 182 | 183 | return ( 184 |
189 | ) 190 | } 191 | 192 | return ( 193 | 200 | {isLoading ? ( 201 | 202 | ) : ( 203 | <> 204 | 205 | 206 | 207 | )} 208 | 209 | ) 210 | } 211 | 212 | const Microlink = ({ 213 | className = '', 214 | apiKey = undefined, 215 | autoPlay = true, 216 | controls = true, 217 | direction = 'ltr', 218 | lazy = true, 219 | loop = true, 220 | media = ['iframe', 'video', 'audio', 'image', 'logo'], 221 | fetchData = true, 222 | muted = true, 223 | playsInline = true, 224 | size = 'normal', 225 | ...props 226 | }) => ( 227 | 242 | {otherProps => } 243 | 244 | ) 245 | 246 | Microlink.propTypes = { 247 | apiKey: PropTypes.string, 248 | autoPlay: PropTypes.bool, 249 | contrast: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), 250 | controls: PropTypes.bool, 251 | direction: PropTypes.string, 252 | lazy: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), 253 | loop: PropTypes.bool, 254 | media: PropTypes.oneOfType([ 255 | PropTypes.string, 256 | PropTypes.arrayOf(PropTypes.string) 257 | ]), 258 | mediaRef: PropTypes.oneOfType([ 259 | PropTypes.func, 260 | PropTypes.shape({ current: PropTypes.elementType }) 261 | ]), 262 | muted: PropTypes.bool, 263 | playsInline: PropTypes.bool, 264 | prerender: PropTypes.oneOf(['auto', true, false]), 265 | size: PropTypes.oneOf(['normal', 'large', 'small']), 266 | url: PropTypes.string.isRequired 267 | } 268 | 269 | export { imageProxy, getApiUrl, fetchFromApi } 270 | 271 | export default Microlink 272 | -------------------------------------------------------------------------------- /packages/react/src/theme.js: -------------------------------------------------------------------------------- 1 | export const speed = { 2 | short: '100ms', 3 | medium: '150ms', 4 | long: '300ms' 5 | } 6 | 7 | export const animation = { 8 | short: 'cubic-bezier(.25,.8,.25,1)', 9 | medium: 'cubic-bezier(.25,.8,.25,1)', 10 | long: 'cubic-bezier(.4, 0, .2, 1)' 11 | } 12 | 13 | const createTransition = (properties, s) => { 14 | const suffix = `${speed[s]} ${animation[s]}` 15 | return properties.map(property => `${property} ${suffix}`).join(', ') 16 | } 17 | 18 | export const transition = { 19 | short: (...properties) => createTransition(properties, 'short'), 20 | medium: (...properties) => createTransition(properties, 'medium'), 21 | long: (...properties) => createTransition(properties, 'long') 22 | } 23 | 24 | // https://primer.style/design/foundations/typography 25 | export const font = { 26 | sans: "InterUI, -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif", 27 | mono: "'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace" 28 | } 29 | -------------------------------------------------------------------------------- /packages/react/src/utils/hooks.js: -------------------------------------------------------------------------------- 1 | /* global IntersectionObserver */ 2 | 3 | import { useCallback, useState } from 'react' 4 | 5 | export const useIntersectionObserver = (enabled, options) => { 6 | const [hasIntersected, setHasIntersected] = useState(false) 7 | 8 | const refCallback = useCallback( 9 | node => { 10 | if (enabled) { 11 | const onIntersect = ([entry], self) => { 12 | if (entry.isIntersecting) { 13 | setHasIntersected(true) 14 | self.unobserve(entry.target) 15 | } 16 | } 17 | const observer = new IntersectionObserver(onIntersect, options) 18 | 19 | if (node !== null) { 20 | observer.observe(node) 21 | } 22 | } else { 23 | setHasIntersected(true) 24 | } 25 | }, 26 | [enabled, options] 27 | ) 28 | 29 | return [hasIntersected, refCallback] 30 | } 31 | -------------------------------------------------------------------------------- /packages/react/src/utils/index.js: -------------------------------------------------------------------------------- 1 | import { fetchFromApi, getApiUrl as createApiUrl } from '@microlink/mql' 2 | import isLocalAddress from 'is-local-address' 3 | import { css } from 'styled-components' 4 | 5 | export const isSSR = typeof window === 'undefined' 6 | 7 | export const castArray = value => [].concat(value) 8 | 9 | export const getPreferredMedia = (data, mediaProps) => { 10 | let prefer 11 | 12 | for (let index = 0; index < mediaProps.length; index++) { 13 | const key = mediaProps[index] 14 | const value = data[key] 15 | if (!isNil(value)) { 16 | prefer = key 17 | break 18 | } 19 | } 20 | 21 | return prefer 22 | } 23 | 24 | export const isFunction = fn => typeof fn === 'function' 25 | 26 | export const isObject = obj => typeof obj === 'object' 27 | 28 | export const isNil = value => value == null 29 | 30 | export const getUrlPath = data => (isObject(data) ? data.url : data) 31 | 32 | export const someProp = (data, props) => 33 | data[props.find(prop => !isNil(data[prop]))] 34 | 35 | export const media = { 36 | mobile: (...args) => css` 37 | @media (max-width: 48em) { 38 | ${css(...args)}; 39 | } 40 | `, 41 | desktop: (...args) => css` 42 | @media (min-width: 48em) { 43 | ${css(...args)}; 44 | } 45 | ` 46 | } 47 | 48 | export const getApiUrl = ({ 49 | apiKey, 50 | contrast = false, 51 | data, 52 | endpoint, 53 | force, 54 | headers, 55 | media, 56 | prerender, 57 | proxy, 58 | ttl, 59 | url 60 | }) => 61 | createApiUrl(url, { 62 | apiKey, 63 | audio: media.includes('audio'), 64 | data, 65 | endpoint, 66 | force, 67 | headers, 68 | iframe: media.includes('iframe'), 69 | palette: contrast, 70 | prerender, 71 | proxy, 72 | screenshot: media.includes('screenshot'), 73 | ttl, 74 | video: media.includes('video') 75 | }) 76 | 77 | export { fetchFromApi } 78 | 79 | export const isLarge = cardSize => cardSize === 'large' 80 | 81 | export const isSmall = cardSize => cardSize === 'small' 82 | 83 | export const imageProxy = url => 84 | isLocalAddress(new URL(url).hostname) 85 | ? url 86 | : `https://images.weserv.nl/?${new URLSearchParams({ 87 | url, 88 | default: url, 89 | l: 9, 90 | af: '', 91 | il: '', 92 | n: -1 93 | }).toString()}` 94 | 95 | export const isLazySupported = !isSSR && 'IntersectionObserver' in window 96 | 97 | export const formatSeconds = secs => { 98 | const secsToNum = parseInt(secs, 10) 99 | const hours = Math.floor(secsToNum / 3600) 100 | const minutes = Math.floor(secsToNum / 60) % 60 101 | const seconds = secsToNum % 60 102 | 103 | return [hours, minutes, seconds] 104 | .filter((v, i) => v > 0 || i > 0) 105 | .map(v => (v >= 10 ? v : `0${v}`)) 106 | .join(':') 107 | } 108 | 109 | export const clampNumber = (num, min, max) => { 110 | switch (true) { 111 | case num <= min: 112 | return min 113 | case num >= max: 114 | return max 115 | default: 116 | return num 117 | } 118 | } 119 | 120 | const BASE_CLASSNAME = 'microlink_card' 121 | const CONTENT_BASE_CLASSNAME = `${BASE_CLASSNAME}__content` 122 | const MEDIA_BASE_CLASSNAME = `${BASE_CLASSNAME}__media` 123 | const CONTROLS_BASE_CLASSNAME = `${MEDIA_BASE_CLASSNAME}__controls` 124 | 125 | export const classNames = { 126 | main: BASE_CLASSNAME, 127 | content: CONTENT_BASE_CLASSNAME, 128 | title: `${CONTENT_BASE_CLASSNAME}_title`, 129 | description: `${CONTENT_BASE_CLASSNAME}_description`, 130 | url: `${CONTENT_BASE_CLASSNAME}_url`, 131 | mediaWrapper: `${MEDIA_BASE_CLASSNAME}_wrapper`, 132 | media: MEDIA_BASE_CLASSNAME, 133 | image: `${MEDIA_BASE_CLASSNAME}_image`, 134 | videoWrapper: `${MEDIA_BASE_CLASSNAME}_video_wrapper`, 135 | video: `${MEDIA_BASE_CLASSNAME}_video`, 136 | audioWrapper: `${MEDIA_BASE_CLASSNAME}_audio_wrapper`, 137 | audio: `${MEDIA_BASE_CLASSNAME}_audio`, 138 | mediaControls: CONTROLS_BASE_CLASSNAME, 139 | playbackControl: `${CONTROLS_BASE_CLASSNAME}_playback`, 140 | volumeControl: `${CONTROLS_BASE_CLASSNAME}_volume`, 141 | rwControl: `${CONTROLS_BASE_CLASSNAME}_rewind`, 142 | ffwControl: `${CONTROLS_BASE_CLASSNAME}_fast_forward`, 143 | rateControl: `${CONTROLS_BASE_CLASSNAME}_rate`, 144 | progressBar: `${CONTROLS_BASE_CLASSNAME}_progress_bar`, 145 | progressTime: `${CONTROLS_BASE_CLASSNAME}_progress_time`, 146 | spinner: `${CONTROLS_BASE_CLASSNAME}_spinner`, 147 | iframe: `${BASE_CLASSNAME}__iframe` 148 | } 149 | -------------------------------------------------------------------------------- /packages/react/stories/media.stories.js: -------------------------------------------------------------------------------- 1 | import { urls, urlsVideo, urlsAudio, urlsIframe } from './util/data' 2 | import { Story } from './util/story' 3 | 4 | export default { title: 'media' } 5 | 6 | export const image = { 7 | name: 'image', 8 | render: () => urls.map(url => Story({ url, media: 'image' })) 9 | } 10 | 11 | export const logo = { 12 | name: 'logo', 13 | render: () => urls.map(url => Story({ url, media: 'logo' })) 14 | } 15 | 16 | export const video = { 17 | name: 'video', 18 | render: () => urlsVideo.map(url => Story({ url, media: 'video' })) 19 | } 20 | 21 | export const audio = { 22 | name: 'audio', 23 | render: () => urlsAudio.map(url => Story({ url, media: 'audio' })) 24 | } 25 | 26 | export const screenshot = { 27 | name: 'screenshot', 28 | render: () => 29 | Story({ 30 | url: urls[0], 31 | media: 'screenshot' 32 | }) 33 | } 34 | 35 | export const ifrmae = { 36 | name: 'iframe', 37 | render: () => 38 | urlsIframe.map(url => 39 | Story({ 40 | url, 41 | sizes: ['normal'], 42 | media: 'iframe' 43 | }) 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /packages/react/stories/props.stories.js: -------------------------------------------------------------------------------- 1 | import { urls, urlsVideo } from './util/data' 2 | import { Story } from './util/story' 3 | 4 | export default { title: 'props' } 5 | 6 | export const main = { 7 | name: 'default', 8 | render: () => urls.map(url => Story({ url })) 9 | } 10 | 11 | export const direction = { 12 | name: 'direction', 13 | render: () => urls.map(url => Story({ url, direction: 'rtl' })) 14 | } 15 | 16 | export const contrast = { 17 | name: 'contrast', 18 | render: () => urls.map(url => Story({ url, contrast: true })) 19 | } 20 | 21 | export const directionAndContrast = { 22 | name: 'direction + contrast', 23 | render: () => 24 | urls.map(url => Story({ url, direction: 'rtl', contrast: true })) 25 | } 26 | 27 | export const autoplayDisabled = { 28 | name: 'autoPlay (disabled)', 29 | render: () => urls.map(url => Story({ url, media: 'video', autoPlay: false })) 30 | } 31 | 32 | export const constrolsDisabled = { 33 | name: 'controls (disabled)', 34 | render: () => urls.map(url => Story({ url, media: 'video', controls: false })) 35 | } 36 | 37 | export const loading = { 38 | name: 'loading', 39 | render: () => Story({ loading: true }) 40 | } 41 | 42 | export const lazy = { 43 | name: 'lazy', 44 | render: () => Story({ lazy: false }, true) 45 | } 46 | 47 | export const lazyTreshold = { 48 | name: 'lazy (with threshold)', 49 | render: () => Story({ lazy: { threshold: 1 } }, true) 50 | } 51 | 52 | export const mediaRef = { 53 | name: 'mediaRef', 54 | render: () => 55 | Story({ 56 | url: urlsVideo[0], 57 | media: 'video', 58 | mediaRef: node => { 59 | if (node) { 60 | console.log( 61 | ` 62 | ┌───────────────┐ 63 | │ Microlink SDK │ 64 | └───────────────┘ 65 | Media Ref: 66 | `, 67 | node 68 | ) 69 | } 70 | } 71 | }) 72 | } 73 | -------------------------------------------------------------------------------- /packages/react/stories/set-data.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Story } from './util/story' 3 | 4 | export default { title: 'setData' } 5 | 6 | export const object = { 7 | name: 'object', 8 | render: () => 9 | Story({ 10 | setData: { 11 | image: { 12 | url: 'https://media.tenor.com/images/5d4791abbfa98823cdbcd82b7ece2ced/tenor.gif' 13 | }, 14 | title: 'Microlink Query Language', 15 | description: 'Turns any web into data', 16 | url: 'https://docs.microlink.io' 17 | } 18 | }) 19 | } 20 | 21 | export const _function = { 22 | name: 'function', 23 | render: () => 24 | Story({ 25 | setData: () => ({ title: 'My Custom Title' }) 26 | }) 27 | } 28 | 29 | export const preferMedia = { 30 | name: 'prefer media', 31 | render: () => ( 32 | <> 33 | {Story({ 34 | url: 'https://youtube.com', 35 | sizes: ['normal'], 36 | media: ['iframe', 'video', 'audio'], 37 | fetchData: false, 38 | setData: () => ({ 39 | iframe: null, 40 | audio: { 41 | url: 'https://invalidurl.lol', 42 | type: 'mp4', 43 | duration: 552.054422, 44 | size: 8935291, 45 | duration_pretty: '9m', 46 | size_pretty: '8.94 MB' 47 | }, 48 | video: { 49 | url: 'https://cdn.microlink.io/data/assets/youtube.com!watch!v=9P6rdqiybaw/r3---sn-ab5l6nzl.googlevideo.com!videoplayback!c=WEB&dur=552.054&ei=-fbwXa7LFq2Khwaf6JnoDg&expire=15.mp4', 50 | type: 'mp4', 51 | duration: 552.007943, 52 | size: 54633895, 53 | height: 720, 54 | width: 1280, 55 | duration_pretty: '9m', 56 | size_pretty: '54.6 MB' 57 | } 58 | }) 59 | })} 60 | {Story({ 61 | url: 'https://example.com', 62 | sizes: ['normal'], 63 | media: ['iframe', 'video', 'audio'], 64 | fetchData: false, 65 | setData: () => ({ 66 | iframe: { 67 | html: "welcome to microlink.io! You're the visitor number 12242! CONGRATS!! You win an API key, just send 1$ to hello@microlink.io for receiving it into your inbox", 68 | scripts: [] 69 | }, 70 | audio: { 71 | url: 'https://invalidurl.lol', 72 | type: 'mp4', 73 | duration: 552.054422, 74 | size: 8935291, 75 | duration_pretty: '9m', 76 | size_pretty: '8.94 MB' 77 | }, 78 | video: { 79 | url: 'https://cdn.microlink.io/data/assets/youtube.com!watch!v=9P6rdqiybaw/r3---sn-ab5l6nzl.googlevideo.com!videoplayback!c=WEB&dur=552.054&ei=-fbwXa7LFq2Khwaf6JnoDg&expire=15.mp4', 80 | type: 'mp4', 81 | duration: 552.007943, 82 | size: 54633895, 83 | height: 720, 84 | width: 1280, 85 | duration_pretty: '9m', 86 | size_pretty: '54.6 MB' 87 | } 88 | }) 89 | })} 90 | 91 | ) 92 | } 93 | -------------------------------------------------------------------------------- /packages/react/stories/style.stories.js: -------------------------------------------------------------------------------- 1 | import { urls } from './util/data' 2 | import { Story } from './util/story' 3 | 4 | export default { title: 'style' } 5 | 6 | export const width = { 7 | name: 'width', 8 | render: () => 9 | ['300px', '400px', '500px', '600px', '700px', '800px'].map((width, index) => 10 | Story({ 11 | url: urls[index], 12 | style: { 13 | marginBottom: '20px', 14 | width 15 | } 16 | }) 17 | ) 18 | } 19 | 20 | export const height = { 21 | name: 'height', 22 | render: () => 23 | ['150px', '175px', '200px', '250px', '300px', '350px'].map( 24 | (height, index) => 25 | Story({ 26 | url: urls[index], 27 | style: { 28 | marginBottom: '20px', 29 | height 30 | } 31 | }) 32 | ) 33 | } 34 | 35 | export const borderRadius = { 36 | name: 'border-radius', 37 | render: () => 38 | ['.42857em', '6px', '10px'].map((borderRadius, index) => 39 | Story({ 40 | url: urls[index], 41 | style: { 42 | marginBottom: '20px', 43 | borderRadius 44 | } 45 | }) 46 | ) 47 | } 48 | 49 | export const misc = { 50 | name: 'misc', 51 | render: () => 52 | urls.map(url => 53 | Story({ 54 | url, 55 | style: { 56 | marginBottom: '20px', 57 | fontFamily: 'Nitti, "Microsoft YaHei", 微软雅黑, monospace', 58 | boxShadow: '0 1px 4px 0 hsla(0, 0%, 0%, 0.2)' 59 | } 60 | }) 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /packages/react/stories/util/data.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import demoLinks from '@microlink/demo-links' 4 | import { pick, chain } from 'lodash' 5 | 6 | const { NODE_ENV } = process.env 7 | 8 | const isTesting = NODE_ENV === 'test' 9 | 10 | const getData = (fn, pickProp) => 11 | chain(isTesting ? pick(demoLinks, pickProp) : demoLinks) 12 | .toPairs() 13 | .filter(fn) 14 | .take(NODE_ENV === 'test' ? 1 : Infinity) 15 | .map('1.url') 16 | .value() 17 | .sort() 18 | 19 | export const urls = getData( 20 | ([name, link]) => !link.audio && !link.video, 21 | 'Apple' 22 | ) 23 | export const urlsVideo = getData(([name, link]) => link.video, 'Facebook') 24 | export const urlsAudio = getData(([name, link]) => link.audio, 'Spotify') 25 | export const urlsIframe = getData(([name, link]) => link.iframe, 'Twitter') 26 | -------------------------------------------------------------------------------- /packages/react/stories/util/story.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { styled } from 'styled-components' 3 | 4 | import Microlink from '../../src' 5 | 6 | const StoryEntry = styled('div')` 7 | display: flex; 8 | flex-direction: column; 9 | padding-bottom: 32px; 10 | margin-bottom: 32px; 11 | 12 | &:not(:last-child):not(:only-child) { 13 | border-bottom: 1px solid #e0e0e0; 14 | } 15 | ` 16 | 17 | const StoryLink = styled('a')` 18 | color: #0366d6; 19 | margin-bottom: 32px; 20 | ` 21 | 22 | const CodeBlock = styled('pre')` 23 | display: inline-block; 24 | padding: 18px 14px; 25 | margin: 0 0 32px; 26 | background: #2b2b2b; 27 | color: #e8417d; 28 | text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); 29 | font-family: Courier New, Courier, Lucida Sans Typewriter, Lucida Typewriter, 30 | monospace; 31 | border-radius: 5px; 32 | min-width: 300px; 33 | max-width: 100%; 34 | overflow: scroll; 35 | ` 36 | 37 | const StyledMicrolink = styled(Microlink)` 38 | &:not(:last-child):not(:only-child) { 39 | margin-bottom: 32px; 40 | } 41 | ` 42 | 43 | const VisualProps = ({ children }) => ( 44 |
45 | {children} 46 |
47 | ) 48 | 49 | export const Story = (storyProps = {}, showProps = false) => { 50 | const { 51 | url = 'https://microlink.io', 52 | sizes = ['normal', 'small', 'large'], 53 | ...props 54 | } = storyProps 55 | 56 | return ( 57 | 58 | {url} 59 | {showProps && ( 60 | {JSON.stringify(storyProps, null, 2)} 61 | )} 62 | {sizes.map(size => ( 63 | 64 | ))} 65 | 66 | ) 67 | } 68 | -------------------------------------------------------------------------------- /packages/react/test/build.mjs: -------------------------------------------------------------------------------- 1 | import $ from 'tinyspawn' 2 | import test from 'ava' 3 | 4 | const evalScript = (code, flags = []) => $('node', ['--eval', code, ...flags]).then(({ stdout }) => stdout) 5 | evalScript.esm = code => evalScript(code, ['--input-type', 'module']) 6 | 7 | test('cjs', async t => { 8 | t.snapshot((await evalScript("console.log(require('./dist/microlink.cjs'))"))) 9 | }) 10 | 11 | test('esm', async t => { 12 | t.snapshot((await evalScript.esm('console.log(await import("./dist/microlink.mjs"))'))) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/react/test/snapshots/build.mjs.md: -------------------------------------------------------------------------------- 1 | # Snapshot report for `test/build.mjs` 2 | 3 | The actual snapshot is saved in `build.mjs.snap`. 4 | 5 | Generated by [AVA](https://avajs.dev). 6 | 7 | ## cjs 8 | 9 | > Snapshot 1 10 | 11 | `{␊ 12 | fetchFromApi: [Getter],␊ 13 | default: [Function: Microlink],␊ 14 | getApiUrl: [Function: getApiUrl],␊ 15 | imageProxy: [Function: imageProxy]␊ 16 | }` 17 | 18 | ## esm 19 | 20 | > Snapshot 1 21 | 22 | `[Module: null prototype] {␊ 23 | default: [Function: Microlink],␊ 24 | fetchFromApi: [AsyncFunction: fetchFromApi],␊ 25 | getApiUrl: [Function: getApiUrl],␊ 26 | imageProxy: [Function: imageProxy]␊ 27 | }` 28 | -------------------------------------------------------------------------------- /packages/react/test/snapshots/build.mjs.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microlinkhq/sdk/5c7e097b8b2474cc4145a7c9521ab064d1fad654/packages/react/test/snapshots/build.mjs.snap -------------------------------------------------------------------------------- /packages/vanilla/.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | save-prefix=~ 3 | shrinkwrap=false 4 | save=false 5 | -------------------------------------------------------------------------------- /packages/vanilla/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [5.5.23](https://github.com/microlinkhq/sdk/compare/v5.5.22...v5.5.23) (2025-02-15) 7 | 8 | **Note:** Version bump only for package @microlink/vanilla 9 | 10 | ## [5.5.22](https://github.com/microlinkhq/sdk/compare/v5.5.21...v5.5.22) (2024-07-18) 11 | 12 | **Note:** Version bump only for package @microlink/vanilla 13 | 14 | ## [5.5.21](https://github.com/microlinkhq/sdk/compare/v5.5.20...v5.5.21) (2024-07-18) 15 | 16 | **Note:** Version bump only for package @microlink/vanilla 17 | 18 | ## [5.5.20](https://github.com/microlinkhq/sdk/compare/v5.5.19...v5.5.20) (2024-07-18) 19 | 20 | **Note:** Version bump only for package @microlink/vanilla 21 | 22 | ## [5.5.19](https://github.com/microlinkhq/sdk/compare/v5.5.18...v5.5.19) (2024-02-29) 23 | 24 | ### Bug Fixes 25 | 26 | * **vanilla:** disable mangle ([abfdc45](https://github.com/microlinkhq/sdk/commit/abfdc45a404df4a491f28db2713ddfe9e2a95aa4)) 27 | 28 | ## [5.5.18](https://github.com/microlinkhq/sdk/compare/v5.5.17...v5.5.18) (2024-01-09) 29 | 30 | **Note:** Version bump only for package @microlink/vanilla 31 | 32 | ## [5.5.17](https://github.com/microlinkhq/sdk/compare/v5.5.16...v5.5.17) (2023-12-10) 33 | 34 | ### Bug Fixes 35 | 36 | * vanilla build alias ([7e004ec](https://github.com/microlinkhq/sdk/commit/7e004ecaa493c4f667fd54b91c5811f994c5ed18)) 37 | 38 | ## [5.5.16](https://github.com/microlinkhq/sdk/compare/v5.5.15...v5.5.16) (2023-12-02) 39 | 40 | ### Bug Fixes 41 | 42 | * replace __VERSION__ ([#300](https://github.com/microlinkhq/sdk/issues/300)) ([c2789a4](https://github.com/microlinkhq/sdk/commit/c2789a47f8a4c3bf5c793de53f9a5a5aa2fccba5)) 43 | 44 | ## [5.5.15](https://github.com/microlinkhq/sdk/compare/v5.5.14...v5.5.15) (2023-03-29) 45 | 46 | **Note:** Version bump only for package @microlink/vanilla 47 | 48 | ## [5.5.14](https://github.com/microlinkhq/sdk/compare/v5.5.13...v5.5.14) (2023-03-22) 49 | 50 | **Note:** Version bump only for package @microlink/vanilla 51 | 52 | ## [5.5.13](https://github.com/microlinkhq/sdk/compare/v5.5.12...v5.5.13) (2023-03-15) 53 | 54 | **Note:** Version bump only for package @microlink/vanilla 55 | 56 | ## [5.5.12](https://github.com/microlinkhq/sdk/compare/v5.5.11...v5.5.12) (2023-01-02) 57 | 58 | **Note:** Version bump only for package @microlink/vanilla 59 | 60 | ## [5.5.11](https://github.com/microlinkhq/sdk/compare/v5.5.10...v5.5.11) (2022-11-18) 61 | 62 | **Note:** Version bump only for package @microlink/vanilla 63 | 64 | ## [5.5.10](https://github.com/microlinkhq/sdk/compare/v5.5.9...v5.5.10) (2022-11-13) 65 | 66 | **Note:** Version bump only for package @microlink/vanilla 67 | 68 | ## [5.5.9](https://github.com/microlinkhq/sdk/compare/v5.5.8...v5.5.9) (2022-07-01) 69 | 70 | **Note:** Version bump only for package @microlink/vanilla 71 | 72 | ## [5.5.8](https://github.com/microlinkhq/sdk/compare/v5.5.7...v5.5.8) (2022-03-13) 73 | 74 | ### Performance Improvements 75 | 76 | * prefer mutation instead of Object.assign ([e9e8b42](https://github.com/microlinkhq/sdk/commit/e9e8b42b3f42591f66469226a1c0db0ec1a061c8)) 77 | 78 | ## [5.5.7](https://github.com/microlinkhq/sdk/compare/v5.5.6...v5.5.7) (2021-10-04) 79 | 80 | **Note:** Version bump only for package @microlink/vanilla 81 | 82 | ## [5.5.6](https://github.com/microlinkhq/sdk/compare/v5.5.5...v5.5.6) (2021-06-05) 83 | 84 | **Note:** Version bump only for package @microlink/vanilla 85 | 86 | ## [5.5.5](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.5.4...v5.5.5) (2021-03-22) 87 | 88 | **Note:** Version bump only for package @microlink/vanilla 89 | 90 | ## [5.5.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.5.3...v5.5.4) (2021-01-17) 91 | 92 | **Note:** Version bump only for package @microlink/vanilla 93 | 94 | ## [5.5.3](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.5.2...v5.5.3) (2020-12-20) 95 | 96 | **Note:** Version bump only for package @microlink/vanilla 97 | 98 | ## [5.5.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.5.1...v5.5.2) (2020-12-12) 99 | 100 | **Note:** Version bump only for package @microlink/vanilla 101 | 102 | ## [5.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.5.0...v5.5.1) (2020-11-20) 103 | 104 | **Note:** Version bump only for package @microlink/vanilla 105 | 106 | # [5.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.4.6...v5.5.0) (2020-11-20) 107 | 108 | ### Bug Fixes 109 | 110 | * array from null ([2a105be](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/2a105be0e6e603b4d77a0297fc6118a238283d22)) 111 | 112 | ## [5.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.4.5...v5.4.6) (2020-07-19) 113 | 114 | **Note:** Version bump only for package @microlink/vanilla 115 | 116 | ## [5.4.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.4.3...v5.4.4) (2020-06-20) 117 | 118 | **Note:** Version bump only for package @microlink/vanilla 119 | 120 | ## [5.4.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.4.0...v5.4.2) (2020-06-18) 121 | 122 | **Note:** Version bump only for package @microlink/vanilla 123 | 124 | # [5.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.3.5...v5.4.0) (2020-06-18) 125 | 126 | **Note:** Version bump only for package @microlink/vanilla 127 | 128 | ## [5.3.5](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.3.4...v5.3.5) (2020-06-15) 129 | 130 | ### Bug Fixes 131 | 132 | * convert collection into an array ([771496c](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/771496c2455e77e57ac3e14937c74ca719b8468c)) 133 | 134 | ## [5.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.3.1...v5.3.2) (2020-06-14) 135 | 136 | ### Bug Fixes 137 | 138 | * cjs bundle name ([c08cc2a](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/c08cc2a57d821abc8179301f86d55e55b0bd7b07)) 139 | 140 | ## [5.3.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.3.0...v5.3.1) (2020-06-14) 141 | 142 | **Note:** Version bump only for package @microlink/vanilla 143 | 144 | # [5.3.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.2.2...v5.3.0) (2020-05-27) 145 | 146 | **Note:** Version bump only for package @microlink/vanilla 147 | 148 | ## [5.2.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.2.1...v5.2.2) (2020-05-19) 149 | 150 | **Note:** Version bump only for package @microlink/vanilla 151 | 152 | ## [5.2.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.2.0...v5.2.1) (2020-05-17) 153 | 154 | **Note:** Version bump only for package @microlink/vanilla 155 | 156 | # [5.2.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.5...v5.2.0) (2020-05-13) 157 | 158 | **Note:** Version bump only for package @microlink/vanilla 159 | 160 | ## [5.1.5](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.4...v5.1.5) (2020-04-25) 161 | 162 | **Note:** Version bump only for package @microlink/vanilla 163 | 164 | ## [5.1.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.3...v5.1.4) (2020-04-03) 165 | 166 | **Note:** Version bump only for package @microlink/vanilla 167 | 168 | ## [5.1.3](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.2...v5.1.3) (2020-03-09) 169 | 170 | **Note:** Version bump only for package @microlink/vanilla 171 | 172 | ## [5.1.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.1...v5.1.2) (2020-03-03) 173 | 174 | **Note:** Version bump only for package @microlink/vanilla 175 | 176 | ## [5.1.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.1.0...v5.1.1) (2020-03-03) 177 | 178 | **Note:** Version bump only for package @microlink/vanilla 179 | 180 | # [5.1.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.12...v5.1.0) (2020-02-22) 181 | 182 | **Note:** Version bump only for package @microlink/vanilla 183 | 184 | ## [5.0.12](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.11...v5.0.12) (2020-02-12) 185 | 186 | ### Bug Fixes 187 | 188 | * markup ([e7a6caa](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/e7a6caace102b41ea506a34797e274d3490a0a8e)) 189 | 190 | ## [5.0.11](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.10...v5.0.11) (2020-02-11) 191 | 192 | ### Bug Fixes 193 | 194 | * mount div by default ([9d8a792](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/9d8a79286e313ed219e0f4b3fd65d9a63ba415cd)) 195 | 196 | ## [5.0.10](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.9...v5.0.10) (2020-02-09) 197 | 198 | **Note:** Version bump only for package @microlink/vanilla 199 | 200 | ## [5.0.9](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.8...v5.0.9) (2020-02-07) 201 | 202 | **Note:** Version bump only for package @microlink/vanilla 203 | 204 | ## [5.0.8](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.7...v5.0.8) (2020-02-07) 205 | 206 | **Note:** Version bump only for package @microlink/vanilla 207 | 208 | ## [5.0.7](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.6...v5.0.7) (2020-02-05) 209 | 210 | **Note:** Version bump only for package @microlink/vanilla 211 | 212 | ## [5.0.6](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.5...v5.0.6) (2020-02-05) 213 | 214 | **Note:** Version bump only for package @microlink/vanilla 215 | 216 | ## [5.0.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.3...v5.0.4) (2020-02-04) 217 | 218 | **Note:** Version bump only for package @microlink/vanilla 219 | 220 | ## [5.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.1...v5.0.2) (2020-01-31) 221 | 222 | **Note:** Version bump only for package @microlink/vanilla 223 | 224 | ## [5.0.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v5.0.0...v5.0.1) (2020-01-31) 225 | 226 | **Note:** Version bump only for package @microlink/vanilla 227 | 228 | # [5.0.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.5.1...v5.0.0) (2020-01-17) 229 | 230 | **Note:** Version bump only for package @microlink/vanilla 231 | 232 | ## [4.5.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.5.0...v4.5.1) (2019-12-29) 233 | 234 | **Note:** Version bump only for package @microlink/vanilla 235 | 236 | # [4.5.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.9...v4.5.0) (2019-12-26) 237 | 238 | **Note:** Version bump only for package @microlink/vanilla 239 | 240 | ## [4.4.9](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.8...v4.4.9) (2019-12-21) 241 | 242 | **Note:** Version bump only for package @microlink/vanilla 243 | 244 | ## [4.4.8](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.7...v4.4.8) (2019-12-13) 245 | 246 | **Note:** Version bump only for package @microlink/vanilla 247 | 248 | ## [4.4.7](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.6...v4.4.7) (2019-12-01) 249 | 250 | **Note:** Version bump only for package @microlink/vanilla 251 | 252 | ## [4.4.6](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.5...v4.4.6) (2019-11-26) 253 | 254 | **Note:** Version bump only for package @microlink/vanilla 255 | 256 | ## [4.4.5](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.4...v4.4.5) (2019-11-25) 257 | 258 | **Note:** Version bump only for package @microlink/vanilla 259 | 260 | ## [4.4.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.3...v4.4.4) (2019-11-21) 261 | 262 | **Note:** Version bump only for package @microlink/vanilla 263 | 264 | ## [4.4.3](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.2...v4.4.3) (2019-11-18) 265 | 266 | **Note:** Version bump only for package @microlink/vanilla 267 | 268 | ## [4.4.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.1...v4.4.2) (2019-11-18) 269 | 270 | **Note:** Version bump only for package @microlink/vanilla 271 | 272 | ## [4.4.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.4.0...v4.4.1) (2019-11-11) 273 | 274 | **Note:** Version bump only for package @microlink/vanilla 275 | 276 | # [4.4.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.3.2...v4.4.0) (2019-11-10) 277 | 278 | **Note:** Version bump only for package @microlink/vanilla 279 | 280 | ## [4.3.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.3.1...v4.3.2) (2019-10-23) 281 | 282 | **Note:** Version bump only for package @microlink/vanilla 283 | 284 | ## [4.3.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.3.0...v4.3.1) (2019-10-16) 285 | 286 | **Note:** Version bump only for package @microlink/vanilla 287 | 288 | # [4.3.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.2.2...v4.3.0) (2019-10-14) 289 | 290 | ### Features 291 | 292 | * use mql as fetcher ([#162](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/issues/162)) ([b7eac46](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/b7eac46312e0148d4a422bb671086cf21a6f4616)) 293 | 294 | ## [4.2.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.2.1...v4.2.2) (2019-09-12) 295 | 296 | **Note:** Version bump only for package @microlink/vanilla 297 | 298 | ## [4.2.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.2.0...v4.2.1) (2019-09-12) 299 | 300 | **Note:** Version bump only for package @microlink/vanilla 301 | 302 | # [4.2.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.1.3...v4.2.0) (2019-09-11) 303 | 304 | **Note:** Version bump only for package @microlink/vanilla 305 | 306 | ## [4.1.3](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.1.2...v4.1.3) (2019-09-04) 307 | 308 | **Note:** Version bump only for package @microlink/vanilla 309 | 310 | ## [4.1.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.1.1...v4.1.2) (2019-08-22) 311 | 312 | **Note:** Version bump only for package @microlink/vanilla 313 | 314 | ## [4.1.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.1.0...v4.1.1) (2019-08-21) 315 | 316 | **Note:** Version bump only for package @microlink/vanilla 317 | 318 | # [4.1.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.0.2...v4.1.0) (2019-08-20) 319 | 320 | **Note:** Version bump only for package @microlink/vanilla 321 | 322 | ## [4.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.0.1...v4.0.2) (2019-08-10) 323 | 324 | **Note:** Version bump only for package @microlink/vanilla 325 | 326 | ## [4.0.1](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.0.0...v4.0.1) (2019-05-07) 327 | 328 | ### Bug Fixes 329 | 330 | * use transparent background for png images ([#145](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/issues/145)) ([b877967](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/b877967)) 331 | 332 | # [4.0.0](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v4.0.0-alpha.3...v4.0.0) (2019-04-30) 333 | 334 | **Note:** Version bump only for package @microlink/vanilla 335 | 336 | ## [3.0.5](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v3.0.4...v3.0.5) (2018-12-24) 337 | 338 | ### Bug Fixes 339 | 340 | * rename is → as ([88c8ecd](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/commit/88c8ecd)) 341 | 342 | ## [3.0.4](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v3.0.3...v3.0.4) (2018-12-23) 343 | 344 | **Note:** Version bump only for package @microlink/vanilla 345 | 346 | ## [3.0.3](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v3.0.2...v3.0.3) (2018-11-23) 347 | 348 | **Note:** Version bump only for package @microlink/vanilla 349 | 350 | ## [3.0.2](http://github.com/microlinkhq/sdk/tree/master/packages/vanilla/compare/v3.0.1...v3.0.2) (2018-11-23) 351 | 352 | **Note:** Version bump only for package @microlink/vanilla 353 | -------------------------------------------------------------------------------- /packages/vanilla/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @microlink/vanilla 7 | 8 | 9 | 10 | 46 | 47 | 48 |
49 |
50 |

default

51 |
<a class="link" href="https://microlink.io">microlink.io</a>
52 | 53 |
54 |
55 |

data-media='logo'

56 |
<a class="link" href="https://microlink.io">microlink.io data-media='logo'</a>
57 | 58 |
59 |
60 |

data-media='video'

61 |
<a class="link" href="https://www.facebook.com/natgeo/videos/10156364216738951" data-media="video">facebook.com/natgeo/videos/10156364216738951</a>
64 | 65 |
66 |
67 |

data-media='audio'

68 |
<a class="link" href="https://open.spotify.com/track/1W2919zs8SBCLTrOB1ftQT?si=4PcqgjH5RlWCvB5q4ukdnw" data-media='audio'</a>
69 | 70 |
71 |
72 |

data-media='screenshot'

73 |
<a class="link" href="https://example.com">example.com data-media='screenshot'</a>
74 | 75 |
76 |
77 |

data-contrast='true'

78 |
<a class="link" href="https://microlink.io">microlink.io data-contrast='true'</a>
79 | 80 |
81 |
82 |

data-size='large'

83 |
<a class="link" href="https://microlink.io">microlink.io data-size='large'</a>
84 | 85 |
86 |
87 |

custom

88 |
<a class="link" href="https://microlink.io">microlink.io data-setData='{"title": "hello world"}'</a>
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 110 | 111 | -------------------------------------------------------------------------------- /packages/vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microlink/vanilla", 3 | "description": "Turn links into beautiful previews.", 4 | "homepage": "https://microlink.io/sdk", 5 | "version": "5.5.23", 6 | "main": "dist/microlink.cjs", 7 | "module": "dist/microlink.mjs", 8 | "jsnext:main": "dist/microlink.mjs", 9 | "repository": { 10 | "directory": "packages/vanilla", 11 | "type": "git", 12 | "url": "git+https://github.com/microlinkhq/sdk.git#master" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/microlinkhq/sdk/issues" 16 | }, 17 | "keywords": [ 18 | "data", 19 | "extraction", 20 | "javascript", 21 | "link", 22 | "microlink", 23 | "preview", 24 | "previsualization", 25 | "vanilla" 26 | ], 27 | "dependencies": { 28 | "@microlink/react": "^5.5.23" 29 | }, 30 | "devDependencies": { 31 | "@rollup/plugin-commonjs": "latest", 32 | "@rollup/plugin-node-resolve": "latest", 33 | "@rollup/plugin-replace": "latest", 34 | "@rollup/plugin-terser": "latest", 35 | "rollup": "latest", 36 | "rollup-plugin-filesize": "latest", 37 | "rollup-plugin-visualizer": "latest" 38 | }, 39 | "engines": { 40 | "node": ">= 10" 41 | }, 42 | "files": [ 43 | "dist" 44 | ], 45 | "scripts": { 46 | "build": "NODE_ENV=production rollup -c rollup.config.js --bundleConfigAsCjs", 47 | "dev": "npm run build -- -w" 48 | }, 49 | "license": "MIT", 50 | "publishConfig": { 51 | "access": "public" 52 | }, 53 | "umd:main": "dist/microlink.umd.js", 54 | "unpkg": "dist/microlink.umd.js" 55 | } 56 | -------------------------------------------------------------------------------- /packages/vanilla/preact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @microlink/preact 8 | 9 | 10 | 11 | 53 | 54 | 55 | 56 |
57 |
58 |

default

59 |
<a class="link" href="https://microlink.io">microlink.io</a>
61 | 62 |
63 | 64 |
65 |

data-media='logo'

66 |
<a class="link" href="https://microlink.io">microlink.io data-media='logo'</a>
68 | 70 |
71 | 72 |
73 |

data-media='video'

74 |
<a class="link" href="https://www.facebook.com/natgeo/videos/10156364216738951" data-media="video">facebook.com/natgeo/videos/10156364216738951</a>
76 | 78 |
79 | 80 |
81 |

data-media='audio'

82 |
<a class="link" href="https://open.spotify.com/track/1W2919zs8SBCLTrOB1ftQT?si=4PcqgjH5RlWCvB5q4ukdnw" data-media='audio'</a>
 83 |       
84 | 87 |
88 | 89 |
90 |

data-media='screenshot'

91 |
<a class="link" href="https://example.com">example.com data-media='screenshot'</a>
93 | 94 |
95 | 96 |
97 |

data-contrast='true'

98 |
<a class="link" href="https://microlink.io">microlink.io data-contrast='true'</a>
100 | 101 |
102 | 103 |
104 |

data-size='large'

105 |
<a class="link" href="https://microlink.io">microlink.io data-size='large'</a>
107 | 108 |
109 | 110 |
111 |

custom

112 |
<a class="link" href="https://microlink.io">microlink.io data-setData='{"title": "hello world"}'</a>
114 | 116 |
117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /packages/vanilla/rollup.config.js: -------------------------------------------------------------------------------- 1 | import nodeResolve from '@rollup/plugin-node-resolve' 2 | import { visualizer } from 'rollup-plugin-visualizer' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import filesize from 'rollup-plugin-filesize' 5 | import replace from '@rollup/plugin-replace' 6 | import terser from '@rollup/plugin-terser' 7 | 8 | const plugins = ({ compress }) => [ 9 | commonjs(), 10 | nodeResolve(), 11 | compress && terser({ mangle: false }), 12 | filesize(), 13 | visualizer({ template: 'treemap' }), 14 | replace({ 15 | preventAssignment: true, 16 | values: { 17 | 'styledComponents.styled': 'styledComponents', 18 | 'process.env.NODE_ENV': JSON.stringify('production'), 19 | __VERSION__: require('./package').version 20 | } 21 | }) 22 | ] 23 | 24 | const globals = { 25 | react: 'React', 26 | 'react-dom': 'ReactDOM', 27 | 'styled-components': 'styled', 28 | '@microlink/mql': 'mql' 29 | } 30 | 31 | const build = ({ file, format, name, exports }) => { 32 | const compress = file.includes('.min.') 33 | return { 34 | input: './src/index.js', 35 | output: { 36 | sourcemap: compress, 37 | file, 38 | format, 39 | exports, 40 | name, 41 | globals 42 | }, 43 | external: Object.keys(globals), 44 | plugins: plugins({ compress }) 45 | } 46 | } 47 | 48 | const builds = [ 49 | build({ 50 | format: 'umd', 51 | file: 'dist/microlink.js', 52 | name: 'microlink' 53 | }), 54 | build({ 55 | format: 'umd', 56 | file: 'dist/microlink.min.js', 57 | name: 'microlink' 58 | }), 59 | build({ 60 | format: 'esm', 61 | file: 'dist/microlink.mjs', 62 | exports: 'named' 63 | }), 64 | build({ 65 | format: 'esm', 66 | file: 'dist/microlink.min.mjs', 67 | exports: 'named' 68 | }), 69 | build({ 70 | format: 'cjs', 71 | file: 'dist/microlink.cjs', 72 | exports: 'named' 73 | }), 74 | build({ 75 | format: 'cjs', 76 | file: 'dist/microlink.min.cjs', 77 | exports: 'named' 78 | }) 79 | ] 80 | 81 | export default builds 82 | -------------------------------------------------------------------------------- /packages/vanilla/src/index.js: -------------------------------------------------------------------------------- 1 | import Microlink from '@microlink/react' 2 | import { createRoot } from 'react-dom' 3 | import React from 'react' 4 | 5 | function parseJSON (value) { 6 | try { 7 | return JSON.parse(value) 8 | } catch (err) { 9 | return value 10 | } 11 | } 12 | 13 | function parseObject (obj) { 14 | return Object.keys(obj).reduce(function (acc, key) { 15 | acc[key] = parseJSON(obj[key]) 16 | return acc 17 | }, {}) 18 | } 19 | 20 | function toArray (input) { 21 | return ( 22 | typeof input === 'string' 23 | ? Array.from(document.querySelectorAll(input)) 24 | : [].concat(input) 25 | ).filter(Boolean) 26 | } 27 | 28 | function microlink (selector, opts, rootNode) { 29 | return toArray(selector).forEach(function (el) { 30 | el.classList.add('microlink_vanilla') 31 | createRoot(rootNode || el).render( 32 | React.createElement( 33 | Microlink, 34 | Object.assign( 35 | { 36 | as: 'div', 37 | url: el.getAttribute('href') 38 | }, 39 | opts, 40 | parseObject(el.dataset) 41 | ) 42 | ) 43 | ) 44 | }) 45 | } 46 | 47 | microlink.version = '__VERSION__' 48 | 49 | export default microlink 50 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | --------------------------------------------------------------------------------