vue#defineCustomElement TypeScript Examples

The following examples show how to use vue#defineCustomElement. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: main.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
I18nHostElement = defineCustomElement(I18nHost)
Example #2
Source File: main.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
HelloI18nElement = defineCustomElement(HelloI18n)
Example #3
Source File: main.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
HelloBlockElement = defineCustomElement(HelloBlock)
Example #4
Source File: wc.test.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
test('basic', async () => {
  const i18n = createI18n<false>({
    legacy: false,
    locale: 'en',
    messages: {
      en: {
        hello: 'hello web components!'
      },
      ja: {
        hello: 'こんにちは Web コンポーネント!'
      }
    }
  })

  const Provider = defineCustomElement({
    setup() {
      provide(I18nInjectionKey, i18n)
      return () => h('my-consumer')
    }
  })
  customElements.define('my-provider', Provider)
  const Consumer = defineCustomElement({
    setup() {
      const { t } = useI18n()
      return () => h('div', t('hello'))
    }
  })
  customElements.define('my-consumer', Consumer)

  container.innerHTML = `<my-provider></my-provider>`
  await nextTick()
  const provider = container.childNodes[0] as VueElement
  const consumer = provider.shadowRoot!.childNodes[0] as VueElement
  expect(consumer.shadowRoot!.innerHTML).toBe(
    `<div>hello web components!</div>`
  )

  i18n.global.locale.value = 'ja'
  await nextTick()
  expect(consumer.shadowRoot!.innerHTML).toBe(
    `<div>こんにちは Web コンポーネント!</div>`
  )
})
Example #5
Source File: wc.test.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
test('custom blocks', async () => {
  const i18n = createI18n<false>({
    legacy: false,
    locale: 'en',
    messages: {
      en: {
        hello: 'hello web components!'
      },
      ja: {
        hello: 'こんにちは Web コンポーネント!'
      }
    }
  })

  const Provider = defineCustomElement({
    setup() {
      provide(I18nInjectionKey, i18n)
      return () => h('my-child-block')
    }
  })
  customElements.define('my-provider-block', Provider)
  const Child = defineCustomElement({
    setup() {
      const instance = getCurrentInstance()
      if (instance == null) {
        throw new Error()
      }
      const options = instance.type as ComponentOptions
      options.__i18n = [
        {
          locale: 'en',
          resource: { foo: 'foo!' }
        },
        {
          locale: 'ja',
          resource: { foo: 'ふー!' }
        }
      ]
      const { t } = useI18n({
        inheritLocale: true,
        useScope: 'local'
      })
      return () => h('div', t('foo'))
    }
  })
  customElements.define('my-child-block', Child)

  container.innerHTML = `<my-provider-block></my-provider-block>`
  await nextTick()
  const provider = container.childNodes[0] as VueElement
  const child = provider.shadowRoot!.childNodes[0] as VueElement
  expect(child.shadowRoot!.innerHTML).toBe(`<div>foo!</div>`)

  i18n.global.locale.value = 'ja'
  await nextTick()
  expect(child.shadowRoot!.innerHTML).toBe(`<div>ふー!</div>`)
})
Example #6
Source File: i18n.test.ts    From vue-i18n-next with MIT License 4 votes vote down vote up
describe('useI18n', () => {
  let org: any // eslint-disable-line @typescript-eslint/no-explicit-any
  let spy: any // eslint-disable-line @typescript-eslint/no-explicit-any
  beforeEach(() => {
    org = console.warn
    spy = jest.fn()
    console.warn = spy
  })
  afterEach(() => {
    console.warn = org
  })

  test('basic', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let composer: unknown
    const App = defineComponent({
      setup() {
        composer = useI18n({
          inheritLocale: false,
          locale: 'en',
          messages: {
            en: {
              hello: 'hello!'
            }
          }
        })
        return {}
      },
      template: `<p>foo</p>`
    })
    await mount(App, i18n)

    expect(i18n.global).not.toEqual(composer)
    expect((composer as Composer).locale.value).toEqual('en')
  })

  test('global scope', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let composer: unknown
    const App = defineComponent({
      setup() {
        composer = useI18n({ useScope: 'global' })
        return {}
      },
      template: `<p>foo</p>`
    })
    await mount(App, i18n)

    expect(i18n.global).toEqual(composer)
    expect((composer as Composer).locale.value).toEqual('ja')
  })

  test('parent scope', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let leaf: unknown
    let parent: unknown
    const App = defineComponent({
      components: {
        Leaf: {
          template: '<p>local</p>',
          setup() {
            leaf = useI18n({ useScope: 'parent' })
            return {}
          }
        }
      },
      setup() {
        parent = useI18n({
          inheritLocale: false,
          locale: 'en',
          messages: {
            en: {
              hello: 'hello!'
            }
          }
        })
        return {}
      },
      template: `<div>parent</div><Leaf />`
    })
    await mount(App, i18n)

    expect(i18n.global).not.toEqual(leaf)
    expect(i18n.global).not.toEqual(parent)
    expect(parent).toEqual(leaf)
    expect((leaf as Composer).locale.value).toEqual('en')
  })

  test('not found parent composer with parent scope', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let composer: unknown
    const App = defineComponent({
      components: {
        Leaf: {
          template: '<p>local</p>',
          setup() {
            composer = useI18n({ useScope: 'parent' })
            return {}
          }
        }
      },
      setup() {
        return {}
      },
      template: `<div>parent</div><Leaf />`
    })
    await mount(App, i18n)

    expect(i18n.global).toEqual(composer)
    expect((composer as Composer).locale.value).toEqual('ja')
  })

  test('empty options', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let composer: unknown
    const App = defineComponent({
      setup() {
        composer = useI18n()
        return {}
      },
      template: `<p>foo</p>`
    })
    await mount(App, i18n)

    expect(i18n.global).toEqual(composer)
    expect((composer as Composer).locale.value).toEqual('ja')
  })

  test('empty options, when have i18n custom blocks', async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let composer: unknown
    const App = defineComponent({
      setup() {
        const instance = getCurrentInstance()
        if (instance == null) {
          throw new Error()
        }
        const options = instance.type as ComponentOptions
        options.__i18n = [
          {
            locale: '',
            resource: { en: { hello: 'Hello,world!' } }
          },
          {
            locale: '',
            resource: { ja: { hello: 'こんにちは、世界!' } }
          }
        ] as any // eslint-disable-line @typescript-eslint/no-explicit-any
        composer = useI18n()
        return { t: (composer as Composer).t }
      },
      template: `<p>{{ t('hello', ['foo'], { locale: 'ja' }) }}</p>`
    })
    const { html } = await mount(App, i18n)

    expect(html()).toEqual('<p>こんにちは、世界!</p>')
    expect(i18n.global).not.toEqual(composer)
    expect((composer as Composer).locale.value).toEqual('ja')
  })

  test(errorMessages[I18nErrorCodes.MUST_BE_CALL_SETUP_TOP], async () => {
    let error = ''
    try {
      useI18n({})
    } catch (e) {
      error = e.message
    }
    expect(error).toEqual(errorMessages[I18nErrorCodes.MUST_BE_CALL_SETUP_TOP])
  })

  test(errorMessages[I18nErrorCodes.NOT_INSLALLED], async () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'ja',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    let error = ''
    const App = defineComponent({
      setup() {
        try {
          useI18n({})
        } catch (e) {
          error = e.message
        }
        return {}
      }
    })
    await mount(App, i18n, { installI18n: false })
    expect(error).toEqual(errorMessages[I18nErrorCodes.NOT_INSLALLED])
  })

  describe('On legacy', () => {
    describe('default', () => {
      test(
        errorMessages[I18nErrorCodes.NOT_AVAILABLE_IN_LEGACY_MODE],
        async () => {
          const i18n = createI18n({
            legacy: true,
            locale: 'ja',
            messages: {
              en: {
                hello: 'hello!'
              }
            }
          })

          let error = ''
          const App = defineComponent({
            setup() {
              try {
                useI18n({
                  locale: 'en',
                  messages: {
                    en: {
                      hello: 'hello!'
                    }
                  }
                })
              } catch (e) {
                error = e.message
              }
              return {}
            },
            template: `<p>foo</p>`
          })
          await mount(App, i18n)
          expect(error).toEqual(
            errorMessages[I18nErrorCodes.NOT_AVAILABLE_IN_LEGACY_MODE]
          )
        }
      )
    })

    describe('enable', () => {
      describe('t', () => {
        test('translation & locale changing', async () => {
          const i18n = createI18n({
            allowComposition: true,
            locale: 'ja',
            messages: {
              en: {
                hello: 'hello!'
              },
              ja: {
                hello: 'こんにちは!'
              }
            }
          })

          const App = defineComponent({
            setup() {
              const { locale, t } = useI18n()
              return { locale, t }
            },
            template: `<p>{{ t('hello') }}</p>`
          })
          const { html } = await mount(App, i18n)
          expect(html()).toEqual('<p>こんにちは!</p>')

          i18n.global.locale = 'en'
          await nextTick()
          expect(html()).toEqual('<p>hello!</p>')
        })

        test('local scope', async () => {
          const i18n = createI18n({
            allowComposition: true,
            locale: 'en',
            messages: {
              en: {
                hello: 'hello!'
              },
              ja: {}
            }
          })

          const App = defineComponent({
            setup() {
              const { locale, t } = useI18n({
                useScope: 'local',
                messages: {
                  en: {
                    world: 'world!'
                  },
                  ja: {
                    world: '世界!'
                  }
                }
              })
              return { locale, t }
            },
            i18n: {},
            template: `<p>{{ locale }}:{{ t('world') }}</p>`
          })
          const { html } = await mount(App, i18n)
          expect(html()).toEqual('<p>en:world!</p>')

          i18n.global.locale = 'ja'
          await nextTick()
          expect(html()).toEqual('<p>ja:世界!</p>')
        })

        test('use i18n option', async () => {
          const i18n = createI18n({
            allowComposition: true,
            locale: 'en',
            messages: {
              en: {
                hello: 'hello!'
              },
              ja: {}
            }
          })

          const App = defineComponent({
            setup() {
              const { locale, t } = useI18n({
                useScope: 'local'
              })
              return { locale, t }
            },
            i18n: {
              messages: {
                en: {
                  world: 'world!'
                },
                ja: {
                  world: '世界!'
                }
              }
            },
            template: `<p>{{ locale }}:{{ t('world') }}</p>`
          })
          const { html } = await mount(App, i18n)
          expect(html()).toEqual('<p>en:world!</p>')
        })

        test('use custom block', async () => {
          const i18n = createI18n({
            allowComposition: true,
            locale: 'ja',
            messages: {
              en: {
                hello: 'hello!'
              },
              ja: {}
            }
          })

          const App = defineComponent({
            setup() {
              const instance = getCurrentInstance()
              if (instance == null) {
                throw new Error()
              }
              const options = instance.type as ComponentOptions
              options.__i18n = [
                {
                  locale: 'ja',
                  resource: {
                    hello: 'こんにちは!'
                  }
                }
              ]
              const { locale, t } = useI18n({
                inheritLocale: true,
                useScope: 'local'
              })
              return { locale, t }
            },
            template: `<p>{{ locale }}:{{ t('hello') }}</p>`
          })
          const { html } = await mount(App, i18n)
          expect(html()).toEqual('<p>ja:こんにちは!</p>')
        })

        test('not defined i18n option in local scope', async () => {
          const i18n = createI18n({
            allowComposition: true,
            locale: 'en',
            messages: {
              en: {
                hello: 'hello!'
              }
            }
          })

          let error = ''
          const App = defineComponent({
            setup() {
              try {
                useI18n({ useScope: 'local' })
              } catch (e) {
                error = e.message
              }
              return {}
            }
          })
          await mount(App, i18n)
          expect(error).toEqual(
            errorMessages[
              I18nErrorCodes.MUST_DEFINE_I18N_OPTION_IN_ALLOW_COMPOSITION
            ]
          )
        })
      })
    })

    describe('d', () => {
      test('datetime formatting', async () => {
        const i18n = createI18n({
          allowComposition: true,
          locale: 'en-US',
          fallbackLocale: ['ja-JP'],
          datetimeFormats: {
            'en-US': {
              short: {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                timeZone: 'America/New_York'
              }
            },
            'ja-JP': {
              long: {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                timeZone: 'Asia/Tokyo'
              },
              short: {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                timeZone: 'Asia/Tokyo'
              }
            }
          }
        })

        const App = defineComponent({
          setup() {
            const { d } = useI18n()
            const dt = new Date(Date.UTC(2012, 11, 20, 3, 0, 0))
            return { d, dt }
          },
          template: `<p>{{ d(dt, 'long') }}</p>`
        })
        const { html } = await mount(App, i18n)
        expect(html()).toEqual('<p>2012/12/20 12:00:00</p>')
      })
    })

    describe('n', () => {
      test('number formatting', async () => {
        const i18n = createI18n({
          allowComposition: true,
          locale: 'en-US',
          fallbackLocale: ['ja-JP'],
          numberFormats: {
            'en-US': {
              currency: {
                style: 'currency',
                currency: 'USD',
                currencyDisplay: 'symbol'
              },
              decimal: {
                style: 'decimal',
                useGrouping: false
              }
            },
            'ja-JP': {
              currency: {
                style: 'currency',
                currency: 'JPY' /*, currencyDisplay: 'symbol'*/
              },
              numeric: {
                style: 'decimal',
                useGrouping: false
              },
              percent: {
                style: 'percent',
                useGrouping: false
              }
            }
          }
        })

        const App = defineComponent({
          setup() {
            const { n } = useI18n()
            const value = 0.99
            return { n, value }
          },
          template: `<p>{{ n(value, { key: 'percent' }) }}</p>`
        })
        const { html } = await mount(App, i18n)
        expect(html()).toEqual('<p>99%</p>')
      })
    })
  })

  test(errorMessages[I18nErrorCodes.NOT_INSLALLED_WITH_PROVIDE], async () => {
    const Provider = defineCustomElement({
      setup() {
        createI18n<false>({ legacy: false })
        return () => h('my-consumer')
      }
    })
    customElements.define('my-provider', Provider)

    let error = ''
    const Consumer = defineCustomElement({
      setup() {
        try {
          useI18n()
        } catch (e) {
          error = e.message
        }
        return () => h('div')
      }
    })
    customElements.define('my-consumer', Consumer)

    container.innerHTML = `<my-provider><my-provider>`
    await nextTick()

    expect(error).toEqual(
      errorMessages[I18nErrorCodes.NOT_INSLALLED_WITH_PROVIDE]
    )
  })
})