diff --git a/.storybook/docs-container.ts b/.storybook/docs-container.ts new file mode 100644 index 00000000..7859afc4 --- /dev/null +++ b/.storybook/docs-container.ts @@ -0,0 +1,52 @@ +import { DocsContainer as BaseContainer } from "@storybook/addon-docs"; +import { themes } from "@storybook/theming"; +import h from "@macrostrat/hyper"; +import { useEffect, useState } from "react"; + +export const DocsContainer = ({ children, context }) => { + // Check for body class changes + const [dark, setDark] = useState( + document.body.classList.contains("bp5-dark") + ); + + console.log(context); + + useEffect(() => { + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.attributeName === "class") { + const dark = document.body.classList.contains("bp5-dark"); + setDark(dark); + } + }); + }); + observer.observe(document.body, { attributes: true }); + return () => observer.disconnect(); + }, []); + + const theme = dark ? themes.dark : themes.light; + + let ctx1 = context; + ctx1.storyById = (id) => { + const storyContext = context.storyById(id); + return { + ...storyContext, + parameters: { + ...(storyContext?.parameters ?? {}), + docs: { + ...(storyContext?.parameters?.docs ?? {}), + theme, + }, + }, + }; + }; + + return h( + BaseContainer, + { + theme, + context: ctx1, + }, + children + ); +}; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000..e240040f --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,29 @@ +import { dirname, join } from "path"; +import type { StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + // vite + stories: ["../packages/**/*.stories.@(mdx|js|jsx|ts|tsx)"], + addons: [ + getAbsolutePath("@storybook/addon-links"), + getAbsolutePath("@storybook/addon-essentials"), + getAbsolutePath("@storybook/addon-viewport"), + getAbsolutePath("storybook-dark-mode"), + ], + core: { + builder: { + name: getAbsolutePath("@storybook/builder-vite"), + options: { + viteConfigPath: require.resolve("../vite.config.ts"), + }, + }, + }, + framework: getAbsolutePath("@storybook/react-vite"), + docs: {}, +}; + +export default config; + +function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, "package.json"))); +} diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html new file mode 100644 index 00000000..b4e22950 --- /dev/null +++ b/.storybook/manager-head.html @@ -0,0 +1 @@ + diff --git a/storybook/manager.ts b/.storybook/manager.ts similarity index 100% rename from storybook/manager.ts rename to .storybook/manager.ts diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 00000000..37267e64 --- /dev/null +++ b/.storybook/preview-head.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/storybook/preview.ts b/.storybook/preview.ts similarity index 93% rename from storybook/preview.ts rename to .storybook/preview.ts index c9d092e3..b65a95ec 100644 --- a/storybook/preview.ts +++ b/.storybook/preview.ts @@ -7,6 +7,7 @@ import h from "@macrostrat/hyper"; import "@macrostrat/style-system"; import { DarkModeProvider } from "@macrostrat/ui-components"; import { useDarkMode } from "storybook-dark-mode"; +import { DocsContainer } from "./docs-container"; FocusStyleManager.onlyShowFocusOnTabs(); @@ -19,7 +20,7 @@ export const parameters = { }, }, docs: { - theme: macrostratTheme, + container: DocsContainer, }, backgrounds: { disable: true, diff --git a/storybook/theme.ts b/.storybook/theme.ts similarity index 100% rename from storybook/theme.ts rename to .storybook/theme.ts diff --git a/storybook/babel.config.json b/babel.config.json similarity index 100% rename from storybook/babel.config.json rename to babel.config.json diff --git a/package.json b/package.json index ed924061..cdd855ff 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "private": true, "repository": "https://github.com/UW-Macrostrat/web-components.git", "scripts": { - "dev": "yarn workspace @macrostrat/storybook run dev", - "build": "yarn workspace @macrostrat/storybook run build", + "dev": "storybook dev -p 6006 --no-open", + "build": "storybook build --debug", "status": "tsx scripts/status.ts", "prepare": "tsx scripts/prepare.ts", "publish": "tsx scripts/publish.ts" @@ -22,12 +22,27 @@ "@macrostrat/column-components": "./packages/column-components/src" }, "devDependencies": { - "@babel/core": "^7.18.10", + "@babel/core": "^7.18.6", "@babel/preset-env": "^7.21.4", "@babel/preset-typescript": "^7.21.4", + "@blueprintjs/core": "^5.10.2", "@parcel/packager-ts": "2.12.0", "@parcel/transformer-sass": "2.12.0", "@parcel/transformer-typescript-types": "2.12.0", + "@storybook/addon-actions": "^8.3.6", + "@storybook/addon-essentials": "^8.3.6", + "@storybook/addon-links": "^8.3.6", + "@storybook/addon-viewport": "^8.3.6", + "@storybook/builder-vite": "^8.3.6", + "@storybook/components": "^8.3.6", + "@storybook/manager-api": "^8.3.6", + "@storybook/preset-scss": "^1.0.3", + "@storybook/preview-api": "^8.3.6", + "@storybook/react": "^8.3.6", + "@storybook/react-vite": "^8.3.6", + "@storybook/theming": "^8.3.6", + "@types/d3-geo": "^2.0.0", + "@types/geojson": "^7946.0.7", "axios": "^0.27.2", "chalk": "^5.0.1", "concurrently": "^7.2.2", @@ -39,9 +54,15 @@ "marked-terminal": "^7.1.0", "node-fetch": "^3.2.9", "prettier": "^2.7.1", + "react": "^18", + "react-dom": "^18", "sass-embedded": "^1.79.4", + "storybook": "^8.3.6", + "storybook-dark-mode": "^4.0.2", "tsx": "^4.19.1", - "typescript": "^5.6.2" + "typescript": "^5.6.2", + "underscore": "^1.12.0", + "use-async-effect": "^2.2.1" }, "publishedPackages": [ "ui-components", @@ -53,7 +74,6 @@ ], "workspaces": [ "packages/*", - "storybook", "toolchain/*" ], "packageManager": "yarn@4.5.0", diff --git a/packages/map-interface/src/dev/map-page.ts b/packages/map-interface/src/dev/map-page.ts index d64ca98d..43c4c365 100644 --- a/packages/map-interface/src/dev/map-page.ts +++ b/packages/map-interface/src/dev/map-page.ts @@ -19,20 +19,9 @@ import { } from "./vector-tile-features"; import { MapPosition } from "@macrostrat/mapbox-utils"; -export enum MacrostratVectorTileset { - Carto = "carto", - CartoSlim = "carto-slim", - IGCPOrogens = "igcp-orogens", -} - -export enum MacrostratRasterTileset { - Carto = "carto", - Emphasized = "emphasized", -} - export const h = hyper.styled(styles); -export function DevMapPage({ +export function MapInspector({ title = "Map inspector", headerElement = null, transformRequest = null, @@ -43,6 +32,7 @@ export function DevMapPage({ style, focusedSource = null, focusedSourceTitle = null, + fitViewport = true, projection = null, }: { headerElement?: React.ReactElement; @@ -56,6 +46,7 @@ export function DevMapPage({ focusedSourceTitle?: string; projection?: string; mapPosition?: MapPosition; + fitViewport?: boolean; }) { /* We apply a custom style to the panel container when we are interacting with the search bar, so that we can block map interactions until search @@ -154,6 +145,7 @@ export function DevMapPage({ ]), detailPanel: detailElement, contextPanelOpen: isOpen, + fitViewport, }, h( MapView, @@ -178,3 +170,6 @@ export function DevMapPage({ ) ); } + +// Legacy export +export const DevMapPage = MapInspector; diff --git a/packages/map-interface/stories/coordinates.stories.ts b/packages/map-interface/stories/coordinates.stories.ts index c22c9e9e..ce2f47fd 100644 --- a/packages/map-interface/stories/coordinates.stories.ts +++ b/packages/map-interface/stories/coordinates.stories.ts @@ -37,3 +37,13 @@ export const Primary: Story = { }, }, }; + +export const LowZoom: Story = { + args: { + position: { + lat: 40.7128, + lng: -74.006, + }, + zoom: 2, + }, +}; diff --git a/packages/map-interface/stories/dev-map-page.stories.ts b/packages/map-interface/stories/dev-map-page.stories.ts index d7bd9500..15fce1b2 100644 --- a/packages/map-interface/stories/dev-map-page.stories.ts +++ b/packages/map-interface/stories/dev-map-page.stories.ts @@ -1,27 +1,55 @@ import h from "@macrostrat/hyper"; import type { Meta } from "@storybook/react"; -import "mapbox-gl/dist/mapbox-gl.css"; +import type { StoryObj } from "@storybook/react"; import { DevMapPage } from "../src"; import Box from "ui-box"; +const mapboxToken = import.meta.env.VITE_MAPBOX_API_TOKEN; + +function WrappedComponent(props) { + return h(DevMapPage, { ...props, mapboxToken }); +} + // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export const meta: Meta = { - title: "Map interface/Dev map page", - component: DevMapPage, + title: "Map interface/Development map page", + component: WrappedComponent, + parameters: { + layout: "fullscreen", + docs: { + story: { + inline: false, + iframeHeight: 500, + }, + }, + }, }; export default meta; -const mapboxToken = import.meta.env.STORYBOOK_MAPBOX_API_TOKEN; - -export function DevMapPageTest() { - return h( - Box, - { className: "container", position: "relative", height: 500 }, - h(DevMapPage, { - mapboxToken, - fitViewport: false, - }) - ); -} +type Story = StoryObj; + +export const Primary: Story = { + args: { + mapPosition: { + camera: { + lat: 0, + lng: 0, + altitude: 50000000, + }, + }, + }, +}; + +export const ZoomedIn: Story = { + args: { + mapPosition: { + camera: { + lat: 40.7128, + lng: -74.006, + altitude: 300000, + }, + }, + }, +}; diff --git a/storybook/main.ts b/storybook/main.ts deleted file mode 100644 index 4d56f974..00000000 --- a/storybook/main.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { StorybookConfig } from "@storybook/react-vite"; - -const config: StorybookConfig = { - // vite - stories: [ - "../packages/**/*.stories.@(mdx|js|jsx|ts|tsx)", - ], - addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-viewport", - "storybook-dark-mode", - ], - core: { - builder: { - name: '@storybook/builder-vite', - options: { - viteConfigPath: "./vite.config.ts", - } - } - }, - framework: "@storybook/react-vite", - docs: {}, -}; - -export default config; diff --git a/storybook/package.json b/storybook/package.json deleted file mode 100644 index 35509f69..00000000 --- a/storybook/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@macrostrat/storybook", - "description": "Documentation for Macrostrat web components", - "private": true, - "scripts": { - "dev": "storybook dev -c . -p 6006 --no-open", - "build": "storybook build -c . --debug" - }, - "author": "Daven Quinn", - "license": "ISC", - "dependencies": { - "@babel/core": "^7.18.6", - "@blueprintjs/core": "^5.10.2", - "@storybook/addon-actions": "^8.3.4", - "@storybook/addon-essentials": "^8.3.4", - "@storybook/addon-links": "^8.3.4", - "@storybook/addon-viewport": "^8.3.4", - "@storybook/builder-vite": "^8.3.4", - "@storybook/components": "^8.3.4", - "@storybook/manager-api": "^8.3.4", - "@storybook/preset-scss": "^1.0.3", - "@storybook/preview-api": "^8.3.4", - "@storybook/react": "^8.3.4", - "@storybook/react-vite": "^8.3.4", - "@storybook/theming": "^8.3.4", - "@types/d3-geo": "^2.0.0", - "@types/geojson": "^7946.0.7", - "react": "^18", - "react-dom": "^18", - "storybook": "^8.3.4", - "storybook-dark-mode": "^4.0.2", - "underscore": "^1.12.0", - "use-async-effect": "^2.2.1" - }, - "devDependencies": { - "@babel/preset-env": "^7.22.10", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "vite": "^5.0.0" - } -} diff --git a/storybook/vite.config.ts b/storybook/vite.config.ts deleted file mode 100644 index 32a0923c..00000000 --- a/storybook/vite.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - resolve: { - conditions: ["typescript"], - }, -}; diff --git a/tsconfig.json b/tsconfig.json index d64a8ea0..48fa36b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ } }, "include": [ - "./storybook/*.ts", - "./packages/**/src/*.ts", + "./_old/*.ts", + "./packages/**/src/*.ts" ] } diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..d891aa6a --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,9 @@ +export default { + resolve: { + conditions: ["typescript"], + }, + // https://vite.dev/config/shared-options.html#css-preprocessoroptions + scss: { + api: "modern-compiler", // or "modern", "legacy" + }, +};