feat: support attribute format for some properties (#33)

* feat: support attribute format for some properties

This allows users to set the locale, data source, and skin tone
emoji using HTML attributes as well as properties.

Fixes #7

* fix: increment bundlesize
This commit is contained in:
Nolan Lawson 2020-08-20 19:29:20 -07:00 committed by GitHub
parent f083ace332
commit 83e516ce21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 6 deletions

View File

@ -233,10 +233,10 @@ The `new Picker(options)` constructor supports several options:
Name | Type | Default | Description |
------ | ------ | ------ | ------ |
`customEmoji` | CustomEmoji[] | - | Array of custom emoji |
`dataSource` | string | "https://cdn.jsdelivr.net/npm/emojibase-data@5/en/data.json" | URL to fetch the emojibase data from |
`dataSource` | string | "https://cdn.jsdelivr.net/npm/emojibase-data@5/en/data.json" | URL to fetch the emojibase data from (`data-source` when used as an attribute) |
`i18n` | I18n | - | i18n object (see below for details) |
`locale` | string | "en" | Locale string |
`skinToneEmoji` | string | "🖐️" | The emoji to use for the skin tone picker |
`skinToneEmoji` | string | "🖐️" | The emoji to use for the skin tone picker (`skin-tone-emoji` when used as an attribute) |
@ -251,13 +251,26 @@ const picker = new Picker({
})
```
These values can also be set at runtime, e.g.:
These values can also be set at runtime:
```js
const picker = new Picker();
picker.dataSource = '/my-emoji.json';
```
Some values can also be set as declarative attributes:
```html
<emoji-picker
locale="fr"
data-source="/fr-emoji.json"
skin-tone-emoji="✌"
></emoji-picker>
```
Note that complex properties like `i18n` or `customEmoji` are not supported as attributes, because the DOM only
supports string attributes, not complex objects.
#### i18n structure
Here is the default English `i18n` object (`"en"` locale):

View File

@ -177,7 +177,7 @@
"bundlesize": [
{
"path": "./bundle.js",
"maxSize": "40 kB",
"maxSize": "40.5 kB",
"compression": "none"
},
{

View File

@ -15,6 +15,19 @@ export default class Picker extends SveltePicker {
log('disconnectedCallback')
this.$destroy()
}
static get observedAttributes () {
return ['locale', 'data-source', 'skin-tone-emoji'] // complex objects aren't supported, also use kebab-case
}
// via https://github.com/sveltejs/svelte/issues/3852#issuecomment-665037015
attributeChangedCallback (attrName, oldValue, newValue) {
super.attributeChangedCallback(
attrName.replace(/-([a-z])/g, (_, up) => up.toUpperCase()),
oldValue,
newValue
)
}
}
customElements.define('emoji-picker', Picker)

View File

@ -9,10 +9,10 @@ export default class Picker extends HTMLElement {
/**
*
* @param dataSource - URL to fetch the emojibase data from
* @param dataSource - URL to fetch the emojibase data from (`data-source` when used as an attribute)
* @param locale - Locale string
* @param i18n - i18n object (see below for details)
* @param skinToneEmoji - The emoji to use for the skin tone picker
* @param skinToneEmoji - The emoji to use for the skin tone picker (`skin-tone-emoji` when used as an attribute)
* @param customEmoji - Array of custom emoji
*/
constructor({

View File

@ -0,0 +1,47 @@
import { basicAfterEach, basicBeforeEach, FR_EMOJI, ALL_EMOJI, mockFrenchDataSource, tick } from '../shared'
import Picker from '../../../src/picker/PickerElement.js'
import { getByRole } from '@testing-library/dom'
describe('attributes tests', () => {
beforeEach(async () => {
basicBeforeEach()
mockFrenchDataSource()
})
afterEach(basicAfterEach)
test('setting initial locale/dataSource issues only one GET', async () => {
const picker = new Picker()
picker.setAttribute('locale', 'fr')
picker.setAttribute('data-source', FR_EMOJI)
document.body.appendChild(picker)
await tick(20)
expect(fetch).toHaveBeenCalledTimes(1)
expect(fetch).toHaveBeenLastCalledWith(FR_EMOJI, undefined)
expect(picker.locale).toEqual('fr')
expect(picker.dataSource).toEqual(FR_EMOJI)
expect(picker.getAttribute('locale')).toEqual('fr')
expect(picker.getAttribute('data-source')).toEqual(FR_EMOJI)
})
test('can set skintone emoji using an attribute', async () => {
const picker = new Picker()
picker.setAttribute('data-source', ALL_EMOJI)
picker.setAttribute('skin-tone-emoji', '✌')
document.body.appendChild(picker)
await tick(20)
expect(getByRole(picker.shadowRoot, 'button', { name: /Choose a skin tone/ }).innerHTML)
.toContain('✌')
expect(picker.skinToneEmoji).toEqual('✌')
expect(picker.getAttribute('skin-tone-emoji')).toEqual('✌')
expect(picker.locale).toEqual('en')
picker.setAttribute('skin-tone-emoji', '🏃')
await tick(20)
expect(getByRole(picker.shadowRoot, 'button', { name: /Choose a skin tone/ }).innerHTML)
.toContain('🏃')
expect(picker.skinToneEmoji).toEqual('🏃')
})
})