diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 0e324c98..3b2d82ff 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -15,4 +15,6 @@ jobs:
lint:
uses: yoriiis/actions/.github/workflows/lint.yml@main
with:
+ eslint-config: 'config/.eslintrc.cjs'
+ stylelint-config: 'config/stylelint.config.cjs'
typescript-status: false
diff --git a/.github/workflows/vercel-deploy-functions.yml b/.github/workflows/vercel-deploy-functions.yml
deleted file mode 100644
index 71956cdd..00000000
--- a/.github/workflows/vercel-deploy-functions.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Deploy Vercel Functions
-
-on:
- workflow_call:
- merge_group:
- push:
- branches:
- - main
-
-jobs:
- build:
- uses: yoriiis/actions/.github/workflows/vercel-deploy-functions.yml@main
- with:
- node-version: 18
- secrets:
- VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f06235c4..6f625fd2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
node_modules
dist
+credentials.json
+.env
+*.tgz
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..7bde396f
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+src/core/check.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64bc1da2..4ccda982 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -78,7 +78,7 @@
### Updates
-- Add prefix `.storelocator-` before all CSS classes use by storelocatorjs to prevent conflicts
+- Add prefix `.st-` before all CSS classes use by storelocatorjs to prevent conflicts
- Rename all CSS class with [FUN](https://benfrain.com/enduring-css-writing-style-sheets-rapidly-changing-long-lived-projects/#h-H2_5) methodology
## 1.0.0
diff --git a/README.md b/README.md
index 7e92858e..62fcc5b2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,22 @@
[](https://github.com/yoriiis/storelocatorjs/actions/workflows/build.yml) [](https://www.jsdelivr.com/package/npm/storelocatorjs)
-Storelocatorjs is a **fast** and **lightweight** Javascript library to easily build a store locator using Google Maps API V3. Only **6Kb** on production with gzip, Storelocatorjs has no dependency with any framework or library and is written in **Javascript native**.
+
+
+## Features
+
+- **Video & audio** - [HTML5 video](./src/providers/html5/README.md), [HTML5 audio](./src/providers/html5/README.md), [Youtube](./src/providers/youtube/README.md), [Vimeo](./src/providers/vimeo/README.md), [Dailymotion](./src/providers/dailymotion/README.md).
+- **Customization** - Choose the control elements you want to display.
+- **No dependency** - Written in native Javascript without any framework.
+- [**Provider API**](./src/providers/README.md) - Use the available providers or create your own.
+- [**Geocoder API**](./src/plugins/README.md) - Use the available geocoder or create your own.
+- [**Events**](#events) - Standardized events for all web browsers, providers and plugins.
+- **Autoload API** - Google Maps, Leaflet, Mapbox and MapLibre API are automatically loaded by their provider.
+- **SVG icons** - SVG are inlined into the library, no sprites to includes.
+- [**Shortcuts**](#shortcuts) - Supports keyboard shortcuts.
+
+
+
-## Examples
+:sparkles: You can support this project with [GitHub Sponsors](https://github.com/sponsors/storelocatorjs)! ♡
+
+## License
+
+The project is available with a license key on the Lemon Squeezy store. [Read more about fullPage's license](https://storelocator.lemonsqueezy.com/checkout/buy/5d697bb7-4cc8-4e6e-b7d7-fec4372a94b1?discount=0).
+
+### Examples
The project includes several examples of `storelocatorjs` implementation in the directory `examples`. Run the following commands to build the assets for the examples:
@@ -20,7 +41,11 @@ npm run build && npm run build:example
## Installation
-The library is available as the `storelocatorjs` package name on [npm](https://www.npmjs.com/package/storelocatorjs).
+> **Warning** storelocatorjs@3 is ESM and uses the [Node.js package `exports`](https://nodejs.org/api/packages.html#exports).
+
+### NPM
+
+NPM is the recommended installation method. Install `storelocatorjs` in your project with the following command:
```bash
npm install storelocatorjs --save-dev
@@ -30,104 +55,167 @@ npm install storelocatorjs --save-dev
yarn add storelocatorjs --dev
```
-## Demo
+> **Note** Minimum supported `Node.js` version is `16.20.0`.
-Online demo is available on [https://storelocatorjs.github.io/demo](https://storelocatorjs.github.io/demo).
+### CDN
-## How it works
+You can also download it and include it with a script tag as an ESM.
-### Cloud functions
+```html
+
+
+```
-All requests to filter stores by geoposition are send to a cloud function as a web service. Storelocatorjs includes the cloud functions project from [Google Firebase](https://firebase.google.com/docs/functions) located in the `./functions` folder.
+> **Note** You can browse the source of the NPM package at [jsdelivr.com/package/npm/storelocatorjs](https://www.jsdelivr.com/package/npm/storelocatorjs).
-### Structure
+## How it works
-The extended usage of the Storelocatorjs with filters and store categories used a minimalist HTML structure.
+### HTML
```html
-
-
-
-
-
-
-
-
-
-
-
-
+
```
-### Options
+### Initialization
-Storelocatorjs contains many options to allow you to easily configure your map according to your needs. Options are available on the [Storelocatorjs website](https://storelocatorjs.github.io/available-options.html).
+Import `storelocatorjs` styleheet and the JavaScript library as an ES6 modules.
+
+```javascript
+import 'storelocatorjs/storelocator.css';
+import Storelocatorjs from 'storelocatorjs';
+```
+
+The `storelocatorjs` constructor accepts an object as configuration with the following parameters:
+
+| Arguments | Type | Description |
+| ------------------- | :----------------: | -------------------------------------------------------------------------------- |
+| `target` | `HTMLElement` | Unique `HTMLElement` to target the storelocator |
+| `licenseKey` | `String` | Mandatory license key |
+| `api.url` | `String` | Endpoint to request and search stores |
+| `api.radius` | `Number` | Radius in km for the research |
+| `api.limit` | `Number` | Limit of search result in the research |
+| `map.provider` | `String` | Map provider |
+| `map.token` | `String` | Map provider token |
+| `map.options` | `String` | Map provider options |
+| `geocoder.provider` | `String\|Function` | Geocoder provider |
+| `geocoder.token` | `String` | Geocoder provider token |
+| `templates.popup` | `Function` | Custom template for marker popup |
+| `templates.result` | `Function` | Custom template for search result |
+| `onReady` | `Function` | Callback function executed when the [storelocator is ready](#storelocator-ready) |
+
+Initialize the storelocator with the configuration object.
+
+```javascript
+new Storelocatorjs({
+ target: document.querySelector('#app'),
+ licenseKey: 'LICENSE_KEY',
+ api: {
+ url: 'ENDPOINT_URL'
+ },
+ map: {
+ provider: GoogleMaps,
+ token: 'MAP_PROVIDER_TOKEN'
+ },
+ geocoder: {
+ provider: 'mapbox',
+ token: 'GEOCODER_PROVIDER_TOKEN'
+ }
+});
+```
-#### Example with the onReady function
+---
-The `onReady` function expose the Google Maps instance as `map` variable and is called when the map is instantiated and ready. With the example below, an automatic search is triggered with location coordinates passed in parameters.
+
+
-```js
-new Storelocator({
- apiKey: '',
- webServiceUrl: ''
-}, onReady: function(map) {
- this.triggerRequest({
- 'lat': 48.8589507,
- 'lng': 2.2770202
+### Storelocator ready
+
+The callback function `onReady` is automatically executed when the storelocator is ready. The Google Maps, Leaflet, Mapbox and MapLibre provider listen to the `onready` event returned by their API.
+
+The function exposes the `storelocator` parameter as the storelocator instance. You can use it to interact with the storelocator instance and the [storelocator methods](#methods).
+
+Example of a storelocator with geolocation requested when ready:
+
+```javascript
+new Storelocatorjs({
+ onReady: function (storelocator) {
+ storelocator.requestUserPosition();
+ }
+});
+```
+
+> **Note** The `onReady` function can also be written with an arrow function.
+
+### Events
+
+`storelocatorjs` exposes the following native `Event` on the `.sl-app` element. Events are standardized for all providers.
+
+| Event Type | Description |
+| --------------- | -------------------------------------------------------------------------------- |
+| `progress` | Sent periodically to inform interested parties of progress downloading the media |
+| `userPosition` | Sent when the user location is requested |
+| `storeFound` | Sent when results where found |
+| `storeNotFound` | Sent when no results found |
+| `zoomIn` | Sent when zooming in |
+| `zoomOut` | Sent when zooming out |
+
+Example of a listener when the storelocator triggers the user position event.
+
+```javascript
+new Storelocatorjs({
+ onReady: (storelocator) => {
+ storelocator.on('userPosition', () => {
+ // The user location is requested
});
-})
+ }
+});
```
-## Browsers support
+### Methods
+
+The storelocator instance exposes the following methods, accessible when the storelocator is ready.
-The project is fully compatible with the most popular web browsers. More information about the Google Maps support on Google Developers. HTML and CSS files are W3C valid.
+| Method | Parameters | Promise | Description |
+| ----------------------- | :----------------: | :-----: | ------------------------------------------------------------------- |
+| `requestUserPosition()` | - | - | Request the user position to search for results around its position |
+| `getInstance()` | - | - | Get the storelocator instance |
+| `loading()` | `Boolean` | - | Set the loading status |
+| `on(event, function)` | `String, Function` | - | Add an event listener |
+| `off(event, function)` | `String, Function` | - | Remove an event listener |
+| `destroy()` | - | - | Destroy the storelocator |
+
+Example of media `duration` recovery.
+
+```javascript
+new Storelocatorjs({
+ onReady: (storelocator) => {
+ storelocator.requestUserPosition();
+ }
+});
+```
-## Licenses
+### Custom CSS properties
-### Commercial license
+The storelocator exposes some custom CSS properties, locally scopped under the `.v-vlite` selector. You can use them to customize the design.
-If you want to use Storelocatorjs to develop commercial sites, themes, projects, and applications, the Commercial License is the appropriate license. With this option, your source code is kept proprietary.
-Purchase a Storelocatorjs Commercial License on the [license page](https://storelocatorjs.github.io/licenses.html#purchasing).
+| Name | Value | Description |
+| ----------------------------- | ------------ | ------------------------ |
+| `--sl-markerSearchColor` | `#107a8b` | Marker search color |
+| `--sl-markerGeolocationColor` | `#107a8b` | Marker geolocation color |
+| `--sl-colorSecondary` | `0.25s ease` | Secondary color |
+| `--sl-transition` | `0.25s ease` | Transition |
+| `--sl-controlsColor` | `0.25s ease` | Controls color |
-### Open source license
+---
-If you are creating an open source application under a license compatible with the [GNU GPL license v3](https://www.gnu.org/licenses/gpl-3.0.html), you may use Storelocatorjs under the terms of the GPLv3.
+## License
-## Contributors
+
-Created with ♥ by [@yoriiis](http://github.com/yoriiis)
+Created with ♡ by [@yoriiis](https://github.com/yoriiis).
diff --git a/config/.eslintrc.js b/config/.eslintrc.cjs
similarity index 91%
rename from config/.eslintrc.js
rename to config/.eslintrc.cjs
index d8e67d01..c3eeada4 100644
--- a/config/.eslintrc.js
+++ b/config/.eslintrc.cjs
@@ -34,5 +34,5 @@ module.exports = {
window: false
},
- ignorePatterns: ['node_modules', 'dist']
+ ignorePatterns: ['node_modules', 'dist', 'src/core/check.js']
}
diff --git a/config/babel.config.js b/config/babel.config.js
deleted file mode 100644
index 6574aafd..00000000
--- a/config/babel.config.js
+++ /dev/null
@@ -1,21 +0,0 @@
-module.exports = function (api) {
- const presets = [
- '@babel/preset-env',
- [
- '@babel/preset-react',
- {
- runtime: 'automatic',
- importSource: 'jsx-dom-cjs'
- }
- ]
- ]
-
- api.cache(true)
-
- const plugins = ['@babel/plugin-proposal-class-properties']
-
- return {
- presets,
- plugins
- }
-}
diff --git a/config/package.js b/config/package.js
new file mode 100644
index 00000000..fd23170e
--- /dev/null
+++ b/config/package.js
@@ -0,0 +1,11 @@
+import { license, name, version, author } from '../package.json'
+
+export const banner =
+ '/*!\n' +
+ ` * @license ${license}\n` +
+ ` * @name ${name}\n` +
+ ` * @version ${version}\n` +
+ ` * @copyright ${new Date().getUTCFullYear()} ${author}\n` +
+ ' */'
+
+export const mapProviders = ['google-maps', 'leaflet', 'mapbox', 'maplibre']
diff --git a/config/postcss.config.cjs b/config/postcss.config.cjs
new file mode 100644
index 00000000..58da132d
--- /dev/null
+++ b/config/postcss.config.cjs
@@ -0,0 +1,22 @@
+module.exports = {
+ plugins: {
+ 'postcss-import': {},
+ 'postcss-url': {},
+ 'postcss-nested': {},
+
+ 'postcss-preset-env': {
+ stage: 2,
+ features: {
+ 'nesting-rules': false,
+ 'custom-properties': {
+ warnings: true,
+ preserve: true
+ }
+ }
+ },
+
+ 'postcss-custom-media': {
+ preserve: false
+ }
+ }
+}
diff --git a/config/postcss.config.js b/config/postcss.config.js
deleted file mode 100644
index dbe7b737..00000000
--- a/config/postcss.config.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const path = require('path')
-
-module.exports = {
- plugins: [
- [
- '@csstools/postcss-global-data',
- {
- files: [path.resolve(__dirname, '../src/css/vars.css')]
- }
- ],
- 'postcss-import',
- 'postcss-url',
- 'postcss-nested',
- [
- 'postcss-preset-env',
- {
- stage: 2,
- features: {
- 'nesting-rules': false,
- 'custom-properties': {
- warnings: true,
- preserve: true
- }
- }
- }
- ],
- [
- 'postcss-custom-media',
- {
- preserve: false
- }
- ]
- ]
-}
diff --git a/config/prettier.config.js b/config/prettier.config.cjs
similarity index 100%
rename from config/prettier.config.js
rename to config/prettier.config.cjs
diff --git a/config/rollup.config.js b/config/rollup.config.js
new file mode 100644
index 00000000..438aec5b
--- /dev/null
+++ b/config/rollup.config.js
@@ -0,0 +1,69 @@
+import { resolve } from 'path'
+import { nodeResolve } from '@rollup/plugin-node-resolve'
+import svg from 'rollup-plugin-svg'
+import postcss from 'rollup-plugin-postcss'
+import alias from '@rollup/plugin-alias'
+import { terser } from 'rollup-plugin-terser'
+import commonjs from '@rollup/plugin-commonjs'
+import { banner, mapProviders } from './package'
+import copy from 'rollup-plugin-copy'
+
+const isProduction = process.env.ENV === 'production'
+const outputDirectory = resolve(__dirname, '../dist')
+
+const createConfig = ({ input, outputFile }) => {
+ return {
+ input,
+ output: [
+ {
+ banner,
+ file: `${outputDirectory}/${outputFile}`,
+ format: 'es'
+ }
+ ],
+ plugins: [
+ commonjs(),
+ nodeResolve({ browser: true }),
+ svg(),
+ postcss({
+ config: {
+ path: resolve(__dirname, 'postcss.config.cjs')
+ },
+ extract: true,
+ minimize: isProduction
+ }),
+ alias({
+ entries: [
+ { find: 'core', replacement: resolve('src/core') },
+ { find: 'shared', replacement: resolve('src/shared') },
+ { find: 'components', replacement: resolve('src/components') },
+ { find: 'map', replacement: resolve('src/map') },
+ { find: 'geocoder', replacement: resolve('src/geocoder') },
+ { find: 'check', replacement: resolve('../license-check/index.js') }
+ ]
+ }),
+ copy({
+ targets: [
+ {
+ src: resolve('node_modules/leaflet/dist/images'),
+ dest: `${outputDirectory}/map`
+ }
+ ]
+ }),
+ ...(isProduction ? [terser()] : [])
+ ]
+ }
+}
+
+export default [
+ ...mapProviders.map((name) =>
+ createConfig({
+ input: `./src/map/${name}/${name}.js`,
+ outputFile: `map/${name}.js`
+ })
+ ),
+ createConfig({
+ input: `./src/core/app.js`,
+ outputFile: `storelocator.js`
+ })
+]
diff --git a/config/setup.js b/config/setup.js
new file mode 100644
index 00000000..b5af516f
--- /dev/null
+++ b/config/setup.js
@@ -0,0 +1,33 @@
+import fs from 'fs'
+import path from 'path'
+import dotenv from 'dotenv'
+
+const appDirectory = fs.realpathSync(process.cwd())
+const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
+
+dotenv.config({ path: resolveApp('examples/.env') })
+
+try {
+ const data = JSON.stringify(
+ {
+ GOOGLEMAPS_TOKEN: process.env.GOOGLEMAPS_TOKEN,
+ MAPBOX_TOKEN: process.env.MAPBOX_TOKEN,
+ JAWG_TOKEN: process.env.JAWG_TOKEN,
+ LEMON_SQUEEZY_LICENSE_KEY: process.env.LEMON_SQUEEZY_LICENSE_KEY
+ },
+ null,
+ '\t'
+ )
+
+ fs.writeFile(resolveApp('examples/credentials.json'), data, 'utf8', (err) => {
+ if (err) {
+ console.error('An error occured when creating credentials file', err)
+ } else {
+ console.log('Credentials file created')
+ }
+ })
+} catch (error) {
+ throw new Error(
+ 'Environments variables are missing in .env ("GOOGLEMAPS_TOKEN", "MAPBOX_TOKEN", "JAWG_TOKEN")'
+ )
+}
diff --git a/config/stylelint.config.js b/config/stylelint.config.cjs
similarity index 51%
rename from config/stylelint.config.js
rename to config/stylelint.config.cjs
index df8ee8ae..43923c69 100644
--- a/config/stylelint.config.js
+++ b/config/stylelint.config.cjs
@@ -5,21 +5,15 @@ module.exports = {
'declaration-colon-newline-after': null,
'value-list-comma-newline-after': null,
'custom-property-pattern': [
- '([a-z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)?$',
+ '^sl(-[a-zA-Z]+)?$',
{
- message: 'Expected custom property name to be FUN-case'
+ message: 'Expected custom property name to be FUN-case with prefix "sl-"'
}
],
'selector-class-pattern': [
- '^([a-z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)?$',
+ '^sl(-[a-zA-Z0-9]+)?$',
{
- message: 'Expected class selector to be FUN-case'
- }
- ],
- 'selector-id-pattern': [
- '^([a-z][a-zA-Z0-9]*)(-[a-z][a-zA-Z0-9]+)?$',
- {
- message: 'Expected id selector to be FUN-case'
+ message: 'Expected class selector to be FUN-case with prefix "sl-"'
}
]
}
diff --git a/config/webpack.config.js b/config/webpack.config.js
deleted file mode 100644
index 4d9e9cba..00000000
--- a/config/webpack.config.js
+++ /dev/null
@@ -1,121 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-const webpack = require('webpack')
-const MiniCssExtractPlugin = require('mini-css-extract-plugin')
-const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
-const TerserPlugin = require('terser-webpack-plugin')
-
-const appDirectory = fs.realpathSync(process.cwd())
-const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
-
-module.exports = (env, argv) => {
- const isProduction = argv.mode === 'production'
-
- const config = {
- context: appDirectory,
- watch: !isProduction,
- entry: {
- storelocator: resolveApp('src/config.js')
- },
- watchOptions: {
- ignored: /node_modules/
- },
- devtool: isProduction ? false : 'source-map',
- output: {
- path: resolveApp('dist'),
- publicPath: '/dist/',
- filename: '[name].js',
- library: {
- name: 'storelocatorjs',
- type: 'umd',
- export: 'default'
- }
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- include: resolveApp('src'),
- use: [
- {
- loader: 'babel-loader',
- options: {
- configFile: resolveApp('config/babel.config.js')
- }
- }
- ]
- },
- {
- test: /\.css$/,
- include: [resolveApp('src'), resolveApp('node_modules/leaflet')],
- use: [
- MiniCssExtractPlugin.loader,
- {
- loader: 'css-loader'
- },
- {
- loader: 'postcss-loader',
- options: {
- postcssOptions: {
- config: resolveApp('config/postcss.config.js')
- }
- }
- }
- ]
- },
- {
- test: /\.svg$/,
- loader: 'svg-inline-loader'
- }
- ]
- },
- plugins: [
- new MiniCssExtractPlugin({
- filename: '[name].css',
- chunkFilename: '[name].css'
- }),
- new webpack.optimize.ModuleConcatenationPlugin()
- ],
- stats: {
- assets: true,
- colors: true,
- hash: false,
- timings: true,
- chunks: false,
- chunkModules: false,
- modules: false,
- children: false,
- entrypoints: false,
- excludeAssets: /.map$/,
- assetsSort: '!size'
- },
- optimization: {
- minimizer: [
- new TerserPlugin({
- extractComments: false,
- parallel: true,
- terserOptions: {
- compress: {
- // Drop console.log|console.info|console.debug
- // Keep console.warn|console.error
- pure_funcs: ['console.log', 'console.info', 'console.debug']
- }
- }
- }),
- new CssMinimizerPlugin()
- ],
- chunkIds: 'deterministic', // or 'named'
- removeAvailableModules: true,
- removeEmptyChunks: true,
- mergeDuplicateChunks: true,
- providedExports: false,
- splitChunks: false
- }
- }
-
- if (!isProduction) {
- config.plugins.push(new webpack.ProgressPlugin())
- }
-
- return config
-}
diff --git a/examples/.env.local b/examples/.env.local
new file mode 100644
index 00000000..dc30d44e
--- /dev/null
+++ b/examples/.env.local
@@ -0,0 +1,3 @@
+GOOGLEMAPS_TOKEN=
+MAPBOX_TOKEN=
+JAWG_TOKEN=
\ No newline at end of file
diff --git a/examples/assets/custom-style.css b/examples/assets/custom-style.css
deleted file mode 100644
index b235ab73..00000000
--- a/examples/assets/custom-style.css
+++ /dev/null
@@ -1,41 +0,0 @@
-.storelocator {
- font-family: 'Roboto', arial, sans-serif;
-}
-
-/* Override form filters style */
-.storelocator-formFilters label.category-1::before {
- border: 2px solid #f60;
-}
-
-.storelocator-formFilters label.category-1::after {
- background-color: #f60;
-}
-
-.storelocator-formFilters label.category-2::before {
- border: 2px solid #fc3;
-}
-
-.storelocator-formFilters label.category-2::after {
- background-color: #fc3;
-}
-
-.storelocator-formFilters label.category-3::before {
- border: 2px solid #ea4c89;
-}
-
-.storelocator-formFilters label.category-3::after {
- background-color: #ea4c89;
-}
-
-/* Override result list item style */
-.storelocator-sidebarResultsListItem[data-category="1"] {
- border-left: 5px solid #f60;
-}
-
-.storelocator-sidebarResultsListItem[data-category="2"] {
- border-left: 5px solid #fc3;
-}
-
-.storelocator-sidebarResultsListItem[data-category="3"] {
- border-left: 5px solid #ea4c89;
-}
\ No newline at end of file
diff --git a/examples/google-maps/config.js b/examples/google-maps/config.js
new file mode 100644
index 00000000..2808f18d
--- /dev/null
+++ b/examples/google-maps/config.js
@@ -0,0 +1,55 @@
+import '../../dist/storelocator.css'
+import Storelocatorjs from '../../dist/storelocator.js'
+import GoogleMaps from '../../dist/map/google-maps.js'
+import credentials from '../credentials.json'
+import mapStyles from './styles.json'
+
+/* eslint-disable no-unused-vars */
+const storelocator = new Storelocatorjs({
+ target: document.querySelector('#app'),
+ licenseKey: credentials.LEMON_SQUEEZY_LICENSE_KEY,
+ api: {
+ url: 'https://storelocatorjs-functions.vercel.app'
+ },
+ map: {
+ provider: GoogleMaps,
+ token: credentials.GOOGLEMAPS_TOKEN,
+ options: {
+ styles: mapStyles.styles
+ }
+ },
+ geocoder: {
+ provider: 'mapbox',
+ token: credentials.MAPBOX_TOKEN
+ },
+ // templates: {
+ // popup: ({ feature }) => {
+ // return `${feature.properties.title}`
+ // },
+ // result: ({ feature }) => {
+ // return `${feature.properties.title}`
+ // }
+ // },
+ onReady: (map) => {
+ console.log('onReady', map)
+
+ map.on('progress', () => {
+ console.log('progress')
+ })
+ map.on('userPosition', (data) => {
+ console.log('userPosition', data)
+ })
+ map.on('storeFound', () => {
+ console.log('storeFound')
+ })
+ map.on('storeNotFound', () => {
+ console.log('storeNotFound')
+ })
+ map.on('zoomIn', () => {
+ console.log('zoomIn')
+ })
+ map.on('zoomOut', () => {
+ console.log('zoomOut')
+ })
+ }
+})
diff --git a/examples/google-maps/index.html b/examples/google-maps/index.html
new file mode 100644
index 00000000..3e4dbf1b
--- /dev/null
+++ b/examples/google-maps/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Storelocatorjs - Google Maps
+
+
+
+
+
+
+
diff --git a/examples/google-maps/styles.json b/examples/google-maps/styles.json
new file mode 100644
index 00000000..8a3a3812
--- /dev/null
+++ b/examples/google-maps/styles.json
@@ -0,0 +1,119 @@
+{
+ "styles": [
+ {
+ "featureType": "administrative",
+ "elementType": "labels.text.fill",
+ "stylers": [{ "color": "#6195a0" }]
+ },
+ {
+ "featureType": "administrative.province",
+ "elementType": "geometry.stroke",
+ "stylers": [{ "visibility": "off" }]
+ },
+ {
+ "featureType": "landscape",
+ "elementType": "geometry",
+ "stylers": [
+ { "lightness": "0" },
+ { "saturation": "0" },
+ { "color": "#f5f5f2" },
+ { "gamma": "1" }
+ ]
+ },
+ {
+ "featureType": "landscape.man_made",
+ "elementType": "all",
+ "stylers": [{ "lightness": "-3" }, { "gamma": "1.00" }]
+ },
+ {
+ "featureType": "landscape.natural.terrain",
+ "elementType": "all",
+ "stylers": [{ "visibility": "off" }]
+ },
+ {
+ "featureType": "poi",
+ "elementType": "all",
+ "stylers": [{ "visibility": "off" }]
+ },
+ {
+ "featureType": "poi.park",
+ "elementType": "geometry.fill",
+ "stylers": [{ "color": "#bae5ce" }, { "visibility": "on" }]
+ },
+ {
+ "featureType": "road",
+ "elementType": "all",
+ "stylers": [{ "saturation": -100 }, { "lightness": 45 }, { "visibility": "simplified" }]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "all",
+ "stylers": [{ "visibility": "simplified" }]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "geometry.fill",
+ "stylers": [{ "color": "#fac9a9" }, { "visibility": "simplified" }]
+ },
+ {
+ "featureType": "road.highway",
+ "elementType": "labels.text",
+ "stylers": [{ "color": "#4e4e4e" }]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "labels.text.fill",
+ "stylers": [{ "color": "#787878" }]
+ },
+ {
+ "featureType": "road.arterial",
+ "elementType": "labels.icon",
+ "stylers": [{ "visibility": "off" }]
+ },
+ {
+ "featureType": "transit",
+ "elementType": "all",
+ "stylers": [{ "visibility": "simplified" }]
+ },
+ {
+ "featureType": "transit.station.airport",
+ "elementType": "labels.icon",
+ "stylers": [
+ { "hue": "#0a00ff" },
+ { "saturation": "-77" },
+ { "gamma": "0.57" },
+ { "lightness": "0" }
+ ]
+ },
+ {
+ "featureType": "transit.station.rail",
+ "elementType": "labels.text.fill",
+ "stylers": [{ "color": "#43321e" }]
+ },
+ {
+ "featureType": "transit.station.rail",
+ "elementType": "labels.icon",
+ "stylers": [
+ { "hue": "#ff6c00" },
+ { "lightness": "4'" },
+ { "gamma": "0.75" },
+ { "saturation": "-68" }
+ ]
+ },
+ {
+ "featureType": "water",
+ "elementType": "all",
+ "stylers": [{ "color": "#eaf6f8" }, { "visibility": "on'" }]
+ },
+ {
+ "featureType": "water",
+ "elementType": "geometry.fill",
+ "stylers": [{ "color": "#c7eced" }]
+ },
+ {
+ "featureType": "water",
+ "elementType": "labels.text.fill",
+ "stylers": [{ "lightness": "-49" }, { "saturation": "-53" }, { "gamma": "0.79" }]
+ }
+ ]
+}
diff --git a/examples/home/index.html b/examples/home/index.html
index 21513bec..9a3fa757 100644
--- a/examples/home/index.html
+++ b/examples/home/index.html
@@ -12,19 +12,10 @@