Skip to content

Commit

Permalink
feat(qrcode): add component p-qrcode
Browse files Browse the repository at this point in the history
  • Loading branch information
adenvt committed Mar 26, 2024
1 parent b0d0da2 commit c72d0e3
Show file tree
Hide file tree
Showing 16 changed files with 648 additions and 42 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@rushstack/eslint-patch": "1.7.2",
"@testing-library/jest-dom": "6.4.2",
"@testing-library/vue": "8.0.3",
"@types/html-escaper": "^3",
"@types/lodash-es": "4.17.12",
"@types/marked": "^5.0.1",
"@types/sanitize-html": "^2",
Expand Down Expand Up @@ -91,13 +92,15 @@
"defu": "6.1.4",
"fast-equals": "^5.0.0",
"fuse.js": "7.0.0",
"html-escaper": "^3.0.3",
"interactjs": "1.10.26",
"lodash-es": "4.17.21",
"marked": "^12.0.0",
"nanodelay": "2.0.2",
"pdfjs-dist": "^3.10.111",
"pdfjs-dist": "^3.11.174",
"postcss-hexrgba": "^2.1.0",
"postcss-lighten-darken": "^0.9.0",
"qr-code-styling": "^1.6.0-rc.1",
"scroll-into-view": "^1.16.2",
"tabbable": "6.2.0",
"vue-collapsed": "^1.2.5",
Expand Down
6 changes: 3 additions & 3 deletions packages/persona/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"import": "./dist/directive/index.mjs",
"types": "./dist/directive/index.d.ts"
},
"./components/*": "./dist/components/"
"./components/": "./dist/components/"
},
"typesVersions": {
"*": {
Expand Down Expand Up @@ -59,7 +59,7 @@
},
"dependencies": {
"@floating-ui/dom": "1.6.3",
"@jill64/universal-sanitizer": "^1.0.2",
"@jill64/universal-sanitizer": "1.2.7",
"@juggle/resize-observer": "3.4.0",
"@nuxt/kit": "3.10.3",
"@splidejs/splide": "4.1.4",
Expand All @@ -73,7 +73,7 @@
"core-js": "3",
"date-fns": "3.6.0",
"defu": "6.1.4",
"fast-equals": "^5.0.0",
"fast-equals": "5.0.1",
"fuse.js": "7.0.0",
"interactjs": "1.10.26",
"lodash-es": "4.17.21",
Expand Down
3 changes: 0 additions & 3 deletions packages/persona/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ export default defineNuxtModule<ModuleOptions>({
async setup (options, nuxt) {
const { resolve } = createResolver(import.meta.url)

// Add alias to unsupported ESM package
nuxt.options.alias['date-fns/locale'] = 'date-fns/esm/locale'

// Add font CDN
if (options.font) {
nuxt.options.app.head.link?.push(
Expand Down
4 changes: 4 additions & 0 deletions src/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ export default defineConfig({
text: 'Progressbar',
link: '/components/progressbar/',
},
{
text: 'Qrcode',
link: '/components/qrcode/',
},
{
text: 'Ringbar',
link: '/components/ringbar/',
Expand Down
28 changes: 15 additions & 13 deletions src/components/input-pin/InputPin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
:error="error"
@keydown="onKeyDown($event)"
@beforeinput.prevent="setValue(i - 1, $event)"
@keyup.left.stop.prevent="prevFocus"
@keyup.right.stop.prevent="nextFocus" />
@keydown.left.stop.prevent="prevFocus"
@keydown.right.stop.prevent="nextFocus" />
</div>
</template>

Expand Down Expand Up @@ -100,7 +100,10 @@ const classNames = computed(() => {
return result
})
const { next: nextFocus, prev: prevFocus } = useFocus(root, false)
const {
next: nextFocus,
prev: prevFocus,
} = useFocus(root, false)
const model = computed<string[]>({
get () {
Expand Down Expand Up @@ -138,19 +141,18 @@ function setValue (index: number, event: InputEvent) {
}
function onKeyDown (event: KeyboardEvent) {
const target = event.target as HTMLInputElement
if (!props.readonly && !props.disabled) {
const target = event.target as HTMLInputElement
if (props.readonly || props.disabled)
return
if (target.value && [...event.key].length === 1 && !event.ctrlKey && !event.metaKey) {
event.preventDefault()
if (target.value && [...event.key].length === 1 && !event.ctrlKey && !event.metaKey) {
event.preventDefault()
target.dispatchEvent(new InputEvent('beforeinput', { inputType: 'insertText', data: event.key }))
} else if (event.key === 'Backspace') {
event.preventDefault()
target.dispatchEvent(new InputEvent('beforeinput', { inputType: 'insertText', data: event.key }))
} else if (event.key === 'Backspace') {
event.preventDefault()
target.dispatchEvent(new InputEvent('beforeinput', { inputType: 'deleteContentBackward' }))
target.dispatchEvent(new InputEvent('beforeinput', { inputType: 'deleteContentBackward' }))
}
}
}
</script>
Expand Down
14 changes: 8 additions & 6 deletions src/components/page/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: Page with toggle expand for responsive purpose
---

<script setup>
import { withBase } from 'vitepress'
import pPage from './Page.vue'
import pSidebarMenu from '../sidebar-menu/SidebarMenu.vue'
import pSidebarBrand from '../sidebar/SidebarBrand.vue'
Expand All @@ -16,12 +17,13 @@ description: Page with toggle expand for responsive purpose
import IconUsers from '@privyid/persona-icon/vue/user-multiple/20.vue'
import IconSettings from '@privyid/persona-icon/vue/adjust/20.vue'
import IconMenu from '@privyid/persona-icon/vue/menu-burger/20.vue'
import IconEN from '../../public/assets/images/img-flag.svg'
import { defineMenu } from '../sidebar-menu'
import { ref } from 'vue-demi'

const model = ref(false)
const modelA = ref(false)
const IconEN = withBase('/assets/images/img-flag.svg')

const model = ref(false)
const modelA = ref(false)
const modelB = ref(false)

const menu = defineMenu([
Expand Down Expand Up @@ -92,8 +94,8 @@ description: Page with toggle expand for responsive purpose
},
{
condensed: true,
title: 'Quick Jump',
items: [
title : 'Quick Jump',
items : [
{
name : 'rejects',
label: 'Rejects',
Expand All @@ -108,7 +110,7 @@ description: Page with toggle expand for responsive purpose
},
{
bottom: true,
items: [
items : [
{
name : 'settings',
label: 'Settings',
Expand Down
11 changes: 5 additions & 6 deletions src/components/pdf-viewer/utils/use-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import type {
EventBus,
} from 'pdfjs-dist/web/pdf_viewer'
import useLoading from '../../overlay/utils/use-loading'
import { useClamp } from '@vueuse/math'
import { useClamp, useMax } from '@vueuse/math'
import { createEventHook } from '@vueuse/core'
import { type EventHook } from '@vueuse/shared'
import {
createEventBus,
createLinkService,
Expand All @@ -38,14 +37,14 @@ export function useViewer (container: Ref<HTMLDivElement>, viewer: Ref<HTMLDivEl

const totalPage = computed(() => pdfDoc.value?.numPages ?? 0)
const scale = useClamp(1, 0.1, 2)
const page = useClamp(1, 1, totalPage)
const page = useClamp(1, 1, useMax(totalPage, 1))
const loading = useLoading()
const ready = shallowRef(false)
const error = shallowRef<Error>()

const loadEvent: EventHook<PDFJS.PDFDocumentProxy> = createEventHook<PDFJS.PDFDocumentProxy>()
const errorEvent: EventHook<Error> = createEventHook<Error>()
const readyEvent: EventHook<PDFViewer> = createEventHook<PDFViewer>()
const loadEvent = createEventHook<PDFJS.PDFDocumentProxy>()
const errorEvent = createEventHook<Error>()
const readyEvent = createEventHook<PDFViewer>()

async function openDoc (url: string, password?: string, config: Partial<OpenDocConfig> = {}) {
loading.value = true
Expand Down
120 changes: 120 additions & 0 deletions src/components/qrcode/Qrcode.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { render } from '@testing-library/vue'
import * as canvas from '../signature-draw/__mocks__/canvas'
import pQrcode from './Qrcode.vue'
import { delay } from 'nanodelay'
import { vi } from 'vitest'
import QRCodeStyling from 'qr-code-styling'
import { nextTick, ref } from 'vue-demi'
import type * as VueUse from '@vueuse/core'
import type * as VueDemi from 'vue-demi'

const qrRender = vi.spyOn(QRCodeStyling.prototype, 'update')

vi.mock('../signature-draw/utils/canvas.ts', () => canvas)

vi.mock('@vueuse/core', async () => {
const vueuse = await vi.importActual('@vueuse/core')
const vueDemi = await vi.importActual('vue-demi')

return {
...vueuse as typeof VueUse,
watchDebounced: (vueDemi as typeof VueDemi).watch,
}
})

beforeEach(() => {
vi.spyOn(window.URL, 'createObjectURL')
.mockImplementation((file: File) => {
return `blob://${file.name}`
})

vi.spyOn(QRCodeStyling.prototype, '_getElement')
.mockReturnValue(Promise.resolve(document.createElement('canvas')))
})

afterEach(() => {
vi.restoreAllMocks()
})

it('should render properly', async () => {
const screen = render({
components: { pQrcode },
template : `
<pQrcode data="hello world" />
`,
})

const qr = screen.queryByTestId('qrcode')

await delay(1)

expect(qr).toBeInTheDocument()
expect(qrRender).toBeCalledTimes(1)
})

it('should re-render if prop changes', async () => {
const variant = ref('square')
const screen = render({
components: { pQrcode },
template : `
<pQrcode data="hello world" :variant="variant" />
`,
setup () {
return { variant }
},
})

const qr = screen.queryByTestId('qrcode')

await delay(1)

expect(qr).toBeInTheDocument()
expect(qrRender).toBeCalledTimes(1)

variant.value = 'dots'
await nextTick()
await delay(1)

expect(qrRender).toBeCalledTimes(2)
})

it('should able to bind the result value using v-model', async () => {
const model = ref()
const screen = render({
components: { pQrcode },
template : `
<pQrcode v-model="model" data="hello world" />
`,
setup () {
return { model }
},
})

const qr = screen.queryByTestId('qrcode')

await delay(1)

expect(qr).toBeInTheDocument()
expect(model.value).toBeInstanceOf(File)
})

it('should able to bind the result in base-64 value using v-model with modifier `.base64`', async () => {
const model = ref()
const screen = render({
components: { pQrcode },
template : `
<pQrcode v-model.base64="model" data="hello world" />
`,
setup () {
return { model }
},
})

const qr = screen.queryByTestId('qrcode')

await delay(1)

expect(qr).toBeInTheDocument()
expect(model.value).not.toBeInstanceOf(File)
expect(model.value).toStartWith('data:image/png;base64,')
})
Loading

0 comments on commit c72d0e3

Please sign in to comment.