@humanforest/slidev-theme 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 +577 -0
- package/assetUrl.js +38 -0
- package/components/Alert.vue +209 -0
- package/components/AreaBox.vue +152 -0
- package/components/AreaChart.vue +145 -0
- package/components/Avatar.vue +267 -0
- package/components/AvatarGroup.vue +94 -0
- package/components/BadgeStrip.vue +203 -0
- package/components/Bars.vue +207 -0
- package/components/BoroughShape.vue +127 -0
- package/components/BrowserFrame.vue +484 -0
- package/components/CalendarGrid.vue +480 -0
- package/components/Card.vue +70 -0
- package/components/Carousel.vue +266 -0
- package/components/ChartFrame.vue +426 -0
- package/components/ChordChart.vue +264 -0
- package/components/ComposedChart.vue +187 -0
- package/components/Contents.vue +86 -0
- package/components/DataTable.vue +244 -0
- package/components/DeckMap.vue +409 -0
- package/components/DeviceFrame.vue +331 -0
- package/components/DonutChart.vue +103 -0
- package/components/DottedMap.vue +126 -0
- package/components/Endorsement.vue +76 -0
- package/components/Grid.vue +169 -0
- package/components/GroupedBarChart.vue +141 -0
- package/components/IconTile.vue +116 -0
- package/components/Kpi.vue +188 -0
- package/components/LineChart.vue +133 -0
- package/components/Logo.vue +203 -0
- package/components/LondonMap.vue +348 -0
- package/components/MarkPair.vue +109 -0
- package/components/Marquee.vue +263 -0
- package/components/NestedDonutChart.vue +295 -0
- package/components/Placeholder.vue +88 -0
- package/components/SankeyChart.vue +223 -0
- package/components/ScatterChart.vue +142 -0
- package/components/StackedBarChart.vue +143 -0
- package/components/StatCard.vue +134 -0
- package/components/StatusTrack.vue +334 -0
- package/components/Timeline.vue +249 -0
- package/components/TimelineChart.vue +329 -0
- package/components/TreemapChart.vue +267 -0
- package/components/backgrounds.js +135 -0
- package/components/boroughGeometry.ts +59 -0
- package/components/chartData.ts +277 -0
- package/components/chartTip.ts +201 -0
- package/components/codeTheme.ts +239 -0
- package/components/deckPalette.ts +157 -0
- package/components/dottedMapGeometry.js +60 -0
- package/components/iconSlugs.js +55 -0
- package/components/iconUrl.js +51 -0
- package/components/mermaidTheme.ts +972 -0
- package/components/motionDuration.ts +41 -0
- package/components/tableRules.ts +257 -0
- package/confidential-mark.vue +151 -0
- package/custom-nav-controls.vue +79 -0
- package/endorsements/b-corp-black.svg +30 -0
- package/endorsements/b-corp-white.svg +30 -0
- package/global-top.vue +1662 -0
- package/icons/forest/bike-asterisk.svg +21 -0
- package/icons/forest/bike-down.svg +19 -0
- package/icons/forest/bike-off.svg +20 -0
- package/icons/forest/bike-up.svg +19 -0
- package/icons/forest/bike-x.svg +19 -0
- package/icons/forest/bike.svg +18 -0
- package/icons/forest/mark-fill.svg +6 -0
- package/icons/forest/mark.svg +6 -0
- package/icons/forest/parking.svg +3 -0
- package/icons/forest/star-fill.svg +4 -0
- package/icons/forest/star.svg +4 -0
- package/icons/forest/traffic-light-caution.svg +8 -0
- package/icons/forest/traffic-light-go.svg +8 -0
- package/icons/forest/traffic-light-lit.svg +8 -0
- package/icons/forest/traffic-light-stop.svg +8 -0
- package/icons/forest/traffic-light.svg +8 -0
- package/icons/lucide/battery.svg +1 -0
- package/icons/lucide/bike.svg +1 -0
- package/icons/lucide/chart-line.svg +1 -0
- package/icons/lucide/check.svg +1 -0
- package/icons/lucide/circle-check.svg +1 -0
- package/icons/lucide/clock.svg +1 -0
- package/icons/lucide/code.svg +1 -0
- package/icons/lucide/component.svg +1 -0
- package/icons/lucide/frame.svg +1 -0
- package/icons/lucide/layout-grid.svg +1 -0
- package/icons/lucide/map-pin.svg +1 -0
- package/icons/lucide/map.svg +1 -0
- package/icons/lucide/palette.svg +1 -0
- package/icons/lucide/table.svg +1 -0
- package/icons/lucide/triangle-alert.svg +1 -0
- package/icons/lucide/type.svg +1 -0
- package/icons/lucide/wrench.svg +1 -0
- package/layouts/bleed.vue +317 -0
- package/layouts/cover.vue +1514 -0
- package/layouts/default.vue +187 -0
- package/layouts/divider.vue +286 -0
- package/layouts/end.vue +384 -0
- package/layouts/quote.vue +218 -0
- package/layouts/split.vue +1875 -0
- package/layouts/stack.vue +944 -0
- package/layouts/statement.vue +67 -0
- package/manifest/chrome.ts +36 -0
- package/manifest/components.ts +49 -0
- package/manifest/index.ts +57 -0
- package/manifest/layouts.ts +37 -0
- package/manifest/manifest.json +6514 -0
- package/manifest/presets.ts +635 -0
- package/notch.js +458 -0
- package/notchPath.js +188 -0
- package/package.json +77 -0
- package/section.js +110 -0
- package/setup/mermaid-renderer.ts +2120 -0
- package/setup/mermaid.ts +30 -0
- package/setup/shiki.ts +44 -0
- package/setup/shortcuts.ts +28 -0
- package/slide-bottom.vue +305 -0
- package/slide-top.vue +268 -0
- package/styles/base.css +2611 -0
- package/styles/index.ts +71 -0
- package/styles/tokens.css +144 -0
- package/uno.config.ts +231 -0
- package/useNotchCuts.js +200 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Every icon slug `<IconTile icon="…">` will accept, derived from the generated collections
|
|
2
|
+
// rather than restated — the same shape backgrounds.js already fixes for background names (see that
|
|
3
|
+
// file's own doc comment for the defect this pattern exists to prevent).
|
|
4
|
+
//
|
|
5
|
+
// task-7-fix-1.md CRITICAL 1: `IconTile.icon` shipped `type: String, required: true` with no
|
|
6
|
+
// validator at all, so nothing — not the manifest, not a gate, not this package's own vitest
|
|
7
|
+
// suite — could tell a real icon slug apart from an invented one. A preset's `fill` prose (Task 7)
|
|
8
|
+
// named "a check icon"; `packages/ui/icons/forest/` has no tick, only bike variants, mark,
|
|
9
|
+
// mark-fill, parking, star, star-fill and traffic-light variants. Every consumer of `<IconTile>`
|
|
10
|
+
// falls back to the Forest mark on a miss (IconTile.vue's own `FALLBACK_ICON`), silently — the
|
|
11
|
+
// slug was never checked against anything real.
|
|
12
|
+
//
|
|
13
|
+
// task-8b (this file): the deck was Forest-only, but Jose's own direction is "icons should come
|
|
14
|
+
// from lucide or from our own icon library" — the design system HAS a tick, in Lucide, the
|
|
15
|
+
// `checklist` preset's own regression just never reached for it. `ICON_SLUGS` now spans BOTH
|
|
16
|
+
// sets, each entry carrying its own namespace prefix (`forest:bike`, `lucide:check`) — a bare,
|
|
17
|
+
// unprefixed name is never valid. That's not pedantry: both sets carry a `bike`, a `star` and a
|
|
18
|
+
// `parking` of their own, so a flat merged namespace would be a real collision the moment both
|
|
19
|
+
// are in play, not a hypothetical one. `FOREST_SLUGS` and `LUCIDE_SLUGS` are exported
|
|
20
|
+
// individually too — `FOREST_SLUGS` is what scripts/deckShowcase.ts's own exhaustive coverage
|
|
21
|
+
// check should track against (every FOREST icon appearing somewhere in the showcase is a
|
|
22
|
+
// meaningful, small, achievable guarantee; the same demand across all ~1,774 Lucide names would
|
|
23
|
+
// not be — nobody is meant to showcase the whole Lucide set, only draw from it).
|
|
24
|
+
//
|
|
25
|
+
// `scripts/icons.ts` already reads `packages/ui/icons/forest/*.svg` with `readdirSync()` and the
|
|
26
|
+
// installed `@iconify-json/lucide/icons.json`'s own key list, writing both into
|
|
27
|
+
// `packages/ui/src/icons.ts`'s `FOREST_ICON_NAMES`/`LUCIDE_ICON_NAMES` exports — re-deriving
|
|
28
|
+
// either list a second time here (a second `readdirSync`, a second `icons.json` read) would be
|
|
29
|
+
// exactly the anti-pattern backgrounds.js itself was written to close: two independent places
|
|
30
|
+
// deriving what should be one list, free to disagree the moment either one changes.
|
|
31
|
+
//
|
|
32
|
+
// Named re-exports, not a default import of the whole module: `forestIcons`' own SVG path data
|
|
33
|
+
// lives in the same source file but is never referenced past this line, so a real bundler's
|
|
34
|
+
// dead-code elimination drops it from anything that imports only these names —
|
|
35
|
+
// packages/slidev-theme/test/manifest.static.test.ts checks the resolution chain; IconTile.vue's
|
|
36
|
+
// own `import.meta.env.DEV` guard on its validator is what actually keeps the ~1,790-name array
|
|
37
|
+
// itself out of a deck's PRODUCTION bundle (see that file's doc comment for why a name array, cheap
|
|
38
|
+
// as it is next to Lucide's 543 KB of path data, still isn't worth paying for in every deck build
|
|
39
|
+
// just to back a check Vue never runs outside dev).
|
|
40
|
+
//
|
|
41
|
+
// Reached by relative path across the package boundary, not a `@humanforest/ui` package
|
|
42
|
+
// specifier — the same trick Kpi.vue already uses for kpiDelta.ts/kpiFormat.ts, and for the same
|
|
43
|
+
// reason: `@humanforest/ui`'s own entry point drags in Nuxt UI, reka-ui and mapbox-gl, none of
|
|
44
|
+
// which a slide needs. `packages/ui/src/icons.ts` has zero imports of its own — a dependency-free
|
|
45
|
+
// leaf, the same standard those two files are held to.
|
|
46
|
+
import { FOREST_ICON_NAMES, LUCIDE_ICON_NAMES } from '@humanforest/ui/icons';
|
|
47
|
+
|
|
48
|
+
/** Every Forest icon, namespaced — `bike-off` → `forest:bike-off`. */
|
|
49
|
+
export const FOREST_SLUGS = FOREST_ICON_NAMES.map((name) => `forest:${name}`);
|
|
50
|
+
|
|
51
|
+
/** Every Lucide icon, namespaced — `check` → `lucide:check`. */
|
|
52
|
+
export const LUCIDE_SLUGS = LUCIDE_ICON_NAMES.map((name) => `lucide:${name}`);
|
|
53
|
+
|
|
54
|
+
/** Every slug `<IconTile icon="…">` resolves — both sets, namespace preserved, never merged flat. */
|
|
55
|
+
export const ICON_SLUGS = [...FOREST_SLUGS, ...LUCIDE_SLUGS];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Resolving a namespaced icon slug to a URL a CSS mask can draw. Extracted from IconTile.vue when
|
|
3
|
+
Marquee needed the same thing — a second copy would have re-derived the scanner trap below by
|
|
4
|
+
hand, and that trap is invisible when you get it wrong.
|
|
5
|
+
|
|
6
|
+
★ THE ICON IS DRAWN AS A CSS MASK, NOT THROUGH UnoCSS'S `i-forest-*` UTILITY. That utility only
|
|
7
|
+
exists once UnoCSS's static scanner sees the literal class string in source — and an `icon` prop
|
|
8
|
+
means the class would have to be assembled at runtime (`i-forest-${icon}`), a string the scanner
|
|
9
|
+
never sees, so the rule for it is silently never generated. Masking the SVG straight from the
|
|
10
|
+
shared icon source sidesteps the scanner entirely.
|
|
11
|
+
|
|
12
|
+
★ THE GLOB PATHS ARE RELATIVE TO THIS DIRECTORY. This file has to stay in components/ beside its
|
|
13
|
+
callers: `import.meta.glob` is resolved against the importing MODULE's own path at build time, so
|
|
14
|
+
moving it one directory up silently resolves nothing and every icon falls back.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Eager + `?url`: this is sixteen-odd URL strings, not the SVG bodies, so resolving the whole set
|
|
18
|
+
// up front costs nothing and keeps the lookup below synchronous.
|
|
19
|
+
const FOREST_ICONS = import.meta.glob('../icons/forest/*.svg', { eager: true, query: '?url', import: 'default' });
|
|
20
|
+
const forestIconPath = (name) => `../icons/forest/${name}.svg`;
|
|
21
|
+
|
|
22
|
+
// The Lucide half of the SAME technique, but sourced differently: there is no per-icon file to
|
|
23
|
+
// glob — @iconify-json/lucide ships one 543 KB icons.json for its whole ~1,774-icon set.
|
|
24
|
+
// scripts/deckIcons.ts pre-extracts ONLY the Lucide names this repo's decks actually reference into
|
|
25
|
+
// packages/slidev-theme/icons/lucide/*.svg, so this glob only ever picks up icons in real use.
|
|
26
|
+
const LUCIDE_ICONS = import.meta.glob('../icons/lucide/*.svg', { eager: true, query: '?url', import: 'default' });
|
|
27
|
+
const lucideIconPath = (name) => `../icons/lucide/${name}.svg`;
|
|
28
|
+
|
|
29
|
+
/* A slug with no matching file masks the glyph out entirely — an invisible shape, no console error,
|
|
30
|
+
and deckAudit measures geometry only, so it passes. Falling back to a real, always-present icon
|
|
31
|
+
turns that into "visibly the wrong icon" instead of "gone". */
|
|
32
|
+
export const FALLBACK_ICON = 'mark-fill';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `icon` is always "<namespace>:<name>". The namespace is never optional: Forest's own set and
|
|
36
|
+
* Lucide's each have a `bike`, a `star` and a `parking`, so a bare name is a real collision.
|
|
37
|
+
* Anything unrecognised returns undefined and the caller applies FALLBACK_ICON.
|
|
38
|
+
*/
|
|
39
|
+
export const resolveIconUrl = (icon) => {
|
|
40
|
+
if (typeof icon !== 'string') return undefined;
|
|
41
|
+
const i = icon.indexOf(':');
|
|
42
|
+
if (i < 0) return undefined;
|
|
43
|
+
const namespace = icon.slice(0, i);
|
|
44
|
+
const name = icon.slice(i + 1);
|
|
45
|
+
if (namespace === 'forest') return FOREST_ICONS[forestIconPath(name)];
|
|
46
|
+
if (namespace === 'lucide') return LUCIDE_ICONS[lucideIconPath(name)];
|
|
47
|
+
return undefined;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** The same resolution with the fallback already applied — what a caller drawing a mask wants. */
|
|
51
|
+
export const iconUrlOrFallback = (icon) => resolveIconUrl(icon) ?? FOREST_ICONS[forestIconPath(FALLBACK_ICON)];
|