Compare commits

...

8 Commits

Author SHA1 Message Date
HarelM 3b95b25777 Remove unneed console.log 2024-01-13 14:38:56 +02:00
Harel M 1da65f2116 Fix missing logo (#863)
Fixes #861
This should hopefully address the last item in the below issue of the
missing logo.
I tested it locally and it seems to be working as expected, I hope this
will be the case once deployed.
- #861
2024-01-12 18:46:10 +02:00
Harel M a62db148cd Remove Storybook, cleanups (#860)
1. Changed references to point to this new repo
2. Fixed docker image publishing to point to ghcr.io.
3. Remove survey link - the survey is closed and there's no point in
keeping it.
4. Remove storybook - Basically a storybook is the ability to look at
components and see how they look and interact with them.
It's a powerful tool for developing component library with "live"
documentation.
But it's an overkill for this project and I would like to reduce
maintenance costs.
Currently all the "stories" are in javascript and not in typescript and
it feels like a waste of time to try and maintain it, along with
updating the storybook library itself and everything around it.
2024-01-12 10:59:57 +02:00
HarelM 6ed10a862f Update pages deploy on every commit to main 2024-01-11 22:57:07 +02:00
HarelM 123e84f19b login to ghcr.io 2024-01-11 22:29:46 +02:00
HarelM d9b1b6f3ae Fix docker deploy, remove unneeded files 2024-01-11 22:24:47 +02:00
Harel M e0cef99c07 Update LICENSE 2024-01-11 22:11:18 +02:00
Harel M eb48bed32a Update MapLibre dependencies, add terrain editing (#859)
This PR aims at updating MapLibre dependencies.

The main goal of this update is to allow adding terrain specification to
the editor.
This requires version 4 of maplibre so currently it will use the
pre-release.
2024-01-11 22:05:47 +02:00
80 changed files with 500 additions and 7069 deletions
-4
View File
@@ -1,4 +0,0 @@
{
"packages": [],
"sandboxes": ["/"]
}
+3 -9
View File
@@ -15,7 +15,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:main . - run: docker build -t test-docker-image-build .
# build the editor # build the editor
build-node: build-node:
@@ -53,17 +53,11 @@ jobs:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
- run: npm ci - run: npm ci
- run: npm run build - run: npm run build
- run: npm run build-storybook - name: artifacts/maputnik
- name: artifacts/editor
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v1
with: with:
name: editor name: maputnik
path: dist path: dist
- name: artifacts/storybook
uses: actions/upload-artifact@v1
with:
name: storybook
path: build/storybook
# Build and upload desktop CLI artifacts # Build and upload desktop CLI artifacts
- name: Set up Go - name: Set up Go
+33 -8
View File
@@ -3,24 +3,49 @@ name: deploy
on: on:
push: push:
branches: [ main ] branches: [ main ]
tags:
- 'v*'
jobs: jobs:
deploy-pages:
name: deploy/pages
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' }}
steps:
- uses: actions/checkout@v4
- name: Use Node.js from nvmrc
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install
run: npm ci
- name: Build
run: npm run build
- name: Upload to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: dist
# publish docker to GitHub registry # publish docker to GitHub registry
deploy-docker: deploy-docker:
name: deploy/docker name: deploy/docker
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' }} if: ${{ github.event_name == 'push' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix:
os: [ubuntu-latest]
steps: steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u orangemug --password-stdin - run: docker build -t ghcr.io/maplibre/maputnik:main .
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:main . - run: docker push ghcr.io/maplibre/maputnik:main
- run: docker push docker.pkg.github.com/maputnik/editor/editor:main
-9
View File
@@ -1,9 +0,0 @@
const config = {
stories: ['../stories/**/*.stories.jsx'],
addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-a11y/register', '@storybook/addon-storysource'],
framework: {
name: '@storybook/react-vite',
options: {}
}
};
export default config;
-7
View File
@@ -1,7 +0,0 @@
import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
import theme from './maputnik.theme';
addons.setConfig({
theme: theme,
});
-8
View File
@@ -1,8 +0,0 @@
import { create } from '@storybook/theming/create';
export default create({
base: 'light',
brandTitle: 'Maputnik',
brandUrl: 'https://github.com/maputnik/editor',
});
+1 -1
View File
@@ -7,7 +7,7 @@ RUN npm install
# Build maputnik # Build maputnik
COPY . . COPY . .
RUN npm run build RUN npx vite build
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Create a clean nginx-alpine slim image with just the build results # Create a clean nginx-alpine slim image with just the build results
+1
View File
@@ -1,5 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2015 Lukas Martinelli
Copyright (c) 2024 MapLibre contributors Copyright (c) 2024 MapLibre contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
+6 -6
View File
@@ -1,10 +1,10 @@
<img width="200" alt="Maputnik logo" src="https://cdn.jsdelivr.net/gh/maputnik/design/logos/logo-color.png" /> <img width="200" alt="Maputnik logo" src="https://cdn.jsdelivr.net/gh/maputnik/design/logos/logo-color.png" />
# Maputnik # Maputnik
[![GitHub CI status](https://github.com/maputnik/editor/workflows/ci/badge.svg)][github-action-ci] [![GitHub CI status](https://github.com/maplibre/maputnik/workflows/ci/badge.svg)][github-action-ci]
[![License](https://img.shields.io/badge/license-MIT-blue.svg)][license] [![License](https://img.shields.io/badge/license-MIT-blue.svg)][license]
[github-action-ci]: https://github.com/maputnik/editor/actions?query=workflow%3Aci [github-action-ci]: https://github.com/maplibre/maputnik/actions?query=workflow%3Aci
[license]: https://tldrlegal.com/license/mit-license [license]: https://tldrlegal.com/license/mit-license
A free and open visual editor for the [MapLibre GL styles](https://maplibre.org/maplibre-style-spec/) A free and open visual editor for the [MapLibre GL styles](https://maplibre.org/maplibre-style-spec/)
@@ -14,18 +14,18 @@ targeted at developers and map designers.
## Usage ## Usage
- :link: Design your maps online at **<https://www.maplibre.org/maputnik/>** (all in local storage) - :link: Design your maps online at **<https://www.maplibre.org/maputnik/>** (all in local storage)
- :link: Use the [Maputnik CLI](https://github.com/maputnik/editor/wiki/Maputnik-CLI) for local style development - :link: Use the [Maputnik CLI](https://github.com/maplibre/maputnik/wiki/Maputnik-CLI) for local style development
- In a Docker, run this command and browse to http://localhost:8888, Ctrl+C to stop the server. - In a Docker, run this command and browse to http://localhost:8888, Ctrl+C to stop the server.
```bash ```bash
docker run -it --rm -p 8888:8888 maputnik/editor docker run -it --rm -p 8888:8888 ghcr.io/maplibre/maputnik:main
``` ```
## Documentation ## Documentation
The documentation can be found in the [Wiki](https://github.com/maputnik/editor/wiki). You are welcome to collaborate! The documentation can be found in the [Wiki](https://github.com/maplibre/maputnik/wiki). You are welcome to collaborate!
- :link: **Study the [Maputnik Wiki](https://github.com/maputnik/editor/wiki)** - :link: **Study the [Maputnik Wiki](https://github.com/maplibre/maputnik/wiki)**
- :video_camera: Design a map from Scratch https://youtu.be/XoDh0gEnBQo - :video_camera: Design a map from Scratch https://youtu.be/XoDh0gEnBQo
[![Design Map from Scratch](https://j.gifs.com/g5XMgl.gif)](https://youtu.be/XoDh0gEnBQo) [![Design Map from Scratch](https://j.gifs.com/g5XMgl.gif)](https://youtu.be/XoDh0gEnBQo)
+2 -2
View File
@@ -79,12 +79,12 @@ describe("modals", () => {
when.click("nav:settings"); when.click("nav:settings");
}); });
describe("when click name", () => { describe("when click name filed spec information", () => {
beforeEach(() => { beforeEach(() => {
when.click("field-doc-button-Name"); when.click("field-doc-button-Name");
}); });
it("name", () => { it("should show the spec information", () => {
then(get.elementsText("spec-field-doc")).shouldInclude( then(get.elementsText("spec-field-doc")).shouldInclude(
"name for the style" "name for the style"
); );
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

+366 -5084
View File
File diff suppressed because it is too large Load Diff
+6 -18
View File
@@ -6,24 +6,22 @@
"main": "''", "main": "''",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
"build": "tsc && vite build", "build": "tsc && vite build --base=/maputnik/",
"lint": "eslint ./src ./cypress --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint ./src ./cypress --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0",
"test": "cypress run", "test": "cypress run",
"cy:open": "cypress open", "cy:open": "cypress open",
"lint-css": "stylelint \"src/styles/*.scss\"", "lint-css": "stylelint \"src/styles/*.scss\""
"storybook": "storybook dev -h 0.0.0.0 -p 6006",
"build-storybook": "storybook build -o build/storybook"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/maputnik/editor" "url": "https://github.com/maplibre/maputnik"
}, },
"author": "Lukas Martinelli", "author": "Lukas Martinelli",
"license": "MIT", "license": "MIT",
"homepage": "https://github.com/maputnik/editor#readme", "homepage": "https://github.com/maplibre/maputnik#readme",
"dependencies": { "dependencies": {
"@mapbox/mapbox-gl-rtl-text": "^0.2.3", "@mapbox/mapbox-gl-rtl-text": "^0.2.3",
"@maplibre/maplibre-gl-style-spec": "^17.0.1", "@maplibre/maplibre-gl-style-spec": "^20.1.0",
"@mdi/js": "^6.6.96", "@mdi/js": "^6.6.96",
"@mdi/react": "^1.5.0", "@mdi/react": "^1.5.0",
"@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/eslint-plugin": "^6.16.0",
@@ -46,7 +44,7 @@
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"mapbox-gl-inspect": "^1.3.1", "mapbox-gl-inspect": "^1.3.1",
"maplibre-gl": "^2.4.0", "maplibre-gl": "^4.0.0-pre.4",
"maputnik-design": "github:maputnik/design#172b06c", "maputnik-design": "github:maputnik/design#172b06c",
"ol": "^6.14.1", "ol": "^6.14.1",
"ol-mapbox-style": "^7.1.1", "ol-mapbox-style": "^7.1.1",
@@ -92,15 +90,6 @@
"@istanbuljs/nyc-config-typescript": "^1.0.2", "@istanbuljs/nyc-config-typescript": "^1.0.2",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@shellygo/cypress-test-utils": "^2.0.17", "@shellygo/cypress-test-utils": "^2.0.17",
"@storybook/addon-a11y": "^7.6.5",
"@storybook/addon-actions": "^7.6.5",
"@storybook/addon-links": "^7.6.5",
"@storybook/addon-storysource": "^7.6.5",
"@storybook/addons": "^7.6.5",
"@storybook/builder-vite": "^7.6.5",
"@storybook/react": "^7.6.5",
"@storybook/react-vite": "^7.6.5",
"@storybook/theming": "^7.6.5",
"@types/codemirror": "^5.60.15", "@types/codemirror": "^5.60.15",
"@types/color": "^3.0.6", "@types/color": "^3.0.6",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
@@ -137,7 +126,6 @@
"mocha": "^9.2.2", "mocha": "^9.2.2",
"postcss": "^8.4.12", "postcss": "^8.4.12",
"react-hot-loader": "^4.13.0", "react-hot-loader": "^4.13.0",
"storybook": "^7.6.5",
"stylelint": "^14.6.1", "stylelint": "^14.6.1",
"stylelint-config-recommended-scss": "^6.0.0", "stylelint-config-recommended-scss": "^6.0.0",
"stylelint-scss": "^4.2.0", "stylelint-scss": "^4.2.0",
+2 -3
View File
@@ -9,7 +9,7 @@ import {unset} from 'lodash'
import {arrayMoveMutable} from 'array-move' import {arrayMoveMutable} from 'array-move'
import hash from "string-hash"; import hash from "string-hash";
import {Map, LayerSpecification, StyleSpecification, ValidationError, SourceSpecification} from 'maplibre-gl' import {Map, LayerSpecification, StyleSpecification, ValidationError, SourceSpecification} from 'maplibre-gl'
import {latest, validate} from '@maplibre/maplibre-gl-style-spec' import {latest, validateStyleMin} from '@maplibre/maplibre-gl-style-spec'
import MapMaplibreGl from './MapMaplibreGl' import MapMaplibreGl from './MapMaplibreGl'
import MapOpenLayers from './MapOpenLayers' import MapOpenLayers from './MapOpenLayers'
@@ -379,8 +379,7 @@ export default class App extends React.Component<any, AppState> {
this.getInitialStateFromUrl(newStyle); this.getInitialStateFromUrl(newStyle);
} }
// This "any" can be removed in latest version of maplibre where maplibre re-exported types from style-spec const errors: ValidationError[] = validateStyleMin(newStyle) || [];
const errors = validate(newStyle as any, latest) || [];
// The validate function doesn't give us errors for duplicate error with // The validate function doesn't give us errors for duplicate error with
// empty string for layer.id, manually deal with that here. // empty string for layer.id, manually deal with that here.
+6 -32
View File
@@ -2,9 +2,10 @@ import React from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import {detect} from 'detect-browser'; import {detect} from 'detect-browser';
import {MdFileDownload, MdOpenInBrowser, MdSettings, MdLayers, MdHelpOutline, MdFindInPage, MdAssignmentTurnedIn} from 'react-icons/md' import {MdFileDownload, MdOpenInBrowser, MdSettings, MdLayers, MdHelpOutline, MdFindInPage} from 'react-icons/md'
import pkgJson from '../../package.json' import pkgJson from '../../package.json'
//@ts-ignore
import maputnikLogo from 'maputnik-design/logos/logo-color.svg?inline'
// This is required because of <https://stackoverflow.com/a/49846426>, there isn't another way to detect support that I'm aware of. // This is required because of <https://stackoverflow.com/a/49846426>, there isn't another way to detect support that I'm aware of.
const browser = detect(); const browser = detect();
@@ -43,29 +44,6 @@ class ToolbarLink extends React.Component<ToolbarLinkProps> {
} }
} }
type ToolbarLinkHighlightedProps = {
className?: string
children?: React.ReactNode
href?: string
onToggleModal?(...args: unknown[]): unknown
};
class ToolbarLinkHighlighted extends React.Component<ToolbarLinkHighlightedProps> {
render() {
return <a
className={classnames('maputnik-toolbar-link', "maputnik-toolbar-link--highlighted", this.props.className)}
href={this.props.href}
rel="noopener noreferrer"
target="_blank"
data-wd-key="toolbar:link-highlighted"
>
<span className="maputnik-toolbar-link-wrapper">
{this.props.children}
</span>
</a>
}
}
type ToolbarSelectProps = { type ToolbarSelectProps = {
children?: React.ReactNode children?: React.ReactNode
wdKey?: string wdKey?: string
@@ -216,9 +194,9 @@ export default class AppToolbar extends React.Component<AppToolbarProps> {
className="maputnik-toolbar-logo" className="maputnik-toolbar-logo"
target="blank" target="blank"
rel="noreferrer noopener" rel="noreferrer noopener"
href="https://github.com/maputnik/editor" href="https://github.com/maplibre/maputnik"
> >
<img src="node_modules/maputnik-design/logos/logo-color.svg" /> <img src={maputnikLogo} alt="Maputnik on GitHub" />
<h1> <h1>
<span className="maputnik-toolbar-name">{pkgJson.name}</span> <span className="maputnik-toolbar-name">{pkgJson.name}</span>
<span className="maputnik-toolbar-version">v{pkgJson.version}</span> <span className="maputnik-toolbar-version">v{pkgJson.version}</span>
@@ -272,14 +250,10 @@ export default class AppToolbar extends React.Component<AppToolbarProps> {
</label> </label>
</ToolbarSelect> </ToolbarSelect>
<ToolbarLink href={"https://github.com/maputnik/editor/wiki"}> <ToolbarLink href={"https://github.com/maplibre/maputnik/wiki"}>
<MdHelpOutline /> <MdHelpOutline />
<IconText>Help</IconText> <IconText>Help</IconText>
</ToolbarLink> </ToolbarLink>
<ToolbarLinkHighlighted href={"https://gregorywolanski.typeform.com/to/cPgaSY"}>
<MdAssignmentTurnedIn />
<IconText>Take the Maputnik Survey</IconText>
</ToolbarLinkHighlighted>
</div> </div>
</div> </div>
</nav> </nav>
+1 -1
View File
@@ -31,7 +31,7 @@ export default class Doc extends React.Component<DocProps> {
const renderValues = ( const renderValues = (
!!values && !!values &&
// HACK: Currently we merge additional values into the style spec, so this is required // HACK: Currently we merge additional values into the style spec, so this is required
// See <https://github.com/maputnik/editor/blob/main/src/components/PropertyGroup.jsx#L16> // See <https://github.com/maplibre/maputnik/blob/main/src/components/PropertyGroup.jsx#L16>
!Array.isArray(values) !Array.isArray(values)
); );
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import Block from './Block' import Block from './Block'
import InputString from './InputString' import InputString from './InputString'
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import Block from './Block' import Block from './Block'
import InputNumber from './InputNumber' import InputNumber from './InputNumber'
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import Block from './Block' import Block from './Block'
import InputNumber from './InputNumber' import InputNumber from './InputNumber'
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import Block from './Block' import Block from './Block'
import InputAutocomplete from './InputAutocomplete' import InputAutocomplete from './InputAutocomplete'
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import Block from './Block' import Block from './Block'
import InputSelect from './InputSelect' import InputSelect from './InputSelect'
import InputString from './InputString' import InputString from './InputString'
+1 -1
View File
@@ -47,7 +47,7 @@ function createStyleFromFilter(filter: LegacyFilterSpecification | ExpressionSpe
"sources": { "sources": {
"tmp": { "tmp": {
"type": "geojson", "type": "geojson",
"data": {} "data": ''
} }
}, },
"sprite": "", "sprite": "",
+8 -28
View File
@@ -14,9 +14,6 @@ import 'maplibre-gl/dist/maplibre-gl.css'
import '../maplibregl.css' import '../maplibregl.css'
import '../libs/maplibre-rtl' import '../libs/maplibre-rtl'
const IS_SUPPORTED = MapLibreGl.supported();
function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container) { function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container) {
ReactDOM.render(popup, mountNode); ReactDOM.render(popup, mountNode);
return mountNode; return mountNode;
@@ -92,8 +89,6 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
} }
updateMapFromProps(props: MapMaplibreGlProps) { updateMapFromProps(props: MapMaplibreGlProps) {
if(!IS_SUPPORTED) return;
if(!this.state.map) return if(!this.state.map) return
//Maplibre GL now does diffing natively so we don't need to calculate //Maplibre GL now does diffing natively so we don't need to calculate
@@ -115,14 +110,12 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
} }
componentDidUpdate() { componentDidUpdate() {
if(!IS_SUPPORTED) return;
const map = this.state.map; const map = this.state.map;
this.updateMapFromProps(this.props); this.updateMapFromProps(this.props);
if(this.state.inspect && this.props.inspectModeEnabled !== this.state.inspect._showInspectMap) { if(this.state.inspect && this.props.inspectModeEnabled !== this.state.inspect._showInspectMap) {
// HACK: Fix for <https://github.com/maputnik/editor/issues/576>, while we wait for a proper fix. // HACK: Fix for <https://github.com/maplibre/maputnik/issues/576>, while we wait for a proper fix.
// eslint-disable-next-line // eslint-disable-next-line
this.state.inspect._popupBlocked = false; this.state.inspect._popupBlocked = false;
this.state.inspect.toggleInspector() this.state.inspect.toggleInspector()
@@ -146,8 +139,6 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
} }
componentDidMount() { componentDidMount() {
if(!IS_SUPPORTED) return;
const mapOpts = { const mapOpts = {
...this.props.options, ...this.props.options,
container: this.container!, container: this.container!,
@@ -235,24 +226,13 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
} }
render() { render() {
if(IS_SUPPORTED) { return <div
return <div className="maputnik-map__map"
className="maputnik-map__map" role="region"
role="region" aria-label="Map view"
aria-label="Map view" ref={x => this.container = x}
ref={x => this.container = x} data-wd-key="maplibre:map"
data-wd-key="maplibre:map" ></div>
></div>
}
else {
return <div
className="maputnik-map maputnik-map--error"
>
<div className="maputnik-map__error-message">
Error: Cannot load MaplibreGL, WebGL is either unsupported or disabled
</div>
</div>
}
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ export default class Modal extends React.Component<ModalProps> {
underlayClickExits: true underlayClickExits: true
} }
// See <https://github.com/maputnik/editor/issues/416> // See <https://github.com/maplibre/maputnik/issues/416>
onClose = () => { onClose = () => {
if (document.activeElement) { if (document.activeElement) {
(document.activeElement as HTMLElement).blur(); (document.activeElement as HTMLElement).blur();
+47 -21
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import type {LightSpecification, StyleSpecification, TransitionSpecification} from 'maplibre-gl' import type {LightSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from 'maplibre-gl'
import FieldArray from './FieldArray' import FieldArray from './FieldArray'
import FieldNumber from './FieldNumber' import FieldNumber from './FieldNumber'
@@ -58,6 +58,25 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
}); });
} }
changeTerrainProperty(property: keyof TerrainSpecification, value: any) {
const terrain = {
...this.props.mapStyle.terrain,
}
if (value === undefined) {
delete terrain[property];
}
else {
// @ts-ignore
terrain[property] = value;
}
this.props.onStyleChanged({
...this.props.mapStyle,
terrain,
});
}
changeStyleProperty(property: keyof StyleSpecification | "owner", value: any) { changeStyleProperty(property: keyof StyleSpecification | "owner", value: any) {
const changedStyle = { const changedStyle = {
...this.props.mapStyle, ...this.props.mapStyle,
@@ -77,10 +96,10 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
render() { render() {
const metadata = this.props.mapStyle.metadata || {} as any; const metadata = this.props.mapStyle.metadata || {} as any;
const {onChangeMetadataProperty, mapStyle} = this.props; const {onChangeMetadataProperty, mapStyle} = this.props;
const inputProps = { }
const light = this.props.mapStyle.light || {}; const light = this.props.mapStyle.light || {};
const transition = this.props.mapStyle.transition || {}; const transition = this.props.mapStyle.transition || {};
const terrain = this.props.mapStyle.terrain || {} as TerrainSpecification;
return <Modal return <Modal
data-wd-key="modal:settings" data-wd-key="modal:settings"
@@ -89,21 +108,21 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
title={'Style Settings'} title={'Style Settings'}
> >
<div className="modal:settings"> <div className="modal:settings">
<FieldString {...inputProps} <FieldString
label={"Name"} label={"Name"}
fieldSpec={latest.$root.name} fieldSpec={latest.$root.name}
data-wd-key="modal:settings.name" data-wd-key="modal:settings.name"
value={this.props.mapStyle.name} value={this.props.mapStyle.name}
onChange={this.changeStyleProperty.bind(this, "name")} onChange={this.changeStyleProperty.bind(this, "name")}
/> />
<FieldString {...inputProps} <FieldString
label={"Owner"} label={"Owner"}
fieldSpec={{doc: "Owner ID of the style. Used by Mapbox or future style APIs."}} fieldSpec={{doc: "Owner ID of the style. Used by Mapbox or future style APIs."}}
data-wd-key="modal:settings.owner" data-wd-key="modal:settings.owner"
value={(this.props.mapStyle as any).owner} value={(this.props.mapStyle as any).owner}
onChange={this.changeStyleProperty.bind(this, "owner")} onChange={this.changeStyleProperty.bind(this, "owner")}
/> />
<FieldUrl {...inputProps} <FieldUrl
fieldSpec={latest.$root.sprite} fieldSpec={latest.$root.sprite}
label="Sprite URL" label="Sprite URL"
data-wd-key="modal:settings.sprite" data-wd-key="modal:settings.sprite"
@@ -111,7 +130,7 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
onChange={this.changeStyleProperty.bind(this, "sprite")} onChange={this.changeStyleProperty.bind(this, "sprite")}
/> />
<FieldUrl {...inputProps} <FieldUrl
label="Glyphs URL" label="Glyphs URL"
fieldSpec={latest.$root.glyphs} fieldSpec={latest.$root.glyphs}
data-wd-key="modal:settings.glyphs" data-wd-key="modal:settings.glyphs"
@@ -119,7 +138,7 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
onChange={this.changeStyleProperty.bind(this, "glyphs")} onChange={this.changeStyleProperty.bind(this, "glyphs")}
/> />
<FieldString {...inputProps} <FieldString
label={fieldSpecAdditional.maputnik.maptiler_access_token.label} label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token} fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
data-wd-key="modal:settings.maputnik:openmaptiles_access_token" data-wd-key="modal:settings.maputnik:openmaptiles_access_token"
@@ -127,7 +146,7 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
onChange={onChangeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")} onChange={onChangeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
/> />
<FieldString {...inputProps} <FieldString
label={fieldSpecAdditional.maputnik.thunderforest_access_token.label} label={fieldSpecAdditional.maputnik.thunderforest_access_token.label}
fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token} fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token}
data-wd-key="modal:settings.maputnik:thunderforest_access_token" data-wd-key="modal:settings.maputnik:thunderforest_access_token"
@@ -141,21 +160,19 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
length={2} length={2}
type="number" type="number"
value={mapStyle.center || []} value={mapStyle.center || []}
default={latest.$root.center.default || [0, 0]} default={[0, 0]}
onChange={this.changeStyleProperty.bind(this, "center")} onChange={this.changeStyleProperty.bind(this, "center")}
/> />
<FieldNumber <FieldNumber
{...inputProps}
label={"Zoom"} label={"Zoom"}
fieldSpec={latest.$root.zoom} fieldSpec={latest.$root.zoom}
value={mapStyle.zoom} value={mapStyle.zoom}
default={latest.$root.zoom.default || 0} default={0}
onChange={this.changeStyleProperty.bind(this, "zoom")} onChange={this.changeStyleProperty.bind(this, "zoom")}
/> />
<FieldNumber <FieldNumber
{...inputProps}
label={"Bearing"} label={"Bearing"}
fieldSpec={latest.$root.bearing} fieldSpec={latest.$root.bearing}
value={mapStyle.bearing} value={mapStyle.bearing}
@@ -164,7 +181,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldNumber <FieldNumber
{...inputProps}
label={"Pitch"} label={"Pitch"}
fieldSpec={latest.$root.pitch} fieldSpec={latest.$root.pitch}
value={mapStyle.pitch} value={mapStyle.pitch}
@@ -173,7 +189,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldEnum <FieldEnum
{...inputProps}
label={"Light anchor"} label={"Light anchor"}
fieldSpec={latest.light.anchor} fieldSpec={latest.light.anchor}
name="light-anchor" name="light-anchor"
@@ -184,7 +199,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldColor <FieldColor
{...inputProps}
label={"Light color"} label={"Light color"}
fieldSpec={latest.light.color} fieldSpec={latest.light.color}
value={light.color as string} value={light.color as string}
@@ -193,7 +207,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldNumber <FieldNumber
{...inputProps}
label={"Light intensity"} label={"Light intensity"}
fieldSpec={latest.light.intensity} fieldSpec={latest.light.intensity}
value={light.intensity as number} value={light.intensity as number}
@@ -202,7 +215,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldArray <FieldArray
{...inputProps}
label={"Light position"} label={"Light position"}
fieldSpec={latest.light.position} fieldSpec={latest.light.position}
type="number" type="number"
@@ -212,8 +224,23 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
onChange={this.changeLightProperty.bind(this, "position")} onChange={this.changeLightProperty.bind(this, "position")}
/> />
<FieldString
label={"Terrain source"}
fieldSpec={latest.terrain.source}
data-wd-key="modal:settings.maputnik:terrain_source"
value={terrain.source}
onChange={this.changeTerrainProperty.bind(this, "source")}
/>
<FieldNumber
label={"Terrain exaggeration"}
fieldSpec={latest.terrain.exaggeration}
value={terrain.exaggeration}
default={latest.terrain.exaggeration.default}
onChange={this.changeTerrainProperty.bind(this, "exaggeration")}
/>
<FieldNumber <FieldNumber
{...inputProps}
label={"Transition delay"} label={"Transition delay"}
fieldSpec={latest.transition.delay} fieldSpec={latest.transition.delay}
value={transition.delay} value={transition.delay}
@@ -222,7 +249,6 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
/> />
<FieldNumber <FieldNumber
{...inputProps}
label={"Transition duration"} label={"Transition duration"}
fieldSpec={latest.transition.duration} fieldSpec={latest.transition.duration}
value={transition.duration} value={transition.duration}
@@ -230,7 +256,7 @@ export default class ModalSettings extends React.Component<ModalSettingsProps> {
onChange={this.changeTransitionProperty.bind(this, "duration")} onChange={this.changeTransitionProperty.bind(this, "duration")}
/> />
<FieldSelect {...inputProps} <FieldSelect
label={fieldSpecAdditional.maputnik.style_renderer.label} label={fieldSpecAdditional.maputnik.style_renderer.label}
fieldSpec={fieldSpecAdditional.maputnik.style_renderer} fieldSpec={fieldSpecAdditional.maputnik.style_renderer}
data-wd-key="modal:settings.maputnik:renderer" data-wd-key="modal:settings.maputnik:renderer"
+2 -2
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {MdAddCircleOutline, MdDelete} from 'react-icons/md' import {MdAddCircleOutline, MdDelete} from 'react-icons/md'
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import type {GeoJSONSourceSpecification, RasterDEMSourceSpecification, RasterSourceSpecification, SourceSpecification, StyleSpecification, VectorSourceSpecification} from 'maplibre-gl' import type {GeoJSONSourceSpecification, RasterDEMSourceSpecification, RasterSourceSpecification, SourceSpecification, StyleSpecification, VectorSourceSpecification} from 'maplibre-gl'
import Modal from './Modal' import Modal from './Modal'
@@ -134,7 +134,7 @@ class AddSource extends React.Component<AddSourceProps, AddSourceState> {
case 'geojson_json': return { case 'geojson_json': return {
type: 'geojson', type: 'geojson',
cluster: (source as GeoJSONSourceSpecification).cluster || false, cluster: (source as GeoJSONSourceSpecification).cluster || false,
data: {} data: ''
} }
case 'tilejson_vector': return { case 'tilejson_vector': return {
type: 'vector', type: 'vector',
+2 -2
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js'; import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import InputButton from './InputButton' import InputButton from './InputButton'
import InputSpec from './InputSpec' import InputSpec from './InputSpec'
@@ -302,7 +302,7 @@ export default class DataProperty extends React.Component<DataPropertyProps, Dat
<div className="maputnik-data-spec-property-input"> <div className="maputnik-data-spec-property-input">
<InputSpec <InputSpec
fieldName={"base"} fieldName={"base"}
fieldSpec={latest.function.base} fieldSpec={latest.function.base as typeof latest.function.base & { type: "number" }}
value={this.props.value?.base} value={this.props.value?.base}
onChange={(_, newValue) => this.changeBase(newValue as number)} onChange={(_, newValue) => this.changeBase(newValue as number)}
/> />
+2 -2
View File
@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js'; import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
import InputButton from './InputButton' import InputButton from './InputButton'
import InputSpec from './InputSpec' import InputSpec from './InputSpec'
@@ -207,7 +207,7 @@ export default class ZoomProperty extends React.Component<ZoomPropertyProps, Zoo
<div className="maputnik-data-spec-property-input"> <div className="maputnik-data-spec-property-input">
<InputSpec <InputSpec
fieldName={"base"} fieldName={"base"}
fieldSpec={latest.function.base} fieldSpec={latest.function.base as typeof latest.function.base & { type: "number" }}
value={this.props.value?.base} value={this.props.value?.base}
onChange={(_, newValue) => this.changeBase(newValue as number | undefined)} onChange={(_, newValue) => this.changeBase(newValue as number | undefined)}
/> />
+1 -1
View File
@@ -1,4 +1,4 @@
{ {
"openmaptiles": "KDhMfHvorAFkFe64wlZb", "openmaptiles": "get_your_own_OpIi9ZULNHzrESv6T2vL",
"thunderforest": "b71f7f0ba4064f5eb9e903859a9cf5c6" "thunderforest": "b71f7f0ba4064f5eb9e903859a9cf5c6"
} }
+2 -2
View File
@@ -2,7 +2,7 @@
import jsonlint from 'jsonlint'; import jsonlint from 'jsonlint';
import CodeMirror, { MarkerRange } from 'codemirror'; import CodeMirror, { MarkerRange } from 'codemirror';
import jsonToAst from 'json-to-ast'; import jsonToAst from 'json-to-ast';
import {expression, validate} from '@maplibre/maplibre-gl-style-spec'; import {expression, validateStyleMin} from '@maplibre/maplibre-gl-style-spec';
type MarkerRangeWithMessage = MarkerRange & {message: string}; type MarkerRangeWithMessage = MarkerRange & {message: string};
@@ -102,7 +102,7 @@ CodeMirror.registerHelper("lint", "mgl", (text: string, opts: any, doc: any) =>
let out: ReturnType<typeof expression.createExpression> | null = null; let out: ReturnType<typeof expression.createExpression> | null = null;
if (context === "layer") { if (context === "layer") {
// Just an empty style so we can validate a layer. // Just an empty style so we can validate a layer.
const errors = validate({ const errors = validateStyleMin({
"version": 8, "version": 8,
"name": "Empty Style", "name": "Empty Style",
"metadata": {}, "metadata": {},
+1 -1
View File
@@ -1,4 +1,4 @@
import {latest} from '@maplibre/maplibre-gl-style-spec' import latest from '@maplibre/maplibre-gl-style-spec/dist/latest.json'
export const combiningFilterOps = ['all', 'any', 'none']; export const combiningFilterOps = ['all', 'any', 'none'];
export const setFilterOps = ['in', '!in']; export const setFilterOps = ['in', '!in'];
+1 -1
View File
@@ -1,3 +1,3 @@
import MapLibreGl from "maplibre-gl" import MapLibreGl from "maplibre-gl"
MapLibreGl.setRTLTextPlugin('https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js', () => {}); MapLibreGl.setRTLTextPlugin('https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js', false);
-26
View File
@@ -1,26 +0,0 @@
import '../src/styles/index.scss';
import React from 'react';
import {Describe} from './ui';
export default {
title: 'Welcome',
};
export const ToStorybook = () => {
return (
<Describe>
<h1>Maputnik component library</h1>
<p>
This is the Maputnik component library, which shows the uses of some commonly used components from the Maputnik editor. This is a stand alone place where we can better refine them and improve their API separate from their use inside the editor.
</p>
<p>
This should also help us better refine our CSS and make it more modular as currently we rely on the cascade quite a bit in a number of places.
</p>
</Describe>
);
}
ToStorybook.story = {
name: 'Intro',
};
-44
View File
@@ -1,44 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldArray from '../src/components/FieldArray';
import {Wrapper} from './ui';
export default {
title: 'FieldArray',
component: FieldArray,
};
export const NumberType = () => {
const [value, setValue] = useActionState("onChange", [1,2,3]);
return (
<Wrapper>
<FieldArray
label="Foobar"
type="number"
value={value}
length={3}
onChange={setValue}
/>
</Wrapper>
);
};
export const StringType = () => {
const [value, setValue] = useActionState("onChange", ["a", "b", "c"]);
return (
<Wrapper>
<FieldArray
label="Foobar"
type="string"
value={value}
length={3}
onChange={setValue}
/>
</Wrapper>
);
};
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldAutocomplete from '../src/components/FieldAutocomplete';
import {Wrapper} from './ui';
export default {
title: 'FieldAutocomplete',
component: FieldAutocomplete,
};
export const Basic = () => {
const options = [["FOO", "foo"], ["BAR", "bar"], ["BAZ", "baz"]];
const [value, setValue] = useActionState("onChange", "bar");
return (
<Wrapper>
<FieldAutocomplete
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-39
View File
@@ -1,39 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldCheckbox from '../src/components/FieldCheckbox';
import {Wrapper} from './ui';
export default {
title: 'FieldCheckbox',
component: FieldCheckbox,
};
export const BasicUnchecked = () => {
const [value, setValue] = useActionState("onChange", false);
return (
<Wrapper>
<FieldCheckbox
label="Foobar"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const BasicChecked = () => {
const [value, setValue] = useActionState("onChange", true);
return (
<Wrapper>
<FieldCheckbox
label="Foobar"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-25
View File
@@ -1,25 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldColor from '../src/components/FieldColor';
import {Wrapper} from './ui';
export default {
title: 'FieldColor',
component: FieldColor,
};
export const Basic = () => {
const [color, setColor] = useActionState("onChange", "#ff0000");
return (
<Wrapper>
<FieldColor
label="Foobar"
value={color}
onChange={setColor}
/>
</Wrapper>
);
};
-56
View File
@@ -1,56 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldDynamicArray from '../src/components/FieldDynamicArray';
import {Wrapper} from './ui';
export default {
title: 'FieldDynamicArray',
component: FieldDynamicArray,
};
export const NumberType = () => {
const [value, setValue] = useActionState("onChange", [1,2,3]);
return (
<Wrapper>
<FieldDynamicArray
label="Foobar"
type="number"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const UrlType = () => {
const [value, setValue] = useActionState("onChange", ["http://example.com"]);
return (
<Wrapper>
<FieldDynamicArray
label="Foobar"
type="url"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const EnumType = () => {
const [value, setValue] = useActionState("onChange", ["foo"]);
return (
<Wrapper>
<FieldDynamicArray
label="Foobar"
fieldSpec={{values: {"foo": null, "bar": null, "baz": null}}}
type="enum"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-78
View File
@@ -1,78 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldEnum from '../src/components/FieldEnum';
import {Wrapper} from './ui';
export default {
title: 'FieldEnum',
component: FieldEnum,
};
export const BasicFew = () => {
const options = ["Foo", "Bar", "Baz"];
const [value, setValue] = useActionState("onChange", "Foo");
return (
<Wrapper>
<FieldEnum
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const BasicFewWithDefault = () => {
const options = ["Foo", "Bar", "Baz"];
const [value, setValue] = useActionState("onChange", null);
return (
<Wrapper>
<FieldEnum
label="Foobar"
options={options}
default={"Baz"}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const BasicMany = () => {
const options = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const [value, setValue] = useActionState("onChange", "a");
return (
<Wrapper>
<FieldEnum
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const BasicManyWithDefault = () => {
const options = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const [value, setValue] = useActionState("onChange", "a");
return (
<Wrapper>
<FieldEnum
label="Foobar"
options={options}
default={"h"}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-39
View File
@@ -1,39 +0,0 @@
import React from 'react';
import FieldFunction from '../src/components/FieldFunction';
import {latest} from '@maplibre/maplibre-gl-style-spec'
export default {
title: 'FieldFunction',
component: FieldFunction,
};
export const Basic = () => {
const value = {
"property": "rank",
"type": "categorical",
"default": "#222",
"stops": [
[
{"zoom": 6, "value": ""},
["#777"]
],
[
{"zoom": 10, "value": ""},
["#444"]
]
]
};
return <div style={{width: "360px"}}>
<FieldFunction
onChange={() => {}}
value={value}
errors={[]}
fieldName={"Color"}
fieldType={"color"}
fieldSpec={latest['paint_fill']['fill-color']}
/>
</div>
};
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldMultiInput from '../src/components/FieldMultiInput';
import {Wrapper} from './ui';
export default {
title: 'FieldMultiInput',
component: FieldMultiInput,
};
export const Basic = () => {
const options = [["FOO", "foo"], ["BAR", "bar"], ["BAZ", "baz"]];
const [value, setValue] = useActionState("onChange", "FOO");
return (
<Wrapper>
<FieldMultiInput
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-41
View File
@@ -1,41 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldNumber from '../src/components/FieldNumber';
import {Wrapper} from './ui';
export default {
title: 'FieldNumber',
component: FieldNumber,
};
export const Basic = () => {
const [value, setValue] = useActionState("onChange", 1);
return (
<Wrapper>
<FieldNumber
label="number"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const Range = () => {
const [value, setValue] = useActionState("onChange", 1);
return (
<Wrapper>
<FieldNumber
label="number"
value={value}
onChange={setValue}
min={1}
max={24}
allowRange={true}
rangeStep={1}
/>
</Wrapper>
);
};
-28
View File
@@ -1,28 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldSelect from '../src/components/FieldSelect';
import {Wrapper} from './ui';
export default {
title: 'FieldSelect',
component: FieldSelect,
};
export const Basic = () => {
const options = [["FOO", "Foo"], ["BAR", "Bar"], ["BAZ", "Baz"]];
const [value, setValue] = useActionState("onChange", "FOO");
return (
<Wrapper>
<FieldSelect
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-25
View File
@@ -1,25 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldString from '../src/components/FieldString';
import {Wrapper} from './ui';
export default {
title: 'FieldString',
component: FieldString,
};
export const Basic = () => {
const [value, setValue] = useActionState("onChange", "Hello world");
return (
<Wrapper>
<FieldString
label="Foobar"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-42
View File
@@ -1,42 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import FieldUrl from '../src/components/FieldUrl';
import {Wrapper} from './ui';
export default {
title: 'FieldUrl',
component: FieldUrl,
};
export const Valid = () => {
const [value, setValue] = useActionState("onChange", "http://example.com");
return (
<Wrapper>
<FieldUrl
label="Foobar"
value={value}
onChange={setValue}
onInput={setValue}
/>
</Wrapper>
);
};
export const Invalid = () => {
const [value, setValue] = useActionState("onChange", "foo");
return (
<Wrapper>
<FieldUrl
label="Foobar"
value={value}
onChange={setValue}
onInput={setValue}
/>
</Wrapper>
);
};
-53
View File
@@ -1,53 +0,0 @@
import React from 'react';
import IconLayer from '../src/components/IconLayer';
import {Wrapper} from './ui';
export default {
title: 'IconLayer',
component: IconLayer,
};
export const IconList = () => {
const types = [
'fill-extrusion',
'raster',
'hillshade',
'heatmap',
'fill',
'background',
'line',
'symbol',
'circle',
'INVALID',
]
return <Wrapper>
<table style={{textAlign: "left"}}>
<thead style={{borderBottom: "solid 1px white"}}>
<tr>
<td>ID</td>
<td>Preview</td>
</tr>
</thead>
<tbody>
{types.map(type => (
<tr>
<td style={{paddingRight: "1em"}}>
<code>{type}</code>
</td>
<td>
<IconLayer type={type} />
</td>
</tr>
))}
</tbody>
</table>
</Wrapper>
};
-42
View File
@@ -1,42 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputArray from '../src/components/InputArray';
import {Wrapper} from './ui';
export default {
title: 'InputArray',
component: InputArray,
};
export const NumberType = () => {
const [value, setValue] = useActionState("onChange", [1,2,3]);
return (
<Wrapper>
<InputArray
type="number"
value={value}
length={3}
onChange={setValue}
/>
</Wrapper>
);
};
export const StringType = () => {
const [value, setValue] = useActionState("onChange", ["a", "b", "c"]);
return (
<Wrapper>
<InputArray
type="string"
value={value}
length={3}
onChange={setValue}
/>
</Wrapper>
);
};
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputAutocomplete from '../src/components/InputAutocomplete';
import {InputContainer} from './ui';
export default {
title: 'InputAutocomplete',
component: InputAutocomplete,
};
export const Basic = () => {
const options = [["FOO", "foo"], ["BAR", "bar"], ["BAZ", "baz"]];
const [value, setValue] = useActionState("onChange", "bar");
return (
<InputContainer>
<InputAutocomplete
label="Foobar"
options={options}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-18
View File
@@ -1,18 +0,0 @@
import React from 'react';
import InputButton from '../src/components/InputButton';
import {action} from '@storybook/addon-actions';
import {InputContainer} from './ui';
export default {
title: 'InputButton',
component: InputButton,
};
export const Basic = () => (
<InputContainer>
<InputButton onClick={action('onClick')}>
Hello InputButton
</InputButton>
</InputContainer>
);
-39
View File
@@ -1,39 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputCheckbox from '../src/components/InputCheckbox';
import {InputContainer} from './ui';
export default {
title: 'InputCheckbox',
component: InputCheckbox,
};
export const BasicUnchecked = () => {
const [value, setValue] = useActionState("onChange", false);
return (
<InputContainer>
<InputCheckbox
label="Foobar"
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const BasicChecked = () => {
const [value, setValue] = useActionState("onChange", true);
return (
<InputContainer>
<InputCheckbox
label="Foobar"
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-25
View File
@@ -1,25 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputColor from '../src/components/InputColor';
import {InputContainer} from './ui';
export default {
title: 'InputColor',
component: InputColor,
};
export const Basic = () => {
const [color, setColor] = useActionState("onChange", "#ff0000");
return (
<InputContainer>
<InputColor
label="Foobar"
value={color}
onChange={setColor}
/>
</InputContainer>
);
};
-53
View File
@@ -1,53 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputDynamicArray from '../src/components/InputDynamicArray';
import {Wrapper} from './ui';
export default {
title: 'InputDynamicArray',
component: InputDynamicArray,
};
export const NumberType = () => {
const [value, setValue] = useActionState("onChange", [1,2,3]);
return (
<Wrapper>
<InputDynamicArray
type="number"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const UrlType = () => {
const [value, setValue] = useActionState("onChange", ["http://example.com"]);
return (
<Wrapper>
<InputDynamicArray
type="url"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
export const EnumType = () => {
const [value, setValue] = useActionState("onChange", ["foo"]);
return (
<Wrapper>
<InputDynamicArray
fieldSpec={{values: {"foo": null, "bar": null, "baz": null}}}
type="enum"
value={value}
onChange={setValue}
/>
</Wrapper>
);
};
-75
View File
@@ -1,75 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputEnum from '../src/components/InputEnum';
import {InputContainer} from './ui';
export default {
title: 'InputEnum',
component: InputEnum,
};
export const BasicFew = () => {
const options = ["Foo", "Bar", "Baz"];
const [value, setValue] = useActionState("onChange", "Foo");
return (
<InputContainer>
<InputEnum
options={options}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const BasicFewWithDefault = () => {
const options = ["Foo", "Bar", "Baz"];
const [value, setValue] = useActionState("onChange", null);
return (
<InputContainer>
<InputEnum
options={options}
default={"Baz"}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const BasicMany = () => {
const options = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const [value, setValue] = useActionState("onChange", "a");
return (
<InputContainer>
<InputEnum
options={options}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const BasicManyWithDefault = () => {
const options = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const [value, setValue] = useActionState("onChange", "a");
return (
<InputContainer>
<InputEnum
options={options}A
default={"h"}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-24
View File
@@ -1,24 +0,0 @@
import React from 'react';
import InputJson from '../src/components/InputJson';
import {action} from '@storybook/addon-actions';
import {Wrapper} from './ui';
export default {
title: 'InputJson',
component: InputJson,
};
export const Basic = () => {
const layer = {
id: "background",
type: "background",
};
return <Wrapper>
<InputJson
layer={layer}
onClick={action('onClick')}
/>
</Wrapper>
};
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputMultiInput from '../src/components/InputMultiInput';
import {InputContainer} from './ui';
export default {
title: 'InputMultiInput',
component: InputMultiInput,
};
export const Basic = () => {
const options = [["FOO", "foo"], ["BAR", "bar"], ["BAZ", "baz"]];
const [value, setValue] = useActionState("onChange", "FOO");
return (
<InputContainer>
<InputMultiInput
options={options}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-42
View File
@@ -1,42 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputNumber from '../src/components/InputNumber';
import {InputContainer} from './ui';
export default {
title: 'InputNumber',
component: InputNumber,
};
export const Basic = () => {
const [value, setValue] = useActionState("onChange", 1);
return (
<InputContainer>
<InputNumber
name="number"
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const Range = () => {
const [value, setValue] = useActionState("onChange", 1);
return (
<InputContainer>
<InputNumber
name="number"
value={value}
onChange={setValue}
min={1}
max={24}
allowRange={true}
rangeStep={1}
/>
</InputContainer>
);
};
-28
View File
@@ -1,28 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputSelect from '../src/components/InputSelect';
import {InputContainer} from './ui';
export default {
title: 'InputSelect',
component: InputSelect,
};
export const Basic = () => {
const options = [["FOO", "Foo"], ["BAR", "Bar"], ["BAZ", "Baz"]];
const [value, setValue] = useActionState("onChange", "FOO");
return (
<InputContainer>
<InputSelect
options={options}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-67
View File
@@ -1,67 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputString from '../src/components/InputString';
import {InputContainer} from './ui';
export default {
title: 'InputString',
component: InputString,
};
export const Basic = () => {
const [value, setValue] = useActionState("onChange", "Hello world");
return (
<InputContainer>
<InputString
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const WithDefault = () => {
const [value, setValue] = useActionState("onChange", null);
return (
<InputContainer>
<InputString
value={value}
default={"Edit me..."}
onChange={setValue}
/>
</InputContainer>
);
};
export const Multiline = () => {
const [value, setValue] = useActionState("onChange", "Hello\nworld");
return (
<InputContainer>
<InputString
multi={true}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
export const MultilineWithDefault = () => {
const [value, setValue] = useActionState("onChange", null);
return (
<InputContainer>
<InputString
multi={true}
default={"Edit\nme.."}
value={value}
onChange={setValue}
/>
</InputContainer>
);
};
-40
View File
@@ -1,40 +0,0 @@
import React from 'react';
import {useActionState} from './helper';
import InputUrl from '../src/components/InputUrl';
import {InputContainer} from './ui';
export default {
title: 'InputUrl',
component: InputUrl,
};
export const Valid = () => {
const [value, setValue] = useActionState("onChange", "http://example.com");
return (
<InputContainer>
<InputUrl
value={value}
onChange={setValue}
onInput={setValue}
/>
</InputContainer>
);
};
export const Invalid = () => {
const [value, setValue] = useActionState("onChange", "foo");
return (
<InputContainer>
<InputUrl
value={value}
onChange={setValue}
onInput={setValue}
/>
</InputContainer>
);
};
-198
View File
@@ -1,198 +0,0 @@
import React from 'react';
import LayerEditor from '../src/components/LayerEditor';
export default {
title: 'LayerEditor',
component: LayerEditor,
};
export const Background = () => (
<div>
<LayerEditor
layer={{id: "background", type: "background"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Fill = () => (
<div>
<LayerEditor
layer={{id: "fill", type: "fill", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Line = () => (
<div>
<LayerEditor
layer={{id: "line", type: "line", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Symbol = () => (
<div>
<LayerEditor
layer={{id: "symbol", type: "symbol", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Raster = () => (
<div>
<LayerEditor
layer={{id: "raster", type: "raster", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Cirlce = () => (
<div>
<LayerEditor
layer={{id: "circle", type: "circle", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const FillExtrusion = () => (
<div>
<LayerEditor
layer={{id: "fill-extrusion", type: "fill-extrusion", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Heatmap = () => (
<div>
<LayerEditor
layer={{id: "heatmap", type: "heatmap", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
export const Hillshade = () => (
<div>
<LayerEditor
layer={{id: "hillshade", type: "hillshade", source: "openmaptiles"}}
sources={{}}
vectorLayers={{}}
spec={latest}
errors={[]}
onLayerChanged={() => {}}
onLayerIdChange={() => {}}
onMoveLayer={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
isFirstLayer={true}
isLastLayer={false}
layerIndex={0}
/>
</div>
);
-55
View File
@@ -1,55 +0,0 @@
import React from 'react';
import LayerList from '../src/components/LayerList';
import {Wrapper} from './ui';
export default {
title: 'LayerList',
component: LayerList,
};
export const Basic = () => (
<Wrapper>
<div style={{width: "200px"}}>
<LayerList
layers={[
{
id: "background",
type: "background",
},
{
id: "water",
type: "fill",
source: "openmaptiles"
},
{
id: "road_trunk",
type: "line",
source: "openmaptiles"
},
{
id: "road_minor",
type: "line",
source: "openmaptiles"
},
{
id: "building",
type: "fill",
source: "openmaptiles"
},
]}
selectedLayerIndex={0}
onLayersChange={() => {}}
onLayerSelect={() => {}}
onLayerDestroy={() => {}}
onLayerCopy={() => {}}
onLayerVisibilityToggle={() => {}}
onMoveLayer={() => {}}
sources={{}}
errors={[]}
/>
</div>
</Wrapper>
);
-104
View File
@@ -1,104 +0,0 @@
import React from 'react';
import MapMaplibreGl from '../src/components/MapMaplibreGl';
export default {
title: 'MapMaplibreGl',
component: MapMaplibreGl,
};
const mapStyle = {
"version": 8,
"sources": {
"test1": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, -10]
},
"properties": {}
}
]
}
},
"test2": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [15, 10]
},
"properties": {}
}
]
}
},
"test3": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-15, 10]
},
"properties": {}
}
]
}
}
},
"sprite": "",
"glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf",
"layers": [
{
"id": "test1",
"type": "circle",
"source": "test1",
"paint": {
"circle-radius": 40,
"circle-color": "red"
}
},
{
"id": "test2",
"type": "circle",
"source": "test2",
"paint": {
"circle-radius": 40,
"circle-color": "green"
}
},
{
"id": "test3",
"type": "circle",
"source": "test3",
"paint": {
"circle-radius": 40,
"circle-color": "blue"
}
}
]
}
export const Basic = () => {
return <div style={{height: "100vh", width: "100vw"}}>
<MapMaplibreGl
mapStyle={mapStyle}
inspectModeEnabled={false}
replaceAccessTokens={(s) => s}
/>
</div>
};
-108
View File
@@ -1,108 +0,0 @@
import React from 'react';
import MapOpenLayers from '../src/components/MapOpenLayers';
export default {
title: 'MapOpenLayers',
component: MapOpenLayers,
};
const mapStyle = {
"version": 8,
"sources": {
"test1": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, -10]
},
"properties": {}
}
]
}
},
"test2": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [15, 10]
},
"properties": {}
}
]
}
},
"test3": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-15, 10]
},
"properties": {}
}
]
}
}
},
"sprite": "",
"glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf",
"layers": [
{
"id": "test1",
"type": "circle",
"source": "test1",
"paint": {
"circle-radius": 40,
"circle-color": "red"
}
},
{
"id": "test2",
"type": "circle",
"source": "test2",
"paint": {
"circle-radius": 40,
"circle-color": "green"
}
},
{
"id": "test3",
"type": "circle",
"source": "test3",
"paint": {
"circle-radius": 40,
"circle-color": "blue"
}
}
]
}
export const Basic = () => {
return <div style={{height: "100vh", width: "100vw", display: "flex"}}>
<MapOpenLayers
mapStyle={mapStyle}
inspectModeEnabled={false}
replaceAccessTokens={(s) => s}
onChange={() => {}}
debugToolbox={true}
/>
</div>
};
-23
View File
@@ -1,23 +0,0 @@
import React from 'react';
import Modal from '../src/components/Modal';
import {Wrapper} from './ui';
export default {
title: 'Modal',
component: Modal,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<Modal title="hello" isOpen={true}>
{[...Array(50).keys()].map(() => {
return <p>Some text</p>
})}
</Modal>
</div>
</Wrapper>
);
-22
View File
@@ -1,22 +0,0 @@
import React from 'react';
import ModalAdd from '../src/components/ModalAdd';
import {Wrapper} from './ui';
export default {
title: 'ModalAdd',
component: ModalAdd,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalAdd
layers={[]}
sources={{}}
isOpen={true}
/>
</div>
</Wrapper>
);
-25
View File
@@ -1,25 +0,0 @@
import React from 'react';
import ModalDebug from '../src/components/ModalDebug';
import {Wrapper} from './ui';
export default {
title: 'ModalDebug',
component: ModalDebug,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalDebug
isOpen={true}
renderer="mlgljs"
maplibreGlDebugOptions={{}}
mapView={{zoom: 1, center: {lat: 0, lng: 0}}}
/>
</div>
</Wrapper>
);
-23
View File
@@ -1,23 +0,0 @@
import React from 'react';
import ModalExport from '../src/components/ModalExport';
import {Wrapper} from './ui';
export default {
title: 'ModalExport',
component: ModalExport,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalExport
isOpen={true}
mapStyle={{}}
/>
</div>
</Wrapper>
);
-22
View File
@@ -1,22 +0,0 @@
import React from 'react';
import ModalLoading from '../src/components/ModalLoading';
import {Wrapper} from './ui';
export default {
title: 'ModalLoading',
component: ModalLoading,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalLoading
isOpen={true}
title="Loading"
message="Loading 'something.geojson'"
/>
</div>
</Wrapper>
);
-29
View File
@@ -1,29 +0,0 @@
import React from 'react';
import ModalOpen from '../src/components/ModalOpen';
import {action} from '@storybook/addon-actions';
import {Wrapper} from './ui';
export default {
title: 'ModalOpen',
component: ModalOpen,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalOpen
isOpen={true}
mapStyle={{}}
onChangeMetadataProperty={action("onChangeMetadataProperty")}
onStyleChanged={action("onStyleChanged")}
/>
</div>
</Wrapper>
);
-26
View File
@@ -1,26 +0,0 @@
import React from 'react';
import ModalSettings from '../src/components/ModalSettings';
import {action} from '@storybook/addon-actions';
import {Wrapper} from './ui';
export default {
title: 'ModalSettings',
component: ModalSettings,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalSettings
isOpen={true}
mapStyle={{}}
onStyleChanged={action("onStyleChanged")}
onChangeMetadataProperty={action("onChangeMetadataProperty")}
/>
</div>
</Wrapper>
);
-30
View File
@@ -1,30 +0,0 @@
import React from 'react';
import ModalSources from '../src/components/ModalSources';
import {action} from '@storybook/addon-actions';
import {Wrapper} from './ui';
export default {
title: 'ModalSources',
component: ModalSources,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalSources
isOpen={true}
mapStyle={{sources: {}}}
onChangeMetadataProperty={action("onChangeMetadataProperty")}
onStyleChanged={action("onStyleChanged")}
/>
</div>
</Wrapper>
);
-26
View File
@@ -1,26 +0,0 @@
import React from 'react';
import ModalSurvey from '../src/components/ModalSurvey';
import {Wrapper} from './ui';
export default {
title: 'ModalSurvey',
component: ModalSurvey,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ModalSurvey
isOpen={true}
/>
</div>
</Wrapper>
);
-23
View File
@@ -1,23 +0,0 @@
import React from 'react';
import ScrollContainer from '../src/components/ScrollContainer';
import {Wrapper} from './ui';
export default {
title: 'ScrollContainer',
component: ScrollContainer,
};
export const Basic = () => (
<Wrapper>
<div style={{maxHeight: "200px"}}>
<ScrollContainer>
{[...Array(50).keys()].map(() => {
return <p>Some text</p>
})}
</ScrollContainer>
</div>
</Wrapper>
);
-12
View File
@@ -1,12 +0,0 @@
import React, {useState} from 'react';
import {action} from '@storybook/addon-actions';
export function useActionState (name, initialVal) {
const [val, fn] = useState(initialVal);
const actionFn = action(name);
function retFn(val) {
actionFn(val);
return fn(val);
}
return [val, retFn];
}
-27
View File
@@ -1,27 +0,0 @@
import React from 'react';
export function Describe ({children}) {
return (
<div style={{maxWidth: "600px", margin: "0.8em"}}>
{children}
</div>
)
}
export function Wrapper ({children}) {
return (
<div style={{maxWidth: "260px", margin: "0.4em"}}>
{children}
</div>
);
};
export function InputContainer ({children}) {
return (
<div style={{maxWidth: "171px", margin: "0.4em"}}>
{children}
</div>
);
};