@liiift-studio/sanity-font-manager 2.3.6 → 2.3.8

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.js CHANGED
@@ -3592,8 +3592,8 @@ var import_icons3 = require("@sanity/icons");
3592
3592
  var import_sanity9 = require("sanity");
3593
3593
  function KeyValueInput({ value = [], onChange }) {
3594
3594
  const [pairs, setPairs] = (0, import_react13.useState)(value);
3595
- const handlePairChange = (0, import_react13.useCallback)((index, field, fieldValue) => {
3596
- const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field]: fieldValue } : pair);
3595
+ const handlePairChange = (0, import_react13.useCallback)((index, field2, fieldValue) => {
3596
+ const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field2]: fieldValue } : pair);
3597
3597
  setPairs(updatedPairs);
3598
3598
  onChange((0, import_sanity9.set)(updatedPairs));
3599
3599
  }, [pairs, onChange]);
@@ -3692,8 +3692,8 @@ function KeyValueReferenceInput(props) {
3692
3692
  setReferenceData(fallback);
3693
3693
  });
3694
3694
  }, [pairs, sanityClient]);
3695
- const handlePairChange = (0, import_react14.useCallback)((index, field, fieldValue) => {
3696
- const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field]: fieldValue } : pair);
3695
+ const handlePairChange = (0, import_react14.useCallback)((index, field2, fieldValue) => {
3696
+ const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field2]: fieldValue } : pair);
3697
3697
  setPairs(updatedPairs);
3698
3698
  onChange((0, import_sanity10.set)(updatedPairs));
3699
3699
  }, [pairs, onChange]);
@@ -6654,6 +6654,7 @@ var stylisticSetField = {
6654
6654
 
6655
6655
  // src/schema/stylesField.js
6656
6656
  var import_sanity_advanced_reference_array = require("sanity-advanced-reference-array");
6657
+ var field = (condition, def) => condition ? [def] : [];
6657
6658
  var fontsFilter = async ({ getClient, document, parent }) => {
6658
6659
  const client = getClient({ apiVersion: "2022-11-09" });
6659
6660
  const typefaceName = document.title;
@@ -6676,20 +6677,31 @@ var variableFontsFilter = async ({ getClient, document, parent }) => {
6676
6677
  params: { existingItems, relatedItemsFiltered }
6677
6678
  };
6678
6679
  };
6680
+ var subfamilyPreferredStyleFilter = async ({ getClient, document, parent }) => {
6681
+ const client = getClient({ apiVersion: "2022-11-09" });
6682
+ const typefaceName = document.title;
6683
+ const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
6684
+ const relatedItemsFiltered = fonts.map((f) => f._id).filter(Boolean);
6685
+ const existingItems = parent.fonts.map((f) => f._ref).filter(Boolean);
6686
+ return {
6687
+ filter: "(_id in $existingItems) && (_id in $relatedItemsFiltered)",
6688
+ params: { existingItems, relatedItemsFiltered }
6689
+ };
6690
+ };
6679
6691
  function createStylesField({
6680
- hasFreeFlag = false,
6681
- displayStylesHidden = false,
6682
- hasSortHeaviestFirst = false,
6683
- hasBuySectionColumns = false,
6684
- hasFontSizeMultiplier = false,
6685
- hasSerifFlag = false,
6686
- hasRegenerateSubfamilies = false,
6687
- hasSubfamilyFontSizeMultiplier = false,
6688
- hasSubfamilyUseListOrder = false,
6689
- hasSubfamilyPreferredStyle = false,
6690
- hasSubfamilyFontFilter = false,
6691
- hasSubfamilyPreview = false,
6692
- pairsHidden = false
6692
+ free = false,
6693
+ displayStyles = true,
6694
+ sortHeaviestFirst = false,
6695
+ buySectionColumns = false,
6696
+ fontSizeMultiplier = false,
6697
+ serif = false,
6698
+ regenerateSubfamilies: regenerateSubfamilies2 = false,
6699
+ subfamilyFontSizeMultiplier = false,
6700
+ subfamilyListOrder = false,
6701
+ subfamilyPreferredStyle = false,
6702
+ subfamilyFontFilter = false,
6703
+ subfamilyPreview = false,
6704
+ pairs = true
6693
6705
  } = {}) {
6694
6706
  const subfamilyFields = [
6695
6707
  {
@@ -6697,21 +6709,21 @@ function createStylesField({
6697
6709
  name: "title",
6698
6710
  type: "string"
6699
6711
  },
6700
- ...hasSubfamilyFontSizeMultiplier ? [{
6712
+ ...field(subfamilyFontSizeMultiplier, {
6701
6713
  title: "Subfamily Font Size Multiplier",
6702
6714
  name: "fontSizeMultiplier",
6703
6715
  type: "number",
6704
6716
  initialValue: 1,
6705
6717
  description: "Adjust font size for this subfamily in the Family Overview (Design Space). Default is 1.0 (100%). Range: 0.5 to 2.0",
6706
6718
  validation: (Rule) => Rule.min(0.5).max(2).precision(2)
6707
- }] : [],
6708
- ...hasSubfamilyUseListOrder ? [{
6719
+ }),
6720
+ ...field(subfamilyListOrder, {
6709
6721
  title: "Use List Order",
6710
6722
  name: "useListOrder",
6711
6723
  type: "boolean",
6712
6724
  initialValue: false,
6713
6725
  description: "Display fonts in the manual order listed below, bypassing programmatic weight-based sorting in the Family Overview."
6714
- }] : [],
6726
+ }),
6715
6727
  {
6716
6728
  title: "Fonts",
6717
6729
  name: "fonts",
@@ -6720,88 +6732,75 @@ function createStylesField({
6720
6732
  of: [{ type: "reference", weak: true, to: [{ type: "font" }] }],
6721
6733
  options: {
6722
6734
  sortable: true,
6723
- ...hasSubfamilyFontFilter ? { filter: fontsFilter } : {}
6735
+ ...subfamilyFontFilter ? { filter: fontsFilter } : {}
6724
6736
  }
6725
6737
  },
6726
- ...hasSubfamilyPreferredStyle ? [{
6727
- title: "SubFamily Preferred Style",
6738
+ ...field(subfamilyPreferredStyle, {
6739
+ title: "Subfamily Preferred Style",
6728
6740
  name: "preferredStyle",
6729
6741
  type: "reference",
6730
6742
  weak: true,
6731
6743
  to: [{ type: "font" }],
6732
- options: {
6733
- filter: async ({ getClient, document, parent }) => {
6734
- const client = getClient({ apiVersion: "2022-11-09" });
6735
- const typefaceName = document.title;
6736
- const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
6737
- const relatedItemsFiltered = fonts.map((f) => f._id).filter(Boolean);
6738
- const existingItems = parent.fonts.map((f) => f._ref).filter(Boolean);
6739
- return {
6740
- filter: "(_id in $existingItems) && (_id in $relatedItemsFiltered)",
6741
- params: { existingItems, relatedItemsFiltered }
6742
- };
6743
- }
6744
- }
6745
- }] : []
6744
+ options: { filter: subfamilyPreferredStyleFilter }
6745
+ })
6746
6746
  ];
6747
6747
  const subfamilyItem = {
6748
6748
  type: "object",
6749
6749
  fields: subfamilyFields,
6750
- ...hasSubfamilyPreview ? {
6750
+ ...subfamilyPreview ? {
6751
6751
  preview: {
6752
6752
  select: { title: "title", fonts: "fonts" },
6753
- prepare(props) {
6754
- const numFonts = Object.keys(props.fonts || {}).length;
6755
- return { title: props.title, subtitle: `${numFonts} fonts` };
6753
+ prepare({ title, fonts }) {
6754
+ return { title, subtitle: `${Object.keys(fonts || {}).length} fonts` };
6756
6755
  }
6757
6756
  }
6758
6757
  } : {}
6759
6758
  };
6760
6759
  const fields = [
6761
- ...hasFreeFlag ? [{
6760
+ ...field(free, {
6762
6761
  title: "Free Typeface",
6763
6762
  name: "free",
6764
6763
  type: "boolean",
6765
- description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.',
6766
- initialValue: false
6767
- }] : [],
6764
+ initialValue: false,
6765
+ description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.'
6766
+ }),
6768
6767
  {
6769
6768
  title: "Display All Styles",
6770
6769
  name: "displayStyles",
6771
6770
  type: "boolean",
6772
6771
  initialValue: true,
6773
- hidden: displayStylesHidden,
6772
+ hidden: !displayStyles,
6774
6773
  description: "Show all Font Styles below collections in Buy Section"
6775
6774
  },
6776
- ...hasSortHeaviestFirst ? [{
6775
+ ...field(sortHeaviestFirst, {
6777
6776
  title: "Sort Fonts Heaviest to Lightest",
6778
6777
  name: "sortHeaviestFirst",
6779
6778
  type: "boolean",
6780
6779
  initialValue: false,
6781
6780
  description: "Sort fonts by weight from heaviest (900) to lightest (100). Default is lightest to heaviest (industry standard)."
6782
- }] : [],
6783
- ...hasBuySectionColumns ? [{
6781
+ }),
6782
+ ...field(buySectionColumns, {
6784
6783
  title: "Multi Column Buy Section",
6785
6784
  name: "buySectionColumns",
6786
6785
  type: "boolean",
6787
6786
  initialValue: true,
6788
6787
  description: "Choose Single Column or Multi Column for the Buy Section, Default is Multi Column"
6789
- }] : [],
6790
- ...hasFontSizeMultiplier ? [{
6788
+ }),
6789
+ ...field(fontSizeMultiplier, {
6791
6790
  title: "Style Grid Font Size Multiplier",
6792
6791
  name: "fontSizeMultiplier",
6793
6792
  type: "number",
6794
6793
  initialValue: 1,
6795
6794
  description: "Adjust font size in the buy section style grid. Default is 1.0 (100%). Range: 0.5 to 2.0",
6796
6795
  validation: (Rule) => Rule.min(0.5).max(2).precision(2)
6797
- }] : [],
6798
- ...hasSerifFlag ? [{
6796
+ }),
6797
+ ...field(serif, {
6799
6798
  title: "Includes Serifs",
6800
6799
  name: "serif",
6801
6800
  type: "boolean",
6802
6801
  initialValue: false,
6803
6802
  description: "Check if this typeface includes serif letterforms. Used for typeface overview serif/sans filters. Frontend automatically treats non-serif typefaces as sans serif."
6804
- }] : [],
6803
+ }),
6805
6804
  {
6806
6805
  title: "Fonts",
6807
6806
  name: "fonts",
@@ -6829,7 +6828,7 @@ function createStylesField({
6829
6828
  description: "Variable fonts are automatically included as a bonus when customers purchase all non-variable styles of this typeface.",
6830
6829
  options: { sortable: true }
6831
6830
  },
6832
- ...hasRegenerateSubfamilies ? [{
6831
+ ...field(regenerateSubfamilies2, {
6833
6832
  title: "Regenerate Subfamilies",
6834
6833
  name: "regenerateSubfamilies",
6835
6834
  type: "string",
@@ -6839,9 +6838,9 @@ function createStylesField({
6839
6838
  },
6840
6839
  description: "Regenerates subfamily groups based on the fonts in this typeface.",
6841
6840
  components: { input: RegenerateSubfamiliesComponent }
6842
- }] : [],
6841
+ }),
6843
6842
  {
6844
- title: "Sub Families",
6843
+ title: "Subfamilies",
6845
6844
  name: "subfamilies",
6846
6845
  type: "array",
6847
6846
  of: [subfamilyItem]
@@ -6863,7 +6862,7 @@ function createStylesField({
6863
6862
  of: [{ type: "reference", weak: true, to: [{ type: "pair" }] }],
6864
6863
  options: { sortable: true },
6865
6864
  validation: (Rule) => Rule.unique(),
6866
- hidden: pairsHidden
6865
+ hidden: !pairs
6867
6866
  }
6868
6867
  ];
6869
6868
  return {
package/dist/index.mjs CHANGED
@@ -3506,8 +3506,8 @@ import { AddIcon, ArrowDownIcon, ArrowUpIcon, TrashIcon as TrashIcon3 } from "@s
3506
3506
  import { set as set4 } from "sanity";
3507
3507
  function KeyValueInput({ value = [], onChange }) {
3508
3508
  const [pairs, setPairs] = useState8(value);
3509
- const handlePairChange = useCallback7((index, field, fieldValue) => {
3510
- const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field]: fieldValue } : pair);
3509
+ const handlePairChange = useCallback7((index, field2, fieldValue) => {
3510
+ const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field2]: fieldValue } : pair);
3511
3511
  setPairs(updatedPairs);
3512
3512
  onChange(set4(updatedPairs));
3513
3513
  }, [pairs, onChange]);
@@ -3606,8 +3606,8 @@ function KeyValueReferenceInput(props) {
3606
3606
  setReferenceData(fallback);
3607
3607
  });
3608
3608
  }, [pairs, sanityClient]);
3609
- const handlePairChange = useCallback8((index, field, fieldValue) => {
3610
- const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field]: fieldValue } : pair);
3609
+ const handlePairChange = useCallback8((index, field2, fieldValue) => {
3610
+ const updatedPairs = pairs.map((pair, idx) => idx === index ? { ...pair, [field2]: fieldValue } : pair);
3611
3611
  setPairs(updatedPairs);
3612
3612
  onChange(set5(updatedPairs));
3613
3613
  }, [pairs, onChange]);
@@ -6568,6 +6568,7 @@ var stylisticSetField = {
6568
6568
 
6569
6569
  // src/schema/stylesField.js
6570
6570
  import { AdvancedRefArray } from "sanity-advanced-reference-array";
6571
+ var field = (condition, def) => condition ? [def] : [];
6571
6572
  var fontsFilter = async ({ getClient, document, parent }) => {
6572
6573
  const client = getClient({ apiVersion: "2022-11-09" });
6573
6574
  const typefaceName = document.title;
@@ -6590,20 +6591,31 @@ var variableFontsFilter = async ({ getClient, document, parent }) => {
6590
6591
  params: { existingItems, relatedItemsFiltered }
6591
6592
  };
6592
6593
  };
6594
+ var subfamilyPreferredStyleFilter = async ({ getClient, document, parent }) => {
6595
+ const client = getClient({ apiVersion: "2022-11-09" });
6596
+ const typefaceName = document.title;
6597
+ const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
6598
+ const relatedItemsFiltered = fonts.map((f) => f._id).filter(Boolean);
6599
+ const existingItems = parent.fonts.map((f) => f._ref).filter(Boolean);
6600
+ return {
6601
+ filter: "(_id in $existingItems) && (_id in $relatedItemsFiltered)",
6602
+ params: { existingItems, relatedItemsFiltered }
6603
+ };
6604
+ };
6593
6605
  function createStylesField({
6594
- hasFreeFlag = false,
6595
- displayStylesHidden = false,
6596
- hasSortHeaviestFirst = false,
6597
- hasBuySectionColumns = false,
6598
- hasFontSizeMultiplier = false,
6599
- hasSerifFlag = false,
6600
- hasRegenerateSubfamilies = false,
6601
- hasSubfamilyFontSizeMultiplier = false,
6602
- hasSubfamilyUseListOrder = false,
6603
- hasSubfamilyPreferredStyle = false,
6604
- hasSubfamilyFontFilter = false,
6605
- hasSubfamilyPreview = false,
6606
- pairsHidden = false
6606
+ free = false,
6607
+ displayStyles = true,
6608
+ sortHeaviestFirst = false,
6609
+ buySectionColumns = false,
6610
+ fontSizeMultiplier = false,
6611
+ serif = false,
6612
+ regenerateSubfamilies: regenerateSubfamilies2 = false,
6613
+ subfamilyFontSizeMultiplier = false,
6614
+ subfamilyListOrder = false,
6615
+ subfamilyPreferredStyle = false,
6616
+ subfamilyFontFilter = false,
6617
+ subfamilyPreview = false,
6618
+ pairs = true
6607
6619
  } = {}) {
6608
6620
  const subfamilyFields = [
6609
6621
  {
@@ -6611,21 +6623,21 @@ function createStylesField({
6611
6623
  name: "title",
6612
6624
  type: "string"
6613
6625
  },
6614
- ...hasSubfamilyFontSizeMultiplier ? [{
6626
+ ...field(subfamilyFontSizeMultiplier, {
6615
6627
  title: "Subfamily Font Size Multiplier",
6616
6628
  name: "fontSizeMultiplier",
6617
6629
  type: "number",
6618
6630
  initialValue: 1,
6619
6631
  description: "Adjust font size for this subfamily in the Family Overview (Design Space). Default is 1.0 (100%). Range: 0.5 to 2.0",
6620
6632
  validation: (Rule) => Rule.min(0.5).max(2).precision(2)
6621
- }] : [],
6622
- ...hasSubfamilyUseListOrder ? [{
6633
+ }),
6634
+ ...field(subfamilyListOrder, {
6623
6635
  title: "Use List Order",
6624
6636
  name: "useListOrder",
6625
6637
  type: "boolean",
6626
6638
  initialValue: false,
6627
6639
  description: "Display fonts in the manual order listed below, bypassing programmatic weight-based sorting in the Family Overview."
6628
- }] : [],
6640
+ }),
6629
6641
  {
6630
6642
  title: "Fonts",
6631
6643
  name: "fonts",
@@ -6634,88 +6646,75 @@ function createStylesField({
6634
6646
  of: [{ type: "reference", weak: true, to: [{ type: "font" }] }],
6635
6647
  options: {
6636
6648
  sortable: true,
6637
- ...hasSubfamilyFontFilter ? { filter: fontsFilter } : {}
6649
+ ...subfamilyFontFilter ? { filter: fontsFilter } : {}
6638
6650
  }
6639
6651
  },
6640
- ...hasSubfamilyPreferredStyle ? [{
6641
- title: "SubFamily Preferred Style",
6652
+ ...field(subfamilyPreferredStyle, {
6653
+ title: "Subfamily Preferred Style",
6642
6654
  name: "preferredStyle",
6643
6655
  type: "reference",
6644
6656
  weak: true,
6645
6657
  to: [{ type: "font" }],
6646
- options: {
6647
- filter: async ({ getClient, document, parent }) => {
6648
- const client = getClient({ apiVersion: "2022-11-09" });
6649
- const typefaceName = document.title;
6650
- const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
6651
- const relatedItemsFiltered = fonts.map((f) => f._id).filter(Boolean);
6652
- const existingItems = parent.fonts.map((f) => f._ref).filter(Boolean);
6653
- return {
6654
- filter: "(_id in $existingItems) && (_id in $relatedItemsFiltered)",
6655
- params: { existingItems, relatedItemsFiltered }
6656
- };
6657
- }
6658
- }
6659
- }] : []
6658
+ options: { filter: subfamilyPreferredStyleFilter }
6659
+ })
6660
6660
  ];
6661
6661
  const subfamilyItem = {
6662
6662
  type: "object",
6663
6663
  fields: subfamilyFields,
6664
- ...hasSubfamilyPreview ? {
6664
+ ...subfamilyPreview ? {
6665
6665
  preview: {
6666
6666
  select: { title: "title", fonts: "fonts" },
6667
- prepare(props) {
6668
- const numFonts = Object.keys(props.fonts || {}).length;
6669
- return { title: props.title, subtitle: `${numFonts} fonts` };
6667
+ prepare({ title, fonts }) {
6668
+ return { title, subtitle: `${Object.keys(fonts || {}).length} fonts` };
6670
6669
  }
6671
6670
  }
6672
6671
  } : {}
6673
6672
  };
6674
6673
  const fields = [
6675
- ...hasFreeFlag ? [{
6674
+ ...field(free, {
6676
6675
  title: "Free Typeface",
6677
6676
  name: "free",
6678
6677
  type: "boolean",
6679
- description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.',
6680
- initialValue: false
6681
- }] : [],
6678
+ initialValue: false,
6679
+ description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.'
6680
+ }),
6682
6681
  {
6683
6682
  title: "Display All Styles",
6684
6683
  name: "displayStyles",
6685
6684
  type: "boolean",
6686
6685
  initialValue: true,
6687
- hidden: displayStylesHidden,
6686
+ hidden: !displayStyles,
6688
6687
  description: "Show all Font Styles below collections in Buy Section"
6689
6688
  },
6690
- ...hasSortHeaviestFirst ? [{
6689
+ ...field(sortHeaviestFirst, {
6691
6690
  title: "Sort Fonts Heaviest to Lightest",
6692
6691
  name: "sortHeaviestFirst",
6693
6692
  type: "boolean",
6694
6693
  initialValue: false,
6695
6694
  description: "Sort fonts by weight from heaviest (900) to lightest (100). Default is lightest to heaviest (industry standard)."
6696
- }] : [],
6697
- ...hasBuySectionColumns ? [{
6695
+ }),
6696
+ ...field(buySectionColumns, {
6698
6697
  title: "Multi Column Buy Section",
6699
6698
  name: "buySectionColumns",
6700
6699
  type: "boolean",
6701
6700
  initialValue: true,
6702
6701
  description: "Choose Single Column or Multi Column for the Buy Section, Default is Multi Column"
6703
- }] : [],
6704
- ...hasFontSizeMultiplier ? [{
6702
+ }),
6703
+ ...field(fontSizeMultiplier, {
6705
6704
  title: "Style Grid Font Size Multiplier",
6706
6705
  name: "fontSizeMultiplier",
6707
6706
  type: "number",
6708
6707
  initialValue: 1,
6709
6708
  description: "Adjust font size in the buy section style grid. Default is 1.0 (100%). Range: 0.5 to 2.0",
6710
6709
  validation: (Rule) => Rule.min(0.5).max(2).precision(2)
6711
- }] : [],
6712
- ...hasSerifFlag ? [{
6710
+ }),
6711
+ ...field(serif, {
6713
6712
  title: "Includes Serifs",
6714
6713
  name: "serif",
6715
6714
  type: "boolean",
6716
6715
  initialValue: false,
6717
6716
  description: "Check if this typeface includes serif letterforms. Used for typeface overview serif/sans filters. Frontend automatically treats non-serif typefaces as sans serif."
6718
- }] : [],
6717
+ }),
6719
6718
  {
6720
6719
  title: "Fonts",
6721
6720
  name: "fonts",
@@ -6743,7 +6742,7 @@ function createStylesField({
6743
6742
  description: "Variable fonts are automatically included as a bonus when customers purchase all non-variable styles of this typeface.",
6744
6743
  options: { sortable: true }
6745
6744
  },
6746
- ...hasRegenerateSubfamilies ? [{
6745
+ ...field(regenerateSubfamilies2, {
6747
6746
  title: "Regenerate Subfamilies",
6748
6747
  name: "regenerateSubfamilies",
6749
6748
  type: "string",
@@ -6753,9 +6752,9 @@ function createStylesField({
6753
6752
  },
6754
6753
  description: "Regenerates subfamily groups based on the fonts in this typeface.",
6755
6754
  components: { input: RegenerateSubfamiliesComponent }
6756
- }] : [],
6755
+ }),
6757
6756
  {
6758
- title: "Sub Families",
6757
+ title: "Subfamilies",
6759
6758
  name: "subfamilies",
6760
6759
  type: "array",
6761
6760
  of: [subfamilyItem]
@@ -6777,7 +6776,7 @@ function createStylesField({
6777
6776
  of: [{ type: "reference", weak: true, to: [{ type: "pair" }] }],
6778
6777
  options: { sortable: true },
6779
6778
  validation: (Rule) => Rule.unique(),
6780
- hidden: pairsHidden
6779
+ hidden: !pairs
6781
6780
  }
6782
6781
  ];
6783
6782
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/sanity-font-manager",
3
- "version": "2.3.6",
3
+ "version": "2.3.8",
4
4
  "description": "Sanity Studio plugin — full font management suite with batch upload, format conversion, metadata extraction, CSS generation, collection/pair generation, and script variant support. Supports Sanity v3, v4, and v5.",
5
5
  "license": "MIT",
6
6
  "author": "Liiift Studio",
@@ -2,7 +2,10 @@
2
2
  import { AdvancedRefArray } from 'sanity-advanced-reference-array';
3
3
  import { RegenerateSubfamiliesComponent } from '../components/RegenerateSubfamiliesComponent.jsx';
4
4
 
5
- // Shared GROQ filter returns fonts from the same typeface, excluding items already in the array
5
+ // Conditionally includes a field definition in an array
6
+ const field = (condition, def) => condition ? [def] : [];
7
+
8
+ // GROQ filter — fonts from the same typeface, excluding items already in the array
6
9
  const fontsFilter = async ({ getClient, document, parent }) => {
7
10
  const client = getClient({ apiVersion: '2022-11-09' });
8
11
  const typefaceName = document.title;
@@ -15,7 +18,7 @@ const fontsFilter = async ({ getClient, document, parent }) => {
15
18
  };
16
19
  };
17
20
 
18
- // Shared GROQ filter — returns variable fonts from the same typeface, excluding items already in the array
21
+ // GROQ filter — variable fonts from the same typeface, excluding items already in the array
19
22
  const variableFontsFilter = async ({ getClient, document, parent }) => {
20
23
  const client = getClient({ apiVersion: '2022-11-09' });
21
24
  const typefaceName = document.title;
@@ -28,61 +31,73 @@ const variableFontsFilter = async ({ getClient, document, parent }) => {
28
31
  };
29
32
  };
30
33
 
34
+ // GROQ filter — non-variable fonts already in the subfamily's fonts array, for preferred style picker
35
+ const subfamilyPreferredStyleFilter = async ({ getClient, document, parent }) => {
36
+ const client = getClient({ apiVersion: '2022-11-09' });
37
+ const typefaceName = document.title;
38
+ const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
39
+ const relatedItemsFiltered = fonts.map(f => f._id).filter(Boolean);
40
+ const existingItems = parent.fonts.map(f => f._ref).filter(Boolean);
41
+ return {
42
+ filter: '(_id in $existingItems) && (_id in $relatedItemsFiltered)',
43
+ params: { existingItems, relatedItemsFiltered },
44
+ };
45
+ };
46
+
31
47
  /**
32
48
  * Generates the Styles object field for a typeface document with configurable per-site options.
33
- * @param {Object} options
34
- * @param {boolean} [options.hasFreeFlag=false] - Add a "Free Typeface" boolean field (MCKL)
35
- * @param {boolean} [options.displayStylesHidden=false] - Hide the displayStyles boolean from editors (Darden, MCKL)
36
- * @param {boolean} [options.hasSortHeaviestFirst=false] - Add sort order toggle (TDF)
37
- * @param {boolean} [options.hasBuySectionColumns=false] - Add multi-column buy section toggle (TDF)
38
- * @param {boolean} [options.hasFontSizeMultiplier=false] - Add style grid font size multiplier (TDF)
39
- * @param {boolean} [options.hasSerifFlag=false] - Add serif/sans classification flag (TDF)
40
- * @param {boolean} [options.hasRegenerateSubfamilies=false] - Add the RegenerateSubfamilies action field (TDF, MCKL)
41
- * @param {boolean} [options.hasSubfamilyFontSizeMultiplier=false] - Add per-subfamily font size multiplier (TDF)
42
- * @param {boolean} [options.hasSubfamilyUseListOrder=false] - Add per-subfamily manual order toggle (TDF)
43
- * @param {boolean} [options.hasSubfamilyPreferredStyle=false] - Add per-subfamily preferred style reference (TDF)
44
- * @param {boolean} [options.hasSubfamilyFontFilter=false] - Filter subfamily font picker to typeface fonts only (TDF)
45
- * @param {boolean} [options.hasSubfamilyPreview=false] - Add preview to subfamily array items showing font count (MCKL)
46
- * @param {boolean} [options.pairsHidden=false] - Hide the pairs array from editors (Darden)
49
+ * @param {Object} [options]
50
+ * @param {boolean} [options.free=false] - Include "Free Typeface" boolean
51
+ * @param {boolean} [options.displayStyles=true] - Show "Display All Styles" toggle to editors
52
+ * @param {boolean} [options.sortHeaviestFirst=false] - Include sort order toggle
53
+ * @param {boolean} [options.buySectionColumns=false] - Include multi-column buy section toggle
54
+ * @param {boolean} [options.fontSizeMultiplier=false] - Include style grid font size multiplier
55
+ * @param {boolean} [options.serif=false] - Include serif/sans classification field
56
+ * @param {boolean} [options.regenerateSubfamilies=false] - Include RegenerateSubfamilies action
57
+ * @param {boolean} [options.subfamilyFontSizeMultiplier=false] - Include per-subfamily font size multiplier
58
+ * @param {boolean} [options.subfamilyListOrder=false] - Include per-subfamily manual order toggle
59
+ * @param {boolean} [options.subfamilyPreferredStyle=false] - Include per-subfamily preferred style picker
60
+ * @param {boolean} [options.subfamilyFontFilter=false] - Filter subfamily font picker to typeface fonts only
61
+ * @param {boolean} [options.subfamilyPreview=false] - Include preview on subfamily array items
62
+ * @param {boolean} [options.pairs=true] - Show pairs array to editors
47
63
  */
48
64
  export function createStylesField({
49
- hasFreeFlag = false,
50
- displayStylesHidden = false,
51
- hasSortHeaviestFirst = false,
52
- hasBuySectionColumns = false,
53
- hasFontSizeMultiplier = false,
54
- hasSerifFlag = false,
55
- hasRegenerateSubfamilies = false,
56
- hasSubfamilyFontSizeMultiplier = false,
57
- hasSubfamilyUseListOrder = false,
58
- hasSubfamilyPreferredStyle = false,
59
- hasSubfamilyFontFilter = false,
60
- hasSubfamilyPreview = false,
61
- pairsHidden = false,
65
+ free = false,
66
+ displayStyles = true,
67
+ sortHeaviestFirst = false,
68
+ buySectionColumns = false,
69
+ fontSizeMultiplier = false,
70
+ serif = false,
71
+ regenerateSubfamilies = false,
72
+ subfamilyFontSizeMultiplier = false,
73
+ subfamilyListOrder = false,
74
+ subfamilyPreferredStyle = false,
75
+ subfamilyFontFilter = false,
76
+ subfamilyPreview = false,
77
+ pairs = true,
62
78
  } = {}) {
63
79
 
64
- // Build the subfamily object item fields conditionally
65
80
  const subfamilyFields = [
66
81
  {
67
82
  title: 'Title',
68
83
  name: 'title',
69
84
  type: 'string',
70
85
  },
71
- ...(hasSubfamilyFontSizeMultiplier ? [{
86
+ ...field(subfamilyFontSizeMultiplier, {
72
87
  title: 'Subfamily Font Size Multiplier',
73
88
  name: 'fontSizeMultiplier',
74
89
  type: 'number',
75
- initialValue: 1.0,
90
+ initialValue: 1,
76
91
  description: 'Adjust font size for this subfamily in the Family Overview (Design Space). Default is 1.0 (100%). Range: 0.5 to 2.0',
77
92
  validation: Rule => Rule.min(0.5).max(2.0).precision(2),
78
- }] : []),
79
- ...(hasSubfamilyUseListOrder ? [{
93
+ }),
94
+ ...field(subfamilyListOrder, {
80
95
  title: 'Use List Order',
81
96
  name: 'useListOrder',
82
97
  type: 'boolean',
83
98
  initialValue: false,
84
99
  description: 'Display fonts in the manual order listed below, bypassing programmatic weight-based sorting in the Family Overview.',
85
- }] : []),
100
+ }),
86
101
  {
87
102
  title: 'Fonts',
88
103
  name: 'fonts',
@@ -91,90 +106,77 @@ export function createStylesField({
91
106
  of: [{ type: 'reference', weak: true, to: [{ type: 'font' }] }],
92
107
  options: {
93
108
  sortable: true,
94
- ...(hasSubfamilyFontFilter ? { filter: fontsFilter } : {}),
109
+ ...(subfamilyFontFilter ? { filter: fontsFilter } : {}),
95
110
  },
96
111
  },
97
- ...(hasSubfamilyPreferredStyle ? [{
98
- title: 'SubFamily Preferred Style',
112
+ ...field(subfamilyPreferredStyle, {
113
+ title: 'Subfamily Preferred Style',
99
114
  name: 'preferredStyle',
100
115
  type: 'reference',
101
116
  weak: true,
102
117
  to: [{ type: 'font' }],
103
- options: {
104
- filter: async ({ getClient, document, parent }) => {
105
- const client = getClient({ apiVersion: '2022-11-09' });
106
- const typefaceName = document.title;
107
- const fonts = await client.fetch('*[_type == "font" && typefaceName == $typefaceName && variableFont == false]', { typefaceName });
108
- const relatedItemsFiltered = fonts.map(f => f._id).filter(Boolean);
109
- const existingItems = parent.fonts.map(f => f._ref).filter(Boolean);
110
- return {
111
- filter: '(_id in $existingItems) && (_id in $relatedItemsFiltered)',
112
- params: { existingItems, relatedItemsFiltered },
113
- };
114
- },
115
- },
116
- }] : []),
118
+ options: { filter: subfamilyPreferredStyleFilter },
119
+ }),
117
120
  ];
118
121
 
119
122
  const subfamilyItem = {
120
123
  type: 'object',
121
124
  fields: subfamilyFields,
122
- ...(hasSubfamilyPreview ? {
125
+ ...(subfamilyPreview ? {
123
126
  preview: {
124
127
  select: { title: 'title', fonts: 'fonts' },
125
- prepare(props) {
126
- const numFonts = Object.keys(props.fonts || {}).length;
127
- return { title: props.title, subtitle: `${numFonts} fonts` };
128
+ prepare({ title, fonts }) {
129
+ return { title, subtitle: `${Object.keys(fonts || {}).length} fonts` };
128
130
  },
129
131
  },
130
132
  } : {}),
131
133
  };
132
134
 
133
135
  const fields = [
134
- ...(hasFreeFlag ? [{
136
+ ...field(free, {
135
137
  title: 'Free Typeface',
136
138
  name: 'free',
137
139
  type: 'boolean',
138
- description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.',
139
140
  initialValue: false,
140
- }] : []),
141
+ description: 'This typeface is free to download and use. This will alter the "Buy" button and checkout experience.',
142
+ }),
141
143
  {
142
144
  title: 'Display All Styles',
143
145
  name: 'displayStyles',
144
146
  type: 'boolean',
145
147
  initialValue: true,
146
- hidden: displayStylesHidden,
148
+ hidden: !displayStyles,
147
149
  description: 'Show all Font Styles below collections in Buy Section',
148
150
  },
149
- ...(hasSortHeaviestFirst ? [{
151
+ ...field(sortHeaviestFirst, {
150
152
  title: 'Sort Fonts Heaviest to Lightest',
151
153
  name: 'sortHeaviestFirst',
152
154
  type: 'boolean',
153
155
  initialValue: false,
154
156
  description: 'Sort fonts by weight from heaviest (900) to lightest (100). Default is lightest to heaviest (industry standard).',
155
- }] : []),
156
- ...(hasBuySectionColumns ? [{
157
+ }),
158
+ ...field(buySectionColumns, {
157
159
  title: 'Multi Column Buy Section',
158
160
  name: 'buySectionColumns',
159
161
  type: 'boolean',
160
162
  initialValue: true,
161
163
  description: 'Choose Single Column or Multi Column for the Buy Section, Default is Multi Column',
162
- }] : []),
163
- ...(hasFontSizeMultiplier ? [{
164
+ }),
165
+ ...field(fontSizeMultiplier, {
164
166
  title: 'Style Grid Font Size Multiplier',
165
167
  name: 'fontSizeMultiplier',
166
168
  type: 'number',
167
- initialValue: 1.0,
169
+ initialValue: 1,
168
170
  description: 'Adjust font size in the buy section style grid. Default is 1.0 (100%). Range: 0.5 to 2.0',
169
171
  validation: Rule => Rule.min(0.5).max(2.0).precision(2),
170
- }] : []),
171
- ...(hasSerifFlag ? [{
172
+ }),
173
+ ...field(serif, {
172
174
  title: 'Includes Serifs',
173
175
  name: 'serif',
174
176
  type: 'boolean',
175
177
  initialValue: false,
176
178
  description: 'Check if this typeface includes serif letterforms. Used for typeface overview serif/sans filters. Frontend automatically treats non-serif typefaces as sans serif.',
177
- }] : []),
179
+ }),
178
180
  {
179
181
  title: 'Fonts',
180
182
  name: 'fonts',
@@ -202,18 +204,16 @@ export function createStylesField({
202
204
  description: 'Variable fonts are automatically included as a bonus when customers purchase all non-variable styles of this typeface.',
203
205
  options: { sortable: true },
204
206
  },
205
- ...(hasRegenerateSubfamilies ? [{
207
+ ...field(regenerateSubfamilies, {
206
208
  title: 'Regenerate Subfamilies',
207
209
  name: 'regenerateSubfamilies',
208
210
  type: 'string',
209
- hidden: ({ parent }) => {
210
- return parent?.styles?.subfamilies?.length === 0 || parent?.styles?.fonts?.length === 0;
211
- },
211
+ hidden: ({ parent }) => parent?.styles?.subfamilies?.length === 0 || parent?.styles?.fonts?.length === 0,
212
212
  description: 'Regenerates subfamily groups based on the fonts in this typeface.',
213
213
  components: { input: RegenerateSubfamiliesComponent },
214
- }] : []),
214
+ }),
215
215
  {
216
- title: 'Sub Families',
216
+ title: 'Subfamilies',
217
217
  name: 'subfamilies',
218
218
  type: 'array',
219
219
  of: [subfamilyItem],
@@ -235,7 +235,7 @@ export function createStylesField({
235
235
  of: [{ type: 'reference', weak: true, to: [{ type: 'pair' }] }],
236
236
  options: { sortable: true },
237
237
  validation: Rule => Rule.unique(),
238
- hidden: pairsHidden,
238
+ hidden: !pairs,
239
239
  },
240
240
  ];
241
241