@humanforest/ui 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.
Files changed (235) hide show
  1. package/LICENSE +67 -0
  2. package/icons/forest/bike-asterisk.svg +21 -0
  3. package/icons/forest/bike-down.svg +19 -0
  4. package/icons/forest/bike-off.svg +20 -0
  5. package/icons/forest/bike-up.svg +19 -0
  6. package/icons/forest/bike-x.svg +19 -0
  7. package/icons/forest/bike.svg +18 -0
  8. package/icons/forest/map/forest-place-count.svg +21 -0
  9. package/icons/forest/map/forest-place-marker.svg +17 -0
  10. package/icons/forest/map/forest-vehicle-marker.svg +73 -0
  11. package/icons/forest/map/manifest.json +373 -0
  12. package/icons/forest/map/place-count-manifest.json +83 -0
  13. package/icons/forest/map/place-manifest.json +74 -0
  14. package/icons/forest/mark-fill.svg +6 -0
  15. package/icons/forest/mark.svg +6 -0
  16. package/icons/forest/parking.svg +3 -0
  17. package/icons/forest/star-fill.svg +4 -0
  18. package/icons/forest/star.svg +4 -0
  19. package/icons/forest/traffic-light-caution.svg +8 -0
  20. package/icons/forest/traffic-light-go.svg +8 -0
  21. package/icons/forest/traffic-light-lit.svg +8 -0
  22. package/icons/forest/traffic-light-stop.svg +8 -0
  23. package/icons/forest/traffic-light.svg +8 -0
  24. package/package.json +64 -0
  25. package/src/address/address.ts +125 -0
  26. package/src/address/autofill.ts +78 -0
  27. package/src/address/geocode.ts +55 -0
  28. package/src/address/index.ts +31 -0
  29. package/src/address/validate.ts +91 -0
  30. package/src/canvas/FCanvasCard.vue +97 -0
  31. package/src/canvas/FCanvasControl.vue +121 -0
  32. package/src/canvas/FCanvasControlGroup.vue +100 -0
  33. package/src/canvas/FCanvasFlyout.vue +216 -0
  34. package/src/canvas/FCanvasHud.vue +402 -0
  35. package/src/canvas/canvasSurface.ts +39 -0
  36. package/src/canvas/index.ts +17 -0
  37. package/src/contexts/ForestContext.vue +53 -0
  38. package/src/contexts/contexts.ts +153 -0
  39. package/src/contexts/index.ts +23 -0
  40. package/src/contexts/marketing-theme.ts +214 -0
  41. package/src/contexts/mobile-theme.ts +402 -0
  42. package/src/filter/FFilterBar.vue +72 -0
  43. package/src/filter/FFilterChip.vue +362 -0
  44. package/src/filter/FFilterClauses.vue +104 -0
  45. package/src/filter/FFilterTrigger.vue +183 -0
  46. package/src/filter/filter.theme.ts +27 -0
  47. package/src/filter/filterClause.ts +265 -0
  48. package/src/filter/filterPredicate.ts +134 -0
  49. package/src/filter/filterSchema.ts +82 -0
  50. package/src/filter/index.ts +36 -0
  51. package/src/forest-preset.ts +68 -0
  52. package/src/icons.ts +79 -0
  53. package/src/index.ts +17 -0
  54. package/src/kpi/FKpi.vue +253 -0
  55. package/src/kpi/FKpiGroup.vue +161 -0
  56. package/src/kpi/index.ts +20 -0
  57. package/src/kpi/kpi.theme.ts +168 -0
  58. package/src/kpi/kpiDelta.ts +82 -0
  59. package/src/kpi/kpiFormat.ts +72 -0
  60. package/src/kpi/kpiGroupState.ts +63 -0
  61. package/src/logo/FLogo.vue +52 -0
  62. package/src/logo/FSubLogo.vue +214 -0
  63. package/src/logo/index.ts +8 -0
  64. package/src/map/FMap.vue +355 -0
  65. package/src/map/FMapCompass.vue +154 -0
  66. package/src/map/FMapCoordinates.vue +134 -0
  67. package/src/map/FMapDrawTools.vue +116 -0
  68. package/src/map/FMapFullscreen.vue +92 -0
  69. package/src/map/FMapGeolocate.vue +208 -0
  70. package/src/map/FMapLayers.vue +75 -0
  71. package/src/map/FMapLegend.vue +45 -0
  72. package/src/map/FMapPopup.vue +129 -0
  73. package/src/map/FMapRamp.vue +69 -0
  74. package/src/map/FMapRegion.vue +77 -0
  75. package/src/map/FMapScale.vue +107 -0
  76. package/src/map/FMapSearch.vue +362 -0
  77. package/src/map/FMapTilt.vue +87 -0
  78. package/src/map/FMapTools.vue +61 -0
  79. package/src/map/FMapZoom.vue +81 -0
  80. package/src/map/FMarker.vue +218 -0
  81. package/src/map/FTrackScrubber.vue +94 -0
  82. package/src/map/FVehicleLegend.vue +72 -0
  83. package/src/map/FVehicleMark.vue +166 -0
  84. package/src/map/bin.ts +196 -0
  85. package/src/map/coordinates.ts +83 -0
  86. package/src/map/density.ts +401 -0
  87. package/src/map/draw.ts +356 -0
  88. package/src/map/ease.ts +67 -0
  89. package/src/map/fullscreen.ts +59 -0
  90. package/src/map/heat.ts +160 -0
  91. package/src/map/index.ts +351 -0
  92. package/src/map/liveMarkers.ts +60 -0
  93. package/src/map/map.css +116 -0
  94. package/src/map/mapColor.ts +31 -0
  95. package/src/map/mapContext.ts +12 -0
  96. package/src/map/mapLayers.ts +55 -0
  97. package/src/map/mapLegend.ts +70 -0
  98. package/src/map/mapSearch.theme.ts +79 -0
  99. package/src/map/mapSearch.ts +279 -0
  100. package/src/map/mapUrl.ts +117 -0
  101. package/src/map/markerAsset.ts +3 -0
  102. package/src/map/padding.ts +39 -0
  103. package/src/map/place.ts +192 -0
  104. package/src/map/ramp.ts +95 -0
  105. package/src/map/regionSelect.ts +163 -0
  106. package/src/map/route.ts +167 -0
  107. package/src/map/scale.ts +329 -0
  108. package/src/map/scaleBar.ts +67 -0
  109. package/src/map/selectionModel.ts +50 -0
  110. package/src/map/sources/coordinates.ts +58 -0
  111. package/src/map/sources/mapboxPlaces.ts +71 -0
  112. package/src/map/style.ts +14 -0
  113. package/src/map/track.ts +279 -0
  114. package/src/map/useFeatureSelect.ts +230 -0
  115. package/src/map/useLiveMarkers.ts +84 -0
  116. package/src/map/useMap.ts +150 -0
  117. package/src/map/useMapDraw.ts +776 -0
  118. package/src/map/useMapOverlay.ts +421 -0
  119. package/src/map/useMapTableSelection.ts +101 -0
  120. package/src/map/useMapUrlState.ts +155 -0
  121. package/src/map/useMarkerSource.ts +163 -0
  122. package/src/map/useRegionSelect.ts +309 -0
  123. package/src/map/useTokenMode.ts +61 -0
  124. package/src/map/useTrackPlayback.ts +131 -0
  125. package/src/map/useVehicleFilter.ts +51 -0
  126. package/src/map/useVisibleFeatures.ts +124 -0
  127. package/src/map/vehicle.ts +807 -0
  128. package/src/map/vehicleFilter.ts +284 -0
  129. package/src/map/vehicleLegend.ts +155 -0
  130. package/src/map/visibleFeatures.ts +192 -0
  131. package/src/map/zone.ts +291 -0
  132. package/src/shell/FAppNavbar.vue +68 -0
  133. package/src/shell/FAppShell.vue +163 -0
  134. package/src/shell/FAppSidebar.vue +215 -0
  135. package/src/shell/FPageToolbar.vue +126 -0
  136. package/src/shell/FScrollShadow.vue +43 -0
  137. package/src/shell/FSidePanel.vue +258 -0
  138. package/src/shell/FToolbarActions.vue +32 -0
  139. package/src/shell/index.ts +33 -0
  140. package/src/shell/nav.ts +37 -0
  141. package/src/shell/pageToolbar.ts +69 -0
  142. package/src/shell/shell.ts +74 -0
  143. package/src/shell/sidePanel.ts +115 -0
  144. package/src/styles/forest.css +852 -0
  145. package/src/styles/index.css +39 -0
  146. package/src/themes/accordion.ts +36 -0
  147. package/src/themes/alert.ts +16 -0
  148. package/src/themes/auth-form.ts +19 -0
  149. package/src/themes/avatar-group.ts +9 -0
  150. package/src/themes/avatar.ts +18 -0
  151. package/src/themes/badge.ts +51 -0
  152. package/src/themes/banner.ts +21 -0
  153. package/src/themes/breadcrumb.ts +10 -0
  154. package/src/themes/button.mechanics.ts +191 -0
  155. package/src/themes/button.ts +136 -0
  156. package/src/themes/calendar.ts +29 -0
  157. package/src/themes/card.ts +67 -0
  158. package/src/themes/carousel.ts +41 -0
  159. package/src/themes/checkbox-group.ts +20 -0
  160. package/src/themes/checkbox.ts +47 -0
  161. package/src/themes/chip.ts +50 -0
  162. package/src/themes/collapsible.ts +26 -0
  163. package/src/themes/color-picker.ts +13 -0
  164. package/src/themes/command-palette.ts +37 -0
  165. package/src/themes/container.ts +14 -0
  166. package/src/themes/context-menu.ts +38 -0
  167. package/src/themes/dashboard-group.ts +11 -0
  168. package/src/themes/dashboard-navbar.ts +10 -0
  169. package/src/themes/dashboard-panel.ts +18 -0
  170. package/src/themes/dashboard-resize-handle.ts +35 -0
  171. package/src/themes/dashboard-sidebar-collapse.ts +7 -0
  172. package/src/themes/dashboard-sidebar-toggle.ts +7 -0
  173. package/src/themes/dashboard-sidebar.ts +58 -0
  174. package/src/themes/dashboard-toolbar.ts +15 -0
  175. package/src/themes/drawer.ts +45 -0
  176. package/src/themes/dropdown-menu.ts +38 -0
  177. package/src/themes/empty.ts +43 -0
  178. package/src/themes/field-group.ts +52 -0
  179. package/src/themes/file-upload.ts +38 -0
  180. package/src/themes/footer-columns.ts +13 -0
  181. package/src/themes/footer.ts +9 -0
  182. package/src/themes/form-field.ts +25 -0
  183. package/src/themes/form.ts +22 -0
  184. package/src/themes/header.ts +12 -0
  185. package/src/themes/icon.ts +61 -0
  186. package/src/themes/index.ts +99 -0
  187. package/src/themes/input-date.ts +73 -0
  188. package/src/themes/input-menu.ts +66 -0
  189. package/src/themes/input-number.ts +58 -0
  190. package/src/themes/input-rating.ts +25 -0
  191. package/src/themes/input-tags.ts +63 -0
  192. package/src/themes/input-time.ts +70 -0
  193. package/src/themes/input.ts +148 -0
  194. package/src/themes/kbd.ts +27 -0
  195. package/src/themes/link.ts +27 -0
  196. package/src/themes/listbox.ts +48 -0
  197. package/src/themes/main.ts +6 -0
  198. package/src/themes/marquee.ts +45 -0
  199. package/src/themes/modal.ts +46 -0
  200. package/src/themes/navigation-menu.ts +80 -0
  201. package/src/themes/page-anchors.ts +7 -0
  202. package/src/themes/page-aside.ts +7 -0
  203. package/src/themes/page-card.ts +22 -0
  204. package/src/themes/page-cta.ts +18 -0
  205. package/src/themes/page-feature.ts +13 -0
  206. package/src/themes/page-header.ts +16 -0
  207. package/src/themes/page-hero.ts +15 -0
  208. package/src/themes/page-links.ts +12 -0
  209. package/src/themes/page-section.ts +14 -0
  210. package/src/themes/page.ts +7 -0
  211. package/src/themes/pagination.ts +17 -0
  212. package/src/themes/pin-input.ts +73 -0
  213. package/src/themes/popover.ts +30 -0
  214. package/src/themes/progress.ts +29 -0
  215. package/src/themes/prose.ts +45 -0
  216. package/src/themes/radio-group.ts +39 -0
  217. package/src/themes/scroll-area.ts +23 -0
  218. package/src/themes/select-menu.ts +71 -0
  219. package/src/themes/select.ts +72 -0
  220. package/src/themes/separator.ts +28 -0
  221. package/src/themes/sidebar.ts +127 -0
  222. package/src/themes/skeleton.ts +15 -0
  223. package/src/themes/slideover.ts +87 -0
  224. package/src/themes/slider.ts +48 -0
  225. package/src/themes/stepper.ts +41 -0
  226. package/src/themes/switch.ts +63 -0
  227. package/src/themes/table.ts +34 -0
  228. package/src/themes/tabs.ts +74 -0
  229. package/src/themes/textarea.ts +77 -0
  230. package/src/themes/timeline.ts +25 -0
  231. package/src/themes/toast.ts +29 -0
  232. package/src/themes/toaster.ts +66 -0
  233. package/src/themes/tooltip.ts +31 -0
  234. package/src/themes/tree.ts +41 -0
  235. package/src/themes/user.ts +28 -0
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Forest theme fragment — UToaster (the toast STACK: viewport, entry/exit, swipe, collapse).
3
+ *
4
+ * Distinct from the `toast` fragment, which styles a single notification's surface. Everything the
5
+ * stack moves lives here, and all of it was stock — this fragment exists only to bring that motion
6
+ * onto the shared tokens. Nothing else about the toaster needs a Forest opinion: the viewport
7
+ * position matrix, the stacking transforms and the swipe translate maths are structure.
8
+ *
9
+ * Timing, by what each thing is:
10
+ * - entry (`toast-slide-in-from-*`) — an overlay arriving, so --motion-base
11
+ * - exit (`toast-closed`, `toast-collapsed-closed`) and swipe-dismiss — --motion-fast, the
12
+ * overlay-exit bucket; a dismissal the user already committed to should get out of the way
13
+ * - the stack reflow (`transition-[transform,translate,height]`, running whenever a sibling
14
+ * enters or leaves) — --motion-base, since it is what visually carries the entry
15
+ * - `pulse-a` / `pulse-b`, the attention nudge on a repeat toast — --motion-base
16
+ * - the front-card opacity fade at duration-100 — --motion-instant
17
+ *
18
+ * Every curve becomes --motion-ease-out. Stock eases the entry and both exits with `ease-in-out`,
19
+ * which the doctrine reserves for movement that starts AND settles on screen; a toast slides in
20
+ * from outside the viewport and leaves it again.
21
+ *
22
+ * Slots touched: base (and its position compounds + the swipeDirection variant).
23
+ * Stock recipe: apps/docs/node_modules/.nuxt-ui/ui/toaster.ts
24
+ */
25
+
26
+ export const toasterTheme = {
27
+ slots: {
28
+ // Exits, the attention pulse, the front-card fade, and the stack reflow. Same keyframes and same
29
+ // property list as stock — only the durations and curves are restated, and tailwind-merge takes
30
+ // the last of each pair in the concat.
31
+ base: [
32
+ 'data-[front=false]:*:duration-(--motion-instant)',
33
+ 'data-[state=closed]:animate-[toast-closed_var(--motion-fast)_var(--motion-ease-out)]',
34
+ 'data-[state=closed]:data-[expanded=false]:data-[front=false]:animate-[toast-collapsed-closed_var(--motion-fast)_var(--motion-ease-out)]',
35
+ 'data-[state=open]:data-[pulsing=odd]:animate-[toast-pulse-a_var(--motion-base)_var(--motion-ease-out)]',
36
+ 'data-[state=open]:data-[pulsing=even]:animate-[toast-pulse-b_var(--motion-base)_var(--motion-ease-out)]',
37
+ 'duration-(--motion-base) ease-(--motion-ease-out)',
38
+ ].join(' '),
39
+ },
40
+ variants: {
41
+ // Swipe-to-dismiss — the fling that completes a gesture the user is already making, so it runs
42
+ // at the exit duration rather than the entry one.
43
+ swipeDirection: {
44
+ up: 'data-[swipe=end]:animate-[toast-slide-up_var(--motion-fast)_var(--motion-ease-out)]',
45
+ right: 'data-[swipe=end]:animate-[toast-slide-right_var(--motion-fast)_var(--motion-ease-out)]',
46
+ down: 'data-[swipe=end]:animate-[toast-slide-down_var(--motion-fast)_var(--motion-ease-out)]',
47
+ left: 'data-[swipe=end]:animate-[toast-slide-left_var(--motion-fast)_var(--motion-ease-out)]',
48
+ },
49
+ },
50
+ // Entry, which stock scopes to the position group (a top toast slides down, a bottom one up). The
51
+ // discriminator arrays mirror stock's exactly so these land as the same compound, applied last.
52
+ compoundVariants: [
53
+ {
54
+ position: ['top-left', 'top-center', 'top-right'],
55
+ class: {
56
+ base: 'data-[state=open]:animate-[toast-slide-in-from-top_var(--motion-base)_var(--motion-ease-out)]',
57
+ },
58
+ },
59
+ {
60
+ position: ['bottom-left', 'bottom-center', 'bottom-right'],
61
+ class: {
62
+ base: 'data-[state=open]:animate-[toast-slide-in-from-bottom_var(--motion-base)_var(--motion-ease-out)]',
63
+ },
64
+ },
65
+ ],
66
+ } as const;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Forest theme fragment — UTooltip (hover/focus hint).
3
+ *
4
+ * Deltas only (the preset APPENDS to stock Nuxt UI):
5
+ * content — flips stock's surface look (`bg-default text-highlighted rounded-sm`) to a floating
6
+ * inverted bubble (`bg-inverted text-inverted`) at the brand radius (`rounded-lg`,
7
+ * 0.5 rem / --ui-radius), and swaps stock's raw `100ms ease` open/close animation for
8
+ * the Forest motion tokens (fast enter, instant exit). Shadow, ring, height, padding,
9
+ * origin and pointer-events are inherited from stock and not restated.
10
+ * arrow — must follow the inverted bubble: stock fills the caret with `fill-bg` (the light
11
+ * surface), which reads as a white pointer on our dark bubble. Re-point it at the
12
+ * inverted bg so the caret matches the content. Stock's `stroke-default` is kept (it
13
+ * aligns with the bubble's inherited ring).
14
+ *
15
+ * Stock slots left untouched: text, kbds (kbds inherit the Forest UKbd theme).
16
+ *
17
+ * Slots sourced from: apps/docs/node_modules/.nuxt-ui/ui/tooltip.ts
18
+ * Slots touched: `content`
19
+ */
20
+
21
+ export const tooltipTheme = {
22
+ slots: {
23
+ // Both open states animate. Stock only ever reaches `delayed-open` through its own hover timer,
24
+ // but a tooltip whose `open` is controlled — the chart components drive theirs from their own
25
+ // hit-testing — reports `instant-open` instead, and matching only the delayed state left those
26
+ // appearing with no transition at all.
27
+ content: 'bg-inverted text-inverted rounded-lg data-[state=delayed-open]:animate-[scale-in_var(--motion-fast)_var(--motion-ease-out)] data-[state=instant-open]:animate-[scale-in_var(--motion-fast)_var(--motion-ease-out)] data-[state=closed]:animate-[scale-out_var(--motion-instant)_var(--motion-ease-out)]',
28
+ // Caret follows the inverted bubble (stock fills it with the light `fill-bg`). stroke-default kept.
29
+ arrow: 'fill-[var(--ui-bg-inverted)]',
30
+ },
31
+ } as const;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Forest theme fragment — UTree (hierarchical disclosure list).
3
+ *
4
+ * Deltas over stock (the preset appends to Nuxt UI):
5
+ * - `link`: a focused row draws an inset focus-visible ring on the before: pseudo that already
6
+ * carries the selection / hover pill.
7
+ * - `linkTrailingIcon`: the expand chevron rotates on --motion-fast / --motion-ease-out rather
8
+ * than stock's hard-coded duration-200 — a small near element, same bucket as the accordion
9
+ * and collapsible chevrons.
10
+ *
11
+ * The pill keeps its stock before:rounded-md (12px) — a tree node is a row, the same shape a sidebar
12
+ * nav row and a command-palette result carry.
13
+ *
14
+ * Everything else is stock: the indent guide (border-s border-default), the folder / chevron icons,
15
+ * the per-colour selected-label and focus colours, and the size ladder all read on the Forest ramps
16
+ * and semantic tokens without an override.
17
+ *
18
+ * Slots touched: link, linkTrailingIcon.
19
+ * Slot names sourced from: apps/docs/node_modules/.nuxt-ui/ui/tree.ts
20
+ */
21
+
22
+ export const treeTheme = {
23
+ slots: {
24
+ link: 'focus-visible:before:ring-inset focus-visible:before:ring-2',
25
+ linkTrailingIcon: 'duration-(--motion-fast) ease-(--motion-ease-out)',
26
+ },
27
+
28
+ // Touch: each node promotes ONE size up under a coarse pointer (borrows the next size's padding /
29
+ // gap / type / icon) — same ladder as the menu/input family. Unlike the input field, tree links
30
+ // position their icons with flex `gap` (not an absolute ps-*/pe-* inset), so bumping horizontal
31
+ // padding here is safe. xl is the ceiling; deltas only. `coarse:` carries the :not(.cut-fixed)
32
+ // escape so a baked mobile cut opts out.
33
+ variants: {
34
+ size: {
35
+ xs: { link: 'coarse:px-2.5 coarse:py-1.5 coarse:gap-1.5' },
36
+ sm: { link: 'coarse:text-sm', linkLeadingIcon: 'coarse:size-5', linkTrailingIcon: 'coarse:size-5' },
37
+ md: { link: 'coarse:px-3 coarse:py-2 coarse:gap-2' },
38
+ lg: { link: 'coarse:text-base', linkLeadingIcon: 'coarse:size-6', linkTrailingIcon: 'coarse:size-6' },
39
+ },
40
+ },
41
+ } as const;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Forest theme fragment — UUser (name + avatar + description row)
3
+ *
4
+ * Deltas only (stock in apps/docs/node_modules/.nuxt-ui/ui/user.ts):
5
+ * - `name`: `font-bold` (stock base is `font-medium`) so the rider/operator name reads with
6
+ * clear hierarchy above the description at every size. Colour is left to stock: the `to:false`
7
+ * variant already sets `text-highlighted` on the non-link name, so restating it here would be
8
+ * dead weight; the `to:true` link state keeps its own `text-default → highlighted` transition.
9
+ * - `wrapper`: `min-w-0` guard so name + description truncate when the row sits inside a flex
10
+ * parent (table cell, narrow sidebar item, list row). Stock wrapper base is empty.
11
+ * - `to.true.avatar`: the hover scale runs on --motion-fast / --motion-ease-out instead of stock's
12
+ * hard-coded duration-200 (bare `ease`). A hover affordance on a small near element is the
13
+ * textbook --motion-fast case.
14
+ *
15
+ * Untouched (all stock): `description` (`text-muted`), `avatar` (`shrink-0`), the 3xs–3xl gap +
16
+ * text size ladder, orientation, chip, and the `to` hover/focus colour transitions.
17
+ */
18
+ export const userTheme = {
19
+ slots: {
20
+ name: 'font-bold',
21
+ wrapper: 'min-w-0',
22
+ },
23
+ variants: {
24
+ to: {
25
+ true: { avatar: 'duration-(--motion-fast) ease-(--motion-ease-out)' },
26
+ },
27
+ },
28
+ } as const;