@humanforest/nuxt-layer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +67 -0
- package/README.md +208 -0
- package/app.config.ts +10 -0
- package/assets/icons/forest/bike-asterisk.svg +21 -0
- package/assets/icons/forest/bike-down.svg +19 -0
- package/assets/icons/forest/bike-off.svg +20 -0
- package/assets/icons/forest/bike-up.svg +19 -0
- package/assets/icons/forest/bike-x.svg +19 -0
- package/assets/icons/forest/bike.svg +18 -0
- package/assets/icons/forest/mark-fill.svg +6 -0
- package/assets/icons/forest/mark.svg +6 -0
- package/assets/icons/forest/parking.svg +3 -0
- package/assets/icons/forest/star-fill.svg +4 -0
- package/assets/icons/forest/star.svg +4 -0
- package/assets/icons/forest/traffic-light-caution.svg +8 -0
- package/assets/icons/forest/traffic-light-go.svg +8 -0
- package/assets/icons/forest/traffic-light-lit.svg +8 -0
- package/assets/icons/forest/traffic-light-stop.svg +8 -0
- package/assets/icons/forest/traffic-light.svg +8 -0
- package/nuxt.config.ts +81 -0
- package/package.json +35 -0
- package/packages/charts/src/FBoroughShape.vue +52 -0
- package/packages/charts/src/FCalendarGrid.vue +332 -0
- package/packages/charts/src/FCellLegend.vue +54 -0
- package/packages/charts/src/FChartFrame.vue +201 -0
- package/packages/charts/src/FChartFrameSingle.vue +91 -0
- package/packages/charts/src/FChartLegend.vue +26 -0
- package/packages/charts/src/FDistributionBar.vue +224 -0
- package/packages/charts/src/FDottedMap.vue +335 -0
- package/packages/charts/src/FLondonMap.vue +399 -0
- package/packages/charts/src/FSparkline.vue +198 -0
- package/packages/charts/src/FStatusTrack.vue +151 -0
- package/packages/charts/src/cellSize.ts +46 -0
- package/packages/charts/src/distribution.ts +99 -0
- package/packages/charts/src/engine.ts +15 -0
- package/packages/charts/src/forestTooltip.ts +110 -0
- package/packages/charts/src/fromCategories.ts +43 -0
- package/packages/charts/src/index.ts +87 -0
- package/packages/charts/src/londonAreas.ts +75 -0
- package/packages/charts/src/londonGrid.ts +67 -0
- package/packages/charts/src/motionDuration.ts +49 -0
- package/packages/charts/src/presets.ts +143 -0
- package/packages/charts/src/resolveVar.ts +21 -0
- package/packages/charts/src/snapTooltip.ts +154 -0
- package/packages/charts/src/tooltipStandIn.ts +58 -0
- package/packages/charts/src/useCellScale.ts +155 -0
- package/packages/charts/src/useChartPalette.ts +61 -0
- package/packages/charts/src/useChartRepaintKey.ts +22 -0
- package/packages/charts/src/useThemeVersion.ts +17 -0
- package/packages/frames/src/FBrowserFrame.vue +53 -0
- package/packages/frames/src/FDeviceFrame.vue +242 -0
- package/packages/frames/src/FFitFrame.vue +83 -0
- package/packages/frames/src/art/iphone-11.svg +124 -0
- package/packages/frames/src/art/iphone-12.svg +601 -0
- package/packages/frames/src/art/iphone-13-pro.svg +820 -0
- package/packages/frames/src/art/iphone-13.svg +849 -0
- package/packages/frames/src/art/iphone-14.svg +681 -0
- package/packages/frames/src/art/iphone-15-pro.svg +633 -0
- package/packages/frames/src/art/iphone-15.svg +713 -0
- package/packages/frames/src/art/iphone-16-plus.svg +685 -0
- package/packages/frames/src/art/iphone-16-pro-max.svg +611 -0
- package/packages/frames/src/art/iphone-16-pro.svg +631 -0
- package/packages/frames/src/art/iphone-16.svg +713 -0
- package/packages/frames/src/art/iphone-17-pro-max.svg +355 -0
- package/packages/frames/src/art/iphone-17.svg +305 -0
- package/packages/frames/src/art/iphone-air.svg +389 -0
- package/packages/frames/src/art/iphone-se-3.svg +473 -0
- package/packages/frames/src/art/iphone-x.svg +652 -0
- package/packages/frames/src/art/pixel-10-pro-xl.svg +32 -0
- package/packages/frames/src/art/pixel-10-pro.svg +32 -0
- package/packages/frames/src/art/pixel-10.svg +32 -0
- package/packages/frames/src/art/pixel-8-pro.svg +208 -0
- package/packages/frames/src/art/pixel-8.svg +208 -0
- package/packages/frames/src/art/pixel-8a.svg +8 -0
- package/packages/frames/src/art/pixel-9-pro-xl.svg +32 -0
- package/packages/frames/src/art/pixel-9-pro.svg +34 -0
- package/packages/frames/src/art/pixel-9a.svg +25 -0
- package/packages/frames/src/art.ts +29 -0
- package/packages/frames/src/devices.ts +337 -0
- package/packages/frames/src/index.ts +15 -0
- package/packages/tokens/geo/london-boroughs.json +1 -0
- package/packages/tokens/geo/london-dots-coarse.json +1 -0
- package/packages/tokens/geo/london-dots-fine.json +1 -0
- package/packages/tokens/geo/london-dots-medium.json +1 -0
- package/packages/tokens/geo/london-dots-ultra.json +1 -0
- package/packages/tokens/geo/london-wards.json +1 -0
- package/packages/tokens/glyphs/glyphs.json +1 -0
- package/packages/tokens/logos/f-rot.svg +4 -0
- package/packages/tokens/logos/f.svg +4 -0
- package/packages/tokens/logos/favicon-c2w.svg +9 -0
- package/packages/tokens/logos/favicon-console.svg +9 -0
- package/packages/tokens/logos/favicon-ds.svg +9 -0
- package/packages/tokens/logos/favicon-fleet.svg +9 -0
- package/packages/tokens/logos/favicon-flex.svg +9 -0
- package/packages/tokens/logos/favicon-plus.svg +9 -0
- package/packages/tokens/logos/favicon-radar.svg +9 -0
- package/packages/tokens/logos/favicon-tower.svg +9 -0
- package/packages/tokens/logos/lockup-horizontal.svg +17 -0
- package/packages/tokens/logos/lockup-vertical.svg +17 -0
- package/packages/tokens/logos/mark-mono.svg +4 -0
- package/packages/tokens/logos/mark.svg +7 -0
- package/packages/tokens/logos/wordmark.svg +9 -0
- package/packages/tokens/src/colourEngine.ts +604 -0
- package/packages/tokens/src/glyphs.ts +127 -0
- package/packages/tokens/src/logo.ts +50 -0
- package/packages/tokens/src/subbrands.ts +44 -0
- package/packages/tokens/src/sublogo.ts +80 -0
- package/packages/ui/icons/forest/map/forest-place-count.svg +21 -0
- package/packages/ui/icons/forest/map/forest-place-marker.svg +17 -0
- package/packages/ui/icons/forest/map/forest-vehicle-marker.svg +73 -0
- package/packages/ui/icons/forest/map/manifest.json +373 -0
- package/packages/ui/icons/forest/map/place-count-manifest.json +83 -0
- package/packages/ui/icons/forest/map/place-manifest.json +74 -0
- package/packages/ui/src/address/address.ts +125 -0
- package/packages/ui/src/address/autofill.ts +78 -0
- package/packages/ui/src/address/geocode.ts +55 -0
- package/packages/ui/src/address/index.ts +31 -0
- package/packages/ui/src/address/validate.ts +91 -0
- package/packages/ui/src/canvas/FCanvasCard.vue +97 -0
- package/packages/ui/src/canvas/FCanvasControl.vue +121 -0
- package/packages/ui/src/canvas/FCanvasControlGroup.vue +100 -0
- package/packages/ui/src/canvas/FCanvasFlyout.vue +216 -0
- package/packages/ui/src/canvas/FCanvasHud.vue +402 -0
- package/packages/ui/src/canvas/canvasSurface.ts +39 -0
- package/packages/ui/src/canvas/index.ts +17 -0
- package/packages/ui/src/contexts/ForestContext.vue +53 -0
- package/packages/ui/src/contexts/contexts.ts +153 -0
- package/packages/ui/src/contexts/index.ts +23 -0
- package/packages/ui/src/contexts/marketing-theme.ts +214 -0
- package/packages/ui/src/contexts/mobile-theme.ts +402 -0
- package/packages/ui/src/filter/FFilterBar.vue +72 -0
- package/packages/ui/src/filter/FFilterChip.vue +362 -0
- package/packages/ui/src/filter/FFilterClauses.vue +104 -0
- package/packages/ui/src/filter/FFilterTrigger.vue +183 -0
- package/packages/ui/src/filter/filter.theme.ts +27 -0
- package/packages/ui/src/filter/filterClause.ts +265 -0
- package/packages/ui/src/filter/filterPredicate.ts +134 -0
- package/packages/ui/src/filter/filterSchema.ts +82 -0
- package/packages/ui/src/filter/index.ts +36 -0
- package/packages/ui/src/forest-preset.ts +68 -0
- package/packages/ui/src/icons.ts +79 -0
- package/packages/ui/src/index.ts +17 -0
- package/packages/ui/src/kpi/FKpi.vue +253 -0
- package/packages/ui/src/kpi/FKpiGroup.vue +161 -0
- package/packages/ui/src/kpi/index.ts +20 -0
- package/packages/ui/src/kpi/kpi.theme.ts +168 -0
- package/packages/ui/src/kpi/kpiDelta.ts +82 -0
- package/packages/ui/src/kpi/kpiFormat.ts +72 -0
- package/packages/ui/src/kpi/kpiGroupState.ts +63 -0
- package/packages/ui/src/logo/FLogo.vue +52 -0
- package/packages/ui/src/logo/FSubLogo.vue +214 -0
- package/packages/ui/src/logo/index.ts +8 -0
- package/packages/ui/src/map/FMap.vue +355 -0
- package/packages/ui/src/map/FMapCompass.vue +154 -0
- package/packages/ui/src/map/FMapCoordinates.vue +134 -0
- package/packages/ui/src/map/FMapDrawTools.vue +116 -0
- package/packages/ui/src/map/FMapFullscreen.vue +92 -0
- package/packages/ui/src/map/FMapGeolocate.vue +208 -0
- package/packages/ui/src/map/FMapLayers.vue +75 -0
- package/packages/ui/src/map/FMapLegend.vue +45 -0
- package/packages/ui/src/map/FMapPopup.vue +129 -0
- package/packages/ui/src/map/FMapRamp.vue +69 -0
- package/packages/ui/src/map/FMapRegion.vue +77 -0
- package/packages/ui/src/map/FMapScale.vue +107 -0
- package/packages/ui/src/map/FMapSearch.vue +362 -0
- package/packages/ui/src/map/FMapTilt.vue +87 -0
- package/packages/ui/src/map/FMapTools.vue +61 -0
- package/packages/ui/src/map/FMapZoom.vue +81 -0
- package/packages/ui/src/map/FMarker.vue +218 -0
- package/packages/ui/src/map/FTrackScrubber.vue +94 -0
- package/packages/ui/src/map/FVehicleLegend.vue +72 -0
- package/packages/ui/src/map/FVehicleMark.vue +166 -0
- package/packages/ui/src/map/bin.ts +196 -0
- package/packages/ui/src/map/coordinates.ts +83 -0
- package/packages/ui/src/map/density.ts +401 -0
- package/packages/ui/src/map/draw.ts +356 -0
- package/packages/ui/src/map/ease.ts +67 -0
- package/packages/ui/src/map/fullscreen.ts +59 -0
- package/packages/ui/src/map/heat.ts +160 -0
- package/packages/ui/src/map/index.ts +351 -0
- package/packages/ui/src/map/liveMarkers.ts +60 -0
- package/packages/ui/src/map/map.css +116 -0
- package/packages/ui/src/map/mapColor.ts +31 -0
- package/packages/ui/src/map/mapContext.ts +12 -0
- package/packages/ui/src/map/mapLayers.ts +55 -0
- package/packages/ui/src/map/mapLegend.ts +70 -0
- package/packages/ui/src/map/mapSearch.theme.ts +79 -0
- package/packages/ui/src/map/mapSearch.ts +279 -0
- package/packages/ui/src/map/mapUrl.ts +117 -0
- package/packages/ui/src/map/markerAsset.ts +3 -0
- package/packages/ui/src/map/padding.ts +39 -0
- package/packages/ui/src/map/place.ts +192 -0
- package/packages/ui/src/map/ramp.ts +95 -0
- package/packages/ui/src/map/regionSelect.ts +163 -0
- package/packages/ui/src/map/route.ts +167 -0
- package/packages/ui/src/map/scale.ts +329 -0
- package/packages/ui/src/map/scaleBar.ts +67 -0
- package/packages/ui/src/map/selectionModel.ts +50 -0
- package/packages/ui/src/map/sources/coordinates.ts +58 -0
- package/packages/ui/src/map/sources/mapboxPlaces.ts +71 -0
- package/packages/ui/src/map/style.ts +14 -0
- package/packages/ui/src/map/track.ts +279 -0
- package/packages/ui/src/map/useFeatureSelect.ts +230 -0
- package/packages/ui/src/map/useLiveMarkers.ts +84 -0
- package/packages/ui/src/map/useMap.ts +150 -0
- package/packages/ui/src/map/useMapDraw.ts +776 -0
- package/packages/ui/src/map/useMapOverlay.ts +421 -0
- package/packages/ui/src/map/useMapTableSelection.ts +101 -0
- package/packages/ui/src/map/useMapUrlState.ts +155 -0
- package/packages/ui/src/map/useMarkerSource.ts +163 -0
- package/packages/ui/src/map/useRegionSelect.ts +309 -0
- package/packages/ui/src/map/useTokenMode.ts +61 -0
- package/packages/ui/src/map/useTrackPlayback.ts +131 -0
- package/packages/ui/src/map/useVehicleFilter.ts +51 -0
- package/packages/ui/src/map/useVisibleFeatures.ts +124 -0
- package/packages/ui/src/map/vehicle.ts +807 -0
- package/packages/ui/src/map/vehicleFilter.ts +284 -0
- package/packages/ui/src/map/vehicleLegend.ts +155 -0
- package/packages/ui/src/map/visibleFeatures.ts +192 -0
- package/packages/ui/src/map/zone.ts +291 -0
- package/packages/ui/src/shell/FAppNavbar.vue +68 -0
- package/packages/ui/src/shell/FAppShell.vue +163 -0
- package/packages/ui/src/shell/FAppSidebar.vue +215 -0
- package/packages/ui/src/shell/FPageToolbar.vue +126 -0
- package/packages/ui/src/shell/FScrollShadow.vue +43 -0
- package/packages/ui/src/shell/FSidePanel.vue +258 -0
- package/packages/ui/src/shell/FToolbarActions.vue +32 -0
- package/packages/ui/src/shell/index.ts +33 -0
- package/packages/ui/src/shell/nav.ts +37 -0
- package/packages/ui/src/shell/pageToolbar.ts +69 -0
- package/packages/ui/src/shell/shell.ts +74 -0
- package/packages/ui/src/shell/sidePanel.ts +115 -0
- package/packages/ui/src/themes/accordion.ts +36 -0
- package/packages/ui/src/themes/alert.ts +16 -0
- package/packages/ui/src/themes/auth-form.ts +19 -0
- package/packages/ui/src/themes/avatar-group.ts +9 -0
- package/packages/ui/src/themes/avatar.ts +18 -0
- package/packages/ui/src/themes/badge.ts +51 -0
- package/packages/ui/src/themes/banner.ts +21 -0
- package/packages/ui/src/themes/breadcrumb.ts +10 -0
- package/packages/ui/src/themes/button.mechanics.ts +191 -0
- package/packages/ui/src/themes/button.ts +136 -0
- package/packages/ui/src/themes/calendar.ts +29 -0
- package/packages/ui/src/themes/card.ts +67 -0
- package/packages/ui/src/themes/carousel.ts +41 -0
- package/packages/ui/src/themes/checkbox-group.ts +20 -0
- package/packages/ui/src/themes/checkbox.ts +47 -0
- package/packages/ui/src/themes/chip.ts +50 -0
- package/packages/ui/src/themes/collapsible.ts +26 -0
- package/packages/ui/src/themes/color-picker.ts +13 -0
- package/packages/ui/src/themes/command-palette.ts +37 -0
- package/packages/ui/src/themes/container.ts +14 -0
- package/packages/ui/src/themes/context-menu.ts +38 -0
- package/packages/ui/src/themes/dashboard-group.ts +11 -0
- package/packages/ui/src/themes/dashboard-navbar.ts +10 -0
- package/packages/ui/src/themes/dashboard-panel.ts +18 -0
- package/packages/ui/src/themes/dashboard-resize-handle.ts +35 -0
- package/packages/ui/src/themes/dashboard-sidebar-collapse.ts +7 -0
- package/packages/ui/src/themes/dashboard-sidebar-toggle.ts +7 -0
- package/packages/ui/src/themes/dashboard-sidebar.ts +58 -0
- package/packages/ui/src/themes/dashboard-toolbar.ts +15 -0
- package/packages/ui/src/themes/drawer.ts +45 -0
- package/packages/ui/src/themes/dropdown-menu.ts +38 -0
- package/packages/ui/src/themes/empty.ts +43 -0
- package/packages/ui/src/themes/field-group.ts +52 -0
- package/packages/ui/src/themes/file-upload.ts +38 -0
- package/packages/ui/src/themes/footer-columns.ts +13 -0
- package/packages/ui/src/themes/footer.ts +9 -0
- package/packages/ui/src/themes/form-field.ts +25 -0
- package/packages/ui/src/themes/form.ts +22 -0
- package/packages/ui/src/themes/header.ts +12 -0
- package/packages/ui/src/themes/icon.ts +61 -0
- package/packages/ui/src/themes/index.ts +99 -0
- package/packages/ui/src/themes/input-date.ts +73 -0
- package/packages/ui/src/themes/input-menu.ts +66 -0
- package/packages/ui/src/themes/input-number.ts +58 -0
- package/packages/ui/src/themes/input-rating.ts +25 -0
- package/packages/ui/src/themes/input-tags.ts +63 -0
- package/packages/ui/src/themes/input-time.ts +70 -0
- package/packages/ui/src/themes/input.ts +148 -0
- package/packages/ui/src/themes/kbd.ts +27 -0
- package/packages/ui/src/themes/link.ts +27 -0
- package/packages/ui/src/themes/listbox.ts +48 -0
- package/packages/ui/src/themes/main.ts +6 -0
- package/packages/ui/src/themes/marquee.ts +45 -0
- package/packages/ui/src/themes/modal.ts +46 -0
- package/packages/ui/src/themes/navigation-menu.ts +80 -0
- package/packages/ui/src/themes/page-anchors.ts +7 -0
- package/packages/ui/src/themes/page-aside.ts +7 -0
- package/packages/ui/src/themes/page-card.ts +22 -0
- package/packages/ui/src/themes/page-cta.ts +18 -0
- package/packages/ui/src/themes/page-feature.ts +13 -0
- package/packages/ui/src/themes/page-header.ts +16 -0
- package/packages/ui/src/themes/page-hero.ts +15 -0
- package/packages/ui/src/themes/page-links.ts +12 -0
- package/packages/ui/src/themes/page-section.ts +14 -0
- package/packages/ui/src/themes/page.ts +7 -0
- package/packages/ui/src/themes/pagination.ts +17 -0
- package/packages/ui/src/themes/pin-input.ts +73 -0
- package/packages/ui/src/themes/popover.ts +30 -0
- package/packages/ui/src/themes/progress.ts +29 -0
- package/packages/ui/src/themes/prose.ts +45 -0
- package/packages/ui/src/themes/radio-group.ts +39 -0
- package/packages/ui/src/themes/scroll-area.ts +23 -0
- package/packages/ui/src/themes/select-menu.ts +71 -0
- package/packages/ui/src/themes/select.ts +72 -0
- package/packages/ui/src/themes/separator.ts +28 -0
- package/packages/ui/src/themes/sidebar.ts +127 -0
- package/packages/ui/src/themes/skeleton.ts +15 -0
- package/packages/ui/src/themes/slideover.ts +87 -0
- package/packages/ui/src/themes/slider.ts +48 -0
- package/packages/ui/src/themes/stepper.ts +41 -0
- package/packages/ui/src/themes/switch.ts +63 -0
- package/packages/ui/src/themes/table.ts +34 -0
- package/packages/ui/src/themes/tabs.ts +74 -0
- package/packages/ui/src/themes/textarea.ts +77 -0
- package/packages/ui/src/themes/timeline.ts +25 -0
- package/packages/ui/src/themes/toast.ts +29 -0
- package/packages/ui/src/themes/toaster.ts +66 -0
- package/packages/ui/src/themes/tooltip.ts +31 -0
- package/packages/ui/src/themes/tree.ts +41 -0
- package/packages/ui/src/themes/user.ts +28 -0
- package/styles.cdn.gen.css +2047 -0
- package/theme.gen.json +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Forest Design System — Licence
|
|
2
|
+
Copyright (c) 2026 HumanForest Ltd. All rights reserved.
|
|
3
|
+
|
|
4
|
+
This software is published openly so that people building Forest products can install it
|
|
5
|
+
without access to its source repository. It is not open-source software.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
1. GRANT
|
|
9
|
+
|
|
10
|
+
You may install, use, copy and modify this software, and incorporate it into applications,
|
|
11
|
+
prototypes, documents and presentations, for the purpose of building or operating Forest
|
|
12
|
+
products, services and communications.
|
|
13
|
+
|
|
14
|
+
This grant is free of charge and requires no separate agreement. It runs to anyone who
|
|
15
|
+
obtains the software from a public registry.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
2. RESERVED
|
|
19
|
+
|
|
20
|
+
All rights not granted above are reserved. In particular, you may not:
|
|
21
|
+
|
|
22
|
+
(a) redistribute this software, modified or unmodified, as a design system, component
|
|
23
|
+
library, template or theme of your own;
|
|
24
|
+
|
|
25
|
+
(b) use the HumanForest and Forest names, logos, wordmarks, sub-brand marks or any
|
|
26
|
+
confusingly similar mark. Nothing here grants any trademark right. The brand marks
|
|
27
|
+
included in these packages are provided to render Forest's own products correctly,
|
|
28
|
+
not as artwork you may adopt;
|
|
29
|
+
|
|
30
|
+
(c) represent your product as being made, endorsed or approved by HumanForest.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
3. THIRD-PARTY MATERIAL
|
|
34
|
+
|
|
35
|
+
Parts of these packages are not HumanForest's to license, and the grant in section 1 does
|
|
36
|
+
not extend to them. Each keeps its own terms:
|
|
37
|
+
|
|
38
|
+
TYPEFACES — Mohr and GT Haptik are licensed to HumanForest by their foundries and are NOT
|
|
39
|
+
sublicensed to you. No font binary is included in any published package. The stylesheets
|
|
40
|
+
reference https://assets.forest.bike/fonts/, which serves them to those entitled to use
|
|
41
|
+
them. If you are not covered by Forest's licences, substitute your own faces. JetBrains
|
|
42
|
+
Mono is licensed under the SIL Open Font License 1.1 and may be used under those terms.
|
|
43
|
+
|
|
44
|
+
GLYPH OUTLINES — packages/tokens ships `glyphs/glyphs.json`, letterforms of the above
|
|
45
|
+
typefaces outlined as vector paths so sub-brand lockups can be composed at runtime. It is
|
|
46
|
+
covered by the same foundry terms as the typefaces themselves, not by section 1.
|
|
47
|
+
|
|
48
|
+
DEVICE ARTWORK — packages/frames ships device renders from Wikimedia Commons under the
|
|
49
|
+
Creative Commons Attribution-ShareAlike 4.0 International licence
|
|
50
|
+
(https://creativecommons.org/licenses/by-sa/4.0/). They are unmodified. Attribution is a
|
|
51
|
+
condition of that licence: see ATTRIBUTION.md in that package, and keep it with the art
|
|
52
|
+
wherever the art travels. Works derived from the artwork must themselves be CC BY-SA 4.0.
|
|
53
|
+
|
|
54
|
+
DEPENDENCIES — third-party packages installed alongside these keep their own licences.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
4. NO WARRANTY
|
|
58
|
+
|
|
59
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
60
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
61
|
+
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
62
|
+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
63
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
64
|
+
DEALINGS IN THE SOFTWARE.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
Questions about use beyond this grant: design@forest.bike
|
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# @humanforest/nuxt-layer
|
|
2
|
+
|
|
3
|
+
Forest design system as a [Nuxt layer](https://nuxt.com/docs/getting-started/layers). Extend it and a
|
|
4
|
+
Nuxt app inherits the Forest theme, colour families, icons and the real brand fonts — no npm publish
|
|
5
|
+
involved.
|
|
6
|
+
|
|
7
|
+
The layer is **self-contained** — no `@humanforest/*` imports, no climbing to sibling packages — so giget
|
|
8
|
+
can fetch this one directory and it still works. The generated files are committed; regenerate them
|
|
9
|
+
from the source packages with `bun run build:layer` (in the design-system repo root).
|
|
10
|
+
|
|
11
|
+
## What the layer delivers
|
|
12
|
+
|
|
13
|
+
- **`nuxt.config.ts`** — registers `@nuxt/ui`, the Forest colour families (`color="forest|maple|river|warm|acid"`), the `i-forest-*` icon set (SVGs in `assets/icons/forest/`), the 23 Forest components below, and the composables listed under "Composables and helpers".
|
|
14
|
+
- **`app.config.ts`** — the Nuxt UI theme: per-component tailwind-variants fragments + the semantic role map (`primary→forest`, `error→maple`, …), read from `theme.gen.json`.
|
|
15
|
+
- **`styles.gen.css`** — fonts + ramps + theme registration + type scale + the motion ladder + the Forest base layer. The `@font-face` rules point at `./files/`, so a giget consumer renders in the brand faces offline. **This file is not published to npm.**
|
|
16
|
+
- **`styles.cdn.gen.css`** — byte-identical from the first token onward; only the `@font-face` rules differ, naming `assets.forest.bike` instead. This is the build the npm package ships, because a public tarball may not carry licensed binaries.
|
|
17
|
+
- **`files/`** — the real brand font binaries. Giget only; excluded from the npm tarball.
|
|
18
|
+
- **`packages/tokens/logos/`** — the 15 generated brand SVGs (mark, wordmark, both lockups, the `f`, and eight sub-brand favicons). Nothing in the layer imports them: `FLogo` and `FSubLogo` compose their marks live. They ship for the uses a component cannot serve — a Vue component does not go in `<link rel="icon">`, an email template or an OG image.
|
|
19
|
+
- **`packages/ui/src`, `packages/charts/src`, `packages/frames/src`** (+ their supporting trees, mirrored at repo-relative paths — see "Regenerating") — the 39 registered Forest components, auto-registered like any Nuxt component, no import needed: `ForestContext`; `FLogo`, `FSubLogo`; `FFilterBar`, `FFilterChip`; `FKpi`, `FKpiGroup`; six shell components (`FAppShell`, `FAppSidebar`, `FAppNavbar`, `FPageToolbar`, `FScrollShadow`, `FSidePanel`); four canvas components (`FCanvasHud`, `FCanvasCard`, `FCanvasControl`, `FCanvasControlGroup`); eight map components (`FMap`, `FMapPopup`, `FMarker`, `FVehicleMark`, and the four controls `FMapZoom`, `FMapCompass`, `FMapTilt`, `FMapGeolocate`); eleven chart components (`FBoroughShape`, `FCalendarGrid`, `FCellLegend`, `FChartFrame`, `FChartFrameSingle`, `FChartLegend`, `FDistributionBar`, `FDottedMap`, `FLondonMap`, `FSparkline`, `FStatusTrack`); three presentation frames (`FDeviceFrame`, `FBrowserFrame`, `FFitFrame`) for staging a prototype at true scale — these carry CC BY-SA 4.0 device art, which is why they ship here and not on public npm. It is the mirrored source trees that make auto-registration possible — the components aren't published separately, they ARE those trees.
|
|
20
|
+
|
|
21
|
+
## Composables and helpers
|
|
22
|
+
|
|
23
|
+
Eight are auto-imported alongside the components — `FMap`'s imperative API plus the chart palette and
|
|
24
|
+
the KPI formatters:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// no import needed
|
|
28
|
+
const { flyTo } = useMapCamera()
|
|
29
|
+
const palette = useChartPalette()
|
|
30
|
+
formatMetric(4218, { format: 'compact' }) // "4.2k"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`useMapReady` · `useMapCamera` · `useMapOverlay` · `useFeatureSelect` · `MAP_SLOT` ·
|
|
34
|
+
`useChartPalette` · `formatMetric` · `formatPercent`
|
|
35
|
+
|
|
36
|
+
This is an ALLOW-LIST, not `imports.dirs`, and the rest is deliberate. A directory scan would take
|
|
37
|
+
every export in the mirrored trees, and those barrels carry names like `token`, `isSelected`,
|
|
38
|
+
`nextKey` and `addClause` — generic enough to collide with a consuming app's own code, silently and
|
|
39
|
+
at a distance. Everything else stays reachable by path:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { STATE_LABEL, resolveMapColor } from '#layers/forest/packages/ui/src/map'
|
|
43
|
+
import { distributionShares } from '#layers/forest/packages/charts/src/distribution'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Those paths are the layer's internal shape, so treat them as less stable than the auto-imported set:
|
|
47
|
+
they move when the source tree is reorganised.
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
Three files in the consuming app. This exact setup is verified end to end: a Nuxt 4 app in a separate
|
|
52
|
+
repo consuming this layer over giget, with the colour ramps, semantic roles, `.type-*` utilities,
|
|
53
|
+
`i-forest-*` icons and the brand font binaries all reaching the production build. The 21 Forest
|
|
54
|
+
components are verified too, but via a local-extends probe app rather than a giget one — see "Local
|
|
55
|
+
development against the layer" for a dependency step that a giget consumer gets automatically and a
|
|
56
|
+
local one does not.
|
|
57
|
+
|
|
58
|
+
**`nuxt.config.ts`**
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
export default defineNuxtConfig({
|
|
62
|
+
// `install: true` is load-bearing — see "Staying up to date".
|
|
63
|
+
// Keep Forest LAST in extends so your own layers and app can override it.
|
|
64
|
+
extends: [['github:humanforest/design-system/packages/nuxt-layer#main', { install: true }]],
|
|
65
|
+
modules: ['@nuxt/ui'],
|
|
66
|
+
css: ['~/assets/css/main.css'],
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**`app/assets/css/main.css`**
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
@import "tailwindcss";
|
|
74
|
+
@import "@nuxt/ui";
|
|
75
|
+
@import "#layers/forest/styles.gen.css";
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Installed from npm instead, the same line names the CDN build — the self-hosted one is not in the
|
|
79
|
+
tarball, so a stale copy of this snippet fails to resolve rather than quietly falling back:
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
@import "@humanforest/nuxt-layer/styles.cdn.gen.css";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**`package.json`** — `nuxt ^4`, `@nuxt/ui ^4`, `tailwindcss ^4`, plus `typescript` in
|
|
86
|
+
`devDependencies`. Without `typescript`, `@nuxt/ui`'s unresolved peer makes bun discard the lockfile and
|
|
87
|
+
re-resolve on every build — noisy rather than fatal, but easy to avoid.
|
|
88
|
+
|
|
89
|
+
**`GIGET_AUTH`** — a GitHub PAT with read access to this private repo, present for **both** install and
|
|
90
|
+
build:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
GIGET_AUTH=$(gh auth token) bun install
|
|
94
|
+
GIGET_AUTH=$(gh auth token) bun run build
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Why the CSS needs its own import line
|
|
98
|
+
|
|
99
|
+
Forest's stylesheet uses Tailwind at-rules (`@utility`, `@custom-variant`) and mode-order-sensitive
|
|
100
|
+
`:root` re-points, so it **must compile in-band with your app's `@import "tailwindcss"`**, after
|
|
101
|
+
`@nuxt/ui`. A layer `css: []` entry would be the wrong build and the wrong order, so the consumer
|
|
102
|
+
imports it from their own entry CSS.
|
|
103
|
+
|
|
104
|
+
It does **not** need copying out of the cache. `#layers/forest` is the alias Nuxt derives from this
|
|
105
|
+
layer's `$meta.name`, and it resolves straight into giget's fetched copy — including the relative
|
|
106
|
+
`url('./files/…')` `@font-face` paths, which Vite rewrites into content-hashed font assets emitted
|
|
107
|
+
alongside the CSS that references them.
|
|
108
|
+
|
|
109
|
+
**You do not need a `@source` line.** Other Nuxt layer setups carry one (e.g.
|
|
110
|
+
`@source ".../node_modules/.c12/*/app/**"`) to make Tailwind scan the fetched layer for used classes.
|
|
111
|
+
`@nuxt/ui` already does this for you: it detects every extended layer — the giget-fetched one included —
|
|
112
|
+
and emits its own `@source` pointing at the resolved path. Verified by removing the manual line and
|
|
113
|
+
rebuilding: byte-identical CSS, same 3,997 selectors, including Forest-only classes such as the
|
|
114
|
+
`coarse:` touch-target utilities that appear in no app template. Copying another layer's glob is
|
|
115
|
+
duplicate work, and here it would also walk the ~27k vendored files that `install: true` creates inside
|
|
116
|
+
the cache. If a future `@nuxt/ui` ever stops auto-detecting layers and Forest classes go missing, add a
|
|
117
|
+
narrow `@source` scoped to the layer root rather than a `**` glob that descends into its `node_modules`.
|
|
118
|
+
|
|
119
|
+
One detail bites silently: **the alias is `#layers/forest`** (from `$meta.name`), not the directory name.
|
|
120
|
+
|
|
121
|
+
**Precedence:** earlier in `extends` wins, and the app wins over every layer. As a foundation, keep
|
|
122
|
+
Forest last.
|
|
123
|
+
|
|
124
|
+
## Staying up to date
|
|
125
|
+
|
|
126
|
+
Push a change to `main` and the **next build of every consuming app picks it up** — no cache-busting
|
|
127
|
+
step, no manual cache deletion.
|
|
128
|
+
|
|
129
|
+
That follows from `{ install: true }`: Nuxt's config loader (c12) passes it to giget as `force: true`,
|
|
130
|
+
which makes giget re-fetch the ref's tarball and extract it over `node_modules/.c12/<hash>/` on every
|
|
131
|
+
build. Drop `install: true` and giget's "destination already exists" guard re-engages, and an app can
|
|
132
|
+
keep building against a stale layer. It is also load-bearing for the build to succeed at all: giget
|
|
133
|
+
only installs the layer's own `dependencies` (`mapbox-gl`, `@unovis/vue`, `@unovis/ts`,
|
|
134
|
+
`tailwind-variants`, `@internationalized/date`) when `install: true` runs it inside the cache — drop
|
|
135
|
+
the flag and every map or chart component fails to resolve its imports, not just goes stale.
|
|
136
|
+
|
|
137
|
+
The trade-off: **freshness and reproducibility are the same knob.** There is no lockfile pin, so a push
|
|
138
|
+
to `main` reaches consumers unbidden. An app that needs reproducible builds should extend a tag or commit
|
|
139
|
+
SHA instead of `#main`, and will then stop receiving updates automatically. Versioning is lockstep across
|
|
140
|
+
the design system, cut as `v0.x.y` git tags — but **no tag has been cut yet**, so `#main` is the only
|
|
141
|
+
option until the first one is (see `CONTRIBUTING.md`). Every build also reaches the
|
|
142
|
+
GitHub API, which is why `GIGET_AUTH` is required at build time and not only at install time.
|
|
143
|
+
|
|
144
|
+
Because giget serves **whatever is committed**, run `bun run build:layer` and commit the regenerated
|
|
145
|
+
files after any token, theme, preset or font change — this includes the mirrored component sources (see
|
|
146
|
+
"What the layer delivers"), since editing `packages/ui/src` or `packages/charts/src` doesn't touch this
|
|
147
|
+
layer's copy until you regenerate it. The layer ships generated output (`theme.gen.json`,
|
|
148
|
+
`styles.gen.css`, the icon set, the font files) alongside 171 mirrored component-source files, not
|
|
149
|
+
generated output alone.
|
|
150
|
+
|
|
151
|
+
## Local development against the layer
|
|
152
|
+
|
|
153
|
+
When you are changing the layer itself, point the app at your local checkout so you see edits without
|
|
154
|
+
pushing:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const useLocalLayer = process.env.USE_LOCAL_LAYER === 'true'
|
|
158
|
+
|
|
159
|
+
export default defineNuxtConfig({
|
|
160
|
+
extends: [
|
|
161
|
+
useLocalLayer
|
|
162
|
+
? '../design-system/packages/nuxt-layer' // adjust to wherever you cloned it
|
|
163
|
+
: ['github:humanforest/design-system/packages/nuxt-layer#main', { install: true }],
|
|
164
|
+
],
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
USE_LOCAL_LAYER=true bun run dev
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**This path does not install the layer's dependencies.** Extending a local directory skips giget
|
|
173
|
+
entirely, so nothing installs `mapbox-gl`, `@unovis/vue`, `@unovis/ts`, `tailwind-variants` or
|
|
174
|
+
`@internationalized/date`: the layer directory has no `node_modules` of its own, and climbing to the
|
|
175
|
+
design-system repo's root `node_modules` doesn't find them either — bun links dependencies
|
|
176
|
+
per-workspace, not at the root. Add all five to the consuming app's own `package.json` `dependencies`.
|
|
177
|
+
Measured against a real probe app: skip this and the build fails with `Failed to resolve import
|
|
178
|
+
"mapbox-gl"` from `packages/ui/src/map/FMap.vue`.
|
|
179
|
+
|
|
180
|
+
The CSS import is unchanged — `#layers/forest` is derived from `$meta.name`, so it resolves whether the
|
|
181
|
+
layer came from a local path or the giget cache.
|
|
182
|
+
|
|
183
|
+
## Fonts: bundled, real, offline
|
|
184
|
+
|
|
185
|
+
This layer has **two channels**, and the font source is the only thing that differs between them.
|
|
186
|
+
|
|
187
|
+
Via giget, from this private repo with a PAT, it carries the real brand fonts: `files/` ships the
|
|
188
|
+
actual woff/woff2 (GT Haptik, Mohr, JetBrains Mono) and `styles.gen.css` points at them with relative
|
|
189
|
+
`url('./files/…')` paths — no CDN, no cross-origin fetch, no `Access-Control-Allow-Origin`
|
|
190
|
+
requirement. Real Mohr renders offline the moment a consuming app resolves this layer. That closed,
|
|
191
|
+
access-controlled distribution is what makes shipping the binaries defensible.
|
|
192
|
+
|
|
193
|
+
Via npm it carries none of them. `styles.cdn.gen.css` names the faces on `assets.forest.bike`, and
|
|
194
|
+
the `files` array leaves both `files/` and `styles.gen.css` out of the tarball — Mohr and GT Haptik
|
|
195
|
+
are licensed to Forest, not to whoever runs `npm add`. A licence-holder who wants to self-host from
|
|
196
|
+
npm brings their own `@font-face` block.
|
|
197
|
+
|
|
198
|
+
Mohr remains licensed **Black + UPPERCASE only**. Because distribution is limited to the private repo
|
|
199
|
+
plus a PAT-gated giget fetch, this stays within the licence — do not copy `files/` out of this channel
|
|
200
|
+
into a publicly published package.
|
|
201
|
+
|
|
202
|
+
## Regenerating
|
|
203
|
+
|
|
204
|
+
Run after any token / theme / preset / font change, then commit the generated files:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
bun run build:layer # emits theme.gen.json, styles.gen.css, assets/icons/forest, files, packages/, apps/
|
|
208
|
+
```
|
package/app.config.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import theme from './theme.gen.json'
|
|
2
|
+
|
|
3
|
+
// Nuxt UI reads its component theme, semantic colour roles and icon aliases from app.config.ui.
|
|
4
|
+
// theme.ui is the resolved forestPreset.ui: per-component tailwind-variants fragments, the
|
|
5
|
+
// primary/secondary/success/… → forest/warm/… role map, and the rating-star icon alias. Deep-merged
|
|
6
|
+
// across layers, so a downstream layer or app can override individual slots. Regenerate via
|
|
7
|
+
// `bun run build:layer`.
|
|
8
|
+
export default defineAppConfig({
|
|
9
|
+
ui: theme.ui
|
|
10
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
<path d="M5 3V7.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
19
|
+
<path d="M7 4L3 6.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
20
|
+
<path d="M3 4L7 6.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
<path d="M4 8L4 2.5M4 8L2 5.5M4 8L6 5.5" stroke-width="2" stroke-linecap="round" />
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 18C20.433 18 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 18 18.5 18Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 18C7.433 18 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 18 5.5 18Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
<path d="M8 18H3" stroke-width="2" stroke-linecap="round" />
|
|
19
|
+
<path d="M21 18H16" stroke-width="2" stroke-linecap="round" />
|
|
20
|
+
</svg>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
<path d="M4 2.5V8M4 2.5L6 5M4 2.5L2 5" stroke-width="2" stroke-linecap="round" />
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
<path d="M3 7L7 3M7 7L3 3" stroke-width="2" stroke-linecap="round" />
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path
|
|
3
|
+
d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z"
|
|
4
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path
|
|
6
|
+
d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z"
|
|
7
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
<path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2"
|
|
9
|
+
stroke-linecap="round" />
|
|
10
|
+
<path d="M8 9H10" stroke-width="2" stroke-linecap="round" />
|
|
11
|
+
<path d="M9 9L12 15" stroke-width="2" stroke-linecap="round" />
|
|
12
|
+
<path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2"
|
|
13
|
+
stroke-linecap="round" />
|
|
14
|
+
<path
|
|
15
|
+
d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16"
|
|
16
|
+
stroke-width="2" stroke-linecap="round" />
|
|
17
|
+
<path d="M5.5 12H3" stroke-width="2" stroke-linecap="round" />
|
|
18
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M12 2L17.2 12.4H15.4L17.2 16H6.8L8.6 12.4H6.8L12 2Z" stroke-width="2"
|
|
3
|
+
stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
<path d="M10.2 16V22H8.6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path d="M13.8 16V22H15.4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M12 2L17.2 12.4H15.4L17.2 16H6.8L8.6 12.4H6.8L12 2Z" stroke-width="2"
|
|
3
|
+
stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
<path d="M10.2 16V22H8.6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<path d="M13.8 16V22H15.4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M4.68 20.5 6.48 3.5H12.99Q16.15 3.5 17.78 5.02Q19.41 6.53 19.32 9.35Q19.24 12.66 17.19 14.43Q15.14 16.2 11.62 16.2H10.22L9.78 20.5ZM10.7 11.79H11.95Q13 11.79 13.57 11.26Q14.14 10.73 14.2 9.74Q14.23 8.88 13.77 8.4Q13.3 7.91 12.38 7.91H11.1Z" />
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M 11.5251 2.2969 a 0.5299 0.5299 0 0 1 0.9498 0 l 2.3095 4.6781 a 2.1196 2.1196 0 0 0 1.5947 1.1598 l 5.165 0.7558 a 0.5299 0.5299 0 0 1 0.2939 0.9038 l -3.7353 3.6373 a 2.1196 2.1196 0 0 0 -0.6109 1.8776 l 0.8818 5.139 a 0.5299 0.5299 0 0 1 -0.7708 0.5599 l -4.6171 -2.4275 a 2.1196 2.1196 0 0 0 -1.9726 0 L 6.3971 21.0082 a 0.5299 0.5299 0 0 1 -0.7698 -0.5599 l 0.8808 -5.138 a 2.1196 2.1196 0 0 0 -0.6109 -1.8786 L 2.162 9.7954 a 0.5299 0.5299 0 0 1 0.2939 -0.9058 l 5.164 -0.7548 a 2.1196 2.1196 0 0 0 1.5967 -1.1598 z"
|
|
3
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M 11.5251 2.2969 a 0.5299 0.5299 0 0 1 0.9498 0 l 2.3095 4.6781 a 2.1196 2.1196 0 0 0 1.5947 1.1598 l 5.165 0.7558 a 0.5299 0.5299 0 0 1 0.2939 0.9038 l -3.7353 3.6373 a 2.1196 2.1196 0 0 0 -0.6109 1.8776 l 0.8818 5.139 a 0.5299 0.5299 0 0 1 -0.7708 0.5599 l -4.6171 -2.4275 a 2.1196 2.1196 0 0 0 -1.9726 0 L 6.3971 21.0082 a 0.5299 0.5299 0 0 1 -0.7698 -0.5599 l 0.8808 -5.138 a 2.1196 2.1196 0 0 0 -0.6109 -1.8786 L 2.162 9.7954 a 0.5299 0.5299 0 0 1 0.2939 -0.9058 l 5.164 -0.7548 a 2.1196 2.1196 0 0 0 1.5967 -1.1598 z"
|
|
3
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="7" y="2" width="10" height="18" rx="2" stroke-width="2" stroke-linecap="round"
|
|
3
|
+
stroke-linejoin="round" />
|
|
4
|
+
<path d="M12 20v2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<circle cx="12" cy="6" r="2" fill="currentColor" stroke="none" />
|
|
6
|
+
<circle cx="12" cy="11" r="2" fill="var(--ui-warning, currentColor)" stroke="none" />
|
|
7
|
+
<circle cx="12" cy="16" r="2" fill="currentColor" stroke="none" />
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="7" y="2" width="10" height="18" rx="2" stroke-width="2" stroke-linecap="round"
|
|
3
|
+
stroke-linejoin="round" />
|
|
4
|
+
<path d="M12 20v2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<circle cx="12" cy="6" r="2" fill="currentColor" stroke="none" />
|
|
6
|
+
<circle cx="12" cy="11" r="2" fill="currentColor" stroke="none" />
|
|
7
|
+
<circle cx="12" cy="16" r="2" fill="var(--ui-success, currentColor)" stroke="none" />
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="7" y="2" width="10" height="18" rx="2" stroke-width="2" stroke-linecap="round"
|
|
3
|
+
stroke-linejoin="round" />
|
|
4
|
+
<path d="M12 20v2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<circle cx="12" cy="6" r="2" fill="var(--ui-error, currentColor)" stroke="none" />
|
|
6
|
+
<circle cx="12" cy="11" r="2" fill="var(--ui-warning, currentColor)" stroke="none" />
|
|
7
|
+
<circle cx="12" cy="16" r="2" fill="var(--ui-success, currentColor)" stroke="none" />
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="7" y="2" width="10" height="18" rx="2" stroke-width="2" stroke-linecap="round"
|
|
3
|
+
stroke-linejoin="round" />
|
|
4
|
+
<path d="M12 20v2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<circle cx="12" cy="6" r="2" fill="var(--ui-error, currentColor)" stroke="none" />
|
|
6
|
+
<circle cx="12" cy="11" r="2" fill="currentColor" stroke="none" />
|
|
7
|
+
<circle cx="12" cy="16" r="2" fill="currentColor" stroke="none" />
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="7" y="2" width="10" height="18" rx="2" stroke-width="2" stroke-linecap="round"
|
|
3
|
+
stroke-linejoin="round" />
|
|
4
|
+
<path d="M12 20v2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
5
|
+
<circle cx="12" cy="6" r="2" fill="currentColor" stroke="none" />
|
|
6
|
+
<circle cx="12" cy="11" r="2" fill="currentColor" stroke="none" />
|
|
7
|
+
<circle cx="12" cy="16" r="2" fill="currentColor" stroke="none" />
|
|
8
|
+
</svg>
|
package/nuxt.config.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import { dirname, join } from 'node:path'
|
|
3
|
+
import theme from './theme.gen.json'
|
|
4
|
+
|
|
5
|
+
// SELF-CONTAINED layer — no @humanforest/* imports, no climbing to sibling packages — so giget can fetch
|
|
6
|
+
// this directory alone (`github:humanforest/design-system/packages/nuxt-layer#main`) and it still
|
|
7
|
+
// works. Regenerate theme.gen.json / styles.gen.css / assets via `bun run build:layer`.
|
|
8
|
+
//
|
|
9
|
+
// CSS is NOT registered here: Forest's stylesheet uses Tailwind at-rules (@utility, @custom-variant)
|
|
10
|
+
// and must be compiled in-band with the app's `@import "tailwindcss"`. So the consumer @imports
|
|
11
|
+
// styles.gen.css from their own entry CSS, after `@nuxt/ui`. See README.md.
|
|
12
|
+
|
|
13
|
+
const currentDir = dirname(fileURLToPath(import.meta.url))
|
|
14
|
+
|
|
15
|
+
export default defineNuxtConfig({
|
|
16
|
+
$meta: { name: 'forest' },
|
|
17
|
+
|
|
18
|
+
// Self-sufficient; deduped when the consumer already lists @nuxt/ui.
|
|
19
|
+
modules: ['@nuxt/ui'],
|
|
20
|
+
|
|
21
|
+
// Forest scale families (color="forest|maple|river|warm|acid") + the default roles the plugin
|
|
22
|
+
// would otherwise drop. From the resolved preset.
|
|
23
|
+
ui: {
|
|
24
|
+
theme: {
|
|
25
|
+
colors: theme.theme.colors as string[]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Forest icons (i-forest-*) — SVGs copied into the layer, so @nuxt/icon scans them from the
|
|
30
|
+
// giget-fetched dir too (currentDir is the cache path at build).
|
|
31
|
+
icon: {
|
|
32
|
+
customCollections: [
|
|
33
|
+
{ prefix: 'forest', dir: join(currentDir, 'assets/icons/forest') }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Forest components, from the mirrored source trees. Absolute paths via currentDir: `~/` in a layer
|
|
38
|
+
// resolves against the CONSUMER's srcDir, not this one. pathPrefix:false keeps map/FMap.vue as
|
|
39
|
+
// <FMap> rather than <MapFMap>; the pattern restricts scanning to SFCs so the sibling .ts modules
|
|
40
|
+
// are not treated as components.
|
|
41
|
+
components: [
|
|
42
|
+
{ path: join(currentDir, 'packages/ui/src'), pathPrefix: false, pattern: '**/*.vue' },
|
|
43
|
+
{ path: join(currentDir, 'packages/charts/src'), pathPrefix: false, pattern: '**/*.vue' },
|
|
44
|
+
// Presentation frames (FDeviceFrame / FBrowserFrame / FFitFrame). They stage a prototype rather
|
|
45
|
+
// than appear in one, so they carry CC BY-SA device art — which is exactly why they ship on this
|
|
46
|
+
// private giget layer and not on public npm. See packages/frames/README.md.
|
|
47
|
+
{ path: join(currentDir, 'packages/frames/src'), pathPrefix: false, pattern: '**/*.vue' }
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
// Auto-imported composables — an ALLOW-LIST, not `imports.dirs`. A directory scan would take every
|
|
51
|
+
// export in the mirrored trees, and those barrels carry names like `token`, `isSelected`, `nextKey`
|
|
52
|
+
// and `addClause`: generic enough that dropping them into a consuming app's global namespace
|
|
53
|
+
// invites a collision the app author never asked for and cannot see coming.
|
|
54
|
+
//
|
|
55
|
+
// Listed here is the call-site API — the imperative half of FMap, the chart palette, the two KPI
|
|
56
|
+
// formatters. Everything else a barrel exports stays reachable, deliberately, by path:
|
|
57
|
+
// import { STATE_LABEL } from '#layers/forest/packages/ui/src/map'
|
|
58
|
+
imports: {
|
|
59
|
+
presets: [
|
|
60
|
+
{
|
|
61
|
+
from: join(currentDir, 'packages/ui/src/map/index.ts'),
|
|
62
|
+
// The four state composables join the list because a console needs all of them and each name
|
|
63
|
+
// says "map" or "vehicle" out loud. Their pure cores do NOT: `collectVisible`, `rowKey` and
|
|
64
|
+
// `patchQuery` are exactly the generic names this allow-list exists to keep out of an app's
|
|
65
|
+
// global namespace, and they stay reachable by path.
|
|
66
|
+
imports: [
|
|
67
|
+
'useMapReady', 'useMapCamera', 'useMapOverlay', 'useFeatureSelect', 'MAP_SLOT',
|
|
68
|
+
'useMapUrlState', 'useVisibleFeatures', 'useMapTableSelection', 'useVehicleFilter'
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
from: join(currentDir, 'packages/ui/src/kpi/index.ts'),
|
|
73
|
+
imports: ['formatMetric', 'formatPercent']
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
from: join(currentDir, 'packages/charts/src/index.ts'),
|
|
77
|
+
imports: ['useChartPalette']
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@humanforest/nuxt-layer",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Forest design system as a Nuxt layer — extend it to inherit the theme, colour roles, icons and brand fonts in one line.",
|
|
6
|
+
"main": "./nuxt.config.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"nuxt.config.ts",
|
|
9
|
+
"app.config.ts",
|
|
10
|
+
"theme.gen.json",
|
|
11
|
+
"styles.cdn.gen.css",
|
|
12
|
+
"assets",
|
|
13
|
+
"packages",
|
|
14
|
+
"apps",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@humanforest/tokens": "^0.1.0",
|
|
19
|
+
"@internationalized/date": "^3.12.2",
|
|
20
|
+
"@mapbox/search-js-core": "^1.6.0",
|
|
21
|
+
"@unovis/ts": "^1.6.7",
|
|
22
|
+
"@unovis/vue": "^1.6.7",
|
|
23
|
+
"mapbox-gl": "^3.28.1",
|
|
24
|
+
"tailwind-variants": "3.2.2"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@nuxt/ui": ">=4.5.0",
|
|
28
|
+
"nuxt": "^4.0.0",
|
|
29
|
+
"vue": "^3.5"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"license": "SEE LICENSE IN LICENSE"
|
|
35
|
+
}
|