@loworbitstudio/visor-theme-engine 0.4.0 → 0.4.2
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/dist/adapters/index.d.ts +73 -8
- package/dist/adapters/index.js +719 -21
- package/dist/{chunk-NZF2MS4L.js → chunk-SXT2KY6D.js} +30 -6
- package/dist/index.d.ts +122 -6
- package/dist/index.js +266 -66
- package/dist/{types-DgAumoCX.d.ts → types-ljcTtODU.d.ts} +57 -0
- package/package.json +1 -1
- package/src/visor-theme.schema.json +68 -0
package/dist/adapters/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FULL_SHADE_STEPS,
|
|
3
|
+
MATERIAL_TEXT_SLOTS,
|
|
3
4
|
SELECTIVE_SHADE_STEPS,
|
|
4
5
|
buildVisorFontUrl,
|
|
5
6
|
generateDarkCss,
|
|
@@ -7,9 +8,10 @@ import {
|
|
|
7
8
|
generatePrimitivesCss,
|
|
8
9
|
generateShadeScale,
|
|
9
10
|
header,
|
|
11
|
+
parseColor,
|
|
10
12
|
resolveThemeFonts,
|
|
11
13
|
sectionComment
|
|
12
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-SXT2KY6D.js";
|
|
13
15
|
|
|
14
16
|
// src/adapters/layers.ts
|
|
15
17
|
var LAYER_ORDER = "@layer visor-primitives, visor-semantic, visor-adaptive, visor-bridge;";
|
|
@@ -128,7 +130,7 @@ var FUMADOCS_BRIDGE_MAP = {
|
|
|
128
130
|
},
|
|
129
131
|
"fd-secondary": { visorToken: "muted", category: "surface" },
|
|
130
132
|
"fd-secondary-foreground": { visorToken: "primary", category: "text" },
|
|
131
|
-
"fd-popover": { visorToken: "
|
|
133
|
+
"fd-popover": { visorToken: "popover", category: "surface" },
|
|
132
134
|
"fd-popover-foreground": { visorToken: "primary", category: "text" },
|
|
133
135
|
"fd-ring": { visorToken: "focus", category: "border" }
|
|
134
136
|
};
|
|
@@ -416,6 +418,7 @@ function docsAdapter(input, options) {
|
|
|
416
418
|
const slug = toKebabCase2(input.config.name);
|
|
417
419
|
const scopeClass = `.${slug}-theme`;
|
|
418
420
|
const includeFontImports = options?.includeFontImports ?? true;
|
|
421
|
+
const fontLines = [];
|
|
419
422
|
const lines = [];
|
|
420
423
|
if (includeFontImports && input.config.typography) {
|
|
421
424
|
const fontResult = resolveThemeFonts(input.config.typography);
|
|
@@ -424,8 +427,8 @@ function docsAdapter(input, options) {
|
|
|
424
427
|
for (const font of fontSlots) {
|
|
425
428
|
if (font && font.source === "google-fonts" && font.cssUrl && !seenUrls.has(font.cssUrl)) {
|
|
426
429
|
seenUrls.add(font.cssUrl);
|
|
427
|
-
|
|
428
|
-
|
|
430
|
+
fontLines.push(`@import url("${font.cssUrl}");`);
|
|
431
|
+
fontLines.push("");
|
|
429
432
|
}
|
|
430
433
|
}
|
|
431
434
|
const scale = input.config.typography?.scale ?? 1;
|
|
@@ -435,17 +438,17 @@ function docsAdapter(input, options) {
|
|
|
435
438
|
seenFamilies.add(font.family);
|
|
436
439
|
for (const weight of font.weights) {
|
|
437
440
|
const url = buildVisorFontUrl(font.org ?? "", font.family, weight);
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
441
|
+
fontLines.push("@font-face {");
|
|
442
|
+
fontLines.push(` font-family: "${font.family}";`);
|
|
443
|
+
fontLines.push(` src: url("${url}") format("woff2");`);
|
|
444
|
+
fontLines.push(` font-weight: ${weight};`);
|
|
445
|
+
fontLines.push(` font-style: ${font.italic ? "italic" : "normal"};`);
|
|
446
|
+
fontLines.push(` font-display: ${font.display};`);
|
|
444
447
|
if (scale !== 1) {
|
|
445
|
-
|
|
448
|
+
fontLines.push(` size-adjust: ${Math.round(scale * 100)}%;`);
|
|
446
449
|
}
|
|
447
|
-
|
|
448
|
-
|
|
450
|
+
fontLines.push("}");
|
|
451
|
+
fontLines.push("");
|
|
449
452
|
}
|
|
450
453
|
}
|
|
451
454
|
}
|
|
@@ -487,16 +490,20 @@ function docsAdapter(input, options) {
|
|
|
487
490
|
const darkDecls = generateSemanticDecls2(input.tokens, "dark");
|
|
488
491
|
const colorsDark = input.config["colors-dark"];
|
|
489
492
|
const darkPrimitiveOverrides = [];
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
493
|
+
for (const role of FULL_SCALE_ROLES2) {
|
|
494
|
+
if (colorsDark?.[role]) {
|
|
495
|
+
const scale = generateShadeScale(colorsDark[role], role);
|
|
496
|
+
for (const step of FULL_SHADE_STEPS) {
|
|
497
|
+
darkPrimitiveOverrides.push(`--color-${role}-${step}: ${scale[step]};`);
|
|
498
|
+
}
|
|
494
499
|
}
|
|
495
500
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
501
|
+
for (const role of SELECTIVE_SCALE_ROLES2) {
|
|
502
|
+
if (colorsDark?.[role]) {
|
|
503
|
+
const scale = generateShadeScale(colorsDark[role], role);
|
|
504
|
+
for (const step of SELECTIVE_SHADE_STEPS) {
|
|
505
|
+
darkPrimitiveOverrides.push(`--color-${role}-${step}: ${scale[step]};`);
|
|
506
|
+
}
|
|
500
507
|
}
|
|
501
508
|
}
|
|
502
509
|
if (darkPrimitiveOverrides.length > 0) {
|
|
@@ -556,14 +563,705 @@ ${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
|
556
563
|
lines.push(sectionComment2("Fumadocs bridge: light"));
|
|
557
564
|
lines.push(block(`html:not(.dark) ${scopeClass}`, generateFumadocsBridgeDecls(input.tokens, "light")));
|
|
558
565
|
lines.push("");
|
|
566
|
+
const layered = wrapInLayer("visor-adaptive", lines.join("\n").trim());
|
|
567
|
+
const head = fontLines.length > 0 ? fontLines.join("\n") + "\n" : "";
|
|
568
|
+
return head + LAYER_ORDER + "\n\n" + layered + "\n";
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// src/flutter/color-to-dart.ts
|
|
572
|
+
function alphaToByte(alphaPct) {
|
|
573
|
+
const clamped = Math.max(0, Math.min(1, alphaPct));
|
|
574
|
+
return Math.round(clamped * 255);
|
|
575
|
+
}
|
|
576
|
+
function byteHex(n) {
|
|
577
|
+
const clamped = Math.max(0, Math.min(255, Math.round(n)));
|
|
578
|
+
return clamped.toString(16).padStart(2, "0").toUpperCase();
|
|
579
|
+
}
|
|
580
|
+
function cssColorToDart(css, alphaOverride) {
|
|
581
|
+
if (css.trim().toLowerCase() === "transparent") {
|
|
582
|
+
const alpha2 = alphaOverride !== void 0 ? alphaOverride : 0;
|
|
583
|
+
const aByte2 = alphaToByte(alpha2);
|
|
584
|
+
return `Color(0x${byteHex(aByte2)}000000)`;
|
|
585
|
+
}
|
|
586
|
+
const parsed = parseColor(css);
|
|
587
|
+
if (!parsed) {
|
|
588
|
+
throw new Error(`Invalid CSS color: ${css}`);
|
|
589
|
+
}
|
|
590
|
+
const [r, g, b] = parsed.rgb;
|
|
591
|
+
const alpha = alphaOverride !== void 0 ? alphaOverride : parsed.alpha ?? 1;
|
|
592
|
+
const aByte = alphaToByte(alpha);
|
|
593
|
+
return `Color(0x${byteHex(aByte)}${byteHex(r)}${byteHex(g)}${byteHex(b)})`;
|
|
594
|
+
}
|
|
595
|
+
function cssColorToOpaqueDart(css) {
|
|
596
|
+
return cssColorToDart(css, 1);
|
|
597
|
+
}
|
|
598
|
+
function opacityVariants(css, percents = [5, 10, 20, 40, 50, 60, 80]) {
|
|
599
|
+
const out = {};
|
|
600
|
+
for (const p of percents) {
|
|
601
|
+
out[`${p}o`] = cssColorToDart(css, p / 100);
|
|
602
|
+
}
|
|
603
|
+
return out;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// src/flutter/emit-colors.ts
|
|
607
|
+
var FULL_SCALE_ROLES3 = ["primary", "accent", "neutral"];
|
|
608
|
+
var SELECTIVE_SCALE_ROLES3 = [
|
|
609
|
+
"success",
|
|
610
|
+
"warning",
|
|
611
|
+
"error",
|
|
612
|
+
"info"
|
|
613
|
+
];
|
|
614
|
+
var DART_HEADER = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
615
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
616
|
+
// Source: .visor.yaml \u2192 Visor theme engine \u2192 flutter adapter.
|
|
617
|
+
|
|
618
|
+
import 'dart:ui';
|
|
619
|
+
|
|
620
|
+
import 'package:visor_core/visor_core.dart';
|
|
621
|
+
`;
|
|
622
|
+
function emitColorsDart(input) {
|
|
623
|
+
const { primitives, tokens } = input;
|
|
624
|
+
const lines = [];
|
|
625
|
+
lines.push(DART_HEADER);
|
|
626
|
+
lines.push(`/// Generated color tokens for the ${input.config.name} theme.`);
|
|
627
|
+
lines.push("///");
|
|
628
|
+
lines.push("/// Do not edit this file manually \u2014 regenerate from .visor.yaml.");
|
|
629
|
+
lines.push("sealed class VisorColors {");
|
|
630
|
+
lines.push(" // ========================================================================");
|
|
631
|
+
lines.push(" // Anchors");
|
|
632
|
+
lines.push(" // ========================================================================");
|
|
633
|
+
lines.push(" static const Color white = Color(0xFFFFFFFF);");
|
|
634
|
+
lines.push(" static const Color black = Color(0xFF000000);");
|
|
635
|
+
lines.push("");
|
|
636
|
+
for (const role of [...FULL_SCALE_ROLES3, ...SELECTIVE_SCALE_ROLES3]) {
|
|
637
|
+
lines.push(
|
|
638
|
+
` // ========================================================================`
|
|
639
|
+
);
|
|
640
|
+
lines.push(` // ${capitalize(role)} scale`);
|
|
641
|
+
lines.push(
|
|
642
|
+
` // ========================================================================`
|
|
643
|
+
);
|
|
644
|
+
const steps = FULL_SCALE_ROLES3.includes(role) ? FULL_SHADE_STEPS : SELECTIVE_SHADE_STEPS;
|
|
645
|
+
const scale = primitives[role];
|
|
646
|
+
for (const step of steps) {
|
|
647
|
+
const value = scale[step];
|
|
648
|
+
lines.push(
|
|
649
|
+
` static const Color ${role}${step} = ${cssColorToOpaqueDart(value)};`
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
lines.push("");
|
|
653
|
+
}
|
|
654
|
+
lines.push(" // ========================================================================");
|
|
655
|
+
lines.push(" // Opacity variants (pre-computed at codegen)");
|
|
656
|
+
lines.push(" // ========================================================================");
|
|
657
|
+
const opacitySources = [
|
|
658
|
+
{ name: "primary500", css: primitives.primary[500] },
|
|
659
|
+
{ name: "primary600", css: primitives.primary[600] },
|
|
660
|
+
{ name: "accent500", css: primitives.accent[500] },
|
|
661
|
+
{ name: "white", css: "#FFFFFF" },
|
|
662
|
+
{ name: "black", css: "#000000" }
|
|
663
|
+
];
|
|
664
|
+
for (const source of opacitySources) {
|
|
665
|
+
const variants = opacityVariants(source.css);
|
|
666
|
+
for (const [suffix, dartColor] of Object.entries(variants)) {
|
|
667
|
+
lines.push(` static const Color ${source.name}_${suffix} = ${dartColor};`);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
lines.push("");
|
|
671
|
+
lines.push(" // ========================================================================");
|
|
672
|
+
lines.push(" // Semantic \u2014 Light");
|
|
673
|
+
lines.push(" // ========================================================================");
|
|
674
|
+
lines.push(` static final VisorColorsData light = ${semanticInstance(tokens, "light")};`);
|
|
675
|
+
lines.push("");
|
|
676
|
+
lines.push(" // ========================================================================");
|
|
677
|
+
lines.push(" // Semantic \u2014 Dark");
|
|
678
|
+
lines.push(" // ========================================================================");
|
|
679
|
+
lines.push(` static final VisorColorsData dark = ${semanticInstance(tokens, "dark")};`);
|
|
680
|
+
lines.push("}");
|
|
681
|
+
return lines.join("\n") + "\n";
|
|
682
|
+
}
|
|
683
|
+
function semanticInstance(tokens, mode) {
|
|
684
|
+
const parts = ["VisorColorsData("];
|
|
685
|
+
const emit = (field, category, tokenName) => {
|
|
686
|
+
const token = tokens[category][tokenName];
|
|
687
|
+
if (!token) {
|
|
688
|
+
throw new Error(
|
|
689
|
+
`Missing semantic token: ${String(category)}.${tokenName}`
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
parts.push(` ${field}: ${cssColorToDart(token[mode])},`);
|
|
693
|
+
};
|
|
694
|
+
emit("textPrimary", "text", "primary");
|
|
695
|
+
emit("textSecondary", "text", "secondary");
|
|
696
|
+
emit("textTertiary", "text", "tertiary");
|
|
697
|
+
emit("textDisabled", "text", "disabled");
|
|
698
|
+
emit("textInverse", "text", "inverse");
|
|
699
|
+
emit("textInverseSecondary", "text", "inverse-secondary");
|
|
700
|
+
emit("textLink", "text", "link");
|
|
701
|
+
emit("textLinkHover", "text", "link-hover");
|
|
702
|
+
emit("textSuccess", "text", "success");
|
|
703
|
+
emit("textWarning", "text", "warning");
|
|
704
|
+
emit("textError", "text", "error");
|
|
705
|
+
emit("textInfo", "text", "info");
|
|
706
|
+
emit("surfacePage", "surface", "page");
|
|
707
|
+
emit("surfaceCard", "surface", "card");
|
|
708
|
+
emit("surfaceSubtle", "surface", "subtle");
|
|
709
|
+
emit("surfaceMuted", "surface", "muted");
|
|
710
|
+
emit("surfaceOverlay", "surface", "overlay");
|
|
711
|
+
emit("surfaceInteractiveDefault", "surface", "interactive-default");
|
|
712
|
+
emit("surfaceInteractiveHover", "surface", "interactive-hover");
|
|
713
|
+
emit("surfaceInteractiveActive", "surface", "interactive-active");
|
|
714
|
+
emit("surfaceInteractiveDisabled", "surface", "interactive-disabled");
|
|
715
|
+
emit("surfaceSelected", "surface", "selected");
|
|
716
|
+
emit("surfaceAccentSubtle", "surface", "accent-subtle");
|
|
717
|
+
emit("surfaceAccentDefault", "surface", "accent-default");
|
|
718
|
+
emit("surfaceAccentStrong", "surface", "accent-strong");
|
|
719
|
+
emit("surfaceSuccessSubtle", "surface", "success-subtle");
|
|
720
|
+
emit("surfaceSuccessDefault", "surface", "success-default");
|
|
721
|
+
emit("surfaceWarningSubtle", "surface", "warning-subtle");
|
|
722
|
+
emit("surfaceWarningDefault", "surface", "warning-default");
|
|
723
|
+
emit("surfaceErrorSubtle", "surface", "error-subtle");
|
|
724
|
+
emit("surfaceErrorDefault", "surface", "error-default");
|
|
725
|
+
emit("surfaceInfoSubtle", "surface", "info-subtle");
|
|
726
|
+
emit("surfaceInfoDefault", "surface", "info-default");
|
|
727
|
+
emit("borderDefault", "border", "default");
|
|
728
|
+
emit("borderMuted", "border", "muted");
|
|
729
|
+
emit("borderStrong", "border", "strong");
|
|
730
|
+
emit("borderFocus", "border", "focus");
|
|
731
|
+
emit("borderDisabled", "border", "disabled");
|
|
732
|
+
emit("borderSuccess", "border", "success");
|
|
733
|
+
emit("borderWarning", "border", "warning");
|
|
734
|
+
emit("borderError", "border", "error");
|
|
735
|
+
emit("borderInfo", "border", "info");
|
|
736
|
+
emit("interactivePrimaryBg", "interactive", "primary-bg");
|
|
737
|
+
emit("interactivePrimaryBgHover", "interactive", "primary-bg-hover");
|
|
738
|
+
emit("interactivePrimaryBgActive", "interactive", "primary-bg-active");
|
|
739
|
+
emit("interactivePrimaryText", "interactive", "primary-text");
|
|
740
|
+
emit("interactiveSecondaryBg", "interactive", "secondary-bg");
|
|
741
|
+
emit("interactiveSecondaryBgHover", "interactive", "secondary-bg-hover");
|
|
742
|
+
emit("interactiveSecondaryBgActive", "interactive", "secondary-bg-active");
|
|
743
|
+
emit("interactiveSecondaryText", "interactive", "secondary-text");
|
|
744
|
+
emit("interactiveSecondaryBorder", "interactive", "secondary-border");
|
|
745
|
+
emit("interactiveDestructiveBg", "interactive", "destructive-bg");
|
|
746
|
+
emit("interactiveDestructiveBgHover", "interactive", "destructive-bg-hover");
|
|
747
|
+
emit("interactiveDestructiveText", "interactive", "destructive-text");
|
|
748
|
+
emit("interactiveGhostBg", "interactive", "ghost-bg");
|
|
749
|
+
emit("interactiveGhostBgHover", "interactive", "ghost-bg-hover");
|
|
750
|
+
parts.push(" )");
|
|
751
|
+
void cssColorToDart;
|
|
752
|
+
return parts.join("\n");
|
|
753
|
+
}
|
|
754
|
+
function capitalize(s) {
|
|
755
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// src/flutter/emit-typography.ts
|
|
759
|
+
var HEADER_COMMENT = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
760
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
761
|
+
`;
|
|
762
|
+
var MATERIAL_3_DEFAULTS = {
|
|
763
|
+
displayLarge: { size: 57, weight: 400, letterSpacing: -0.25 },
|
|
764
|
+
displayMedium: { size: 45, weight: 400 },
|
|
765
|
+
displaySmall: { size: 36, weight: 400 },
|
|
766
|
+
headlineLarge: { size: 32, weight: 400 },
|
|
767
|
+
headlineMedium: { size: 28, weight: 400 },
|
|
768
|
+
headlineSmall: { size: 24, weight: 400 },
|
|
769
|
+
titleLarge: { size: 22, weight: 400 },
|
|
770
|
+
titleMedium: { size: 16, weight: 500, letterSpacing: 0.15 },
|
|
771
|
+
titleSmall: { size: 14, weight: 500, letterSpacing: 0.1 },
|
|
772
|
+
bodyLarge: { size: 16, weight: 400, letterSpacing: 0.5 },
|
|
773
|
+
bodyMedium: { size: 14, weight: 400, letterSpacing: 0.25 },
|
|
774
|
+
bodySmall: { size: 12, weight: 400, letterSpacing: 0.4 },
|
|
775
|
+
labelLarge: { size: 14, weight: 500, letterSpacing: 0.1 },
|
|
776
|
+
labelMedium: { size: 12, weight: 500, letterSpacing: 0.5 },
|
|
777
|
+
labelSmall: { size: 11, weight: 500, letterSpacing: 0.5 },
|
|
778
|
+
labelXSmall: { size: 10, weight: 500, letterSpacing: 0.5 }
|
|
779
|
+
};
|
|
780
|
+
function emitTypographyDart(input) {
|
|
781
|
+
const slots = input.config.typography.slots;
|
|
782
|
+
const overriddenSlots = MATERIAL_TEXT_SLOTS.filter((name) => slots[name]);
|
|
783
|
+
const hasOverrides = overriddenSlots.length > 0;
|
|
784
|
+
const lines = [];
|
|
785
|
+
lines.push(HEADER_COMMENT);
|
|
786
|
+
if (hasOverrides) {
|
|
787
|
+
lines.push("import 'package:flutter/material.dart';");
|
|
788
|
+
}
|
|
789
|
+
lines.push("import 'package:visor_core/visor_core.dart';");
|
|
790
|
+
lines.push("");
|
|
791
|
+
lines.push(
|
|
792
|
+
"/// Generated typography tokens \u2014 Material 3 type-scale + `labelXSmall`."
|
|
793
|
+
);
|
|
794
|
+
lines.push("///");
|
|
795
|
+
lines.push(
|
|
796
|
+
"/// Font family is not baked in here; `VisorTheme.build()` applies it"
|
|
797
|
+
);
|
|
798
|
+
lines.push(
|
|
799
|
+
"/// globally via `TextTheme.apply(fontFamily: ...)`. Override per-slot"
|
|
800
|
+
);
|
|
801
|
+
lines.push("/// values in `.visor.yaml` under `typography.slots`.");
|
|
802
|
+
lines.push("sealed class VisorTextStyles {");
|
|
803
|
+
if (!hasOverrides) {
|
|
804
|
+
lines.push(" static final VisorTextStylesData instance =");
|
|
805
|
+
lines.push(" VisorTextStylesData.defaults;");
|
|
806
|
+
} else {
|
|
807
|
+
lines.push(" static final VisorTextStylesData instance =");
|
|
808
|
+
lines.push(
|
|
809
|
+
" VisorTextStylesData.defaults.copyWith("
|
|
810
|
+
);
|
|
811
|
+
for (const name of overriddenSlots) {
|
|
812
|
+
const override = slots[name];
|
|
813
|
+
lines.push(...emitSlot(name, override).map((l) => ` ${l}`));
|
|
814
|
+
}
|
|
815
|
+
lines.push(" );");
|
|
816
|
+
}
|
|
817
|
+
lines.push("}");
|
|
818
|
+
return lines.join("\n") + "\n";
|
|
819
|
+
}
|
|
820
|
+
function emitSlot(name, override) {
|
|
821
|
+
const d = MATERIAL_3_DEFAULTS[name];
|
|
822
|
+
const size = override.size ?? d.size;
|
|
823
|
+
const weight = override.weight ?? d.weight;
|
|
824
|
+
const letterSpacing = override["letter-spacing"] !== void 0 ? override["letter-spacing"] : d.letterSpacing;
|
|
825
|
+
const styleLines = [
|
|
826
|
+
`${name}: const TextStyle(`,
|
|
827
|
+
` fontSize: ${size},`,
|
|
828
|
+
` fontWeight: FontWeight.w${weight},`
|
|
829
|
+
];
|
|
830
|
+
if (letterSpacing !== void 0) {
|
|
831
|
+
styleLines.push(` letterSpacing: ${letterSpacing},`);
|
|
832
|
+
}
|
|
833
|
+
styleLines.push(`),`);
|
|
834
|
+
return styleLines;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/flutter/emit-spacing.ts
|
|
838
|
+
var DART_HEADER2 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
839
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
840
|
+
|
|
841
|
+
import 'package:visor_core/visor_core.dart';
|
|
842
|
+
`;
|
|
843
|
+
function emitSpacingDart(input) {
|
|
844
|
+
const base = input.config.spacing.base;
|
|
845
|
+
const lines = [];
|
|
846
|
+
lines.push(DART_HEADER2);
|
|
847
|
+
lines.push("/// Generated spacing tokens.");
|
|
848
|
+
lines.push("///");
|
|
849
|
+
lines.push(`/// Base unit: ${base}px. Scale derived by multiplication:`);
|
|
850
|
+
lines.push("/// xs=1\xD7, sm=2\xD7, md=3\xD7, lg=4\xD7, xl=6\xD7, xxl=8\xD7, xxxl=12\xD7.");
|
|
851
|
+
lines.push("sealed class VisorSpacing {");
|
|
852
|
+
lines.push(" static final VisorSpacingData instance = VisorSpacingData(");
|
|
853
|
+
lines.push(` xs: ${fmt(base * 1)},`);
|
|
854
|
+
lines.push(` sm: ${fmt(base * 2)},`);
|
|
855
|
+
lines.push(` md: ${fmt(base * 3)},`);
|
|
856
|
+
lines.push(` lg: ${fmt(base * 4)},`);
|
|
857
|
+
lines.push(` xl: ${fmt(base * 6)},`);
|
|
858
|
+
lines.push(` xxl: ${fmt(base * 8)},`);
|
|
859
|
+
lines.push(` xxxl: ${fmt(base * 12)},`);
|
|
860
|
+
lines.push(" );");
|
|
861
|
+
lines.push("}");
|
|
862
|
+
return lines.join("\n") + "\n";
|
|
863
|
+
}
|
|
864
|
+
function fmt(n) {
|
|
865
|
+
return Number.isInteger(n) ? `${n}` : `${n}`;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// src/flutter/emit-radius.ts
|
|
869
|
+
var DART_HEADER3 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
870
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
871
|
+
|
|
872
|
+
import 'package:visor_core/visor_core.dart';
|
|
873
|
+
`;
|
|
874
|
+
function emitRadiusDart(input) {
|
|
875
|
+
const r = input.config.radius;
|
|
876
|
+
const lines = [];
|
|
877
|
+
lines.push(DART_HEADER3);
|
|
878
|
+
lines.push("/// Generated border-radius tokens (raw pixel values).");
|
|
879
|
+
lines.push("sealed class VisorRadius {");
|
|
880
|
+
lines.push(" static final VisorRadiusData instance = VisorRadiusData(");
|
|
881
|
+
lines.push(` sm: ${r.sm},`);
|
|
882
|
+
lines.push(` md: ${r.md},`);
|
|
883
|
+
lines.push(` lg: ${r.lg},`);
|
|
884
|
+
lines.push(` xl: ${r.xl},`);
|
|
885
|
+
lines.push(` pill: ${r.pill},`);
|
|
886
|
+
lines.push(" );");
|
|
887
|
+
lines.push("}");
|
|
888
|
+
return lines.join("\n") + "\n";
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// src/flutter/emit-shadows.ts
|
|
892
|
+
var DART_HEADER4 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
893
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
894
|
+
|
|
895
|
+
import 'package:flutter/material.dart';
|
|
896
|
+
import 'package:visor_core/visor_core.dart';
|
|
897
|
+
`;
|
|
898
|
+
var SHADOW_KEYS = ["xs", "sm", "md", "lg", "xl"];
|
|
899
|
+
function emitShadowsDart(input) {
|
|
900
|
+
const s = input.config.shadows;
|
|
901
|
+
const lines = [];
|
|
902
|
+
lines.push(DART_HEADER4);
|
|
903
|
+
lines.push("/// Generated elevation/shadow tokens.");
|
|
904
|
+
lines.push("///");
|
|
905
|
+
lines.push("/// Each value is a `List<BoxShadow>` \u2014 CSS box-shadow strings");
|
|
906
|
+
lines.push("/// supporting multi-layer shadows compile to the same list here.");
|
|
907
|
+
lines.push("sealed class VisorShadows {");
|
|
908
|
+
lines.push(" static final VisorShadowsData instance = VisorShadowsData(");
|
|
909
|
+
for (const key of SHADOW_KEYS) {
|
|
910
|
+
const dart = parseShadowListToDart(s[key]);
|
|
911
|
+
lines.push(` ${key}: ${dart},`);
|
|
912
|
+
}
|
|
913
|
+
lines.push(" );");
|
|
914
|
+
lines.push("}");
|
|
915
|
+
return lines.join("\n") + "\n";
|
|
916
|
+
}
|
|
917
|
+
function parseShadowListToDart(css) {
|
|
918
|
+
if (css.trim().toLowerCase() === "none") return "const <BoxShadow>[]";
|
|
919
|
+
const shadows = splitTopLevelCommas(css);
|
|
920
|
+
if (shadows.length === 0) return "const <BoxShadow>[]";
|
|
921
|
+
const parts = shadows.map(parseSingleShadow);
|
|
922
|
+
return `const <BoxShadow>[
|
|
923
|
+
${parts.map((p) => " " + p).join(",\n")},
|
|
924
|
+
]`;
|
|
925
|
+
}
|
|
926
|
+
function parseSingleShadow(raw) {
|
|
927
|
+
const css = raw.trim();
|
|
928
|
+
if (/\binset\b/i.test(css)) {
|
|
929
|
+
throw new Error(
|
|
930
|
+
`box-shadow 'inset' is not representable on Flutter BoxShadow: "${raw}"`
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
const colorRe = /(#[0-9a-f]{3,8}|rgba?\([^)]*\)|hsla?\([^)]*\)|oklch\([^)]*\)|oklab\([^)]*\))\s*$/i;
|
|
934
|
+
const colorMatch = css.match(colorRe);
|
|
935
|
+
if (!colorMatch || colorMatch.index === void 0) {
|
|
936
|
+
throw new Error(`Invalid box-shadow: missing trailing color in "${raw}"`);
|
|
937
|
+
}
|
|
938
|
+
const color = colorMatch[1];
|
|
939
|
+
const lengthsPart = css.slice(0, colorMatch.index).trim();
|
|
940
|
+
const lengths = lengthsPart.split(/\s+/).filter(Boolean);
|
|
941
|
+
if (lengths.length < 2) {
|
|
942
|
+
throw new Error(
|
|
943
|
+
`Invalid box-shadow: need at least x and y offsets in "${raw}"`
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
if (lengths.length > 4) {
|
|
947
|
+
throw new Error(
|
|
948
|
+
`Invalid box-shadow: too many length values in "${raw}" (max 4: x y blur spread)`
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
const [x, y, blur = "0", spread = "0"] = lengths;
|
|
952
|
+
const offsetX = parseLength(x, raw);
|
|
953
|
+
const offsetY = parseLength(y, raw);
|
|
954
|
+
const blurRadius = parseLength(blur, raw);
|
|
955
|
+
const spreadRadius = parseLength(spread, raw);
|
|
956
|
+
const colorDart = cssColorToDart(color);
|
|
957
|
+
const parts = [
|
|
958
|
+
`offset: Offset(${offsetX}, ${offsetY})`,
|
|
959
|
+
`blurRadius: ${blurRadius}`
|
|
960
|
+
];
|
|
961
|
+
if (spreadRadius !== 0) {
|
|
962
|
+
parts.push(`spreadRadius: ${spreadRadius}`);
|
|
963
|
+
}
|
|
964
|
+
parts.push(`color: ${colorDart}`);
|
|
965
|
+
return `BoxShadow(${parts.join(", ")})`;
|
|
966
|
+
}
|
|
967
|
+
function parseLength(token, raw) {
|
|
968
|
+
const cleaned = token.trim().replace(/px$/i, "");
|
|
969
|
+
const n = Number(cleaned);
|
|
970
|
+
if (!Number.isFinite(n)) {
|
|
971
|
+
throw new Error(`Invalid shadow length "${token}" in "${raw}"`);
|
|
972
|
+
}
|
|
973
|
+
return n;
|
|
974
|
+
}
|
|
975
|
+
function splitTopLevelCommas(input) {
|
|
976
|
+
const parts = [];
|
|
977
|
+
let depth = 0;
|
|
978
|
+
let buf = "";
|
|
979
|
+
for (const c of input) {
|
|
980
|
+
if (c === "(") depth++;
|
|
981
|
+
else if (c === ")") depth--;
|
|
982
|
+
if (c === "," && depth === 0) {
|
|
983
|
+
if (buf.trim()) parts.push(buf.trim());
|
|
984
|
+
buf = "";
|
|
985
|
+
} else {
|
|
986
|
+
buf += c;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (buf.trim()) parts.push(buf.trim());
|
|
990
|
+
return parts;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
// src/flutter/emit-strokes.ts
|
|
994
|
+
var DART_HEADER5 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
995
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
996
|
+
|
|
997
|
+
import 'package:visor_core/visor_core.dart';
|
|
998
|
+
`;
|
|
999
|
+
function emitStrokesDart(input) {
|
|
1000
|
+
const s = input.config.strokeWidths;
|
|
1001
|
+
const lines = [];
|
|
1002
|
+
lines.push(DART_HEADER5);
|
|
1003
|
+
lines.push("/// Generated stroke-width tokens (raw pixel values).");
|
|
1004
|
+
lines.push("sealed class VisorStrokeWidths {");
|
|
1005
|
+
lines.push(" static final VisorStrokeWidthsData instance = VisorStrokeWidthsData(");
|
|
1006
|
+
lines.push(` thin: ${s.thin},`);
|
|
1007
|
+
lines.push(` regular: ${s.regular},`);
|
|
1008
|
+
lines.push(` medium: ${s.medium},`);
|
|
1009
|
+
lines.push(` thick: ${s.thick},`);
|
|
1010
|
+
lines.push(" );");
|
|
1011
|
+
lines.push("}");
|
|
1012
|
+
return lines.join("\n") + "\n";
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// src/flutter/emit-opacity.ts
|
|
1016
|
+
var DART_HEADER6 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
1017
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
1018
|
+
|
|
1019
|
+
import 'package:visor_core/visor_core.dart';
|
|
1020
|
+
`;
|
|
1021
|
+
function emitOpacityDart() {
|
|
1022
|
+
const lines = [];
|
|
1023
|
+
lines.push(DART_HEADER6);
|
|
1024
|
+
lines.push("/// Generated opacity tokens (raw alpha values in [0, 1]).");
|
|
1025
|
+
lines.push("///");
|
|
1026
|
+
lines.push("/// Fixed across themes \u2014 opacity is a math primitive, not a brand decision.");
|
|
1027
|
+
lines.push("sealed class VisorOpacity {");
|
|
1028
|
+
lines.push(" static final VisorOpacityData instance = VisorOpacityData(");
|
|
1029
|
+
lines.push(" alpha5: 0.05,");
|
|
1030
|
+
lines.push(" alpha10: 0.1,");
|
|
1031
|
+
lines.push(" alpha12: 0.12,");
|
|
1032
|
+
lines.push(" alpha20: 0.2,");
|
|
1033
|
+
lines.push(" alpha40: 0.4,");
|
|
1034
|
+
lines.push(" alpha50: 0.5,");
|
|
1035
|
+
lines.push(" alpha60: 0.6,");
|
|
1036
|
+
lines.push(" alpha80: 0.8,");
|
|
1037
|
+
lines.push(" );");
|
|
1038
|
+
lines.push("}");
|
|
559
1039
|
return lines.join("\n") + "\n";
|
|
560
1040
|
}
|
|
1041
|
+
|
|
1042
|
+
// src/flutter/emit-motion.ts
|
|
1043
|
+
var DART_HEADER7 = `// GENERATED BY visor \u2014 DO NOT EDIT.
|
|
1044
|
+
// Regenerate with \`visor theme apply --adapter flutter\`.
|
|
1045
|
+
|
|
1046
|
+
import 'package:flutter/material.dart';
|
|
1047
|
+
import 'package:visor_core/visor_core.dart';
|
|
1048
|
+
`;
|
|
1049
|
+
function emitMotionDart(input) {
|
|
1050
|
+
const m = input.config.motion;
|
|
1051
|
+
const fast = parseDurationToDart(m["duration-fast"]);
|
|
1052
|
+
const normal = parseDurationToDart(m["duration-normal"]);
|
|
1053
|
+
const slow = parseDurationToDart(m["duration-slow"]);
|
|
1054
|
+
const easing = parseEasingToDart(m.easing);
|
|
1055
|
+
const lines = [];
|
|
1056
|
+
lines.push(DART_HEADER7);
|
|
1057
|
+
lines.push("/// Generated motion tokens \u2014 durations + default easing curve.");
|
|
1058
|
+
lines.push("sealed class VisorMotion {");
|
|
1059
|
+
lines.push(" static final VisorMotionData instance = VisorMotionData(");
|
|
1060
|
+
lines.push(` durationFast: ${fast},`);
|
|
1061
|
+
lines.push(` durationNormal: ${normal},`);
|
|
1062
|
+
lines.push(` durationSlow: ${slow},`);
|
|
1063
|
+
lines.push(` easing: ${easing},`);
|
|
1064
|
+
lines.push(" );");
|
|
1065
|
+
lines.push("}");
|
|
1066
|
+
return lines.join("\n") + "\n";
|
|
1067
|
+
}
|
|
1068
|
+
function parseDurationToDart(css) {
|
|
1069
|
+
const trimmed = css.trim().toLowerCase();
|
|
1070
|
+
let ms;
|
|
1071
|
+
if (trimmed.endsWith("ms")) {
|
|
1072
|
+
ms = Number(trimmed.slice(0, -2));
|
|
1073
|
+
} else if (trimmed.endsWith("s")) {
|
|
1074
|
+
ms = Number(trimmed.slice(0, -1)) * 1e3;
|
|
1075
|
+
} else {
|
|
1076
|
+
throw new Error(`Invalid duration "${css}": expected "<N>ms" or "<N>s"`);
|
|
1077
|
+
}
|
|
1078
|
+
if (!Number.isFinite(ms) || ms < 0) {
|
|
1079
|
+
throw new Error(`Invalid duration "${css}": must be a non-negative number`);
|
|
1080
|
+
}
|
|
1081
|
+
return `Duration(milliseconds: ${Math.round(ms)})`;
|
|
1082
|
+
}
|
|
1083
|
+
var KEYWORD_TO_CURVE = {
|
|
1084
|
+
linear: "Curves.linear",
|
|
1085
|
+
ease: "Curves.ease",
|
|
1086
|
+
"ease-in": "Curves.easeIn",
|
|
1087
|
+
"ease-out": "Curves.easeOut",
|
|
1088
|
+
"ease-in-out": "Curves.easeInOut"
|
|
1089
|
+
};
|
|
1090
|
+
function parseEasingToDart(css) {
|
|
1091
|
+
const trimmed = css.trim().toLowerCase();
|
|
1092
|
+
if (trimmed in KEYWORD_TO_CURVE) {
|
|
1093
|
+
return KEYWORD_TO_CURVE[trimmed];
|
|
1094
|
+
}
|
|
1095
|
+
const cbMatch = trimmed.match(
|
|
1096
|
+
/^cubic-bezier\(\s*(-?\d*\.?\d+)\s*,\s*(-?\d*\.?\d+)\s*,\s*(-?\d*\.?\d+)\s*,\s*(-?\d*\.?\d+)\s*\)$/
|
|
1097
|
+
);
|
|
1098
|
+
if (cbMatch) {
|
|
1099
|
+
const [, a, b, c, d] = cbMatch;
|
|
1100
|
+
return `Cubic(${a}, ${b}, ${c}, ${d})`;
|
|
1101
|
+
}
|
|
1102
|
+
console.warn(
|
|
1103
|
+
`visor: unsupported easing "${css}" \u2014 falling back to Curves.easeInOut.`
|
|
1104
|
+
);
|
|
1105
|
+
return "Curves.easeInOut";
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
// src/flutter/emit-theme.ts
|
|
1109
|
+
function emitThemeDart(options) {
|
|
1110
|
+
const { themeClassName, emitLight, emitDark, tokenImports } = options;
|
|
1111
|
+
const lines = [
|
|
1112
|
+
`// GENERATED BY visor \u2014 DO NOT EDIT.`,
|
|
1113
|
+
`// Regenerate with \`visor theme apply --adapter flutter\`.`,
|
|
1114
|
+
``,
|
|
1115
|
+
`import 'package:flutter/material.dart';`,
|
|
1116
|
+
`import 'package:visor_core/visor_core.dart';`,
|
|
1117
|
+
``,
|
|
1118
|
+
...tokenImports.map((p) => `import '${p}';`),
|
|
1119
|
+
``,
|
|
1120
|
+
`/// Assembled Material 3 [ThemeData] for this project.`,
|
|
1121
|
+
`///`,
|
|
1122
|
+
`/// Wire into [MaterialApp]:`,
|
|
1123
|
+
`/// \`\`\`dart`,
|
|
1124
|
+
`/// MaterialApp(`,
|
|
1125
|
+
`/// theme: ${themeClassName}.light,`,
|
|
1126
|
+
`/// darkTheme: ${themeClassName}.dark,`,
|
|
1127
|
+
`/// );`,
|
|
1128
|
+
`/// \`\`\``,
|
|
1129
|
+
`sealed class ${themeClassName} {`
|
|
1130
|
+
];
|
|
1131
|
+
if (emitLight) {
|
|
1132
|
+
lines.push(
|
|
1133
|
+
` static ThemeData get light => VisorTheme.build(`,
|
|
1134
|
+
` colors: VisorColors.light,`,
|
|
1135
|
+
` brightness: Brightness.light,`,
|
|
1136
|
+
` textStyles: VisorTextStyles.instance,`,
|
|
1137
|
+
` spacing: VisorSpacing.instance,`,
|
|
1138
|
+
` radius: VisorRadius.instance,`,
|
|
1139
|
+
` shadows: VisorShadows.instance,`,
|
|
1140
|
+
` strokeWidths: VisorStrokeWidths.instance,`,
|
|
1141
|
+
` opacity: VisorOpacity.instance,`,
|
|
1142
|
+
` motion: VisorMotion.instance,`,
|
|
1143
|
+
` );`,
|
|
1144
|
+
``
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
if (emitDark) {
|
|
1148
|
+
lines.push(
|
|
1149
|
+
` static ThemeData get dark => VisorTheme.build(`,
|
|
1150
|
+
` colors: VisorColors.dark,`,
|
|
1151
|
+
` brightness: Brightness.dark,`,
|
|
1152
|
+
` textStyles: VisorTextStyles.instance,`,
|
|
1153
|
+
` spacing: VisorSpacing.instance,`,
|
|
1154
|
+
` radius: VisorRadius.instance,`,
|
|
1155
|
+
` shadows: VisorShadows.instance,`,
|
|
1156
|
+
` strokeWidths: VisorStrokeWidths.instance,`,
|
|
1157
|
+
` opacity: VisorOpacity.instance,`,
|
|
1158
|
+
` motion: VisorMotion.instance,`,
|
|
1159
|
+
` );`,
|
|
1160
|
+
``
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
lines.push(`}`);
|
|
1164
|
+
lines.push(``);
|
|
1165
|
+
return lines.join("\n");
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// src/adapters/flutter.ts
|
|
1169
|
+
function flutterAdapter(input, options) {
|
|
1170
|
+
const packageName = options?.packageName ?? "ui";
|
|
1171
|
+
const themeClassName = options?.themeClassName ?? "VisorAppTheme";
|
|
1172
|
+
const visorCoreVersion = options?.visorCoreVersion ?? "^0.1.0";
|
|
1173
|
+
const tokensOnly = options?.tokensOnly ?? false;
|
|
1174
|
+
const lightOnly = options?.lightOnly ?? false;
|
|
1175
|
+
const darkOnly = options?.darkOnly ?? false;
|
|
1176
|
+
const files = {};
|
|
1177
|
+
files["lib/src/colors/visor_colors.dart"] = emitColorsDart(input);
|
|
1178
|
+
files["lib/src/typography/visor_text_styles.dart"] = emitTypographyDart(input);
|
|
1179
|
+
files["lib/src/spacing/visor_spacing.dart"] = emitSpacingDart(input);
|
|
1180
|
+
files["lib/src/radius/visor_radius.dart"] = emitRadiusDart(input);
|
|
1181
|
+
files["lib/src/shadows/visor_shadows.dart"] = emitShadowsDart(input);
|
|
1182
|
+
files["lib/src/strokes/visor_stroke_widths.dart"] = emitStrokesDart(input);
|
|
1183
|
+
files["lib/src/opacity/visor_opacity.dart"] = emitOpacityDart();
|
|
1184
|
+
files["lib/src/motion/visor_motion.dart"] = emitMotionDart(input);
|
|
1185
|
+
if (!tokensOnly) {
|
|
1186
|
+
files["pubspec.yaml"] = emitPubspec(packageName, visorCoreVersion);
|
|
1187
|
+
files["lib/ui.dart"] = emitBarrel();
|
|
1188
|
+
files["lib/src/theme/visor_theme.dart"] = emitThemeDart({
|
|
1189
|
+
themeClassName,
|
|
1190
|
+
emitLight: !darkOnly,
|
|
1191
|
+
emitDark: !lightOnly,
|
|
1192
|
+
tokenImports: [
|
|
1193
|
+
"../colors/visor_colors.dart",
|
|
1194
|
+
"../typography/visor_text_styles.dart",
|
|
1195
|
+
"../spacing/visor_spacing.dart",
|
|
1196
|
+
"../radius/visor_radius.dart",
|
|
1197
|
+
"../shadows/visor_shadows.dart",
|
|
1198
|
+
"../strokes/visor_stroke_widths.dart",
|
|
1199
|
+
"../opacity/visor_opacity.dart",
|
|
1200
|
+
"../motion/visor_motion.dart"
|
|
1201
|
+
]
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
return { files };
|
|
1205
|
+
}
|
|
1206
|
+
function emitPubspec(packageName, visorCoreVersion) {
|
|
1207
|
+
return [
|
|
1208
|
+
`name: ${packageName}`,
|
|
1209
|
+
`description: Generated Visor tokens for this project. Regenerate with \`visor theme apply\`.`,
|
|
1210
|
+
`version: 0.1.0+1`,
|
|
1211
|
+
`publish_to: none`,
|
|
1212
|
+
``,
|
|
1213
|
+
`environment:`,
|
|
1214
|
+
` sdk: ^3.5.0`,
|
|
1215
|
+
` flutter: ^3.24.0`,
|
|
1216
|
+
``,
|
|
1217
|
+
`dependencies:`,
|
|
1218
|
+
` flutter:`,
|
|
1219
|
+
` sdk: flutter`,
|
|
1220
|
+
` visor_core: ${visorCoreVersion}`,
|
|
1221
|
+
``,
|
|
1222
|
+
`dev_dependencies:`,
|
|
1223
|
+
` flutter_test:`,
|
|
1224
|
+
` sdk: flutter`,
|
|
1225
|
+
``,
|
|
1226
|
+
`flutter:`,
|
|
1227
|
+
` uses-material-design: true`,
|
|
1228
|
+
``
|
|
1229
|
+
].join("\n");
|
|
1230
|
+
}
|
|
1231
|
+
function emitBarrel() {
|
|
1232
|
+
return [
|
|
1233
|
+
`/// Generated barrel for the Visor tokens package.`,
|
|
1234
|
+
`library;`,
|
|
1235
|
+
``,
|
|
1236
|
+
`export 'src/colors/visor_colors.dart';`,
|
|
1237
|
+
`export 'src/typography/visor_text_styles.dart';`,
|
|
1238
|
+
`export 'src/spacing/visor_spacing.dart';`,
|
|
1239
|
+
`export 'src/radius/visor_radius.dart';`,
|
|
1240
|
+
`export 'src/shadows/visor_shadows.dart';`,
|
|
1241
|
+
`export 'src/strokes/visor_stroke_widths.dart';`,
|
|
1242
|
+
`export 'src/opacity/visor_opacity.dart';`,
|
|
1243
|
+
`export 'src/motion/visor_motion.dart';`,
|
|
1244
|
+
`export 'src/theme/visor_theme.dart';`,
|
|
1245
|
+
``,
|
|
1246
|
+
`// Re-export visor_core so consumers can access ThemeExtensions with a`,
|
|
1247
|
+
`// single import of this package.`,
|
|
1248
|
+
`export 'package:visor_core/visor_core.dart';`,
|
|
1249
|
+
``
|
|
1250
|
+
].join("\n");
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// src/adapters/types.ts
|
|
1254
|
+
function isAdapterFileMap(output) {
|
|
1255
|
+
return typeof output !== "string";
|
|
1256
|
+
}
|
|
561
1257
|
export {
|
|
562
1258
|
FUMADOCS_BRIDGE_MAP,
|
|
563
1259
|
LAYER_ORDER,
|
|
564
1260
|
deckAdapter,
|
|
565
1261
|
docsAdapter,
|
|
1262
|
+
flutterAdapter,
|
|
566
1263
|
fumadocsAdapter,
|
|
1264
|
+
isAdapterFileMap,
|
|
567
1265
|
nextjsAdapter,
|
|
568
1266
|
wrapInLayer
|
|
569
1267
|
};
|