Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize layer selector #259

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11,641 changes: 3,936 additions & 7,705 deletions package-lock.json

Large diffs are not rendered by default.

64 changes: 32 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,51 +77,51 @@
},
"dependencies": {
"@arcgis/core": "^4.30.9",
"lucide-react": "^0.436.0",
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"react-hook-form": "^7.52.1",
"lucide-react": "^0.447.0",
"react": ">=18.3.1",
"react-dom": ">=18.3.1",
"react-hook-form": "^7.53.0",
"react-lorem-ipsum": "^1.4.10"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.8.0",
"@chromatic-com/storybook": "^2.0.2",
"@mdx-js/react": "^3.0.1",
"@storybook/addon-actions": "^8.2.9",
"@storybook/addon-essentials": "^8.2.9",
"@storybook/addon-interactions": "^8.2.9",
"@storybook/addon-links": "^8.2.9",
"@storybook/addon-themes": "^8.2.9",
"@storybook/react": "^8.2.9",
"@storybook/react-vite": "^8.2.9",
"@storybook/test": "^8.2.9",
"@testing-library/react": "^16.0.0",
"@types/node": "^22.5.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"@storybook/addon-actions": "^8.3.4",
"@storybook/addon-essentials": "^8.3.4",
"@storybook/addon-interactions": "^8.3.4",
"@storybook/addon-links": "^8.3.4",
"@storybook/addon-themes": "^8.3.4",
"@storybook/react": "^8.3.4",
"@storybook/react-vite": "^8.3.4",
"@storybook/test": "^8.3.4",
"@testing-library/react": "^16.0.1",
"@types/node": "^22.7.4",
"@vitejs/plugin-react": "^4.3.2",
"autoprefixer": "^10.4.20",
"chokidar-cli": "^3.0.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.35.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-hooks": "^4.6.2",
"jsdom": "^24.1.1",
"msw": "^2.4.1",
"jsdom": "^25.0.1",
"msw": "^2.4.9",
"msw-storybook-addon": "^2.0.3",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.40",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-packagejson": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.6.5",
"prettier-plugin-packagejson": "^2.5.2",
"prettier-plugin-tailwindcss": "^0.6.8",
"read-pkg": "^9.0.1",
"release-please": "^16.12.0",
"storybook": "^8.2.9",
"tailwindcss": "^3.4.7",
"tailwindcss-react-aria-components": "^1.1.4",
"vite": "^5.4.6",
"vite-plugin-dts": "^4.0.3",
"vitest": "^2.0.4"
"release-please": "^16.14.1",
"storybook": "^8.3.4",
"tailwindcss": "^3.4.13",
"tailwindcss-react-aria-components": "^1.1.6",
"vite": "^5.4.8",
"vite-plugin-dts": "^4.2.3",
"vitest": "^2.1.2"
},
"msw": {
"workerDirectory": [
Expand Down
3 changes: 2 additions & 1 deletion packages/layer-selector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"test": "vitest --config ../../vite.config.js"
},
"dependencies": {
"clsx": "^2.1.1"
"clsx": "^2.1.1",
"tailwindcss-animate": "^1.0.7"
},
"peerDependencies": {
"@arcgis/core": "^4.20.0",
Expand Down
26 changes: 26 additions & 0 deletions packages/layer-selector/src/LayerSelector.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { LayerSelector } from './LayerSelector.tsx';

export default {
component: LayerSelector,
parameters: {
layout: 'padded',
},
args: {
expanded: false,
options: {
baseLayers: [
{ id: 'Hybrid', name: 'Hybrid' },
{ id: 'Lite', name: 'Lite' },
{ id: 'Terrain', name: 'Terrain' },
{ id: 'Topo', name: 'Topo' },
{ id: 'Color IR', name: 'Color IR' },
],
overlays: [
{ id: 'Address points', name: 'Address points' },
{ id: 'Land ownership', name: 'Land ownership' },
],
},
},
};

export const Example = (args) => <LayerSelector {...args}></LayerSelector>;
97 changes: 97 additions & 0 deletions packages/layer-selector/src/LayerSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
Collection,
Dialog,
DialogTrigger,
Popover as RACPopover,
Header,
} from 'react-aria-components';
import { LayersIcon } from 'lucide-react';
import type { PopoverProps } from 'react-aria-components';
import {
Button,
Radio,
RadioGroup,
CheckboxGroup,
Checkbox,
} from '@ugrc/utah-design-system/src';
import MapView from '@arcgis/core/views/MapView';

type LayerFactory = {
Factory: new () => __esri.Layer;
url: string;
id: string;
opacity: number;
};
type SelectorOptions = {
view: MapView;
quadWord: string;
baseLayers: Array<
string | { token: string; selected: boolean } | LayerFactory
>;
overlays?: Array<string | LayerFactory>;
position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
};

const Popover = (props: PopoverProps) => {
return (
<RACPopover
{...props}
className={({ isEntering, isExiting }) =>
`group min-w-48 max-w-sm overflow-y-auto rounded-lg bg-white px-3 py-2 ring-1 ring-black/10 drop-shadow-lg dark:bg-zinc-800 dark:ring-white/10 ${
isEntering
? 'animate-in fade-in placement-top:slide-in-from-bottom-1 placement-bottom:slide-in-from-top-1 duration-500 ease-out'
: ''
} ${
isExiting
? 'animate-out fade-out placement-top:slide-out-to-bottom-1 placement-bottom:slide-out-to-top-1 duration-150 ease-in'
: ''
} `
}
/>
);
};

export function LayerSelector({
options,
...props
}: {
options: SelectorOptions;
}) {
return (
<DialogTrigger {...props}>
<div className="inline-flex max-w-fit border border-black bg-white dark:border-zinc-500 dark:bg-zinc-900">
<Button
aria-label="Map layers"
className="px-1.5 outline-none focus-visible:ring-2 focus-visible:ring-white/75"
variant="icon"
>
<LayersIcon className="block size-8 p-1" />
</Button>
</div>
<Popover>
<Dialog className="outline-none">
<Header className="font-bold dark:text-white">Base maps</Header>
<RadioGroup className="flex-1">
<Collection items={options.baseLayers}>
{(item) => (
<Radio className="pl-2" value={item.name}>
{item.name}
</Radio>
)}
</Collection>
</RadioGroup>
<Header className="pt-3 font-bold dark:text-white">Overlays</Header>
<CheckboxGroup className="flex-1">
<Collection items={props.options.overlays}>
{(item) => (
<Checkbox className="pl-2" value="test">
{item.name}
</Checkbox>
)}
</Collection>
</CheckboxGroup>
</Dialog>
</Popover>
</DialogTrigger>
);
}
19 changes: 8 additions & 11 deletions packages/layer-selector/src/LayerSelectorContainer.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { ExpandableContainer } from './';
import './LayerSelector.css';

export default {
component: ExpandableContainer,
parameters: {
layout: 'centered',
},
args: {
expanded: false,
},
};

export const closed = () => (
<ExpandableContainer>
<div style={{ width: '200px', height: '200px', border: '1px solid black' }}>
peek-a-boo
</div>
</ExpandableContainer>
);

export const open = () => (
<ExpandableContainer expanded={true}>
export const Example = (args) => (
<ExpandableContainer {...args}>
<div style={{ width: '200px', height: '200px', border: '1px solid black' }}>
peek-a-boo
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/popover/src/Popover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function Popover({
<RadixPopover.Portal>
<RadixPopover.Content
side="bottom"
className="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-10 mr-2 rounded-md bg-white p-4 shadow-md outline-none dark:bg-slate-900"
className="z-10 mr-2 rounded-md bg-white p-4 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:bg-slate-900"
sideOffset={4}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* - Please do NOT serve this file on production.
*/

const PACKAGE_VERSION = '2.4.5'
const PACKAGE_VERSION = '2.4.9'
const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()
Expand Down
3 changes: 2 additions & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import ugrcTheme from './packages/tailwind-preset/src/index';
import rac from 'tailwindcss-react-aria-components';
import animate from 'tailwindcss-animate';

export default {
content: ['./packages/**/*.{js,jsx,ts,tsx}'],
darkMode: ['class'],
presets: [ugrcTheme],
plugins: [rac],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be added to the preset? If not, then it needs to be documented.

plugins: [rac, animate],
};
Loading