Skip to content

Commit

Permalink
✨ (vue) Add basic Utterances component
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Jul 8, 2021
1 parent efac502 commit 705c944
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 0 deletions.
164 changes: 164 additions & 0 deletions packages/vue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<p align="center">

<h1 align="center">utterances-vue-component</h1>
</p>

<p align="center">
Type safety vue component for utterances
</p>

<div align="center">

[![test](https://github.com/TomokiMiyauci/utterances-vue-component/actions/workflows/test.yml/badge.svg)](https://github.com/TomokiMiyauci/utterances-vue-component/actions/workflows/test.yml)
[![GitHub release](https://img.shields.io/github/release/TomokiMiyauci/utterances-vue-component.svg)](https://github.com/TomokiMiyauci/utterances-vue-component/releases)
![npm download](https://img.shields.io/npm/dw/utterances-vue-component?color=blue)

![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/TomokiMiyauci/utterances-vue-component)
[![dependencies Status](https://status.david-dm.org/gh/TomokiMiyauci/utterances-vue-component.svg)](https://david-dm.org/TomokiMiyauci/utterances-vue-component)
[![codecov](https://codecov.io/gh/TomokiMiyauci/utterances-vue-component/branch/main/graph/badge.svg?token=SPAi5Pv2wd)](https://codecov.io/gh/TomokiMiyauci/utterances-vue-component)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f43b1c317e11445399d85ce6efc06504)](https://www.codacy.com/gh/TomokiMiyauci/utterances-vue-component/dashboard?utm_source=github.com&utm_medium=referral&utm_content=TomokiMiyauci/utterances-vue-component&utm_campaign=Badge_Grade)
![npm type definitions](https://img.shields.io/npm/types/utterances-vue-component)
![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)
![Gitmoji](https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat)
![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

</div>

---

Vue component for [utterances](https://utteranc.es/) 🔮

Utterances is a lightweight comments widget built on GitHub issues, for blog comments, wiki pages and more.

## :sparkles: Features

- :books: Pure TypeScript and TSX and provides type definition
- :earth_americas: Multiple modules, providing `ES modules` and `Commonjs`
- :package: Optimized, super slim size

## :zap: Quick view

Locally

Local import of components is recommended.
This is a type-safe props.

```html
<template>
<Utterances
repo="TomokiMiyauci/utterances-component"
theme="github-dark"
issueTerm="pathname"
/>
</template>

<script setup lang="ts">
import { Utterances } from 'utterances-vue-component'
</script>
```

Globally

You can also register a component globally.
There will be no more type inference for props.
If there is no reason to do so, local import is recommended.

```ts
import { createApp } from 'vue'
import App from './App.vue'
import { plugin } from 'utterances-vue-component'

createApp(App).use(plugin).mount('#app')
```

```html
<template>
<Utterances
repo="TomokiMiyauci/me"
issue-term="pathname"
theme="github-light"
/>
</template>
```

## :dizzy: Install

### :package: Node.js

```bash
npm i utterances-vue-component
or
yarn add utterances-vue-component
```

### :globe_with_meridians: Browser

The module that bundles the dependencies is obtained from
[skypack](https://www.skypack.dev/view/utterances-vue-component).

import like this:

```tsx
import { Utterances } from 'https://cdn.skypack.dev/utterances-vue-component'
```

**peerDependency**

| package | version |
| ------- | -------- |
| `vue` | `^3.0.0` |

## API

### Props

It has a strict type definition.
No default value is set to respect the original behavior.

[Official document](https://utteranc.es/)

| Name | Type | Description |
| ------------- | ---------------------------- | -------------------------------------------------------------------------------------------------- |
| `repo` | `${String}/${String}` | Repository for Utterances to connect to. Expected value: `username/repo` |
| `theme` | `Theme` | The Utterance theme. |
| `label` | `string?` | Choose the label that will be assigned to issues created by Utterances. |
| `issueTerm` | `Term` &#124; `string[]`[^1] | The mapping between blog posts and GitHub issues. <td rowspan="2">One of them[^2]</td> |
| `issueNumber` | `number` | You configure Utterances to load a specific issue by number. Issues are not automatically created. |

```ts
declare type Theme =
| 'github-light'
| 'github-dark'
| 'preferred-color-scheme'
| 'github-dark-orange'
| 'icy-dark'
| 'dark-blue'
| 'photon-dark'
| 'boxy-light'
declare type Term = 'pathname' | 'url' | 'title' | 'og:title'
```
[^1]: If you chose "Issue title contains specific term", specify the specific term as string array.
[^2]: Unfortunately, props in vue cannot be exclusively defined. You can specify either an `issueTerm` or an `issueNumber`.
## :handshake: Contributing
Contributions, issues and feature requests are welcome!<br />Feel free to check
[issues](https://github.com/TomokiMiyauci/utterance-component/issues).
[Contributing guide](./.github/CONTRIBUTING.md)
## :seedling: Show your support
Give a ⭐️ if this project helped you!
<a href="https://www.patreon.com/tomoki_miyauci">
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
</a>
## :bulb: License
Copyright © 2021-present [TomokiMiyauci](https://github.com/TomokiMiyauci).
Released under the [MIT](./LICENSE) license
9 changes: 9 additions & 0 deletions packages/vue/_debug/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<Utterances
repo="TomokiMiyauci/me"
issue-term="pathname"
theme="github-light"
/>
</template>

<script setup lang="ts"></script>
5 changes: 5 additions & 0 deletions packages/vue/_debug/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createApp } from 'vue'
import App from './App.vue'
import { plugin } from '../lib/index'

createApp(App).use(plugin).mount('#app')
13 changes: 13 additions & 0 deletions packages/vue/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/_debug/main.ts"></script>
</body>
</html>
35 changes: 35 additions & 0 deletions packages/vue/lib/Utterances.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineComponent, PropType, onMounted, ref } from 'vue'
import type { LegacyRef } from 'react'
import { Theme, UtterancesProps, Repo, Term } from '@shared/types'
import { createScriptElement, putChildElement } from '@shared/util'

const Utterances = defineComponent({
props: {
repo: {
type: String as PropType<Repo>,
required: true
},
theme: {
type: String as PropType<Theme>,
required: true
},
label: String,
issueTerm: String as PropType<Term>,
issueNumber: Number
},

setup(props) {
const divRef = ref<HTMLDivElement>()
onMounted(() => {
if (!divRef.value) return

const scriptEl = createScriptElement(props as UtterancesProps)

divRef.value = putChildElement(divRef.value, scriptEl)
})

return () => <div ref={divRef as any as LegacyRef<HTMLDivElement>} />
}
})

export default Utterances
8 changes: 8 additions & 0 deletions packages/vue/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Utterances from './Utterances'
import { Plugin } from 'vue'

const plugin: Plugin = {
install: (app) => app.component('Utterances', Utterances)
}

export { Utterances, plugin }
49 changes: 49 additions & 0 deletions packages/vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "utterances-vue-component",
"description": "Type safety vue component for utterances",
"version": "0.0.0",
"license": "MIT",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.es.js"
}
},
"sideEffects": false,
"scripts": {
"cz": "yarn --cwd ../.. cz",
"commit": "yarn cz",
"prepare": "yarn --cwd ../..",
"dev": "vite",
"lint": "vue-tsc --noEmit",
"build": "yarn build:script && yarn build:types",
"build:script": "vite build",
"build:types": "dts-bundle-generator --no-banner --no-check --external-imports=vue -o dist/index.d.ts lib/index.ts",
"serve": "vite preview"
},
"peerDependencies": {
"vue": "^3.0.0"
},
"devDependencies": {
"@types/vfile-message": "^2.0.0",
"@vitejs/plugin-vue": "^1.2.4",
"@vitejs/plugin-vue-jsx": "^1.1.6",
"@vue/compiler-sfc": "^3.1.4",
"dts-bundle-generator": "^5.9.0",
"vue": "^3.1.4",
"vue-tsc": "^0.2.0"
},
"author": {
"name": "TomokiMiyauci",
"email": "development.operation6.6.6@gmail.com",
"url": "https://miyauchi.dev/"
},
"repository": {
"type": "git",
"url": "https://github.com/TomokiMiyauci/utterances-component.git",
"directory": "packages/vue"
}
}
5 changes: 5 additions & 0 deletions packages/vue/shims-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
28 changes: 28 additions & 0 deletions packages/vue/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"declaration": true,
"declarationDir": "dist",
"baseUrl": ".",
"paths": {
"@shared/*": ["../../*"]
}
},

"include": [
"lib/**/*.ts",
"lib/**/*.d.ts",
"lib/**/*.tsx",
"lib/**/*.vue",
"_debug/**/*.vue"
]
}
29 changes: 29 additions & 0 deletions packages/vue/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { peerDependencies } from './package.json'
import jsx from '@vitejs/plugin-vue-jsx'

const external = Object.keys(peerDependencies)

export default defineConfig({
resolve: {
alias: {
'@shared': resolve(__dirname, '..', '..')
}
},
plugins: [jsx(), vue()],
build: {
lib: {
entry: resolve(__dirname, 'lib', 'index.ts'),
formats: ['cjs', 'es'],
fileName: 'index'
},
rollupOptions: {
external,
output: {
format: 'cjs'
}
}
}
})

0 comments on commit 705c944

Please sign in to comment.