@wistia/ui 0.13.8 → 0.13.9-beta.412620d7.ab720f6

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/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  /*
3
- * @license @wistia/ui v0.13.8
3
+ * @license @wistia/ui v0.13.9-beta.412620d7.ab720f6
4
4
  *
5
5
  * Copyright (c) 2024-2025, Wistia, Inc. and its affiliates.
6
6
  *
@@ -148,6 +148,7 @@ __export(index_exports, {
148
148
  ValueNameOrHexCode: () => ValueNameOrHexCode,
149
149
  ValueSwatch: () => ValueSwatch,
150
150
  WistiaLogo: () => WistiaLogo,
151
+ calculateContrast: () => calculateContrast,
151
152
  colorSchemeOptions: () => colorSchemeOptions,
152
153
  copyToClipboard: () => copyToClipboard,
153
154
  dateTime: () => dateTime,
@@ -9761,6 +9762,16 @@ var compositeOverWhite = (color, alpha = 1) => {
9761
9762
  b: compositeChannel(colorAsRgb.b)
9762
9763
  };
9763
9764
  };
9765
+ var calculateContrast = ({
9766
+ backgroundColor,
9767
+ foregroundColor = DEFAULT_COLOR_FOR_COMPARISON,
9768
+ backgroundOpacity = DEFAULT_OPACITY_FOR_CONTRAST_CALCULATION
9769
+ }) => {
9770
+ const backgroundColorAsRgb = convertToRgb(backgroundColor);
9771
+ const foregroundColorAsRgb = convertToRgb(foregroundColor);
9772
+ const compositeBackground = compositeOverWhite(backgroundColorAsRgb, backgroundOpacity);
9773
+ return (0, import_fn3.wcagContrast)(compositeBackground, foregroundColorAsRgb);
9774
+ };
9764
9775
  var snapValueToEdges = (value) => {
9765
9776
  if (value > 1 - VALUE_CHANNEL_SNAP_EPSILON) {
9766
9777
  return 1;
@@ -9783,13 +9794,15 @@ var updateSearchBounds = (searchingBrighter, contrast, minContrast, midValue, se
9783
9794
  return { newSearchLow: searchLow, newSearchHigh: midValue };
9784
9795
  };
9785
9796
  var getAccessibleColorByValueChannelChange = ({
9786
- originalHsv,
9797
+ originalColor,
9787
9798
  colorForComparison,
9788
9799
  minContrast,
9789
9800
  maxIterations = 50,
9790
9801
  direction,
9791
- opacityForContrastCalculation
9802
+ opacityForContrastCalculation,
9803
+ shouldConvertToHex = true
9792
9804
  }) => {
9805
+ const originalHsv = convertToHsv(originalColor);
9793
9806
  const searchingBrighter = direction === "brighter";
9794
9807
  const lowValue = searchingBrighter ? originalHsv.v : 0;
9795
9808
  const highValue = searchingBrighter ? 1 : originalHsv.v;
@@ -9800,10 +9813,11 @@ var getAccessibleColorByValueChannelChange = ({
9800
9813
  v: extremeValue,
9801
9814
  mode: "hsv"
9802
9815
  };
9803
- const extremeContrast = (0, import_fn3.wcagContrast)(
9804
- compositeOverWhite(extremeVariant, opacityForContrastCalculation),
9805
- colorForComparison
9806
- );
9816
+ const extremeContrast = calculateContrast({
9817
+ backgroundColor: shouldConvertToHex ? (0, import_fn3.formatHex)(extremeVariant) : extremeVariant,
9818
+ foregroundColor: colorForComparison,
9819
+ backgroundOpacity: opacityForContrastCalculation
9820
+ });
9807
9821
  if (extremeContrast < minContrast) {
9808
9822
  return null;
9809
9823
  }
@@ -9819,10 +9833,11 @@ var getAccessibleColorByValueChannelChange = ({
9819
9833
  v: midValue,
9820
9834
  mode: "hsv"
9821
9835
  };
9822
- const contrast = (0, import_fn3.wcagContrast)(
9823
- compositeOverWhite(candidateHsv, opacityForContrastCalculation),
9824
- colorForComparison
9825
- );
9836
+ const contrast = calculateContrast({
9837
+ backgroundColor: shouldConvertToHex ? (0, import_fn3.formatHex)(candidateHsv) : candidateHsv,
9838
+ foregroundColor: colorForComparison,
9839
+ backgroundOpacity: opacityForContrastCalculation
9840
+ });
9826
9841
  if (contrast >= minContrast) {
9827
9842
  bestSoFar = candidateHsv;
9828
9843
  }
@@ -9842,7 +9857,7 @@ var getAccessibleColorByValueChannelChange = ({
9842
9857
  }
9843
9858
  return bestSoFar;
9844
9859
  };
9845
- var chooseClosestDerivativeToOriginal = (brighterOption, darkerOption, originalHsv) => {
9860
+ var chooseClosestDerivativeToOriginal = (brighterOption, darkerOption, originalColor) => {
9846
9861
  const hsvDifference = (0, import_fn3.differenceEuclidean)("hsv");
9847
9862
  if (!brighterOption && !darkerOption) {
9848
9863
  return null;
@@ -9853,8 +9868,8 @@ var chooseClosestDerivativeToOriginal = (brighterOption, darkerOption, originalH
9853
9868
  if (!darkerOption && brighterOption != null) {
9854
9869
  return brighterOption;
9855
9870
  }
9856
- const brighterDifference = brighterOption === null ? Infinity : hsvDifference(originalHsv, brighterOption);
9857
- const darkerDifference = darkerOption === null ? Infinity : hsvDifference(originalHsv, darkerOption);
9871
+ const brighterDifference = brighterOption === null ? Infinity : hsvDifference(originalColor, brighterOption);
9872
+ const darkerDifference = darkerOption === null ? Infinity : hsvDifference(originalColor, darkerOption);
9858
9873
  if (brighterDifference <= darkerDifference && brighterOption != null) {
9859
9874
  return brighterOption;
9860
9875
  }
@@ -9864,12 +9879,13 @@ var chooseClosestDerivativeToOriginal = (brighterOption, darkerOption, originalH
9864
9879
  throw new Error("Unable to determine the best accessible color variant");
9865
9880
  };
9866
9881
  var getAccessibleColorBySaturationAndValueChange = ({
9867
- originalHsv,
9882
+ originalColor,
9868
9883
  colorForComparison,
9869
9884
  minContrast,
9870
9885
  direction,
9871
9886
  opacityForContrastCalculation
9872
9887
  }) => {
9888
+ const originalHsv = convertToHsv(originalColor);
9873
9889
  const hsvDifference = (0, import_fn3.differenceEuclidean)("hsv");
9874
9890
  const maxIterations = 50;
9875
9891
  let lowStep = 0;
@@ -9895,7 +9911,11 @@ var getAccessibleColorBySaturationAndValueChange = ({
9895
9911
  };
9896
9912
  };
9897
9913
  const checkContrast = (hsv) => {
9898
- return (0, import_fn3.wcagContrast)(compositeOverWhite(hsv, opacityForContrastCalculation), colorForComparison);
9914
+ return calculateContrast({
9915
+ backgroundColor: (0, import_fn3.formatHex)(hsv),
9916
+ foregroundColor: colorForComparison,
9917
+ backgroundOpacity: opacityForContrastCalculation
9918
+ });
9899
9919
  };
9900
9920
  const extremeHsv = getHsvForStep(highStep);
9901
9921
  if (checkContrast(extremeHsv) < minContrast) {
@@ -9924,7 +9944,7 @@ var getAccessibleColorBySaturationAndValueChange = ({
9924
9944
  return bestCandidate;
9925
9945
  };
9926
9946
  var getAccessibleColorInDirection = ({
9927
- originalHsv,
9947
+ originalColor,
9928
9948
  colorForComparison,
9929
9949
  minContrast,
9930
9950
  maxIterations = 50,
@@ -9932,7 +9952,7 @@ var getAccessibleColorInDirection = ({
9932
9952
  opacityForContrastCalculation
9933
9953
  }) => {
9934
9954
  const valueResult = getAccessibleColorByValueChannelChange({
9935
- originalHsv,
9955
+ originalColor,
9936
9956
  colorForComparison,
9937
9957
  minContrast,
9938
9958
  maxIterations,
@@ -9943,7 +9963,7 @@ var getAccessibleColorInDirection = ({
9943
9963
  return valueResult;
9944
9964
  }
9945
9965
  return getAccessibleColorBySaturationAndValueChange({
9946
- originalHsv,
9966
+ originalColor,
9947
9967
  colorForComparison,
9948
9968
  minContrast,
9949
9969
  direction,
@@ -9951,21 +9971,23 @@ var getAccessibleColorInDirection = ({
9951
9971
  });
9952
9972
  };
9953
9973
  var getAccessibleColor = ({
9954
- originalHsv,
9974
+ originalColor,
9955
9975
  colorForComparison,
9956
9976
  minContrast = DEFAULT_MIN_CONTRAST,
9957
9977
  maxIterations = 50,
9958
9978
  opacityForContrastCalculation
9959
9979
  }) => {
9960
- const originalContrast = (0, import_fn3.wcagContrast)(
9961
- compositeOverWhite(originalHsv, opacityForContrastCalculation),
9962
- colorForComparison
9963
- );
9980
+ const originalColorAsHsv = convertToHsv(originalColor);
9981
+ const originalContrast = calculateContrast({
9982
+ backgroundColor: (0, import_fn3.formatHex)(originalColorAsHsv),
9983
+ foregroundColor: colorForComparison,
9984
+ backgroundOpacity: opacityForContrastCalculation
9985
+ });
9964
9986
  if (originalContrast >= minContrast) {
9965
- return originalHsv;
9987
+ return convertToHsv(originalColor);
9966
9988
  }
9967
9989
  const brighterOption = getAccessibleColorInDirection({
9968
- originalHsv,
9990
+ originalColor,
9969
9991
  colorForComparison,
9970
9992
  minContrast,
9971
9993
  maxIterations,
@@ -9973,43 +9995,45 @@ var getAccessibleColor = ({
9973
9995
  opacityForContrastCalculation
9974
9996
  });
9975
9997
  const darkerOption = getAccessibleColorInDirection({
9976
- originalHsv,
9998
+ originalColor,
9977
9999
  colorForComparison,
9978
10000
  minContrast,
9979
10001
  maxIterations,
9980
10002
  direction: "darker",
9981
10003
  opacityForContrastCalculation
9982
10004
  });
9983
- const result = chooseClosestDerivativeToOriginal(brighterOption, darkerOption, originalHsv);
10005
+ const result = chooseClosestDerivativeToOriginal(brighterOption, darkerOption, originalColor);
9984
10006
  if (result == null) {
9985
10007
  throw new Error(
9986
- `Unable to get accessible derivative for ${(0, import_fn3.formatHex)(originalHsv)} at minimum contrast ratio ${minContrast}`
10008
+ `Unable to get accessible derivative for ${(0, import_fn3.formatHex)(originalColor)} at minimum contrast ratio ${minContrast}`
9987
10009
  );
9988
10010
  }
9989
10011
  return result;
9990
10012
  };
9991
10013
  var hasAccessibleDerivatives = ({
9992
- originalHsv,
10014
+ originalColor,
9993
10015
  colorForComparison,
9994
10016
  minContrast = DEFAULT_MIN_CONTRAST,
9995
10017
  opacityForContrastCalculation
9996
10018
  }) => {
9997
- const originalContrast = (0, import_fn3.wcagContrast)(
9998
- compositeOverWhite(originalHsv, opacityForContrastCalculation),
9999
- colorForComparison
10000
- );
10019
+ const originalColorAsHsv = convertToHsv(originalColor);
10020
+ const originalContrast = calculateContrast({
10021
+ backgroundColor: (0, import_fn3.formatHex)(originalColorAsHsv),
10022
+ foregroundColor: colorForComparison,
10023
+ backgroundOpacity: opacityForContrastCalculation
10024
+ });
10001
10025
  if (originalContrast >= minContrast) {
10002
10026
  return true;
10003
10027
  }
10004
10028
  const brighterOption = getAccessibleColorInDirection({
10005
- originalHsv,
10029
+ originalColor,
10006
10030
  colorForComparison,
10007
10031
  minContrast,
10008
10032
  direction: "brighter",
10009
10033
  opacityForContrastCalculation
10010
10034
  });
10011
10035
  const darkerOption = getAccessibleColorInDirection({
10012
- originalHsv,
10036
+ originalColor,
10013
10037
  colorForComparison,
10014
10038
  minContrast,
10015
10039
  direction: "darker",
@@ -10033,27 +10057,28 @@ var ColorPickerProvider = ({
10033
10057
  const [nonDerivedValueAsHsv, setNonDerivedValueAsHsv] = (0, import_react41.useState)(convertToHsv(valueAsHex));
10034
10058
  const [shouldEnforceMinContrast, setShouldEnforceMinContrast] = (0, import_react41.useState)(false);
10035
10059
  const getAccessibleDerivativeColor = (0, import_react41.useCallback)(
10036
- (originalHsv) => getAccessibleColor({
10037
- originalHsv,
10060
+ (originalColor) => getAccessibleColor({
10061
+ originalColor,
10038
10062
  colorForComparison,
10039
10063
  minContrast: minimumContrastRatio,
10040
10064
  opacityForContrastCalculation
10041
10065
  }),
10042
10066
  [colorForComparison, minimumContrastRatio, opacityForContrastCalculation]
10043
10067
  );
10044
- const valueAsHsv = shouldEnforceMinContrast ? getAccessibleDerivativeColor(nonDerivedValueAsHsv) : nonDerivedValueAsHsv;
10045
- const currentContrastRatio = (0, import_fn4.wcagContrast)(
10046
- compositeOverWhite(valueAsHsv, opacityForContrastCalculation),
10047
- colorForComparison
10048
- );
10068
+ const valueAsHsv = shouldEnforceMinContrast ? getAccessibleDerivativeColor((0, import_fn4.formatHex)(nonDerivedValueAsHsv)) : nonDerivedValueAsHsv;
10069
+ const currentContrastRatio = calculateContrast({
10070
+ backgroundColor: valueAsHex,
10071
+ foregroundColor: colorForComparison,
10072
+ backgroundOpacity: opacityForContrastCalculation
10073
+ });
10049
10074
  const hasAccessibleDerivativesValue = (0, import_react41.useMemo)(() => {
10050
10075
  return hasAccessibleDerivatives({
10051
- originalHsv: valueAsHsv,
10076
+ originalColor: valueAsHex,
10052
10077
  colorForComparison,
10053
10078
  minContrast: minimumContrastRatio,
10054
10079
  opacityForContrastCalculation
10055
10080
  });
10056
- }, [valueAsHsv, colorForComparison, minimumContrastRatio, opacityForContrastCalculation]);
10081
+ }, [valueAsHex, colorForComparison, minimumContrastRatio, opacityForContrastCalculation]);
10057
10082
  const onChangeNonDerivedValueAsHsv = (0, import_react41.useCallback)((nonDerivedValue) => {
10058
10083
  setNonDerivedValueAsHsv(nonDerivedValue);
10059
10084
  }, []);
@@ -10077,15 +10102,21 @@ var ColorPickerProvider = ({
10077
10102
  const setShouldEnforceMinContrastWrapped = (0, import_react41.useCallback)(
10078
10103
  (newShouldEnforceMinContrast) => {
10079
10104
  setShouldEnforceMinContrast(newShouldEnforceMinContrast);
10080
- const newColorAsHsv = newShouldEnforceMinContrast ? getAccessibleDerivativeColor(valueAsHsv) : nonDerivedValueAsHsv;
10105
+ const newColorAsHsv = newShouldEnforceMinContrast ? getAccessibleDerivativeColor(valueAsHex) : nonDerivedValueAsHsv;
10081
10106
  const currentHsv = valueAsHsv;
10082
10107
  if (currentHsv.h !== newColorAsHsv.h || currentHsv.s !== newColorAsHsv.s || currentHsv.v !== newColorAsHsv.v) {
10083
10108
  changeValueSmoothly(newColorAsHsv);
10084
10109
  }
10085
10110
  },
10086
- [changeValueSmoothly, getAccessibleDerivativeColor, nonDerivedValueAsHsv, valueAsHsv]
10111
+ [
10112
+ changeValueSmoothly,
10113
+ getAccessibleDerivativeColor,
10114
+ nonDerivedValueAsHsv,
10115
+ valueAsHex,
10116
+ valueAsHsv
10117
+ ]
10087
10118
  );
10088
- const whatValuePropShouldBe = shouldEnforceMinContrast ? (0, import_fn4.formatHex)(getAccessibleDerivativeColor(nonDerivedValueAsHsv)) : (0, import_fn4.formatHex)(nonDerivedValueAsHsv);
10119
+ const whatValuePropShouldBe = shouldEnforceMinContrast ? (0, import_fn4.formatHex)(getAccessibleDerivativeColor((0, import_fn4.formatHex)(nonDerivedValueAsHsv))) : (0, import_fn4.formatHex)(nonDerivedValueAsHsv);
10089
10120
  (0, import_react41.useEffect)(() => {
10090
10121
  if (valueAsHex !== whatValuePropShouldBe && !isTransitioning) {
10091
10122
  onValueChange(whatValuePropShouldBe);
@@ -10716,6 +10747,9 @@ var Container6 = import_styled_components57.default.div`
10716
10747
  justify-content: end;
10717
10748
  align-items: center;
10718
10749
  `;
10750
+ var floorToTenth = (value) => {
10751
+ return Math.floor(value * 10) / 10;
10752
+ };
10719
10753
  var ContrastIndicator = () => {
10720
10754
  const { currentContrastRatio, minimumContrastRatio } = useColorPickerState();
10721
10755
  const isContrastSufficient = currentContrastRatio >= minimumContrastRatio;
@@ -10735,7 +10769,7 @@ var ContrastIndicator = () => {
10735
10769
  renderAs: "span",
10736
10770
  variant: "body4Mono",
10737
10771
  children: [
10738
- currentContrastRatio.toFixed(2),
10772
+ floorToTenth(currentContrastRatio).toFixed(1),
10739
10773
  ":1"
10740
10774
  ]
10741
10775
  }
@@ -11547,11 +11581,13 @@ var calculateContrastCurve = (width, height, hue, minimumContrastRatio, colorFor
11547
11581
  const saturationChanel = x / (width - 1);
11548
11582
  const initialValueChannelForSearch = limit === "upper" ? 0 : 1;
11549
11583
  const colorForXAsHsv = getAccessibleColorByValueChannelChange({
11550
- originalHsv: { h: hue, s: saturationChanel, v: initialValueChannelForSearch, mode: "hsv" },
11584
+ originalColor: { h: hue, s: saturationChanel, v: initialValueChannelForSearch, mode: "hsv" },
11551
11585
  colorForComparison,
11552
11586
  minContrast: minimumContrastRatio,
11553
11587
  direction: limit === "upper" ? "brighter" : "darker",
11554
- opacityForContrastCalculation
11588
+ opacityForContrastCalculation,
11589
+ // We set shouldConvertToHex to false to make the curve smoother.
11590
+ shouldConvertToHex: false
11555
11591
  });
11556
11592
  if (colorForXAsHsv != null) {
11557
11593
  const point = {
@@ -13047,49 +13083,52 @@ var import_styled_components74 = __toESM(require("styled-components"));
13047
13083
  var import_type_guards40 = require("@wistia/type-guards");
13048
13084
  var import_jsx_runtime262 = require("react/jsx-runtime");
13049
13085
  var DEFAULT_ELEMENT5 = "div";
13086
+ var getGridTemplateColumns = (maxColumns, minChildWidth, expandItems) => {
13087
+ if (minChildWidth === "auto" && maxColumns === "auto") {
13088
+ return import_styled_components74.css`
13089
+ grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
13090
+ `;
13091
+ }
13092
+ const gridMode = expandItems ? "auto-fit" : "auto-fill";
13093
+ const minChildWidthValue = minChildWidth === "auto" ? 0 : minChildWidth;
13094
+ if (maxColumns === "auto") {
13095
+ return import_styled_components74.css`
13096
+ grid-template-columns: repeat(${gridMode}, minmax(${minChildWidthValue}px, 1fr));
13097
+ `;
13098
+ }
13099
+ return import_styled_components74.css`
13100
+ /* Adapted from https://9elements.com/blog/building-a-rock-solid-auto-grid/ */
13101
+ --wui-grid-total-column-gap-width: calc(${maxColumns - 1} * var(--wui-grid-column-gap));
13102
+ --wui-grid-max-column-width: calc(
13103
+ (100% - var(--wui-grid-total-column-gap-width)) / ${maxColumns}
13104
+ );
13105
+
13106
+ grid-template-columns: repeat(
13107
+ ${gridMode},
13108
+ minmax(max(${minChildWidthValue}px, var(--wui-grid-max-column-width)), 1fr)
13109
+ );
13110
+ `;
13111
+ };
13050
13112
  var StyledGrid = import_styled_components74.default.div`
13051
13113
  --wui-grid-column-gap: ${({ $columnGap }) => `var(--wui-${$columnGap})`};
13052
13114
  --wui-grid-row-gap: ${({ $rowGap }) => `var(--wui-${$rowGap})`};
13053
- --wui-grid-min-column-size: ${({ $minChildWidth }) => $minChildWidth === "auto" ? "0" : `${$minChildWidth}px`};
13054
- --wui-grid-max-columns: ${({ $maxColumns }) => $maxColumns === "auto" ? "infinity" : $maxColumns};
13055
- --wui-grid-column-gap-count: calc(var(--wui-grid-max-columns) - 1);
13056
- --wui-grid-total-column-gap-width: calc(
13057
- var(--wui-grid-column-gap-count) * var(--wui-grid-column-gap)
13058
- );
13059
- --wui-grid-max-column-width: calc(
13060
- (100% - var(--wui-grid-total-column-gap-width)) / var(--wui-grid-max-columns)
13061
- );
13062
13115
 
13063
13116
  display: grid;
13064
13117
  gap: var(--wui-grid-column-gap) var(--wui-grid-row-gap);
13065
13118
  width: 100%;
13066
13119
 
13067
- ${({ $maxColumns, $minChildWidth }) => {
13068
- if ($maxColumns === "auto" && $minChildWidth === "auto") {
13069
- return import_styled_components74.css`
13070
- grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
13071
- `;
13072
- }
13073
- if ($maxColumns !== "auto" && $minChildWidth === "auto") {
13074
- return import_styled_components74.css`
13075
- grid-template-columns: repeat(${$maxColumns}, minmax(0, 1fr));
13076
- `;
13077
- }
13078
- if ($maxColumns === "auto" && $minChildWidth !== "auto") {
13079
- return import_styled_components74.css`
13080
- grid-template-columns: repeat(auto-fit, minmax(${$minChildWidth}px, 1fr));
13081
- `;
13082
- }
13083
- return import_styled_components74.css`
13084
- grid-template-columns: repeat(
13085
- auto-fit,
13086
- minmax(max(var(--wui-grid-min-column-size), var(--wui-grid-max-column-width)), 1fr)
13087
- );
13088
- `;
13089
- }}
13120
+ ${({ $maxColumns, $minChildWidth, $expandItems }) => getGridTemplateColumns($maxColumns, $minChildWidth, $expandItems)}
13090
13121
  `;
13091
13122
  var GridComponent = (0, import_react61.forwardRef)(
13092
- ({ children, columns = "auto", minChildWidth = "auto", gap = "space-02", renderAs, ...props }, ref) => {
13123
+ ({
13124
+ children,
13125
+ columns = "auto",
13126
+ minChildWidth = "auto",
13127
+ gap = "space-02",
13128
+ expandItems = false,
13129
+ renderAs,
13130
+ ...props
13131
+ }, ref) => {
13093
13132
  const responsiveGap = useResponsiveProp(gap);
13094
13133
  const { column, row } = (0, import_type_guards40.isRecord)(responsiveGap) ? responsiveGap : { column: responsiveGap, row: responsiveGap };
13095
13134
  const responsiveColumns = useResponsiveProp(columns);
@@ -13099,6 +13138,7 @@ var GridComponent = (0, import_react61.forwardRef)(
13099
13138
  {
13100
13139
  ref,
13101
13140
  $columnGap: column,
13141
+ $expandItems: expandItems,
13102
13142
  $maxColumns: responsiveColumns,
13103
13143
  $minChildWidth: responsiveMinChildWidth,
13104
13144
  $rowGap: row,
@@ -16972,6 +17012,7 @@ var ContextMenu = ({
16972
17012
  ValueNameOrHexCode,
16973
17013
  ValueSwatch,
16974
17014
  WistiaLogo,
17015
+ calculateContrast,
16975
17016
  colorSchemeOptions,
16976
17017
  copyToClipboard,
16977
17018
  dateTime,