@valbuild/core 0.100.0 → 0.101.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.
@@ -5452,6 +5452,647 @@ var datetime = function datetime(options) {
5452
5452
  return new DateTimeSchema(options);
5453
5453
  };
5454
5454
 
5455
+ /**
5456
+ * Parsing / formatting of the CSS color strings stored by `s.color()`.
5457
+ *
5458
+ * Colors are stored as plain CSS strings so that they can be used directly in
5459
+ * `style` attributes and CSS custom properties. The schema decides which family
5460
+ * (`hex`, `rgb`, `hsl` or `oklch`) the string is written in, this module does
5461
+ * the conversion between them.
5462
+ *
5463
+ * All colors are sRGB: `oklch` is only used as an output notation, so any
5464
+ * `oklch` value that falls outside the sRGB gamut is clipped when converted
5465
+ * back to the other formats.
5466
+ */
5467
+
5468
+ var COLOR_FORMATS = ["hex", "rgb", "hsl", "oklch"];
5469
+ var DEFAULT_COLOR_FORMAT = "hsl";
5470
+
5471
+ /**
5472
+ * A color, normalized to sRGB.
5473
+ *
5474
+ * `r`, `g` and `b` are 0-255 (not rounded), `a` is 0-1.
5475
+ */
5476
+
5477
+ /**
5478
+ * Which color notation a string uses, or `null` if it is not a notation we
5479
+ * recognize. This looks at the syntax only: `detectColorFormat` says nothing
5480
+ * about whether the value actually parses (`hsl(nope)` is still `"hsl"`).
5481
+ */
5482
+ function detectColorFormat(value) {
5483
+ var trimmed = value.trim().toLowerCase();
5484
+ if (trimmed.startsWith("#")) {
5485
+ return "hex";
5486
+ }
5487
+ if (trimmed.startsWith("rgb(") || trimmed.startsWith("rgba(")) {
5488
+ return "rgb";
5489
+ }
5490
+ if (trimmed.startsWith("hsl(") || trimmed.startsWith("hsla(")) {
5491
+ return "hsl";
5492
+ }
5493
+ if (trimmed.startsWith("oklch(")) {
5494
+ return "oklch";
5495
+ }
5496
+ return null;
5497
+ }
5498
+ function clamp(value, min, max) {
5499
+ if (Number.isNaN(value)) {
5500
+ return min;
5501
+ }
5502
+ return Math.min(max, Math.max(min, value));
5503
+ }
5504
+
5505
+ /**
5506
+ * Splits the inside of a CSS color function into components.
5507
+ *
5508
+ * Handles both the legacy comma syntax (`rgb(1, 2, 3, 0.5)`) and the modern
5509
+ * space syntax (`rgb(1 2 3 / 0.5)`), returning the alpha (if any) separately.
5510
+ */
5511
+ function splitComponents(args) {
5512
+ var slashParts = args.split("/");
5513
+ if (slashParts.length > 2) {
5514
+ return null;
5515
+ }
5516
+ var alpha = slashParts.length === 2 ? slashParts[1].trim() : null;
5517
+ var head = slashParts[0].trim();
5518
+ if (head === "") {
5519
+ return null;
5520
+ }
5521
+ var components;
5522
+ if (head.includes(",")) {
5523
+ if (alpha !== null) {
5524
+ // Mixing the comma and the slash syntax is not valid CSS
5525
+ return null;
5526
+ }
5527
+ components = head.split(",").map(function (part) {
5528
+ return part.trim();
5529
+ });
5530
+ if (components.length === 4) {
5531
+ alpha = components[3];
5532
+ components = components.slice(0, 3);
5533
+ }
5534
+ } else {
5535
+ components = head.split(/\s+/);
5536
+ }
5537
+ if (components.length !== 3 || components.some(function (part) {
5538
+ return part === "";
5539
+ })) {
5540
+ return null;
5541
+ }
5542
+ if (alpha === "") {
5543
+ return null;
5544
+ }
5545
+ return {
5546
+ components: components,
5547
+ alpha: alpha
5548
+ };
5549
+ }
5550
+ function parseNumber(value) {
5551
+ if (!/^[+-]?(\d+\.?\d*|\.\d+)$/.test(value)) {
5552
+ return null;
5553
+ }
5554
+ var parsed = Number(value);
5555
+ return Number.isFinite(parsed) ? parsed : null;
5556
+ }
5557
+
5558
+ /**
5559
+ * A `<number>` or a `<percentage>`, where 100% maps to `percentageBasis`.
5560
+ */
5561
+ function parseNumberOrPercentage(value, percentageBasis) {
5562
+ if (value.endsWith("%")) {
5563
+ var percentage = parseNumber(value.slice(0, -1));
5564
+ return percentage === null ? null : percentage / 100 * percentageBasis;
5565
+ }
5566
+ return parseNumber(value);
5567
+ }
5568
+ function parsePercentage(value) {
5569
+ if (!value.endsWith("%")) {
5570
+ return null;
5571
+ }
5572
+ return parseNumber(value.slice(0, -1));
5573
+ }
5574
+ function parseAlpha(value) {
5575
+ if (value === null) {
5576
+ return 1;
5577
+ }
5578
+ if (value === "none") {
5579
+ return 0;
5580
+ }
5581
+ var parsed = parseNumberOrPercentage(value, 1);
5582
+ return parsed === null ? null : clamp(parsed, 0, 1);
5583
+ }
5584
+ function parseHue(value) {
5585
+ var match = /^([+-]?(?:\d+\.?\d*|\.\d+))(deg|grad|rad|turn)?$/.exec(value);
5586
+ if (!match) {
5587
+ return null;
5588
+ }
5589
+ var amount = Number(match[1]);
5590
+ switch (match[2]) {
5591
+ case "grad":
5592
+ return amount / 400 * 360;
5593
+ case "rad":
5594
+ return amount * 180 / Math.PI;
5595
+ case "turn":
5596
+ return amount * 360;
5597
+ default:
5598
+ return amount;
5599
+ }
5600
+ }
5601
+ function normalizeHue(hue) {
5602
+ var wrapped = hue % 360;
5603
+ return wrapped < 0 ? wrapped + 360 : wrapped;
5604
+ }
5605
+ function parseHex(value) {
5606
+ var hex = value.slice(1);
5607
+ if (!/^[0-9a-f]+$/i.test(hex)) {
5608
+ return null;
5609
+ }
5610
+ var expand = function expand(_char) {
5611
+ return parseInt(_char + _char, 16);
5612
+ };
5613
+ var pair = function pair(index) {
5614
+ return parseInt(hex.slice(index, index + 2), 16);
5615
+ };
5616
+ if (hex.length === 3 || hex.length === 4) {
5617
+ return {
5618
+ r: expand(hex[0]),
5619
+ g: expand(hex[1]),
5620
+ b: expand(hex[2]),
5621
+ a: hex.length === 4 ? expand(hex[3]) / 255 : 1
5622
+ };
5623
+ }
5624
+ if (hex.length === 6 || hex.length === 8) {
5625
+ return {
5626
+ r: pair(0),
5627
+ g: pair(2),
5628
+ b: pair(4),
5629
+ a: hex.length === 8 ? pair(6) / 255 : 1
5630
+ };
5631
+ }
5632
+ return null;
5633
+ }
5634
+ function extractFunctionArgs(value, name) {
5635
+ if (!value.startsWith(name + "(") || !value.endsWith(")")) {
5636
+ return null;
5637
+ }
5638
+ return value.slice(name.length + 1, -1);
5639
+ }
5640
+ function parseRgb(value) {
5641
+ var _extractFunctionArgs;
5642
+ var args = (_extractFunctionArgs = extractFunctionArgs(value, "rgba")) !== null && _extractFunctionArgs !== void 0 ? _extractFunctionArgs : extractFunctionArgs(value, "rgb");
5643
+ if (args === null) {
5644
+ return null;
5645
+ }
5646
+ var split = splitComponents(args);
5647
+ if (!split) {
5648
+ return null;
5649
+ }
5650
+ var channels = split.components.map(function (component) {
5651
+ return component === "none" ? 0 : parseNumberOrPercentage(component, 255);
5652
+ });
5653
+ var alpha = parseAlpha(split.alpha);
5654
+ if (channels.some(function (channel) {
5655
+ return channel === null;
5656
+ }) || alpha === null) {
5657
+ return null;
5658
+ }
5659
+ return {
5660
+ r: clamp(channels[0], 0, 255),
5661
+ g: clamp(channels[1], 0, 255),
5662
+ b: clamp(channels[2], 0, 255),
5663
+ a: alpha
5664
+ };
5665
+ }
5666
+ function parseHsl(value) {
5667
+ var _extractFunctionArgs2, _parsePercentage, _parsePercentage2;
5668
+ var args = (_extractFunctionArgs2 = extractFunctionArgs(value, "hsla")) !== null && _extractFunctionArgs2 !== void 0 ? _extractFunctionArgs2 : extractFunctionArgs(value, "hsl");
5669
+ if (args === null) {
5670
+ return null;
5671
+ }
5672
+ var split = splitComponents(args);
5673
+ if (!split) {
5674
+ return null;
5675
+ }
5676
+ var _split$components = _slicedToArray(split.components, 3),
5677
+ rawHue = _split$components[0],
5678
+ rawSaturation = _split$components[1],
5679
+ rawLightness = _split$components[2];
5680
+ var hue = rawHue === "none" ? 0 : parseHue(rawHue);
5681
+ // CSS requires percentages for s/l in hsl(), but the modern syntax also
5682
+ // allows bare numbers, so accept both.
5683
+ var saturation = rawSaturation === "none" ? 0 : (_parsePercentage = parsePercentage(rawSaturation)) !== null && _parsePercentage !== void 0 ? _parsePercentage : parseNumber(rawSaturation);
5684
+ var lightness = rawLightness === "none" ? 0 : (_parsePercentage2 = parsePercentage(rawLightness)) !== null && _parsePercentage2 !== void 0 ? _parsePercentage2 : parseNumber(rawLightness);
5685
+ var alpha = parseAlpha(split.alpha);
5686
+ if (hue === null || saturation === null || lightness === null || alpha === null) {
5687
+ return null;
5688
+ }
5689
+ return _objectSpread2(_objectSpread2({}, hslToRgb(normalizeHue(hue), clamp(saturation, 0, 100), clamp(lightness, 0, 100))), {}, {
5690
+ a: alpha
5691
+ });
5692
+ }
5693
+ function parseOklch(value) {
5694
+ var args = extractFunctionArgs(value, "oklch");
5695
+ if (args === null) {
5696
+ return null;
5697
+ }
5698
+ var split = splitComponents(args);
5699
+ if (!split) {
5700
+ return null;
5701
+ }
5702
+ var _split$components2 = _slicedToArray(split.components, 3),
5703
+ rawLightness = _split$components2[0],
5704
+ rawChroma = _split$components2[1],
5705
+ rawHue = _split$components2[2];
5706
+ // Lightness is a <number> in 0-1 or a <percentage>, chroma is a <number>
5707
+ // where 0.4 is roughly the maximum, or a <percentage> where 100% = 0.4.
5708
+ var lightness = rawLightness === "none" ? 0 : parseNumberOrPercentage(rawLightness, 1);
5709
+ var chroma = rawChroma === "none" ? 0 : parseNumberOrPercentage(rawChroma, 0.4);
5710
+ var hue = rawHue === "none" ? 0 : parseHue(rawHue);
5711
+ var alpha = parseAlpha(split.alpha);
5712
+ if (lightness === null || chroma === null || hue === null || alpha === null) {
5713
+ return null;
5714
+ }
5715
+ return _objectSpread2(_objectSpread2({}, oklchToRgb(clamp(lightness, 0, 1), Math.max(0, chroma), normalizeHue(hue))), {}, {
5716
+ a: alpha
5717
+ });
5718
+ }
5719
+
5720
+ /**
5721
+ * Parses a CSS color string into sRGB channels.
5722
+ *
5723
+ * Accepts hex (3, 4, 6 and 8 digits), `rgb()` / `rgba()`, `hsl()` / `hsla()`
5724
+ * and `oklch()`, in both the legacy comma and the modern space syntax. Returns
5725
+ * `null` if the value is not a color we can parse - notably: named colors
5726
+ * (`red`), `color()`, `lab()` and `color-mix()` are not supported.
5727
+ */
5728
+ function parseColor(value) {
5729
+ var normalized = value.trim().toLowerCase();
5730
+ if (normalized === "") {
5731
+ return null;
5732
+ }
5733
+ switch (detectColorFormat(normalized)) {
5734
+ case "hex":
5735
+ return parseHex(normalized);
5736
+ case "rgb":
5737
+ return parseRgb(normalized);
5738
+ case "hsl":
5739
+ return parseHsl(normalized);
5740
+ case "oklch":
5741
+ return parseOklch(normalized);
5742
+ default:
5743
+ return null;
5744
+ }
5745
+ }
5746
+
5747
+ /**
5748
+ * Rounds to at most `decimals` decimals, without trailing zeros.
5749
+ */
5750
+ function round(value, decimals) {
5751
+ var factor = Math.pow(10, decimals);
5752
+ // `|| 0` normalizes -0 to 0
5753
+ return Math.round(value * factor) / factor || 0;
5754
+ }
5755
+ function toHexPair(value) {
5756
+ return clamp(Math.round(value), 0, 255).toString(16).padStart(2, "0");
5757
+ }
5758
+ function rgbToHsl(r, g, b) {
5759
+ var red = r / 255;
5760
+ var green = g / 255;
5761
+ var blue = b / 255;
5762
+ var max = Math.max(red, green, blue);
5763
+ var min = Math.min(red, green, blue);
5764
+ var delta = max - min;
5765
+ var l = (max + min) / 2;
5766
+ if (delta === 0) {
5767
+ return {
5768
+ h: 0,
5769
+ s: 0,
5770
+ l: l * 100
5771
+ };
5772
+ }
5773
+ var s = delta / (1 - Math.abs(2 * l - 1));
5774
+ var h;
5775
+ if (max === red) {
5776
+ h = (green - blue) / delta % 6;
5777
+ } else if (max === green) {
5778
+ h = (blue - red) / delta + 2;
5779
+ } else {
5780
+ h = (red - green) / delta + 4;
5781
+ }
5782
+ return {
5783
+ h: normalizeHue(h * 60),
5784
+ s: s * 100,
5785
+ l: l * 100
5786
+ };
5787
+ }
5788
+ function hslToRgb(h, s, l) {
5789
+ var saturation = s / 100;
5790
+ var lightness = l / 100;
5791
+ var c = (1 - Math.abs(2 * lightness - 1)) * saturation;
5792
+ var hPrime = normalizeHue(h) / 60;
5793
+ var x = c * (1 - Math.abs(hPrime % 2 - 1));
5794
+ var m = lightness - c / 2;
5795
+ var rgb;
5796
+ if (hPrime < 1) {
5797
+ rgb = [c, x, 0];
5798
+ } else if (hPrime < 2) {
5799
+ rgb = [x, c, 0];
5800
+ } else if (hPrime < 3) {
5801
+ rgb = [0, c, x];
5802
+ } else if (hPrime < 4) {
5803
+ rgb = [0, x, c];
5804
+ } else if (hPrime < 5) {
5805
+ rgb = [x, 0, c];
5806
+ } else {
5807
+ rgb = [c, 0, x];
5808
+ }
5809
+ return {
5810
+ r: (rgb[0] + m) * 255,
5811
+ g: (rgb[1] + m) * 255,
5812
+ b: (rgb[2] + m) * 255
5813
+ };
5814
+ }
5815
+ function srgbToLinear(channel) {
5816
+ var c = channel / 255;
5817
+ return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
5818
+ }
5819
+ function linearToSrgb(channel) {
5820
+ var c = channel <= 0.0031308 ? channel * 12.92 : 1.055 * Math.pow(channel, 1 / 2.4) - 0.055;
5821
+ return clamp(c * 255, 0, 255);
5822
+ }
5823
+
5824
+ /**
5825
+ * sRGB to Oklch, using Björn Ottosson's Oklab matrices.
5826
+ */
5827
+ function rgbToOklch(r, g, b) {
5828
+ var lr = srgbToLinear(r);
5829
+ var lg = srgbToLinear(g);
5830
+ var lb = srgbToLinear(b);
5831
+ var _long = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
5832
+ var medium = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
5833
+ var _short = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
5834
+ var lightness = 0.2104542553 * _long + 0.793617785 * medium - 0.0040720468 * _short;
5835
+ var a = 1.9779984951 * _long - 2.428592205 * medium + 0.4505937099 * _short;
5836
+ var bComponent = 0.0259040371 * _long + 0.7827717662 * medium - 0.808675766 * _short;
5837
+ var chroma = Math.sqrt(a * a + bComponent * bComponent);
5838
+ // Achromatic colors have an undefined hue: report 0 rather than the noise
5839
+ // that atan2 of two near-zero numbers produces.
5840
+ var hue = chroma < 1e-6 ? 0 : normalizeHue(Math.atan2(bComponent, a) * 180 / Math.PI);
5841
+ return {
5842
+ l: clamp(lightness, 0, 1),
5843
+ c: chroma,
5844
+ h: hue
5845
+ };
5846
+ }
5847
+
5848
+ /**
5849
+ * Oklch to sRGB. Out of gamut colors are clipped per channel.
5850
+ */
5851
+ function oklchToRgb(l, c, h) {
5852
+ var hueRadians = normalizeHue(h) * Math.PI / 180;
5853
+ var a = c * Math.cos(hueRadians);
5854
+ var bComponent = c * Math.sin(hueRadians);
5855
+ var _long2 = Math.pow(l + 0.3963377774 * a + 0.2158037573 * bComponent, 3);
5856
+ var medium = Math.pow(l - 0.1055613458 * a - 0.0638541728 * bComponent, 3);
5857
+ var _short2 = Math.pow(l - 0.0894841775 * a - 1.291485548 * bComponent, 3);
5858
+ return {
5859
+ r: linearToSrgb(4.0767416621 * _long2 - 3.3077115913 * medium + 0.2309699292 * _short2),
5860
+ g: linearToSrgb(-1.2684380046 * _long2 + 2.6097574011 * medium - 0.3413193965 * _short2),
5861
+ b: linearToSrgb(-0.0041960863 * _long2 - 0.7034186147 * medium + 1.707614701 * _short2)
5862
+ };
5863
+ }
5864
+
5865
+ /**
5866
+ * Serializes a color to the canonical string of the given format.
5867
+ *
5868
+ * The modern, space separated CSS syntax is used for the color functions
5869
+ * (`rgb(255 0 0 / 0.5)`). Alpha is only included when it is not fully opaque.
5870
+ */
5871
+ function formatColor(color, format) {
5872
+ var alpha = clamp(color.a, 0, 1);
5873
+ var alphaSuffix = alpha >= 1 ? "" : " / ".concat(round(alpha, 4));
5874
+ switch (format) {
5875
+ case "hex":
5876
+ {
5877
+ var hex = "#".concat(toHexPair(color.r)).concat(toHexPair(color.g)).concat(toHexPair(color.b));
5878
+ return alpha >= 1 ? hex : "".concat(hex).concat(toHexPair(alpha * 255));
5879
+ }
5880
+ case "rgb":
5881
+ {
5882
+ var r = clamp(Math.round(color.r), 0, 255);
5883
+ var g = clamp(Math.round(color.g), 0, 255);
5884
+ var b = clamp(Math.round(color.b), 0, 255);
5885
+ return "rgb(".concat(r, " ").concat(g, " ").concat(b).concat(alphaSuffix, ")");
5886
+ }
5887
+ case "hsl":
5888
+ {
5889
+ var _rgbToHsl = rgbToHsl(color.r, color.g, color.b),
5890
+ h = _rgbToHsl.h,
5891
+ s = _rgbToHsl.s,
5892
+ l = _rgbToHsl.l;
5893
+ return "hsl(".concat(round(h, 2), " ").concat(round(s, 2), "% ").concat(round(l, 2), "%").concat(alphaSuffix, ")");
5894
+ }
5895
+ case "oklch":
5896
+ {
5897
+ var _rgbToOklch = rgbToOklch(color.r, color.g, color.b),
5898
+ _l = _rgbToOklch.l,
5899
+ c = _rgbToOklch.c,
5900
+ _h = _rgbToOklch.h;
5901
+ return "oklch(".concat(round(_l, 4), " ").concat(round(c, 4), " ").concat(round(_h, 2)).concat(alphaSuffix, ")");
5902
+ }
5903
+ }
5904
+ }
5905
+
5906
+ /**
5907
+ * Converts a color string to the canonical string of the given format, or
5908
+ * `null` if the input cannot be parsed.
5909
+ */
5910
+ function convertColor(value, format) {
5911
+ var parsed = parseColor(value);
5912
+ if (parsed === null) {
5913
+ return null;
5914
+ }
5915
+ return formatColor(parsed, format);
5916
+ }
5917
+
5918
+ /**
5919
+ * `#rrggbb`, which is what `<input type="color">` uses as its value.
5920
+ */
5921
+ function colorToHex(color) {
5922
+ return "#".concat(toHexPair(color.r)).concat(toHexPair(color.g)).concat(toHexPair(color.b));
5923
+ }
5924
+
5925
+ /**
5926
+ * An example of the canonical output of each format, used in error messages so
5927
+ * that the expected syntax is obvious from the error alone.
5928
+ */
5929
+ var FORMAT_EXAMPLES = {
5930
+ hex: "#3b82f6",
5931
+ rgb: "rgb(59 130 246)",
5932
+ hsl: "hsl(217.22 91.22% 59.8%)",
5933
+ oklch: "oklch(0.6231 0.188 259.81)"
5934
+ };
5935
+ var ColorSchema = /*#__PURE__*/function (_Schema) {
5936
+ function ColorSchema(options) {
5937
+ var _this;
5938
+ var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
5939
+ var customValidateFunctions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
5940
+ var isReadonly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
5941
+ var isHidden = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
5942
+ var description = arguments.length > 5 ? arguments[5] : undefined;
5943
+ _classCallCheck(this, ColorSchema);
5944
+ _this = _callSuper(this, ColorSchema);
5945
+ _this.options = options;
5946
+ _this.opt = opt;
5947
+ _this.customValidateFunctions = customValidateFunctions;
5948
+ _this.isReadonly = isReadonly;
5949
+ _this.isHidden = isHidden;
5950
+ _this.description = description;
5951
+ return _this;
5952
+ }
5953
+ _inherits(ColorSchema, _Schema);
5954
+ return _createClass(ColorSchema, [{
5955
+ key: "describe",
5956
+ value: function describe(description) {
5957
+ return new ColorSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, this.isHidden, description !== null && description !== void 0 ? description : undefined);
5958
+ }
5959
+ }, {
5960
+ key: "validate",
5961
+ value: function validate(validationFunction) {
5962
+ return new ColorSchema(this.options, this.opt, [].concat(_toConsumableArray(this.customValidateFunctions), [validationFunction]), this.isReadonly, this.isHidden, this.description);
5963
+ }
5964
+ }, {
5965
+ key: "executeCustomValidateAt",
5966
+ value: function executeCustomValidateAt(path, src) {
5967
+ return this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
5968
+ path: path
5969
+ });
5970
+ }
5971
+ }, {
5972
+ key: "executeValidate",
5973
+ value: function executeValidate(path, src) {
5974
+ var _this$options$format, _this$options;
5975
+ var errors = this.executeCustomValidateFunctions(src, this.customValidateFunctions, {
5976
+ path: path
5977
+ });
5978
+ if (this.opt && (src === null || src === undefined)) {
5979
+ return errors.length > 0 ? _defineProperty({}, path, errors) : false;
5980
+ }
5981
+ if (typeof src !== "string") {
5982
+ errors.push({
5983
+ message: "Expected 'string', got '".concat(_typeof(src), "'"),
5984
+ value: src
5985
+ });
5986
+ return _defineProperty({}, path, errors);
5987
+ }
5988
+ var expectedFormat = (_this$options$format = (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.format) !== null && _this$options$format !== void 0 ? _this$options$format : DEFAULT_COLOR_FORMAT;
5989
+ var parsed = parseColor(src);
5990
+ if (parsed === null) {
5991
+ errors.push({
5992
+ message: "Invalid color: '".concat(src, "'. Expected a CSS color in the '").concat(expectedFormat, "' format (e.g. '").concat(FORMAT_EXAMPLES[expectedFormat], "')"),
5993
+ value: src
5994
+ });
5995
+ } else {
5996
+ var _this$options3;
5997
+ var actualFormat = detectColorFormat(src);
5998
+ if (actualFormat !== expectedFormat) {
5999
+ var _this$options2;
6000
+ // Drop alpha from the SUGGESTION when alpha is not enabled, the same way
6001
+ // the field's commit does. Keeping it would suggest a value that fails
6002
+ // the alpha check immediately below, so following the advice would not
6003
+ // clear the error.
6004
+ var suggestion = formatColor((_this$options2 = this.options) !== null && _this$options2 !== void 0 && _this$options2.alpha ? parsed : _objectSpread2(_objectSpread2({}, parsed), {}, {
6005
+ a: 1
6006
+ }), expectedFormat);
6007
+ errors.push({
6008
+ message: "Expected a color in the '".concat(expectedFormat, "' format (e.g. '").concat(FORMAT_EXAMPLES[expectedFormat], "'), got '").concat(src, "'. Did you mean '").concat(suggestion, "'?"),
6009
+ value: src
6010
+ });
6011
+ }
6012
+ if (!((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.alpha) && parsed.a < 1) {
6013
+ errors.push({
6014
+ message: "Color '".concat(src, "' has an alpha channel, but alpha is not enabled. Use s.color({ alpha: true }) to allow transparency"),
6015
+ value: src
6016
+ });
6017
+ }
6018
+ }
6019
+ if (errors.length > 0) {
6020
+ return _defineProperty({}, path, errors);
6021
+ }
6022
+ return false;
6023
+ }
6024
+ }, {
6025
+ key: "executeAssert",
6026
+ value: function executeAssert(path, src) {
6027
+ if (this.opt && src === null) {
6028
+ return {
6029
+ success: true,
6030
+ data: src
6031
+ };
6032
+ }
6033
+ if (src === null) {
6034
+ return {
6035
+ success: false,
6036
+ errors: _defineProperty({}, path, [{
6037
+ message: "Expected 'string', got 'null'",
6038
+ typeError: true
6039
+ }])
6040
+ };
6041
+ }
6042
+ if (typeof src !== "string") {
6043
+ return {
6044
+ success: false,
6045
+ errors: _defineProperty({}, path, [{
6046
+ message: "Expected 'string', got '".concat(_typeof(src), "'"),
6047
+ typeError: true
6048
+ }])
6049
+ };
6050
+ }
6051
+ return {
6052
+ success: true,
6053
+ data: src
6054
+ };
6055
+ }
6056
+ }, {
6057
+ key: "nullable",
6058
+ value: function nullable() {
6059
+ return new ColorSchema(this.options, true, [], this.isReadonly, this.isHidden, this.description);
6060
+ }
6061
+ }, {
6062
+ key: "readonly",
6063
+ value: function readonly() {
6064
+ return new ColorSchema(this.options, this.opt, this.customValidateFunctions, true, this.isHidden, this.description);
6065
+ }
6066
+ }, {
6067
+ key: "hidden",
6068
+ value: function hidden() {
6069
+ return new ColorSchema(this.options, this.opt, this.customValidateFunctions, this.isReadonly, true, this.description);
6070
+ }
6071
+ }, {
6072
+ key: "executeSerialize",
6073
+ value: function executeSerialize() {
6074
+ var _this$customValidateF;
6075
+ return {
6076
+ type: "color",
6077
+ opt: this.opt,
6078
+ options: this.options,
6079
+ customValidate: this.customValidateFunctions && ((_this$customValidateF = this.customValidateFunctions) === null || _this$customValidateF === void 0 ? void 0 : _this$customValidateF.length) > 0,
6080
+ readonly: this.isReadonly,
6081
+ hidden: this.isHidden,
6082
+ description: this.description
6083
+ };
6084
+ }
6085
+ }, {
6086
+ key: "executeRender",
6087
+ value: function executeRender() {
6088
+ return {};
6089
+ }
6090
+ }]);
6091
+ }(Schema);
6092
+ var color = function color(options) {
6093
+ return new ColorSchema(options);
6094
+ };
6095
+
5455
6096
  function router(router, keyOrItem, maybeItem) {
5456
6097
  if (maybeItem) {
5457
6098
  return new RecordSchema(maybeItem, false, [], router, keyOrItem);
@@ -5541,6 +6182,7 @@ function initSchema() {
5541
6182
  files: files,
5542
6183
  date: date,
5543
6184
  datetime: datetime,
6185
+ color: color,
5544
6186
  route: route,
5545
6187
  router: router,
5546
6188
  images: images
@@ -7263,6 +7905,8 @@ function deserializeSchemaImpl(serialized) {
7263
7905
  return new DateSchema(serialized.options, serialized.opt, [], false, false, serialized.description);
7264
7906
  case "dateTime":
7265
7907
  return new DateTimeSchema(serialized.options, serialized.opt, [], false, false, serialized.description);
7908
+ case "color":
7909
+ return new ColorSchema(serialized.options, serialized.opt, [], false, false, serialized.description);
7266
7910
  default:
7267
7911
  {
7268
7912
  var exhaustiveCheck = serialized;
@@ -7549,6 +8193,13 @@ var Internal = {
7549
8193
  joinModuleFilePathAndModulePath: joinModuleFilePathAndModulePath,
7550
8194
  nextAppRouter: nextAppRouter,
7551
8195
  externalPageRouter: externalPageRouter,
8196
+ color: {
8197
+ parseColor: parseColor,
8198
+ formatColor: formatColor,
8199
+ convertColor: convertColor,
8200
+ detectColorFormat: detectColorFormat,
8201
+ colorToHex: colorToHex
8202
+ },
7552
8203
  remote: {
7553
8204
  createRemoteRef: createRemoteRef,
7554
8205
  getValidationBasis: getValidationBasis,
@@ -7629,4 +8280,4 @@ function tryJsonParse(str) {
7629
8280
  }
7630
8281
  }
7631
8282
 
7632
- export { ArraySchema as A, BooleanSchema as B, DEFAULT_CONTENT_HOST as D, FATAL_ERROR_TYPES as F, GenericSelector as G, Internal as I, KeyOfSchema as K, LiteralSchema as L, ModuleFilePathSep as M, NumberSchema as N, ObjectSchema as O, PatchError as P, RecordSchema as R, Schema as S, UnionSchema as U, VAL_EXTENSION as V, _typeof as _, _slicedToArray as a, _createClass as b, _classCallCheck as c, _toConsumableArray as d, DEFAULT_APP_HOST as e, extractValModules as f, DEFAULT_VAL_REMOTE_HOST as g, FILE_REF_PROP as h, initVal as i, FILE_REF_SUBTYPE_TAG as j, derefPatch as k, StringSchema as l, modules as m, ImageSchema as n, FileSchema as o, DateSchema as p, DateTimeSchema as q, RouteSchema as r, splitModuleFilePathAndModulePath as s, RichTextSchema as t, deserializeSchema as u, getSourcePathFromRoute as v };
8283
+ export { ArraySchema as A, BooleanSchema as B, ColorSchema as C, DEFAULT_CONTENT_HOST as D, FATAL_ERROR_TYPES as F, GenericSelector as G, Internal as I, KeyOfSchema as K, LiteralSchema as L, ModuleFilePathSep as M, NumberSchema as N, ObjectSchema as O, PatchError as P, RecordSchema as R, Schema as S, UnionSchema as U, VAL_EXTENSION as V, _typeof as _, _slicedToArray as a, _createClass as b, _classCallCheck as c, _toConsumableArray as d, DEFAULT_APP_HOST as e, extractValModules as f, DEFAULT_VAL_REMOTE_HOST as g, FILE_REF_PROP as h, initVal as i, FILE_REF_SUBTYPE_TAG as j, derefPatch as k, StringSchema as l, modules as m, ImageSchema as n, FileSchema as o, DateSchema as p, COLOR_FORMATS as q, DEFAULT_COLOR_FORMAT as r, splitModuleFilePathAndModulePath as s, DateTimeSchema as t, RouteSchema as u, RichTextSchema as v, deserializeSchema as w, getSourcePathFromRoute as x };
@@ -2,14 +2,17 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dist_valbuildCore = require('./index-202e48a3.cjs.dev.js');
5
+ var dist_valbuildCore = require('./index-3e2d700e.cjs.dev.js');
6
6
  require('./result-bb1f436e.cjs.dev.js');
7
7
 
8
8
 
9
9
 
10
10
  exports.ArraySchema = dist_valbuildCore.ArraySchema;
11
11
  exports.BooleanSchema = dist_valbuildCore.BooleanSchema;
12
+ exports.COLOR_FORMATS = dist_valbuildCore.COLOR_FORMATS;
13
+ exports.ColorSchema = dist_valbuildCore.ColorSchema;
12
14
  exports.DEFAULT_APP_HOST = dist_valbuildCore.DEFAULT_APP_HOST;
15
+ exports.DEFAULT_COLOR_FORMAT = dist_valbuildCore.DEFAULT_COLOR_FORMAT;
13
16
  exports.DEFAULT_CONTENT_HOST = dist_valbuildCore.DEFAULT_CONTENT_HOST;
14
17
  exports.DEFAULT_VAL_REMOTE_HOST = dist_valbuildCore.DEFAULT_VAL_REMOTE_HOST;
15
18
  exports.DateSchema = dist_valbuildCore.DateSchema;