# UGRC Design System

This is UGRC's [React Aria](https://react-spectrum.adobe.com/react-aria/) plus [Tailwind CSS](https://tailwindcss.com/) implementation of the [Utah Design System](https://designsystem.utah.gov/).

## Tailwind Colors

This design system expects Tailwind CSS primary, secondary, and accent colors ranging from 50-950. The UGRC default presets can be used for this from [@ugrc/tailwind-preset](https://www.npmjs.com/package/@ugrc/tailwind-preset).

## TypeScript Configuration

When using spatial components that integrate with ArcGIS and Calcite web components (such as `LayerSelector`), you need to include type references in your project's TypeScript configuration. Add the following to your `vite-env.d.ts` or a similar type declaration file:

```typescript
/// <reference types="@arcgis/map-components/types/react" />
/// <reference types="@esri/calcite-components/types/react" />
```

This ensures TypeScript recognizes the global types for ArcGIS and Calcite elements (e.g., `HTMLArcgisMapElement`, `HTMLCalciteCheckboxElement`) used by these components.

## Firebase Providers

Components and providers that integrate with Firebase (such as `FirebaseAppProvider`, `FirebaseAuthProvider`, and `UtahIdLogin`) require `firebase` to be installed by the consuming application.

## Development Dependencies

The exact `react`, `react-dom`, `react-aria`, `react-aria-components`, and `react-stately` versions in `devDependencies` pin this package's test runtime to the versions used by the workspace. Without them, pnpm can resolve a separate React runtime for React Aria, which causes invalid-hook errors in component tests. These pins are only for local development and testing; the published peer dependency ranges remain flexible for consumers.

## Imports

This package no longer exposes a root barrel file. Import components, providers, and shared types from explicit subpaths instead.

```tsx
import { Header } from '@ugrc/utah-design-system/components/Header';
import { FirebaseAppProvider } from '@ugrc/utah-design-system/contexts/FirebaseAppProvider';
import { FirebaseAuthProvider } from '@ugrc/utah-design-system/contexts/FirebaseAuthProvider';
import type { ComponentSize } from '@ugrc/utah-design-system/types';
```

Secondary exports stay with their owning module. If you previously imported one of these symbols from `@ugrc/utah-design-system`, import it from the listed subpath instead.

| Export                                                                                                                            | New import path                                               |
| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `CheckboxGroup`, `CheckboxGroupProps`                                                                                             | `@ugrc/utah-design-system/components/Checkbox`                |
| `DisclosureHeader`, `DisclosureHeaderProps`, `DisclosurePanel`, `DisclosurePanelProps`, `DisclosureGroup`, `DisclosureGroupProps` | `@ugrc/utah-design-system/components/Disclosure`              |
| `DefaultDrawerTriggerProps`                                                                                                       | `@ugrc/utah-design-system/components/Drawer`                  |
| `Label`, `Description`, `FieldError`, `FieldGroup`, `Input`, `TextAreaInput`, `fieldBorderStyles`, `fieldGroupStyles`             | `@ugrc/utah-design-system/components/Field`                   |
| `FormError`                                                                                                                       | `@ugrc/utah-design-system/components/FormErrors`              |
| `dnrStandardLinks`, `GovOpsAddress`, `NaturalResourcesAddress`, `OfficialUtahWebsite`                                             | `@ugrc/utah-design-system/components/Footer`                  |
| `useGeocoding`                                                                                                                    | `@ugrc/utah-design-system/components/Geocode`                 |
| `HeaderLink`, `HeaderProps`, `UgrcLogo`                                                                                           | `@ugrc/utah-design-system/components/Header`                  |
| `ExternalLink`                                                                                                                    | `@ugrc/utah-design-system/components/Link`                    |
| `ListBoxItem`, `DropdownItem`, `DropdownSection`, `DropdownSectionProps`, `itemStyles`, `dropdownItemStyles`                      | `@ugrc/utah-design-system/components/ListBox`                 |
| `MenuItem`, `MenuSeparator`, `MenuSection`                                                                                        | `@ugrc/utah-design-system/components/Menu`                    |
| `RadioGroup`, `RadioGroupProps`                                                                                                   | `@ugrc/utah-design-system/components/Radio`                   |
| `SelectItem`, `SelectSection`, `SelectProps`                                                                                      | `@ugrc/utah-design-system/components/Select`                  |
| `AsyncListItem`, `ugrcApiProvider`, `masqueradeProvider`, `featureServiceProvider`, `multiProvider`, `SherlockProps`              | `@ugrc/utah-design-system/components/Sherlock`                |
| `BusyBar`                                                                                                                         | `@ugrc/utah-design-system/components/Spinner`                 |
| `TabList`, `Tab`, `TabPanel`                                                                                                      | `@ugrc/utah-design-system/components/Tabs`                    |
| `Tag`, `TagProps`, `TagGroupProps`                                                                                                | `@ugrc/utah-design-system/components/TagGroup`                |
| `useFirebaseAnalytics`                                                                                                            | `@ugrc/utah-design-system/contexts/FirebaseAnalyticsProvider` |
| `useFirebaseApp`                                                                                                                  | `@ugrc/utah-design-system/contexts/FirebaseAppProvider`       |
| `useFirebaseAuth`                                                                                                                 | `@ugrc/utah-design-system/contexts/FirebaseAuthProvider`      |
| `useFirebaseFunctions`                                                                                                            | `@ugrc/utah-design-system/contexts/FirebaseFunctionsProvider` |
| `useFirebaseStorage`                                                                                                              | `@ugrc/utah-design-system/contexts/FirebaseStorageProvider`   |
| `useFirestore`                                                                                                                    | `@ugrc/utah-design-system/contexts/FirestoreProvider`         |

## Header

The Header component requires a custom font for the SVG text.

### Remote

```html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Source+Sans+3&display=swap"
  rel="stylesheet"
/>
```

### Local

```css
@font-face {
  font-family: 'SourceSansPro-Regular';
  src: url('/fonts/SourceSans3-Regular.otf.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'SourceSansPro-Black';
  src: url('/fonts/SourceSans3-Black.otf.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
```

## Layer Selector

A component for managing map basemaps and overlay layers.

This is a component that allows the user to quickly toggle visibility of layers or base maps in a web map. It has `baseLayers`, `operationalLayers`, and `referenceLayers` properties that allow you to add layers to the corresponding properties of your map's [Basemap](https://developers.arcgis.com/javascript/latest/api-reference/esri-Basemap.html). It also supports adding entire base maps via the `basemaps` property. When this property is used, the individual parts of the base map (`baseLayers` and `referenceLayers`) are mixed into the base map that Layer Selector manages.

Layers defined in `baseLayers` or `basemaps` are represented as radio buttons in a single group. You are required to pass at least one value to at least one of these properties. The first value in `basemaps` is selected by default. If no value is passed to `basemaps`, then the first value in `baseLayers` is selected by default. The `operationalLayers` and `referenceLayers` properties are represented as checkboxes.

**Important:** When using `LayerSelector`, you must set a `basemap` prop on the related `arcgis-map` element (e.g., `basemap="streets"`). This is required because the map component needs an initial basemap to properly initialize the view before `LayerSelector` can take over basemap management. Without it, the initial extent related properties (center, zoom, scale, etc.) will not be honored.

This component will not work with base `@arcgis/core/views/MapView` API since it is built on top of the `arcgis-expand` component.

### Example

```tsx
<arcgis-map basemap="streets">
  <LayerSelector basemaps={['Lite', 'Imagery']} />
</arcgis-map>
```

#### Migration from previous API (breaking change)

In earlier versions, `LayerSelector` accepted a single `options` prop (e.g., `<LayerSelector options={{ basemaps: ['Lite', 'Imagery'] }} />`). This has been replaced with flat props in order to be more idiomatic in React and easier to type and document.

**Before (deprecated API):**

```tsx
useEffect(() => {
  // ...
  setSelectorOptions({
    options: {
      basemaps: ['Lite', 'Imagery'],
      operationalLayers: ['Parcels', 'Roads'],
    },
  });
}, []);

<arcgis-map basemap="streets">
  {selectorOptions && <LayerSelector {...selectorOptions} />}
</arcgis-map>;
```

**After (current API):**

```tsx
<arcgis-map basemap="streets">
  <LayerSelector
    // no need to pass a reference to the map since it's handled internally
    basemaps={['Lite', 'Imagery']}
    operationalLayers={['Parcels', 'Roads']}
  />
</arcgis-map>
```

When upgrading, move properties that were previously nested under `options` (such as `basemaps`, `operationalLayers`, `referenceLayers`, and `baseLayers`) to top-level props on `LayerSelector`.
