innoboxrr-form-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/index.js +32 -0
- package/package.json +41 -0
- package/src/files.js +160 -0
- package/src/theme.js +139 -0
- package/src/timezone.js +434 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# innoboxrr-form-core
|
|
2
|
+
|
|
3
|
+
Lo que comparten [`innoboxrr-form-elements`](../form-elements) (Vue) y
|
|
4
|
+
[`innoboxrr-react-form-elements`](../react-form-elements) (React) y no depende
|
|
5
|
+
de ningún framework.
|
|
6
|
+
|
|
7
|
+
Estaba duplicado en los dos paquetes, que es exactamente como dos copias
|
|
8
|
+
empiezan a divergir.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
npm i innoboxrr-form-core
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Tema
|
|
15
|
+
|
|
16
|
+
Antes cada componente llevaba su cadena CSS incrustada como valor por defecto
|
|
17
|
+
de `customClass` —repetida en los dos paquetes— y el código que genera
|
|
18
|
+
`larapack-generator` esperaba `inputClass` y `buttonClass` de un mixin global
|
|
19
|
+
que la aplicación anfitriona tenía que registrar sin que nada lo dijera.
|
|
20
|
+
|
|
21
|
+
Ahora es un mapa de tokens que la aplicación ajusta **una vez**, al arrancar:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import { setTheme } from 'innoboxrr-form-core'
|
|
25
|
+
|
|
26
|
+
setTheme({
|
|
27
|
+
input: 'form-control',
|
|
28
|
+
select: 'form-select',
|
|
29
|
+
button: 'btn btn-primary',
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Los tokens:
|
|
34
|
+
|
|
35
|
+
| Grupo | Tokens |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Envoltorios | `field`, `fieldInner`, `label`, `help`, `helpIcon`, `error` |
|
|
38
|
+
| Controles | `input`, `select`, `textarea`, `checkbox`, `radio`, `file` |
|
|
39
|
+
| Botones | `button`, `buttonSecondary`, `buttonDanger`, `buttonLink` |
|
|
40
|
+
|
|
41
|
+
Los valores de fábrica son los de UIkit + Tailwind que ya usaba el ecosistema,
|
|
42
|
+
así que actualizar no cambia nada de aspecto.
|
|
43
|
+
|
|
44
|
+
`customClass` sigue existiendo y **reemplaza** al token, para el caso puntual.
|
|
45
|
+
Antes unos controles lo reemplazaban y otros lo sumaban a una clase incrustada;
|
|
46
|
+
ahora se comportan todos igual.
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import { getTheme, resetTheme, onThemeChange, classFor } from 'innoboxrr-form-core'
|
|
50
|
+
|
|
51
|
+
getTheme() // el tema completo
|
|
52
|
+
getTheme('input') // la clase de un token
|
|
53
|
+
classFor('input', c) // el token, salvo que llegue customClass
|
|
54
|
+
resetTheme() // vuelve a fábrica (sobre todo para pruebas)
|
|
55
|
+
onThemeChange(fn) // devuelve la función para dejar de escuchar
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Los dos paquetes de componentes se suscriben, así que **un `setTheme` en
|
|
59
|
+
caliente repinta lo que ya esté montado**: leerlo directamente no lo haría,
|
|
60
|
+
porque el tema es estado de módulo, fuera del framework.
|
|
61
|
+
|
|
62
|
+
## Archivos
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import { describeFiles, sizeParser, isImage } from 'innoboxrr-form-core'
|
|
66
|
+
|
|
67
|
+
describeFiles(files, { maxSize: 2048, validMimes: ['image/png'] })
|
|
68
|
+
// [{ file, name, size, type, preview, uploaded, validation, errors, path, id }]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`describeFiles` **no toca los `File`**. La versión anterior les escribía las
|
|
72
|
+
propiedades encima con `Object.assign`: el `File` es del navegador y no es
|
|
73
|
+
sitio para campos inventados, y así no se podía describir el mismo archivo dos
|
|
74
|
+
veces con reglas distintas. El original sigue a mano en `.file`, que es lo que
|
|
75
|
+
hay que meter en el `FormData`.
|
|
76
|
+
|
|
77
|
+
`validateFiles` es la misma función devolviendo una promesa, por compatibilidad.
|
|
78
|
+
|
|
79
|
+
La vista previa de lo que no es imagen es un `data:` URI. Antes era una URL de
|
|
80
|
+
`icon-library.com`: cada archivo disparaba una petición a un tercero que puede
|
|
81
|
+
caerse o cambiar.
|
|
82
|
+
|
|
83
|
+
## Zonas horarias
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { timezones } from 'innoboxrr-form-core'
|
|
87
|
+
// [{ label: 'America/Mexico_City', value: 'America/Mexico_City' }, ...]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Pruebas
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
npm test
|
|
94
|
+
```
|
package/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* innoboxrr-form-core
|
|
3
|
+
*
|
|
4
|
+
* Lo que comparten innoboxrr-form-elements y innoboxrr-react-form-elements y
|
|
5
|
+
* no depende de ningun framework: el tema, la validacion de archivos y la
|
|
6
|
+
* lista de zonas horarias.
|
|
7
|
+
*
|
|
8
|
+
* Estaba duplicado en los dos paquetes, que es exactamente como dos copias
|
|
9
|
+
* empiezan a divergir.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
classFor,
|
|
14
|
+
defaultTheme,
|
|
15
|
+
getTheme,
|
|
16
|
+
onThemeChange,
|
|
17
|
+
resetTheme,
|
|
18
|
+
setTheme,
|
|
19
|
+
} from './src/theme.js'
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
FILE_ICON,
|
|
23
|
+
describeFiles,
|
|
24
|
+
errorsFor,
|
|
25
|
+
isImage,
|
|
26
|
+
isVideo,
|
|
27
|
+
previewFor,
|
|
28
|
+
sizeParser,
|
|
29
|
+
validateFiles,
|
|
30
|
+
} from './src/files.js'
|
|
31
|
+
|
|
32
|
+
export { default as timezones } from './src/timezone.js'
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "innoboxrr-form-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "El nucleo agnostico de los formularios innoboxrr: tema, archivos y zonas horarias.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js",
|
|
9
|
+
"./theme": "./src/theme.js",
|
|
10
|
+
"./files": "./src/files.js",
|
|
11
|
+
"./timezone": "./src/timezone.js",
|
|
12
|
+
"./src/*": "./src/*"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"index.js",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/innoboxrr/form-core.git"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"form",
|
|
29
|
+
"theme",
|
|
30
|
+
"innoboxrr"
|
|
31
|
+
],
|
|
32
|
+
"author": "Homero Raul Vargas Cruz",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"jsdom": "^25.0.0",
|
|
39
|
+
"vitest": "^3.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/files.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validación y descripción de archivos, antes de subirlos.
|
|
3
|
+
*
|
|
4
|
+
* No toca el DOM ni depende de ningún framework: entra una lista de `File` y
|
|
5
|
+
* sale una lista de descriptores.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* El icono genérico de un archivo sin vista previa.
|
|
10
|
+
*
|
|
11
|
+
* Antes esto era una URL de icon-library.com: cada archivo que no fuera imagen
|
|
12
|
+
* disparaba una petición a un tercero, que además puede caerse o cambiar. Un
|
|
13
|
+
* data URI no sale del navegador.
|
|
14
|
+
*/
|
|
15
|
+
export const FILE_ICON = 'data:image/svg+xml;utf8,'
|
|
16
|
+
+ encodeURIComponent(
|
|
17
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">'
|
|
18
|
+
+ '<path fill="#cbd5e1" d="M12 4h16l10 10v30H12z"/>'
|
|
19
|
+
+ '<path fill="#94a3b8" d="M28 4l10 10H28z"/>'
|
|
20
|
+
+ '</svg>'
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const IMAGE_TYPES = ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/avif']
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {object} FileRules
|
|
27
|
+
* @property {number} [maxSize] bytes; 0 o ausente significa sin límite
|
|
28
|
+
* @property {string[]} [validMimes] lista blanca; ausente significa cualquiera
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {object} FileEntry
|
|
33
|
+
* @property {File} file
|
|
34
|
+
* @property {string} name
|
|
35
|
+
* @property {number} size
|
|
36
|
+
* @property {string} type
|
|
37
|
+
* @property {string} preview
|
|
38
|
+
* @property {boolean} uploaded
|
|
39
|
+
* @property {boolean} validation
|
|
40
|
+
* @property {string[]} errors
|
|
41
|
+
* @property {string|undefined} path
|
|
42
|
+
* @property {string|number|undefined} id
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {File} file
|
|
47
|
+
* @returns {boolean}
|
|
48
|
+
*/
|
|
49
|
+
export function isImage(file) {
|
|
50
|
+
return Boolean(file?.type?.startsWith('image/'))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {File} file
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
export function isVideo(file) {
|
|
58
|
+
return Boolean(file?.type?.startsWith('video/'))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {File} file
|
|
63
|
+
* @param {FileRules} rules
|
|
64
|
+
* @returns {string[]}
|
|
65
|
+
*/
|
|
66
|
+
export function errorsFor(file, rules = {}) {
|
|
67
|
+
const errors = []
|
|
68
|
+
|
|
69
|
+
if (Array.isArray(rules.validMimes) && ! rules.validMimes.includes(file?.type)) {
|
|
70
|
+
errors.push('failMimeValidation')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (rules.maxSize && file?.size > rules.maxSize) {
|
|
74
|
+
errors.push('failMaxSizeValidation')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return errors
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* La vista previa de un archivo.
|
|
82
|
+
*
|
|
83
|
+
* `URL.createObjectURL` no existe en Node, ni en jsdom, ni en un render de
|
|
84
|
+
* servidor. Sin la guarda, validar una imagen fuera del navegador lanzaba.
|
|
85
|
+
*
|
|
86
|
+
* @param {File} file
|
|
87
|
+
* @returns {string}
|
|
88
|
+
*/
|
|
89
|
+
export function previewFor(file) {
|
|
90
|
+
if (! IMAGE_TYPES.includes(file?.type)) {
|
|
91
|
+
return FILE_ICON
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (typeof URL === 'undefined' || typeof URL.createObjectURL !== 'function') {
|
|
95
|
+
return FILE_ICON
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return URL.createObjectURL(file)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Describe cada archivo sin tocarlo.
|
|
103
|
+
*
|
|
104
|
+
* La versión anterior escribía las propiedades **sobre el propio File** con
|
|
105
|
+
* `Object.assign`. Funcionaba, pero dejaba objetos del navegador con campos
|
|
106
|
+
* inventados y hacía imposible describir el mismo archivo dos veces con reglas
|
|
107
|
+
* distintas. El `File` original sigue disponible en `.file`, que es lo que hay
|
|
108
|
+
* que meter en el `FormData`.
|
|
109
|
+
*
|
|
110
|
+
* @param {File[]} files
|
|
111
|
+
* @param {FileRules} rules
|
|
112
|
+
* @returns {Promise<FileEntry[]>}
|
|
113
|
+
*/
|
|
114
|
+
export function validateFiles(files = [], rules = {}) {
|
|
115
|
+
return Promise.resolve(describeFiles(files, rules))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* La versión síncrona. `validateFiles` devuelve una promesa por compatibilidad
|
|
120
|
+
* con quien ya la esperaba, pero aquí no hay nada asíncrono.
|
|
121
|
+
*
|
|
122
|
+
* @param {File[]} files
|
|
123
|
+
* @param {FileRules} rules
|
|
124
|
+
* @returns {FileEntry[]}
|
|
125
|
+
*/
|
|
126
|
+
export function describeFiles(files = [], rules = {}) {
|
|
127
|
+
return Array.from(files ?? []).map((file) => {
|
|
128
|
+
const errors = errorsFor(file, rules)
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
file,
|
|
132
|
+
name: file?.name ?? '',
|
|
133
|
+
size: file?.size ?? 0,
|
|
134
|
+
type: file?.type ?? '',
|
|
135
|
+
preview: previewFor(file),
|
|
136
|
+
uploaded: false,
|
|
137
|
+
validation: errors.length === 0,
|
|
138
|
+
errors,
|
|
139
|
+
path: undefined,
|
|
140
|
+
id: undefined,
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Bytes en algo legible.
|
|
147
|
+
*
|
|
148
|
+
* @param {number} bytes
|
|
149
|
+
* @returns {string}
|
|
150
|
+
*/
|
|
151
|
+
export function sizeParser(bytes) {
|
|
152
|
+
if (! bytes) {
|
|
153
|
+
return '0 Byte'
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const units = ['Bytes', 'KB', 'MB', 'GB', 'TB']
|
|
157
|
+
const unit = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
|
|
158
|
+
|
|
159
|
+
return `${Math.round(bytes / Math.pow(1024, unit))} ${units[unit]}`
|
|
160
|
+
}
|
package/src/theme.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las clases CSS de los formularios, en un solo sitio.
|
|
3
|
+
*
|
|
4
|
+
* Antes cada componente llevaba su cadena incrustada como valor por defecto de
|
|
5
|
+
* `customClass`, repetida en los dos paquetes; y el codigo generado por
|
|
6
|
+
* larapack esperaba `inputClass` y `buttonClass` de un mixin global que la
|
|
7
|
+
* aplicacion anfitriona tenia que registrar sin que nada lo dijera.
|
|
8
|
+
*
|
|
9
|
+
* Ahora hay un tema: un mapa de tokens que la aplicacion ajusta una vez, al
|
|
10
|
+
* arrancar, y que leen los dos paquetes de componentes.
|
|
11
|
+
*
|
|
12
|
+
* import { setTheme } from 'innoboxrr-form-core'
|
|
13
|
+
*
|
|
14
|
+
* setTheme({ input: 'form-control', button: 'btn btn-primary' })
|
|
15
|
+
*
|
|
16
|
+
* Un componente sigue admitiendo `customClass` para el caso puntual; lo que
|
|
17
|
+
* cambia es que ya no es la unica forma de cambiar el aspecto de todo.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {Record<string, string>} Theme
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** @type {Theme} */
|
|
25
|
+
export const defaultTheme = {
|
|
26
|
+
// ENVOLTORIOS
|
|
27
|
+
field: 'uk-margin',
|
|
28
|
+
fieldInner: 'uk-inline uk-width-1-1',
|
|
29
|
+
label: 'ml-2 text-sm font-medium text-gray-900 dark:text-white',
|
|
30
|
+
help: 'cursor-pointer',
|
|
31
|
+
helpIcon: 'fa-solid fa-circle-question',
|
|
32
|
+
error: 'fe-input-error text-red-600 font-bold',
|
|
33
|
+
|
|
34
|
+
// CONTROLES
|
|
35
|
+
input: 'uk-input uk-form-large uk-border-rounded',
|
|
36
|
+
select: 'uk-select uk-form-large uk-border-rounded',
|
|
37
|
+
textarea: 'uk-textarea uk-form-large uk-border-rounded',
|
|
38
|
+
checkbox: 'uk-checkbox',
|
|
39
|
+
radio: 'uk-radio',
|
|
40
|
+
file: 'uk-input uk-form-large uk-border-rounded',
|
|
41
|
+
|
|
42
|
+
// BOTONES
|
|
43
|
+
button: 'uk-button uk-width-1-1 button',
|
|
44
|
+
buttonSecondary: 'uk-button uk-button-default',
|
|
45
|
+
buttonDanger: 'uk-button uk-button-danger',
|
|
46
|
+
buttonLink: 'uk-button uk-button-link',
|
|
47
|
+
|
|
48
|
+
// NAVEGACION
|
|
49
|
+
//
|
|
50
|
+
// Estos no vienen de UIkit a proposito. El codigo generado por larapack
|
|
51
|
+
// pintaba las migas con un <BreadcrumbsComponent> que no existe en ningun
|
|
52
|
+
// paquete del ecosistema: cada aplicacion tenia que registrarlo
|
|
53
|
+
// globalmente sin que nada lo declarara, y la rama React directamente no
|
|
54
|
+
// tenia migas. Con estos tokens el componente se genera dentro del modulo
|
|
55
|
+
// y se estiliza desde aqui, como todo lo demas.
|
|
56
|
+
actionMenu: 'flex items-center gap-3',
|
|
57
|
+
actionMenuItem: 'text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300',
|
|
58
|
+
actionMenuDanger: 'text-sm text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300',
|
|
59
|
+
|
|
60
|
+
breadcrumb: 'flex items-center flex-wrap gap-2 text-sm mb-4',
|
|
61
|
+
breadcrumbLink: 'text-slate-500 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100',
|
|
62
|
+
breadcrumbCurrent: 'font-medium text-slate-900 dark:text-slate-100',
|
|
63
|
+
breadcrumbSeparator: 'text-slate-300 dark:text-slate-600 select-none',
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** @type {Theme} */
|
|
67
|
+
let theme = { ...defaultTheme }
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Los oyentes existen para que un componente ya montado se entere de un cambio
|
|
71
|
+
* de tema. Sin esto, `setTheme` en caliente solo afectaria a lo que se montara
|
|
72
|
+
* despues.
|
|
73
|
+
*
|
|
74
|
+
* @type {Set<(theme: Theme) => void>}
|
|
75
|
+
*/
|
|
76
|
+
const listeners = new Set()
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Ajusta el tema. Se mezcla con el actual, asi que se puede cambiar un token
|
|
80
|
+
* sin repetir los demas.
|
|
81
|
+
*
|
|
82
|
+
* @param {Partial<Theme>} tokens
|
|
83
|
+
* @returns {Theme}
|
|
84
|
+
*/
|
|
85
|
+
export function setTheme(tokens = {}) {
|
|
86
|
+
theme = { ...theme, ...tokens }
|
|
87
|
+
|
|
88
|
+
listeners.forEach((listener) => listener(theme))
|
|
89
|
+
|
|
90
|
+
return theme
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Devuelve el tema completo, o la clase de un token.
|
|
95
|
+
*
|
|
96
|
+
* @param {string} [token]
|
|
97
|
+
* @returns {Theme|string}
|
|
98
|
+
*/
|
|
99
|
+
export function getTheme(token) {
|
|
100
|
+
return token === undefined ? theme : (theme[token] ?? '')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* La clase de un control, dejando que `customClass` mande cuando llegue.
|
|
105
|
+
*
|
|
106
|
+
* Es lo que llaman los componentes: el token da el aspecto de todo el
|
|
107
|
+
* proyecto, y `customClass` resuelve el caso puntual.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} token
|
|
110
|
+
* @param {string|null|undefined} customClass
|
|
111
|
+
* @returns {string}
|
|
112
|
+
*/
|
|
113
|
+
export function classFor(token, customClass) {
|
|
114
|
+
return customClass ?? getTheme(token)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Vuelve a los valores de fabrica. Sobre todo para las pruebas: un tema es
|
|
119
|
+
* estado de modulo, y sin esto una prueba se filtraria a la siguiente.
|
|
120
|
+
*
|
|
121
|
+
* @returns {Theme}
|
|
122
|
+
*/
|
|
123
|
+
export function resetTheme() {
|
|
124
|
+
theme = { ...defaultTheme }
|
|
125
|
+
|
|
126
|
+
listeners.forEach((listener) => listener(theme))
|
|
127
|
+
|
|
128
|
+
return theme
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {(theme: Theme) => void} listener
|
|
133
|
+
* @returns {() => void} para dejar de escuchar
|
|
134
|
+
*/
|
|
135
|
+
export function onThemeChange(listener) {
|
|
136
|
+
listeners.add(listener)
|
|
137
|
+
|
|
138
|
+
return () => listeners.delete(listener)
|
|
139
|
+
}
|
package/src/timezone.js
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
const timezones = [
|
|
2
|
+
{ label: 'Africa/Abidjan', value: 'Africa/Abidjan' },
|
|
3
|
+
{ label: 'Africa/Accra', value: 'Africa/Accra' },
|
|
4
|
+
{ label: 'Africa/Addis_Ababa', value: 'Africa/Addis_Ababa' },
|
|
5
|
+
{ label: 'Africa/Algiers', value: 'Africa/Algiers' },
|
|
6
|
+
{ label: 'Africa/Asmara', value: 'Africa/Asmara' },
|
|
7
|
+
{ label: 'Africa/Bamako', value: 'Africa/Bamako' },
|
|
8
|
+
{ label: 'Africa/Bangui', value: 'Africa/Bangui' },
|
|
9
|
+
{ label: 'Africa/Banjul', value: 'Africa/Banjul' },
|
|
10
|
+
{ label: 'Africa/Bissau', value: 'Africa/Bissau' },
|
|
11
|
+
{ label: 'Africa/Blantyre', value: 'Africa/Blantyre' },
|
|
12
|
+
{ label: 'Africa/Brazzaville', value: 'Africa/Brazzaville' },
|
|
13
|
+
{ label: 'Africa/Bujumbura', value: 'Africa/Bujumbura' },
|
|
14
|
+
{ label: 'Africa/Cairo', value: 'Africa/Cairo' },
|
|
15
|
+
{ label: 'Africa/Casablanca', value: 'Africa/Casablanca' },
|
|
16
|
+
{ label: 'Africa/Ceuta', value: 'Africa/Ceuta' },
|
|
17
|
+
{ label: 'Africa/Conakry', value: 'Africa/Conakry' },
|
|
18
|
+
{ label: 'Africa/Dakar', value: 'Africa/Dakar' },
|
|
19
|
+
{ label: 'Africa/Dar_es_Salaam', value: 'Africa/Dar_es_Salaam' },
|
|
20
|
+
{ label: 'Africa/Djibouti', value: 'Africa/Djibouti' },
|
|
21
|
+
{ label: 'Africa/Douala', value: 'Africa/Douala' },
|
|
22
|
+
{ label: 'Africa/El_Aaiun', value: 'Africa/El_Aaiun' },
|
|
23
|
+
{ label: 'Africa/Freetown', value: 'Africa/Freetown' },
|
|
24
|
+
{ label: 'Africa/Gaborone', value: 'Africa/Gaborone' },
|
|
25
|
+
{ label: 'Africa/Harare', value: 'Africa/Harare' },
|
|
26
|
+
{ label: 'Africa/Johannesburg', value: 'Africa/Johannesburg' },
|
|
27
|
+
{ label: 'Africa/Juba', value: 'Africa/Juba' },
|
|
28
|
+
{ label: 'Africa/Kampala', value: 'Africa/Kampala' },
|
|
29
|
+
{ label: 'Africa/Khartoum', value: 'Africa/Khartoum' },
|
|
30
|
+
{ label: 'Africa/Kigali', value: 'Africa/Kigali' },
|
|
31
|
+
{ label: 'Africa/Kinshasa', value: 'Africa/Kinshasa' },
|
|
32
|
+
{ label: 'Africa/Lagos', value: 'Africa/Lagos' },
|
|
33
|
+
{ label: 'Africa/Libreville', value: 'Africa/Libreville' },
|
|
34
|
+
{ label: 'Africa/Lome', value: 'Africa/Lome' },
|
|
35
|
+
{ label: 'Africa/Luanda', value: 'Africa/Luanda' },
|
|
36
|
+
{ label: 'Africa/Lubumbashi', value: 'Africa/Lubumbashi' },
|
|
37
|
+
{ label: 'Africa/Lusaka', value: 'Africa/Lusaka' },
|
|
38
|
+
{ label: 'Africa/Malabo', value: 'Africa/Malabo' },
|
|
39
|
+
{ label: 'Africa/Maputo', value: 'Africa/Maputo' },
|
|
40
|
+
{ label: 'Africa/Maseru', value: 'Africa/Maseru' },
|
|
41
|
+
{ label: 'Africa/Mbabane', value: 'Africa/Mbabane' },
|
|
42
|
+
{ label: 'Africa/Mogadishu', value: 'Africa/Mogadishu' },
|
|
43
|
+
{ label: 'Africa/Monrovia', value: 'Africa/Monrovia' },
|
|
44
|
+
{ label: 'Africa/Nairobi', value: 'Africa/Nairobi' },
|
|
45
|
+
{ label: 'Africa/Ndjamena', value: 'Africa/Ndjamena' },
|
|
46
|
+
{ label: 'Africa/Niamey', value: 'Africa/Niamey' },
|
|
47
|
+
{ label: 'Africa/Nouakchott', value: 'Africa/Nouakchott' },
|
|
48
|
+
{ label: 'Africa/Ouagadougou', value: 'Africa/Ouagadougou' },
|
|
49
|
+
{ label: 'Africa/Porto-Novo', value: 'Africa/Porto-Novo' },
|
|
50
|
+
{ label: 'Africa/Sao_Tome', value: 'Africa/Sao_Tome' },
|
|
51
|
+
{ label: 'Africa/Tripoli', value: 'Africa/Tripoli' },
|
|
52
|
+
{ label: 'Africa/Tunis', value: 'Africa/Tunis' },
|
|
53
|
+
{ label: 'Africa/Windhoek', value: 'Africa/Windhoek' },
|
|
54
|
+
|
|
55
|
+
{ label: 'America/Adak', value: 'America/Adak' },
|
|
56
|
+
{ label: 'America/Anchorage', value: 'America/Anchorage' },
|
|
57
|
+
{ label: 'America/Anguilla', value: 'America/Anguilla' },
|
|
58
|
+
{ label: 'America/Antigua', value: 'America/Antigua' },
|
|
59
|
+
{ label: 'America/Araguaina', value: 'America/Araguaina' },
|
|
60
|
+
{ label: 'America/Argentina/Buenos_Aires', value: 'America/Argentina/Buenos_Aires' },
|
|
61
|
+
{ label: 'America/Argentina/Catamarca', value: 'America/Argentina/Catamarca' },
|
|
62
|
+
{ label: 'America/Argentina/Cordoba', value: 'America/Argentina/Cordoba' },
|
|
63
|
+
{ label: 'America/Argentina/Jujuy', value: 'America/Argentina/Jujuy' },
|
|
64
|
+
{ label: 'America/Argentina/La_Rioja', value: 'America/Argentina/La_Rioja' },
|
|
65
|
+
{ label: 'America/Argentina/Mendoza', value: 'America/Argentina/Mendoza' },
|
|
66
|
+
{ label: 'America/Argentina/Rio_Gallegos', value: 'America/Argentina/Rio_Gallegos' },
|
|
67
|
+
{ label: 'America/Argentina/Salta', value: 'America/Argentina/Salta' },
|
|
68
|
+
{ label: 'America/Argentina/San_Juan', value: 'America/Argentina/San_Juan' },
|
|
69
|
+
{ label: 'America/Argentina/San_Luis', value: 'America/Argentina/San_Luis' },
|
|
70
|
+
{ label: 'America/Argentina/Tucuman', value: 'America/Argentina/Tucuman' },
|
|
71
|
+
{ label: 'America/Argentina/Ushuaia', value: 'America/Argentina/Ushuaia' },
|
|
72
|
+
{ label: 'America/Aruba', value: 'America/Aruba' },
|
|
73
|
+
{ label: 'America/Asuncion', value: 'America/Asuncion' },
|
|
74
|
+
{ label: 'America/Atikokan', value: 'America/Atikokan' },
|
|
75
|
+
{ label: 'America/Bahia', value: 'America/Bahia' },
|
|
76
|
+
{ label: 'America/Bahia_Banderas', value: 'America/Bahia_Banderas' },
|
|
77
|
+
{ label: 'America/Barbados', value: 'America/Barbados' },
|
|
78
|
+
{ label: 'America/Belem', value: 'America/Belem' },
|
|
79
|
+
{ label: 'America/Belize', value: 'America/Belize' },
|
|
80
|
+
{ label: 'America/Blanc-Sablon', value: 'America/Blanc-Sablon' },
|
|
81
|
+
{ label: 'America/Boa_Vista', value: 'America/Boa_Vista' },
|
|
82
|
+
{ label: 'America/Bogota', value: 'America/Bogota' },
|
|
83
|
+
{ label: 'America/Boise', value: 'America/Boise' },
|
|
84
|
+
{ label: 'America/Cambridge_Bay', value: 'America/Cambridge_Bay' },
|
|
85
|
+
{ label: 'America/Campo_Grande', value: 'America/Campo_Grande' },
|
|
86
|
+
{ label: 'America/Cancun', value: 'America/Cancun' },
|
|
87
|
+
{ label: 'America/Caracas', value: 'America/Caracas' },
|
|
88
|
+
{ label: 'America/Cayenne', value: 'America/Cayenne' },
|
|
89
|
+
{ label: 'America/Cayman', value: 'America/Cayman' },
|
|
90
|
+
{ label: 'America/Chicago', value: 'America/Chicago' },
|
|
91
|
+
{ label: 'America/Chihuahua', value: 'America/Chihuahua' },
|
|
92
|
+
{ label: 'America/Ciudad_Juarez', value: 'America/Ciudad_Juarez' },
|
|
93
|
+
{ label: 'America/Costa_Rica', value: 'America/Costa_Rica' },
|
|
94
|
+
{ label: 'America/Creston', value: 'America/Creston' },
|
|
95
|
+
{ label: 'America/Cuiaba', value: 'America/Cuiaba' },
|
|
96
|
+
{ label: 'America/Curacao', value: 'America/Curacao' },
|
|
97
|
+
{ label: 'America/Danmarkshavn', value: 'America/Danmarkshavn' },
|
|
98
|
+
{ label: 'America/Dawson', value: 'America/Dawson' },
|
|
99
|
+
{ label: 'America/Dawson_Creek', value: 'America/Dawson_Creek' },
|
|
100
|
+
{ label: 'America/Denver', value: 'America/Denver' },
|
|
101
|
+
{ label: 'America/Detroit', value: 'America/Detroit' },
|
|
102
|
+
{ label: 'America/Dominica', value: 'America/Dominica' },
|
|
103
|
+
{ label: 'America/Edmonton', value: 'America/Edmonton' },
|
|
104
|
+
{ label: 'America/Eirunepe', value: 'America/Eirunepe' },
|
|
105
|
+
{ label: 'America/El_Salvador', value: 'America/El_Salvador' },
|
|
106
|
+
{ label: 'America/Fort_Nelson', value: 'America/Fort_Nelson' },
|
|
107
|
+
{ label: 'America/Fortaleza', value: 'America/Fortaleza' },
|
|
108
|
+
{ label: 'America/Glace_Bay', value: 'America/Glace_Bay' },
|
|
109
|
+
{ label: 'America/Goose_Bay', value: 'America/Goose_Bay' },
|
|
110
|
+
{ label: 'America/Grand_Turk', value: 'America/Grand_Turk' },
|
|
111
|
+
{ label: 'America/Grenada', value: 'America/Grenada' },
|
|
112
|
+
{ label: 'America/Guadeloupe', value: 'America/Guadeloupe' },
|
|
113
|
+
{ label: 'America/Guatemala', value: 'America/Guatemala' },
|
|
114
|
+
{ label: 'America/Guayaquil', value: 'America/Guayaquil' },
|
|
115
|
+
{ label: 'America/Guyana', value: 'America/Guyana' },
|
|
116
|
+
{ label: 'America/Halifax', value: 'America/Halifax' },
|
|
117
|
+
{ label: 'America/Havana', value: 'America/Havana' },
|
|
118
|
+
{ label: 'America/Hermosillo', value: 'America/Hermosillo' },
|
|
119
|
+
{ label: 'America/Indiana/Indianapolis', value: 'America/Indiana/Indianapolis' },
|
|
120
|
+
{ label: 'America/Indiana/Knox', value: 'America/Indiana/Knox' },
|
|
121
|
+
{ label: 'America/Indiana/Marengo', value: 'America/Indiana/Marengo' },
|
|
122
|
+
{ label: 'America/Indiana/Petersburg', value: 'America/Indiana/Petersburg' },
|
|
123
|
+
{ label: 'America/Indiana/Tell_City', value: 'America/Indiana/Tell_City' },
|
|
124
|
+
{ label: 'America/Indiana/Vevay', value: 'America/Indiana/Vevay' },
|
|
125
|
+
{ label: 'America/Indiana/Vincennes', value: 'America/Indiana/Vincennes' },
|
|
126
|
+
{ label: 'America/Indiana/Winamac', value: 'America/Indiana/Winamac' },
|
|
127
|
+
{ label: 'America/Inuvik', value: 'America/Inuvik' },
|
|
128
|
+
{ label: 'America/Iqaluit', value: 'America/Iqaluit' },
|
|
129
|
+
{ label: 'America/Jamaica', value: 'America/Jamaica' },
|
|
130
|
+
{ label: 'America/Juneau', value: 'America/Juneau' },
|
|
131
|
+
{ label: 'America/Kentucky/Louisville', value: 'America/Kentucky/Louisville' },
|
|
132
|
+
{ label: 'America/Kentucky/Monticello', value: 'America/Kentucky/Monticello' },
|
|
133
|
+
{ label: 'America/Kralendijk', value: 'America/Kralendijk' },
|
|
134
|
+
{ label: 'America/La_Paz', value: 'America/La_Paz' },
|
|
135
|
+
{ label: 'America/Lima', value: 'America/Lima' },
|
|
136
|
+
{ label: 'America/Los_Angeles', value: 'America/Los_Angeles' },
|
|
137
|
+
{ label: 'America/Lower_Princes', value: 'America/Lower_Princes' },
|
|
138
|
+
{ label: 'America/Maceio', value: 'America/Maceio' },
|
|
139
|
+
{ label: 'America/Managua', value: 'America/Managua' },
|
|
140
|
+
{ label: 'America/Manaus', value: 'America/Manaus' },
|
|
141
|
+
{ label: 'America/Marigot', value: 'America/Marigot' },
|
|
142
|
+
{ label: 'America/Martinique', value: 'America/Martinique' },
|
|
143
|
+
{ label: 'America/Matamoros', value: 'America/Matamoros' },
|
|
144
|
+
{ label: 'America/Mazatlan', value: 'America/Mazatlan' },
|
|
145
|
+
{ label: 'America/Menominee', value: 'America/Menominee' },
|
|
146
|
+
{ label: 'America/Merida', value: 'America/Merida' },
|
|
147
|
+
{ label: 'America/Metlakatla', value: 'America/Metlakatla' },
|
|
148
|
+
{ label: 'America/Mexico_City', value: 'America/Mexico_City' },
|
|
149
|
+
{ label: 'America/Miquelon', value: 'America/Miquelon' },
|
|
150
|
+
{ label: 'America/Moncton', value: 'America/Moncton' },
|
|
151
|
+
{ label: 'America/Monterrey', value: 'America/Monterrey' },
|
|
152
|
+
{ label: 'America/Montevideo', value: 'America/Montevideo' },
|
|
153
|
+
{ label: 'America/Montserrat', value: 'America/Montserrat' },
|
|
154
|
+
{ label: 'America/Nassau', value: 'America/Nassau' },
|
|
155
|
+
{ label: 'America/New_York', value: 'America/New_York' },
|
|
156
|
+
{ label: 'America/Nome', value: 'America/Nome' },
|
|
157
|
+
{ label: 'America/Noronha', value: 'America/Noronha' },
|
|
158
|
+
{ label: 'America/North_Dakota/Beulah', value: 'America/North_Dakota/Beulah' },
|
|
159
|
+
{ label: 'America/North_Dakota/Center', value: 'America/North_Dakota/Center' },
|
|
160
|
+
{ label: 'America/North_Dakota/New_Salem', value: 'America/North_Dakota/New_Salem' },
|
|
161
|
+
{ label: 'America/Nuuk', value: 'America/Nuuk' },
|
|
162
|
+
{ label: 'America/Ojinaga', value: 'America/Ojinaga' },
|
|
163
|
+
{ label: 'America/Panama', value: 'America/Panama' },
|
|
164
|
+
{ label: 'America/Paramaribo', value: 'America/Paramaribo' },
|
|
165
|
+
{ label: 'America/Phoenix', value: 'America/Phoenix' },
|
|
166
|
+
{ label: 'America/Port-au-Prince', value: 'America/Port-au-Prince' },
|
|
167
|
+
{ label: 'America/Port_of_Spain', value: 'America/Port_of_Spain' },
|
|
168
|
+
{ label: 'America/Porto_Velho', value: 'America/Porto_Velho' },
|
|
169
|
+
{ label: 'America/Puerto_Rico', value: 'America/Puerto_Rico' },
|
|
170
|
+
{ label: 'America/Punta_Arenas', value: 'America/Punta_Arenas' },
|
|
171
|
+
{ label: 'America/Rankin_Inlet', value: 'America/Rankin_Inlet' },
|
|
172
|
+
{ label: 'America/Recife', value: 'America/Recife' },
|
|
173
|
+
{ label: 'America/Regina', value: 'America/Regina' },
|
|
174
|
+
{ label: 'America/Resolute', value: 'America/Resolute' },
|
|
175
|
+
{ label: 'America/Rio_Branco', value: 'America/Rio_Branco' },
|
|
176
|
+
{ label: 'America/Santarem', value: 'America/Santarem' },
|
|
177
|
+
{ label: 'America/Santiago', value: 'America/Santiago' },
|
|
178
|
+
{ label: 'America/Santo_Domingo', value: 'America/Santo_Domingo' },
|
|
179
|
+
{ label: 'America/Sao_Paulo', value: 'America/Sao_Paulo' },
|
|
180
|
+
{ label: 'America/Scoresbysund', value: 'America/Scoresbysund' },
|
|
181
|
+
{ label: 'America/Sitka', value: 'America/Sitka' },
|
|
182
|
+
{ label: 'America/St_Barthelemy', value: 'America/St_Barthelemy' },
|
|
183
|
+
{ label: 'America/St_Johns', value: 'America/St_Johns' },
|
|
184
|
+
{ label: 'America/St_Kitts', value: 'America/St_Kitts' },
|
|
185
|
+
{ label: 'America/St_Lucia', value: 'America/St_Lucia' },
|
|
186
|
+
{ label: 'America/St_Thomas', value: 'America/St_Thomas' },
|
|
187
|
+
{ label: 'America/St_Vincent', value: 'America/St_Vincent' },
|
|
188
|
+
{ label: 'America/Swift_Current', value: 'America/Swift_Current' },
|
|
189
|
+
{ label: 'America/Tegucigalpa', value: 'America/Tegucigalpa' },
|
|
190
|
+
{ label: 'America/Thule', value: 'America/Thule' },
|
|
191
|
+
{ label: 'America/Tijuana', value: 'America/Tijuana' },
|
|
192
|
+
{ label: 'America/Toronto', value: 'America/Toronto' },
|
|
193
|
+
{ label: 'America/Tortola', value: 'America/Tortola' },
|
|
194
|
+
{ label: 'America/Vancouver', value: 'America/Vancouver' },
|
|
195
|
+
{ label: 'America/Whitehorse', value: 'America/Whitehorse' },
|
|
196
|
+
{ label: 'America/Winnipeg', value: 'America/Winnipeg' },
|
|
197
|
+
{ label: 'America/Yakutat', value: 'America/Yakutat' },
|
|
198
|
+
{ label: 'America/Yellowknife', value: 'America/Yellowknife' },
|
|
199
|
+
|
|
200
|
+
{ label: 'Antarctica/Casey', value: 'Antarctica/Casey' },
|
|
201
|
+
{ label: 'Antarctica/Davis', value: 'Antarctica/Davis' },
|
|
202
|
+
{ label: 'Antarctica/DumontDUrville', value: 'Antarctica/DumontDUrville' },
|
|
203
|
+
{ label: 'Antarctica/Macquarie', value: 'Antarctica/Macquarie' },
|
|
204
|
+
{ label: 'Antarctica/Mawson', value: 'Antarctica/Mawson' },
|
|
205
|
+
{ label: 'Antarctica/McMurdo', value: 'Antarctica/McMurdo' },
|
|
206
|
+
{ label: 'Antarctica/Palmer', value: 'Antarctica/Palmer' },
|
|
207
|
+
{ label: 'Antarctica/Rothera', value: 'Antarctica/Rothera' },
|
|
208
|
+
{ label: 'Antarctica/Syowa', value: 'Antarctica/Syowa' },
|
|
209
|
+
{ label: 'Antarctica/Troll', value: 'Antarctica/Troll' },
|
|
210
|
+
{ label: 'Antarctica/Vostok', value: 'Antarctica/Vostok' },
|
|
211
|
+
|
|
212
|
+
{ label: 'Arctic/Longyearbyen', value: 'Arctic/Longyearbyen' },
|
|
213
|
+
|
|
214
|
+
{ label: 'Asia/Aden', value: 'Asia/Aden' },
|
|
215
|
+
{ label: 'Asia/Almaty', value: 'Asia/Almaty' },
|
|
216
|
+
{ label: 'Asia/Amman', value: 'Asia/Amman' },
|
|
217
|
+
{ label: 'Asia/Anadyr', value: 'Asia/Anadyr' },
|
|
218
|
+
{ label: 'Asia/Aqtau', value: 'Asia/Aqtau' },
|
|
219
|
+
{ label: 'Asia/Aqtobe', value: 'Asia/Aqtobe' },
|
|
220
|
+
{ label: 'Asia/Ashgabat', value: 'Asia/Ashgabat' },
|
|
221
|
+
{ label: 'Asia/Atyrau', value: 'Asia/Atyrau' },
|
|
222
|
+
{ label: 'Asia/Baghdad', value: 'Asia/Baghdad' },
|
|
223
|
+
{ label: 'Asia/Bahrain', value: 'Asia/Bahrain' },
|
|
224
|
+
{ label: 'Asia/Baku', value: 'Asia/Baku' },
|
|
225
|
+
{ label: 'Asia/Bangkok', value: 'Asia/Bangkok' },
|
|
226
|
+
{ label: 'Asia/Barnaul', value: 'Asia/Barnaul' },
|
|
227
|
+
{ label: 'Asia/Beirut', value: 'Asia/Beirut' },
|
|
228
|
+
{ label: 'Asia/Bishkek', value: 'Asia/Bishkek' },
|
|
229
|
+
{ label: 'Asia/Brunei', value: 'Asia/Brunei' },
|
|
230
|
+
{ label: 'Asia/Chita', value: 'Asia/Chita' },
|
|
231
|
+
{ label: 'Asia/Choibalsan', value: 'Asia/Choibalsan' },
|
|
232
|
+
{ label: 'Asia/Colombo', value: 'Asia/Colombo' },
|
|
233
|
+
{ label: 'Asia/Damascus', value: 'Asia/Damascus' },
|
|
234
|
+
{ label: 'Asia/Dhaka', value: 'Asia/Dhaka' },
|
|
235
|
+
{ label: 'Asia/Dili', value: 'Asia/Dili' },
|
|
236
|
+
{ label: 'Asia/Dubai', value: 'Asia/Dubai' },
|
|
237
|
+
{ label: 'Asia/Dushanbe', value: 'Asia/Dushanbe' },
|
|
238
|
+
{ label: 'Asia/Famagusta', value: 'Asia/Famagusta' },
|
|
239
|
+
{ label: 'Asia/Gaza', value: 'Asia/Gaza' },
|
|
240
|
+
{ label: 'Asia/Hebron', value: 'Asia/Hebron' },
|
|
241
|
+
{ label: 'Asia/Ho_Chi_Minh', value: 'Asia/Ho_Chi_Minh' },
|
|
242
|
+
{ label: 'Asia/Hong_Kong', value: 'Asia/Hong_Kong' },
|
|
243
|
+
{ label: 'Asia/Hovd', value: 'Asia/Hovd' },
|
|
244
|
+
{ label: 'Asia/Irkutsk', value: 'Asia/Irkutsk' },
|
|
245
|
+
{ label: 'Asia/Jakarta', value: 'Asia/Jakarta' },
|
|
246
|
+
{ label: 'Asia/Jayapura', value: 'Asia/Jayapura' },
|
|
247
|
+
{ label: 'Asia/Jerusalem', value: 'Asia/Jerusalem' },
|
|
248
|
+
{ label: 'Asia/Kabul', value: 'Asia/Kabul' },
|
|
249
|
+
{ label: 'Asia/Kamchatka', value: 'Asia/Kamchatka' },
|
|
250
|
+
{ label: 'Asia/Karachi', value: 'Asia/Karachi' },
|
|
251
|
+
{ label: 'Asia/Kathmandu', value: 'Asia/Kathmandu' },
|
|
252
|
+
{ label: 'Asia/Khandyga', value: 'Asia/Khandyga' },
|
|
253
|
+
{ label: 'Asia/Kolkata', value: 'Asia/Kolkata' },
|
|
254
|
+
{ label: 'Asia/Krasnoyarsk', value: 'Asia/Krasnoyarsk' },
|
|
255
|
+
{ label: 'Asia/Kuala_Lumpur', value: 'Asia/Kuala_Lumpur' },
|
|
256
|
+
{ label: 'Asia/Kuching', value: 'Asia/Kuching' },
|
|
257
|
+
{ label: 'Asia/Kuwait', value: 'Asia/Kuwait' },
|
|
258
|
+
{ label: 'Asia/Macau', value: 'Asia/Macau' },
|
|
259
|
+
{ label: 'Asia/Magadan', value: 'Asia/Magadan' },
|
|
260
|
+
{ label: 'Asia/Makassar', value: 'Asia/Makassar' },
|
|
261
|
+
{ label: 'Asia/Manila', value: 'Asia/Manila' },
|
|
262
|
+
{ label: 'Asia/Muscat', value: 'Asia/Muscat' },
|
|
263
|
+
{ label: 'Asia/Nicosia', value: 'Asia/Nicosia' },
|
|
264
|
+
{ label: 'Asia/Novokuznetsk', value: 'Asia/Novokuznetsk' },
|
|
265
|
+
{ label: 'Asia/Novosibirsk', value: 'Asia/Novosibirsk' },
|
|
266
|
+
{ label: 'Asia/Omsk', value: 'Asia/Omsk' },
|
|
267
|
+
{ label: 'Asia/Oral', value: 'Asia/Oral' },
|
|
268
|
+
{ label: 'Asia/Phnom_Penh', value: 'Asia/Phnom_Penh' },
|
|
269
|
+
{ label: 'Asia/Pontianak', value: 'Asia/Pontianak' },
|
|
270
|
+
{ label: 'Asia/Pyongyang', value: 'Asia/Pyongyang' },
|
|
271
|
+
{ label: 'Asia/Qatar', value: 'Asia/Qatar' },
|
|
272
|
+
{ label: 'Asia/Qostanay', value: 'Asia/Qostanay' },
|
|
273
|
+
{ label: 'Asia/Qyzylorda', value: 'Asia/Qyzylorda' },
|
|
274
|
+
{ label: 'Asia/Riyadh', value: 'Asia/Riyadh' },
|
|
275
|
+
{ label: 'Asia/Sakhalin', value: 'Asia/Sakhalin' },
|
|
276
|
+
{ label: 'Asia/Samarkand', value: 'Asia/Samarkand' },
|
|
277
|
+
{ label: 'Asia/Seoul', value: 'Asia/Seoul' },
|
|
278
|
+
{ label: 'Asia/Shanghai', value: 'Asia/Shanghai' },
|
|
279
|
+
{ label: 'Asia/Singapore', value: 'Asia/Singapore' },
|
|
280
|
+
{ label: 'Asia/Srednekolymsk', value: 'Asia/Srednekolymsk' },
|
|
281
|
+
{ label: 'Asia/Taipei', value: 'Asia/Taipei' },
|
|
282
|
+
{ label: 'Asia/Tashkent', value: 'Asia/Tashkent' },
|
|
283
|
+
{ label: 'Asia/Tbilisi', value: 'Asia/Tbilisi' },
|
|
284
|
+
{ label: 'Asia/Tehran', value: 'Asia/Tehran' },
|
|
285
|
+
{ label: 'Asia/Thimphu', value: 'Asia/Thimphu' },
|
|
286
|
+
{ label: 'Asia/Tokyo', value: 'Asia/Tokyo' },
|
|
287
|
+
{ label: 'Asia/Tomsk', value: 'Asia/Tomsk' },
|
|
288
|
+
{ label: 'Asia/Ulaanbaatar', value: 'Asia/Ulaanbaatar' },
|
|
289
|
+
{ label: 'Asia/Urumqi', value: 'Asia/Urumqi' },
|
|
290
|
+
{ label: 'Asia/Ust-Nera', value: 'Asia/Ust-Nera' },
|
|
291
|
+
{ label: 'Asia/Vientiane', value: 'Asia/Vientiane' },
|
|
292
|
+
{ label: 'Asia/Vladivostok', value: 'Asia/Vladivostok' },
|
|
293
|
+
{ label: 'Asia/Yakutsk', value: 'Asia/Yakutsk' },
|
|
294
|
+
{ label: 'Asia/Yangon', value: 'Asia/Yangon' },
|
|
295
|
+
{ label: 'Asia/Yekaterinburg', value: 'Asia/Yekaterinburg' },
|
|
296
|
+
{ label: 'Asia/Yerevan', value: 'Asia/Yerevan' },
|
|
297
|
+
|
|
298
|
+
{ label: 'Atlantic/Azores', value: 'Atlantic/Azores' },
|
|
299
|
+
{ label: 'Atlantic/Bermuda', value: 'Atlantic/Bermuda' },
|
|
300
|
+
{ label: 'Atlantic/Canary', value: 'Atlantic/Canary' },
|
|
301
|
+
{ label: 'Atlantic/Cape_Verde', value: 'Atlantic/Cape_Verde' },
|
|
302
|
+
{ label: 'Atlantic/Faroe', value: 'Atlantic/Faroe' },
|
|
303
|
+
{ label: 'Atlantic/Madeira', value: 'Atlantic/Madeira' },
|
|
304
|
+
{ label: 'Atlantic/Reykjavik', value: 'Atlantic/Reykjavik' },
|
|
305
|
+
{ label: 'Atlantic/South_Georgia', value: 'Atlantic/South_Georgia' },
|
|
306
|
+
{ label: 'Atlantic/St_Helena', value: 'Atlantic/St_Helena' },
|
|
307
|
+
{ label: 'Atlantic/Stanley', value: 'Atlantic/Stanley' },
|
|
308
|
+
|
|
309
|
+
{ label: 'Australia/Adelaide', value: 'Australia/Adelaide' },
|
|
310
|
+
{ label: 'Australia/Brisbane', value: 'Australia/Brisbane' },
|
|
311
|
+
{ label: 'Australia/Broken_Hill', value: 'Australia/Broken_Hill' },
|
|
312
|
+
{ label: 'Australia/Darwin', value: 'Australia/Darwin' },
|
|
313
|
+
{ label: 'Australia/Eucla', value: 'Australia/Eucla' },
|
|
314
|
+
{ label: 'Australia/Hobart', value: 'Australia/Hobart' },
|
|
315
|
+
{ label: 'Australia/Lindeman', value: 'Australia/Lindeman' },
|
|
316
|
+
{ label: 'Australia/Lord_Howe', value: 'Australia/Lord_Howe' },
|
|
317
|
+
{ label: 'Australia/Melbourne', value: 'Australia/Melbourne' },
|
|
318
|
+
{ label: 'Australia/Perth', value: 'Australia/Perth' },
|
|
319
|
+
{ label: 'Australia/Sydney', value: 'Australia/Sydney' },
|
|
320
|
+
|
|
321
|
+
{ label: 'Europe/Amsterdam', value: 'Europe/Amsterdam' },
|
|
322
|
+
{ label: 'Europe/Andorra', value: 'Europe/Andorra' },
|
|
323
|
+
{ label: 'Europe/Astrakhan', value: 'Europe/Astrakhan' },
|
|
324
|
+
{ label: 'Europe/Athens', value: 'Europe/Athens' },
|
|
325
|
+
{ label: 'Europe/Belgrade', value: 'Europe/Belgrade' },
|
|
326
|
+
{ label: 'Europe/Berlin', value: 'Europe/Berlin' },
|
|
327
|
+
{ label: 'Europe/Bratislava', value: 'Europe/Bratislava' },
|
|
328
|
+
{ label: 'Europe/Brussels', value: 'Europe/Brussels' },
|
|
329
|
+
{ label: 'Europe/Bucharest', value: 'Europe/Bucharest' },
|
|
330
|
+
{ label: 'Europe/Budapest', value: 'Europe/Budapest' },
|
|
331
|
+
{ label: 'Europe/Busingen', value: 'Europe/Busingen' },
|
|
332
|
+
{ label: 'Europe/Chisinau', value: 'Europe/Chisinau' },
|
|
333
|
+
{ label: 'Europe/Copenhagen', value: 'Europe/Copenhagen' },
|
|
334
|
+
{ label: 'Europe/Dublin', value: 'Europe/Dublin' },
|
|
335
|
+
{ label: 'Europe/Gibraltar', value: 'Europe/Gibraltar' },
|
|
336
|
+
{ label: 'Europe/Guernsey', value: 'Europe/Guernsey' },
|
|
337
|
+
{ label: 'Europe/Helsinki', value: 'Europe/Helsinki' },
|
|
338
|
+
{ label: 'Europe/Isle_of_Man', value: 'Europe/Isle_of_Man' },
|
|
339
|
+
{ label: 'Europe/Istanbul', value: 'Europe/Istanbul' },
|
|
340
|
+
{ label: 'Europe/Jersey', value: 'Europe/Jersey' },
|
|
341
|
+
{ label: 'Europe/Kaliningrad', value: 'Europe/Kaliningrad' },
|
|
342
|
+
{ label: 'Europe/Kirov', value: 'Europe/Kirov' },
|
|
343
|
+
{ label: 'Europe/Kyiv', value: 'Europe/Kyiv' },
|
|
344
|
+
{ label: 'Europe/Lisbon', value: 'Europe/Lisbon' },
|
|
345
|
+
{ label: 'Europe/Ljubljana', value: 'Europe/Ljubljana' },
|
|
346
|
+
{ label: 'Europe/London', value: 'Europe/London' },
|
|
347
|
+
{ label: 'Europe/Luxembourg', value: 'Europe/Luxembourg' },
|
|
348
|
+
{ label: 'Europe/Madrid', value: 'Europe/Madrid' },
|
|
349
|
+
{ label: 'Europe/Malta', value: 'Europe/Malta' },
|
|
350
|
+
{ label: 'Europe/Mariehamn', value: 'Europe/Mariehamn' },
|
|
351
|
+
{ label: 'Europe/Minsk', value: 'Europe/Minsk' },
|
|
352
|
+
{ label: 'Europe/Monaco', value: 'Europe/Monaco' },
|
|
353
|
+
{ label: 'Europe/Moscow', value: 'Europe/Moscow' },
|
|
354
|
+
{ label: 'Europe/Oslo', value: 'Europe/Oslo' },
|
|
355
|
+
{ label: 'Europe/Paris', value: 'Europe/Paris' },
|
|
356
|
+
{ label: 'Europe/Podgorica', value: 'Europe/Podgorica' },
|
|
357
|
+
{ label: 'Europe/Prague', value: 'Europe/Prague' },
|
|
358
|
+
{ label: 'Europe/Riga', value: 'Europe/Riga' },
|
|
359
|
+
{ label: 'Europe/Rome', value: 'Europe/Rome' },
|
|
360
|
+
{ label: 'Europe/Samara', value: 'Europe/Samara' },
|
|
361
|
+
{ label: 'Europe/San_Marino', value: 'Europe/San_Marino' },
|
|
362
|
+
{ label: 'Europe/Sarajevo', value: 'Europe/Sarajevo' },
|
|
363
|
+
{ label: 'Europe/Saratov', value: 'Europe/Saratov' },
|
|
364
|
+
{ label: 'Europe/Simferopol', value: 'Europe/Simferopol' },
|
|
365
|
+
{ label: 'Europe/Skopje', value: 'Europe/Skopje' },
|
|
366
|
+
{ label: 'Europe/Sofia', value: 'Europe/Sofia' },
|
|
367
|
+
{ label: 'Europe/Stockholm', value: 'Europe/Stockholm' },
|
|
368
|
+
{ label: 'Europe/Tallinn', value: 'Europe/Tallinn' },
|
|
369
|
+
{ label: 'Europe/Tirane', value: 'Europe/Tirane' },
|
|
370
|
+
{ label: 'Europe/Ulyanovsk', value: 'Europe/Ulyanovsk' },
|
|
371
|
+
{ label: 'Europe/Vaduz', value: 'Europe/Vaduz' },
|
|
372
|
+
{ label: 'Europe/Vatican', value: 'Europe/Vatican' },
|
|
373
|
+
{ label: 'Europe/Vienna', value: 'Europe/Vienna' },
|
|
374
|
+
{ label: 'Europe/Vilnius', value: 'Europe/Vilnius' },
|
|
375
|
+
{ label: 'Europe/Volgograd', value: 'Europe/Volgograd' },
|
|
376
|
+
{ label: 'Europe/Warsaw', value: 'Europe/Warsaw' },
|
|
377
|
+
{ label: 'Europe/Zagreb', value: 'Europe/Zagreb' },
|
|
378
|
+
{ label: 'Europe/Zurich', value: 'Europe/Zurich' },
|
|
379
|
+
|
|
380
|
+
{ label: 'Indian/Antananarivo', value: 'Indian/Antananarivo' },
|
|
381
|
+
{ label: 'Indian/Chagos', value: 'Indian/Chagos' },
|
|
382
|
+
{ label: 'Indian/Christmas', value: 'Indian/Christmas' },
|
|
383
|
+
{ label: 'Indian/Cocos', value: 'Indian/Cocos' },
|
|
384
|
+
{ label: 'Indian/Comoro', value: 'Indian/Comoro' },
|
|
385
|
+
{ label: 'Indian/Kerguelen', value: 'Indian/Kerguelen' },
|
|
386
|
+
{ label: 'Indian/Mahe', value: 'Indian/Mahe' },
|
|
387
|
+
{ label: 'Indian/Maldives', value: 'Indian/Maldives' },
|
|
388
|
+
{ label: 'Indian/Mauritius', value: 'Indian/Mauritius' },
|
|
389
|
+
{ label: 'Indian/Mayotte', value: 'Indian/Mayotte' },
|
|
390
|
+
{ label: 'Indian/Reunion', value: 'Indian/Reunion' },
|
|
391
|
+
|
|
392
|
+
{ label: 'Pacific/Apia', value: 'Pacific/Apia' },
|
|
393
|
+
{ label: 'Pacific/Auckland', value: 'Pacific/Auckland' },
|
|
394
|
+
{ label: 'Pacific/Bougainville', value: 'Pacific/Bougainville' },
|
|
395
|
+
{ label: 'Pacific/Chatham', value: 'Pacific/Chatham' },
|
|
396
|
+
{ label: 'Pacific/Chuuk', value: 'Pacific/Chuuk' },
|
|
397
|
+
{ label: 'Pacific/Easter', value: 'Pacific/Easter' },
|
|
398
|
+
{ label: 'Pacific/Efate', value: 'Pacific/Efate' },
|
|
399
|
+
{ label: 'Pacific/Fakaofo', value: 'Pacific/Fakaofo' },
|
|
400
|
+
{ label: 'Pacific/Fiji', value: 'Pacific/Fiji' },
|
|
401
|
+
{ label: 'Pacific/Funafuti', value: 'Pacific/Funafuti' },
|
|
402
|
+
{ label: 'Pacific/Galapagos', value: 'Pacific/Galapagos' },
|
|
403
|
+
{ label: 'Pacific/Gambier', value: 'Pacific/Gambier' },
|
|
404
|
+
{ label: 'Pacific/Guadalcanal', value: 'Pacific/Guadalcanal' },
|
|
405
|
+
{ label: 'Pacific/Guam', value: 'Pacific/Guam' },
|
|
406
|
+
{ label: 'Pacific/Honolulu', value: 'Pacific/Honolulu' },
|
|
407
|
+
{ label: 'Pacific/Kanton', value: 'Pacific/Kanton' },
|
|
408
|
+
{ label: 'Pacific/Kiritimati', value: 'Pacific/Kiritimati' },
|
|
409
|
+
{ label: 'Pacific/Kosrae', value: 'Pacific/Kosrae' },
|
|
410
|
+
{ label: 'Pacific/Kwajalein', value: 'Pacific/Kwajalein' },
|
|
411
|
+
{ label: 'Pacific/Majuro', value: 'Pacific/Majuro' },
|
|
412
|
+
{ label: 'Pacific/Marquesas', value: 'Pacific/Marquesas' },
|
|
413
|
+
{ label: 'Pacific/Midway', value: 'Pacific/Midway' },
|
|
414
|
+
{ label: 'Pacific/Nauru', value: 'Pacific/Nauru' },
|
|
415
|
+
{ label: 'Pacific/Niue', value: 'Pacific/Niue' },
|
|
416
|
+
{ label: 'Pacific/Norfolk', value: 'Pacific/Norfolk' },
|
|
417
|
+
{ label: 'Pacific/Noumea', value: 'Pacific/Noumea' },
|
|
418
|
+
{ label: 'Pacific/Pago_Pago', value: 'Pacific/Pago_Pago' },
|
|
419
|
+
{ label: 'Pacific/Palau', value: 'Pacific/Palau' },
|
|
420
|
+
{ label: 'Pacific/Pitcairn', value: 'Pacific/Pitcairn' },
|
|
421
|
+
{ label: 'Pacific/Pohnpei', value: 'Pacific/Pohnpei' },
|
|
422
|
+
{ label: 'Pacific/Port_Moresby', value: 'Pacific/Port_Moresby' },
|
|
423
|
+
{ label: 'Pacific/Rarotonga', value: 'Pacific/Rarotonga' },
|
|
424
|
+
{ label: 'Pacific/Saipan', value: 'Pacific/Saipan' },
|
|
425
|
+
{ label: 'Pacific/Tahiti', value: 'Pacific/Tahiti' },
|
|
426
|
+
{ label: 'Pacific/Tarawa', value: 'Pacific/Tarawa' },
|
|
427
|
+
{ label: 'Pacific/Tongatapu', value: 'Pacific/Tongatapu' },
|
|
428
|
+
{ label: 'Pacific/Wake', value: 'Pacific/Wake' },
|
|
429
|
+
{ label: 'Pacific/Wallis', value: 'Pacific/Wallis' },
|
|
430
|
+
|
|
431
|
+
{ label: 'UTC', value: 'UTC' }
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
export default timezones;
|