fontdue-js 2.8.3 → 2.9.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.
Files changed (28) hide show
  1. package/dist/__generated__/CharacterViewerIDQuery.graphql.d.ts +1 -1
  2. package/dist/__generated__/CharacterViewerIDQuery.graphql.js +153 -115
  3. package/dist/__generated__/CharacterViewerSlugQuery.graphql.d.ts +1 -1
  4. package/dist/__generated__/CharacterViewerSlugQuery.graphql.js +157 -114
  5. package/dist/__generated__/CharacterViewerStyleRefetchQuery.graphql.d.ts +21 -0
  6. package/dist/__generated__/CharacterViewerStyleRefetchQuery.graphql.js +205 -0
  7. package/dist/__generated__/CharacterViewer_collection.graphql.d.ts +18 -53
  8. package/dist/__generated__/CharacterViewer_collection.graphql.js +95 -111
  9. package/dist/__generated__/CharacterViewer_family.graphql.d.ts +1 -23
  10. package/dist/__generated__/CharacterViewer_family.graphql.js +3 -89
  11. package/dist/__generated__/CharacterViewer_style.graphql.d.ts +39 -0
  12. package/dist/__generated__/CharacterViewer_style.graphql.js +157 -0
  13. package/dist/__generated__/StoreModalIndexQuery.graphql.d.ts +1 -1
  14. package/dist/__generated__/StoreModalIndexQuery.graphql.js +8 -8
  15. package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +1 -1
  16. package/dist/__generated__/StoreModalProductQuery.graphql.js +3 -3
  17. package/dist/__generated__/useTotalStyles_fontCollection.graphql.d.ts +2 -1
  18. package/dist/__generated__/useTotalStyles_fontCollection.graphql.js +17 -16
  19. package/dist/components/CharacterViewer/StyleSelect.d.ts +1 -1
  20. package/dist/components/CharacterViewer/index.js +175 -250
  21. package/dist/components/StoreModal/StoreModalFamilyButton.js +7 -9
  22. package/dist/components/StoreModal/StoreModalIndexItem.js +7 -9
  23. package/dist/components/useTotalStyles.d.ts +1 -1
  24. package/dist/components/useTotalStyles.js +9 -8
  25. package/dist/fontdue.css +41 -56
  26. package/dist/utils.d.ts +1 -0
  27. package/dist/utils.js +7 -2
  28. package/package.json +1 -1
@@ -9,16 +9,19 @@ exports.CharacterViewerPreloadedSlugQueryRenderer = CharacterViewerPreloadedSlug
9
9
  exports.default = CharacterViewer;
10
10
  var _CharacterViewerSlugQuery2 = _interopRequireDefault(require("../../__generated__/CharacterViewerSlugQuery.graphql"));
11
11
  var _CharacterViewerIDQuery2 = _interopRequireDefault(require("../../__generated__/CharacterViewerIDQuery.graphql"));
12
- var _CharacterViewer_family2 = _interopRequireDefault(require("../../__generated__/CharacterViewer_family.graphql"));
12
+ var _CharacterViewer_style2 = _interopRequireDefault(require("../../__generated__/CharacterViewer_style.graphql"));
13
13
  var _CharacterViewer_collection2 = _interopRequireDefault(require("../../__generated__/CharacterViewer_collection.graphql"));
14
+ var _CharacterViewer_family2 = _interopRequireDefault(require("../../__generated__/CharacterViewer_family.graphql"));
14
15
  var _react = _interopRequireWildcard(require("react"));
15
16
  var _reactRelay = require("react-relay");
16
17
  var _resizeObserver = _interopRequireDefault(require("@react-hook/resize-observer"));
17
18
  var _utils = require("../../utils");
18
- var _Select = _interopRequireDefault(require("../Select"));
19
19
  var _useFontStyle = _interopRequireDefault(require("../useFontStyle"));
20
20
  var _Stylesheet = _interopRequireDefault(require("../Stylesheet"));
21
21
  var _useSerializablePreloadedQuery = _interopRequireDefault(require("../../relay/useSerializablePreloadedQuery"));
22
+ var _StyleSelect = _interopRequireDefault(require("./StyleSelect"));
23
+ var _Checkbox = _interopRequireDefault(require("../Checkbox"));
24
+ var _CharacterViewerStyleRefetchQuery = _interopRequireDefault(require("../../__generated__/CharacterViewerStyleRefetchQuery.graphql"));
22
25
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
26
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
24
27
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -37,75 +40,6 @@ function useSize() {
37
40
  height: size === null || size === void 0 ? void 0 : size.height
38
41
  };
39
42
  }
40
- const collectionInfo = collection => ({
41
- id: collection.id,
42
- name: collection.name,
43
- fontStyles: collection.fontStyles,
44
- isVariableFont: collection.isVariableFont,
45
- cssUrl: collection.cssUrl,
46
- collectionType: collection.collectionType
47
- });
48
- const StyleSelect = _ref => {
49
- let {
50
- collections,
51
- value,
52
- onChange
53
- } = _ref;
54
- const handleChange = e => {
55
- const value = e.target.value;
56
- if (value.includes(':::')) {
57
- var _fontStyle$variableIn;
58
- const [fontStyleId, variableInstanceName] = value.split(':::');
59
- const fontStyle = collections.flatMap(coll => coll.fontStyles).find(style => style.id === fontStyleId);
60
- const instance = fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$variableIn = fontStyle.variableInstances) === null || _fontStyle$variableIn === void 0 ? void 0 : _fontStyle$variableIn.find(_ref2 => {
61
- let {
62
- name
63
- } = _ref2;
64
- return name === variableInstanceName;
65
- });
66
- let variableSettings;
67
- if (instance) variableSettings = (0, _utils.variableInstanceSettings)(instance);
68
- onChange({
69
- fontStyleId,
70
- variableSettings
71
- });
72
- } else {
73
- onChange({
74
- fontStyleId: value
75
- });
76
- }
77
- };
78
- let selectValue = value.fontStyleId;
79
- if (value.variableSettings) {
80
- var _fontStyle$variableIn2;
81
- const fontStyle = collections.flatMap(coll => coll.fontStyles).find(style => style.id === value.fontStyleId);
82
- const instance = fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$variableIn2 = fontStyle.variableInstances) === null || _fontStyle$variableIn2 === void 0 ? void 0 : _fontStyle$variableIn2.find(instance => (0, _utils.compareVariableSettings)(instance, value.variableSettings));
83
- if (instance) {
84
- selectValue = `${value.fontStyleId}:::${instance.name}`;
85
- }
86
- }
87
- return /*#__PURE__*/_react.default.createElement(_Select.default, {
88
- options: collections.flatMap(coll => {
89
- var _coll$fontStyles2;
90
- if (coll.isVariableFont) {
91
- var _coll$fontStyles;
92
- return ((_coll$fontStyles = coll.fontStyles) === null || _coll$fontStyles === void 0 ? void 0 : _coll$fontStyles.flatMap(style => {
93
- var _style$variableInstan;
94
- return (_style$variableInstan = style.variableInstances) === null || _style$variableInstan === void 0 ? void 0 : _style$variableInstan.map(instance => ({
95
- value: `${style.id}:::${instance.name}`,
96
- text: `${coll.name} ${instance.name}`
97
- })).filter(_utils.notEmpty);
98
- }).filter(_utils.notEmpty)) ?? [];
99
- }
100
- return ((_coll$fontStyles2 = coll.fontStyles) === null || _coll$fontStyles2 === void 0 ? void 0 : _coll$fontStyles2.map(style => ({
101
- value: style.id,
102
- text: `${coll.name} ${style.name}`
103
- })).filter(_utils.notEmpty)) ?? [];
104
- }),
105
- value: selectValue,
106
- onChange: handleChange
107
- });
108
- };
109
43
  function Character(props) {
110
44
  const ref = (0, _react.useRef)(null);
111
45
  const [size, setSize] = (0, _react.useState)(1);
@@ -120,6 +54,23 @@ function Character(props) {
120
54
  "data-size": size
121
55
  }));
122
56
  }
57
+ function GlyphMeta(_ref) {
58
+ let {
59
+ glyph,
60
+ featuresChecked,
61
+ setFeaturesChecked,
62
+ getGlyphName,
63
+ getUnicodeName
64
+ } = _ref;
65
+ if (!glyph) return null;
66
+ const unicodeName = getUnicodeName(glyph);
67
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, "Glyph name"), /*#__PURE__*/_react.default.createElement("span", null, getGlyphName(glyph)), unicodeName && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, "Unicode name"), /*#__PURE__*/_react.default.createElement("span", {
68
+ title: unicodeName
69
+ }, unicodeName)), /*#__PURE__*/_react.default.createElement("span", null, "Unicode decimal"), /*#__PURE__*/_react.default.createElement("span", null, glyph.string.split('').map(str => str.charCodeAt(0).toString(10)).join(', ')), /*#__PURE__*/_react.default.createElement("span", null, "Unicode hex"), /*#__PURE__*/_react.default.createElement("span", null, glyph.string.split('').map(str => str.charCodeAt(0).toString(16).padStart(4, '0')).join(', ')), glyph.features && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", null, "OpenType feature", glyph.features.length > 1 ? 's' : ''), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement("label", null, /*#__PURE__*/_react.default.createElement(_Checkbox.default, {
70
+ checked: featuresChecked,
71
+ onChange: e => setFeaturesChecked(e.target.checked)
72
+ }), glyph.features.join(', ')))));
73
+ }
123
74
  function useUnicodeData() {
124
75
  const [data, setData] = (0, _react.useState)();
125
76
  (0, _react.useEffect)(() => {
@@ -136,26 +87,85 @@ function useUnicodeData() {
136
87
  }, []);
137
88
  return data;
138
89
  }
90
+ function compareGlyphs(a, b) {
91
+ var _a$features, _b$features;
92
+ if (!a || !b) return false;
93
+ if (a.string !== b.string) return false;
94
+ if (((_a$features = a.features) === null || _a$features === void 0 ? void 0 : _a$features.length) !== ((_b$features = b.features) === null || _b$features === void 0 ? void 0 : _b$features.length)) return false;
95
+ if (a.features && b.features) {
96
+ return a.features.every(feature => {
97
+ var _b$features2;
98
+ return (_b$features2 = b.features) === null || _b$features2 === void 0 ? void 0 : _b$features2.includes(feature);
99
+ });
100
+ }
101
+ return true;
102
+ }
103
+ function charCode(c) {
104
+ return c.charCodeAt(0);
105
+ }
106
+ function fromCharCode(code) {
107
+ return String.fromCharCode(code);
108
+ }
109
+ function flattenCharacterList(charSet, glyphNames) {
110
+ if (!glyphNames) return null;
111
+ return {
112
+ features: charSet.features,
113
+ characters: charSet.characters.reduce((acc, item) => {
114
+ if (item.__typename === 'CharacterString') {
115
+ acc.push(item.string);
116
+ } else if (item.__typename === 'CharacterRange') {
117
+ for (let code = charCode(item.first); code <= charCode(item.last); code++) {
118
+ acc.push(fromCharCode(code));
119
+ }
120
+ }
121
+ return acc;
122
+ }, []).filter(string => glyphNames.some(_ref2 => {
123
+ let {
124
+ characters,
125
+ features
126
+ } = _ref2;
127
+ return compareGlyphs({
128
+ string,
129
+ features: charSet.features
130
+ }, {
131
+ string: characters,
132
+ features
133
+ });
134
+ }))
135
+ };
136
+ }
137
+ _CharacterViewer_family2.default.hash && _CharacterViewer_family2.default.hash !== "02c42505dc4e330bb7c9034ba54e12f6" && console.error("The definition of 'CharacterViewer_family' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewer_family2.default;
139
138
  function CharacterViewerComponent(_ref3) {
140
- var _collection$children, _collection$fontStyle, _collection$children2, _collection$children3, _collection$children4, _fontStyle$glyphNames, _fontStyle$glyphNames2, _fontStyle$featureCha, _fontStyle$featureCha2, _fontStyle$featureCha3, _fontStyle$featureCha4, _fontStyle$glyphNames3, _fontStyle$glyphNames4, _fontStyle$featureCha5, _fontStyle$characterB, _fontStyle$featureCha6, _fontStyle$featureCha7, _fontStyle$featureCha8;
141
139
  let {
142
140
  collection: collectionKey
143
141
  } = _ref3;
144
- const collection = (0, _reactRelay.useFragment)((_CharacterViewer_collection2.default.hash && _CharacterViewer_collection2.default.hash !== "2f49d241268129a888942889cad0bebb" && console.error("The definition of 'CharacterViewer_collection' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewer_collection2.default), collectionKey);
145
- const allCollections = [collectionInfo(collection)].concat(((_collection$children = collection.children) === null || _collection$children === void 0 ? void 0 : _collection$children.map(collectionInfo)) ?? []);
142
+ const collection = (0, _reactRelay.useFragment)((_CharacterViewer_collection2.default.hash && _CharacterViewer_collection2.default.hash !== "806e33bb73206ac443c6880d2941131d" && console.error("The definition of 'CharacterViewer_collection' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewer_collection2.default), collectionKey);
143
+ const [fontStyle, refetchFontStyle] = (0, _reactRelay.useRefetchableFragment)((_CharacterViewer_style2.default.hash && _CharacterViewer_style2.default.hash !== "cd4bc4064dd23132ba3bf3d207fe6cb9" && console.error("The definition of 'CharacterViewer_style' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewer_style2.default), collection.featureStyle);
144
+ let families = [];
145
+ if (collection.collectionType === 'family') families = [collection];
146
+ if (collection.collectionType === 'superfamily' && collection.children) families = collection.children;
146
147
  const unicodeData = useUnicodeData();
147
- const initialFontStyle = collection.featureStyle ?? ((_collection$fontStyle = collection.fontStyles) === null || _collection$fontStyle === void 0 ? void 0 : _collection$fontStyle[0]) ?? ((_collection$children2 = collection.children) === null || _collection$children2 === void 0 ? void 0 : (_collection$children3 = _collection$children2[0]) === null || _collection$children3 === void 0 ? void 0 : (_collection$children4 = _collection$children3.fontStyles) === null || _collection$children4 === void 0 ? void 0 : _collection$children4[0]);
148
148
  let initialVariableSettings;
149
- if (initialFontStyle && initialFontStyle.variableInstances) {
150
- initialVariableSettings = (0, _utils.variableInstanceSettings)(initialFontStyle.variableInstances[0]);
149
+ if (fontStyle !== null && fontStyle !== void 0 && fontStyle.variableInstances) {
150
+ initialVariableSettings = (0, _utils.variableInstanceSettings)(fontStyle.variableInstances[0]);
151
151
  }
152
- const [fontStyleId, setFontStyleId] = (0, _react.useState)((initialFontStyle === null || initialFontStyle === void 0 ? void 0 : initialFontStyle.id) ?? null);
153
152
  const [variableSettings, setVariableSettings] = (0, _react.useState)(initialVariableSettings);
153
+ const [featuresChecked, setFeaturesChecked] = (0, _react.useState)(true);
154
+ const environment = (0, _reactRelay.useRelayEnvironment)();
154
155
  const handleStyleSelect = value => {
155
- setFontStyleId(value.fontStyleId);
156
- setVariableSettings(value.variableSettings);
156
+ const variables = {
157
+ id: value.fontStyleId
158
+ };
159
+ // avoid Suspense using fetchQuery. future react may simplify this
160
+ (0, _reactRelay.fetchQuery)(environment, _CharacterViewerStyleRefetchQuery.default, variables).subscribe({
161
+ complete: () => {
162
+ refetchFontStyle(variables, {
163
+ fetchPolicy: 'store-only'
164
+ });
165
+ setVariableSettings(value.variableSettings);
166
+ }
167
+ });
157
168
  };
158
- const fontStyle = allCollections.flatMap(coll => coll.fontStyles).find(style => style.id === fontStyleId);
159
169
  let {
160
170
  style
161
171
  } = (0, _useFontStyle.default)({
@@ -169,33 +179,31 @@ function CharacterViewerComponent(_ref3) {
169
179
  ...(0, _utils.variableSettingsCSS)(variableSettings)
170
180
  };
171
181
  }
172
- const [selectedCharacter, setSelectedCharacter] = (0, _react.useState)('A');
173
- const [activeCharacter, setActiveCharacter] = (0, _react.useState)('A');
174
- const visibleCharacter = activeCharacter ?? selectedCharacter;
175
- const visibleCharacterGlyphName = fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$glyphNames = fontStyle.glyphNames) === null || _fontStyle$glyphNames === void 0 ? void 0 : (_fontStyle$glyphNames2 = _fontStyle$glyphNames.find(_ref4 => {
176
- let {
177
- characters,
178
- feature
179
- } = _ref4;
180
- return feature === null && visibleCharacter === characters;
181
- })) === null || _fontStyle$glyphNames2 === void 0 ? void 0 : _fontStyle$glyphNames2.name;
182
- const [selectedFeatureCharacter, setSelectedFeatureCharacter] = (0, _react.useState)();
183
- const [activeFeatureCharacter, setActiveFeatureCharacter] = (0, _react.useState)([(fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$featureCha = fontStyle.featureCharacters) === null || _fontStyle$featureCha === void 0 ? void 0 : (_fontStyle$featureCha2 = _fontStyle$featureCha[0]) === null || _fontStyle$featureCha2 === void 0 ? void 0 : _fontStyle$featureCha2.characters[0]) ?? '', fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$featureCha3 = fontStyle.featureCharacters) === null || _fontStyle$featureCha3 === void 0 ? void 0 : (_fontStyle$featureCha4 = _fontStyle$featureCha3[0]) === null || _fontStyle$featureCha4 === void 0 ? void 0 : _fontStyle$featureCha4.feature]);
184
- const visibleFeatureCharacter = activeFeatureCharacter ?? selectedFeatureCharacter;
185
- const visibleFeatureCharacterGlyphName = fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$glyphNames3 = fontStyle.glyphNames) === null || _fontStyle$glyphNames3 === void 0 ? void 0 : (_fontStyle$glyphNames4 = _fontStyle$glyphNames3.find(_ref5 => {
186
- let {
187
- characters,
188
- feature
189
- } = _ref5;
190
- return feature === (visibleFeatureCharacter === null || visibleFeatureCharacter === void 0 ? void 0 : visibleFeatureCharacter[1]) && (visibleFeatureCharacter === null || visibleFeatureCharacter === void 0 ? void 0 : visibleFeatureCharacter[0]) === characters;
191
- })) === null || _fontStyle$glyphNames4 === void 0 ? void 0 : _fontStyle$glyphNames4.name;
192
- const featureUnicodeDecimal = visibleFeatureCharacter === null || visibleFeatureCharacter === void 0 ? void 0 : visibleFeatureCharacter[0].split('').map(char => char.charCodeAt(0).toString(10)).join(', ');
193
- const featureUnicodeHex = visibleFeatureCharacter === null || visibleFeatureCharacter === void 0 ? void 0 : visibleFeatureCharacter[0].split('').map(char => char.charCodeAt(0).toString(16).padStart(4, '0')).join(', ');
182
+ const [selectedGlyph, setSelectedGlyph] = (0, _react.useState)({
183
+ string: 'A'
184
+ });
185
+ const [activeGlyph, setActiveGlyph] = (0, _react.useState)({
186
+ string: 'A'
187
+ });
188
+ const visibleGlyph = activeGlyph ?? selectedGlyph;
189
+ const getGlyphName = (0, _react.useCallback)(glyph => {
190
+ var _fontStyle$glyphNames, _fontStyle$glyphNames2;
191
+ return (fontStyle === null || fontStyle === void 0 ? void 0 : (_fontStyle$glyphNames = fontStyle.glyphNames) === null || _fontStyle$glyphNames === void 0 ? void 0 : (_fontStyle$glyphNames2 = _fontStyle$glyphNames.find(_ref4 => {
192
+ let {
193
+ characters,
194
+ features
195
+ } = _ref4;
196
+ return compareGlyphs(glyph, {
197
+ string: characters,
198
+ features
199
+ });
200
+ })) === null || _fontStyle$glyphNames2 === void 0 ? void 0 : _fontStyle$glyphNames2.name) ?? null;
201
+ }, [fontStyle, compareGlyphs]);
202
+ const getUnicodeName = (0, _react.useCallback)(glyph => {
203
+ return (unicodeData === null || unicodeData === void 0 ? void 0 : unicodeData[glyph.string.charCodeAt(0)]) ?? null;
204
+ }, [unicodeData]);
194
205
  const handleMouseLeave = () => {
195
- if (selectedCharacter) setActiveCharacter(undefined);
196
- };
197
- const handleFeatureCharacterMouseLeave = () => {
198
- if (selectedFeatureCharacter) setActiveFeatureCharacter(undefined);
206
+ if (selectedGlyph) setActiveGlyph(undefined);
199
207
  };
200
208
  const {
201
209
  ref: blocksRef,
@@ -206,12 +214,6 @@ function CharacterViewerComponent(_ref3) {
206
214
  width: monitorWidth
207
215
  } = useSize();
208
216
  if (!fontStyle) return null;
209
- const characterVariants = (_fontStyle$featureCha5 = fontStyle.featureCharacters) === null || _fontStyle$featureCha5 === void 0 ? void 0 : _fontStyle$featureCha5.filter(_ref6 => {
210
- let {
211
- feature
212
- } = _ref6;
213
- return feature.startsWith('cv');
214
- });
215
217
  const lines = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
216
218
  className: "character-viewer__monitor__line",
217
219
  "data-name": "baseline"
@@ -248,6 +250,19 @@ function CharacterViewerComponent(_ref3) {
248
250
  }, "x-Height"), /*#__PURE__*/_react.default.createElement("span", {
249
251
  className: "character-viewer__monitor__line__value"
250
252
  }, fontStyle.verticalMetrics.xHeight)));
253
+ const groups = (0, _react.useMemo)(() => {
254
+ var _collection$glyphGrou;
255
+ return (_collection$glyphGrou = collection.glyphGroups) === null || _collection$glyphGrou === void 0 ? void 0 : _collection$glyphGrou.map(_ref5 => {
256
+ let {
257
+ name,
258
+ characterSets
259
+ } = _ref5;
260
+ return {
261
+ name,
262
+ characterSets: characterSets.map(set => flattenCharacterList(set, fontStyle.glyphNames)).filter(_utils.notEmpty)
263
+ };
264
+ });
265
+ }, [collection, fontStyle]);
251
266
  return /*#__PURE__*/_react.default.createElement("div", {
252
267
  className: "character-viewer",
253
268
  style: {
@@ -259,45 +274,50 @@ function CharacterViewerComponent(_ref3) {
259
274
  '--line-gap': fontStyle.verticalMetrics.lineGap ?? undefined,
260
275
  '--monitor-width': monitorWidth
261
276
  }
262
- }, allCollections.filter(coll => coll.collectionType === 'family').map(coll => /*#__PURE__*/_react.default.createElement(_Stylesheet.default, {
277
+ }, families.filter(coll => coll.collectionType === 'family').map(coll => /*#__PURE__*/_react.default.createElement(_Stylesheet.default, {
263
278
  key: coll.id,
264
279
  href: coll.cssUrl
265
280
  })), /*#__PURE__*/_react.default.createElement("div", {
266
281
  className: "character-viewer__character-map"
267
282
  }, /*#__PURE__*/_react.default.createElement("div", {
268
283
  className: "character-viewer__monitor"
269
- }, visibleCharacter && /*#__PURE__*/_react.default.createElement("div", {
284
+ }, visibleGlyph && /*#__PURE__*/_react.default.createElement("div", {
270
285
  className: "character-viewer__monitor__container"
271
286
  }, /*#__PURE__*/_react.default.createElement("div", {
272
- className: "character-viewer__monitor__title"
273
- }, "Character map"), /*#__PURE__*/_react.default.createElement("div", {
274
287
  className: "character-viewer__monitor__character-container"
275
288
  }, /*#__PURE__*/_react.default.createElement("div", {
276
289
  className: "character-viewer__monitor__character",
277
- style: style,
290
+ style: {
291
+ ...style,
292
+ fontFeatureSettings: visibleGlyph.features && featuresChecked ? `${visibleGlyph.features.map(feature => `'${feature}' 1`).join(', ')}` : `'calt' off, 'liga' off`
293
+ },
278
294
  ref: monitorRef
279
- }, /*#__PURE__*/_react.default.createElement("span", null, visibleCharacter)), lines), /*#__PURE__*/_react.default.createElement("div", {
295
+ }, /*#__PURE__*/_react.default.createElement("span", null, visibleGlyph.string)), lines), /*#__PURE__*/_react.default.createElement("div", {
280
296
  className: "character-viewer__monitor__details"
281
- }, /*#__PURE__*/_react.default.createElement("span", null, "Font style"), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(StyleSelect, {
282
- collections: allCollections,
297
+ }, /*#__PURE__*/_react.default.createElement("span", null, "Font style"), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_StyleSelect.default, {
298
+ collections: families,
283
299
  onChange: handleStyleSelect,
284
300
  value: {
285
- fontStyleId,
301
+ fontStyleId: fontStyle.id,
286
302
  variableSettings
287
303
  }
288
- })), /*#__PURE__*/_react.default.createElement("span", null, "Glyph name"), /*#__PURE__*/_react.default.createElement("span", null, visibleCharacterGlyphName), /*#__PURE__*/_react.default.createElement("span", null, "Unicode name"), /*#__PURE__*/_react.default.createElement("span", {
289
- title: (unicodeData === null || unicodeData === void 0 ? void 0 : unicodeData[visibleCharacter.charCodeAt(0)]) ?? ''
290
- }, unicodeData ? unicodeData[visibleCharacter.charCodeAt(0)] ?? '' : 'Loading...'), /*#__PURE__*/_react.default.createElement("span", null, "Unicode decimal"), /*#__PURE__*/_react.default.createElement("span", null, visibleCharacter.charCodeAt(0).toString(10)), /*#__PURE__*/_react.default.createElement("span", null, "Unicode hex"), /*#__PURE__*/_react.default.createElement("span", null, visibleCharacter.charCodeAt(0).toString(16).padStart(4, '0'))))), /*#__PURE__*/_react.default.createElement("div", {
304
+ })), /*#__PURE__*/_react.default.createElement(GlyphMeta, {
305
+ glyph: visibleGlyph,
306
+ getGlyphName: getGlyphName,
307
+ getUnicodeName: getUnicodeName,
308
+ featuresChecked: featuresChecked,
309
+ setFeaturesChecked: setFeaturesChecked
310
+ })))), /*#__PURE__*/_react.default.createElement("div", {
291
311
  className: "character-viewer_blocks",
292
312
  ref: blocksRef,
293
313
  style: {
294
314
  '--width': blocksWidth ?? 600
295
315
  }
296
- }, (_fontStyle$characterB = fontStyle.characterBlocks) === null || _fontStyle$characterB === void 0 ? void 0 : _fontStyle$characterB.map((_ref7, i) => {
316
+ }, groups === null || groups === void 0 ? void 0 : groups.map((_ref6, i) => {
297
317
  let {
298
318
  name,
299
- characters
300
- } = _ref7;
319
+ characterSets
320
+ } = _ref6;
301
321
  return /*#__PURE__*/_react.default.createElement("div", {
302
322
  className: "character-viewer__block",
303
323
  key: i,
@@ -308,126 +328,31 @@ function CharacterViewerComponent(_ref3) {
308
328
  className: "character-viewer__block__characters",
309
329
  style: style,
310
330
  onMouseLeave: handleMouseLeave
311
- }, characters.map((chars, j) => /*#__PURE__*/_react.default.createElement(Character, {
312
- key: j,
313
- onClick: () => setSelectedCharacter(chars),
314
- onMouseEnter: () => setActiveCharacter(chars),
315
- "data-selected": selectedCharacter === chars
316
- }, chars))));
317
- }))), (_fontStyle$featureCha6 = fontStyle.featureCharacters) !== null && _fontStyle$featureCha6 !== void 0 && _fontStyle$featureCha6.length ? /*#__PURE__*/_react.default.createElement("div", {
318
- className: "character-viewer__features-map"
319
- }, /*#__PURE__*/_react.default.createElement("div", {
320
- className: "character-viewer__feature-monitor"
321
- }, visibleFeatureCharacter && /*#__PURE__*/_react.default.createElement("div", {
322
- className: "character-viewer__feature-monitor__container"
323
- }, /*#__PURE__*/_react.default.createElement("div", {
324
- className: "character-viewer__feature-monitor__title"
325
- }, "OpenType features"), /*#__PURE__*/_react.default.createElement("div", {
326
- className: "character-viewer__feature-monitor__labels"
327
- }, /*#__PURE__*/_react.default.createElement("span", {
328
- className: "character-viewer__feature-monitor__label"
329
- }, "OFF"), /*#__PURE__*/_react.default.createElement("span", {
330
- className: "character-viewer__feature-monitor__label"
331
- }, "ON")), /*#__PURE__*/_react.default.createElement("div", {
332
- className: "character-viewer__feature-monitor__characters"
333
- }, /*#__PURE__*/_react.default.createElement("div", {
334
- className: "character-viewer__feature-monitor__characters__off"
335
- }, /*#__PURE__*/_react.default.createElement("div", {
336
- className: "character-viewer__feature-monitor__character",
337
- style: {
338
- ...style,
339
- fontFeatureSettings: `'calt' off, 'liga' off, '${visibleFeatureCharacter[1]}' off`
340
- }
341
- }, visibleFeatureCharacter[0])), /*#__PURE__*/_react.default.createElement("div", {
342
- className: "character-viewer__feature-monitor__characters__on"
343
- }, /*#__PURE__*/_react.default.createElement("div", {
344
- className: "character-viewer__feature-monitor__character",
345
- style: {
346
- ...style,
347
- fontFeatureSettings: `'${visibleFeatureCharacter[1]}' on`
348
- }
349
- }, visibleFeatureCharacter[0])), lines), /*#__PURE__*/_react.default.createElement("div", {
350
- className: "character-viewer__monitor__details"
351
- }, /*#__PURE__*/_react.default.createElement("span", null, "Font style"), /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(StyleSelect, {
352
- collections: allCollections,
353
- onChange: handleStyleSelect,
354
- value: {
355
- fontStyleId,
356
- variableSettings
357
- }
358
- })), /*#__PURE__*/_react.default.createElement("span", null, "Glyph name"), /*#__PURE__*/_react.default.createElement("span", null, visibleFeatureCharacterGlyphName), /*#__PURE__*/_react.default.createElement("span", null, "Unicode decimal"), /*#__PURE__*/_react.default.createElement("span", {
359
- title: featureUnicodeDecimal
360
- }, featureUnicodeDecimal), /*#__PURE__*/_react.default.createElement("span", null, "Unicode hex"), /*#__PURE__*/_react.default.createElement("span", {
361
- title: featureUnicodeHex
362
- }, featureUnicodeHex), /*#__PURE__*/_react.default.createElement("span", null, "OpenType feature"), /*#__PURE__*/_react.default.createElement("span", null, visibleFeatureCharacter[1])))), /*#__PURE__*/_react.default.createElement("div", {
363
- className: "character-viewer_blocks",
364
- style: {
365
- '--width': blocksWidth ?? 600
366
- }
367
- }, (_fontStyle$featureCha7 = fontStyle.featureCharacters) === null || _fontStyle$featureCha7 === void 0 ? void 0 : (_fontStyle$featureCha8 = _fontStyle$featureCha7.filter(_ref8 => {
368
- let {
369
- feature
370
- } = _ref8;
371
- return !feature.startsWith('cv');
372
- })) === null || _fontStyle$featureCha8 === void 0 ? void 0 : _fontStyle$featureCha8.map((_ref9, i) => {
373
- let {
374
- name,
375
- feature,
376
- characters
377
- } = _ref9;
378
- return /*#__PURE__*/_react.default.createElement("div", {
379
- className: "character-viewer__block",
380
- key: i,
381
- "data-feature": feature,
382
- "data-name": name
383
- }, /*#__PURE__*/_react.default.createElement("div", {
384
- className: "character-viewer__block__name"
385
- }, name), /*#__PURE__*/_react.default.createElement("div", {
386
- className: "character-viewer__block__characters",
387
- style: {
388
- ...style,
389
- fontFeatureSettings: `'${feature}' 1`
390
- },
391
- onMouseLeave: handleFeatureCharacterMouseLeave
392
- }, characters.map((chars, j) => /*#__PURE__*/_react.default.createElement(Character, {
331
+ }, characterSets.map((set, j) => /*#__PURE__*/_react.default.createElement("div", {
393
332
  key: j,
394
- onClick: () => setSelectedFeatureCharacter([chars, feature]),
395
- onMouseEnter: () => setActiveFeatureCharacter([chars, feature]),
396
- "data-selected": (selectedFeatureCharacter === null || selectedFeatureCharacter === void 0 ? void 0 : selectedFeatureCharacter[0]) === chars && (selectedFeatureCharacter === null || selectedFeatureCharacter === void 0 ? void 0 : selectedFeatureCharacter[1]) === feature
397
- }, chars))));
398
- }), characterVariants !== null && characterVariants !== void 0 && characterVariants.length ? /*#__PURE__*/_react.default.createElement("div", {
399
- className: "character-viewer__block",
400
- key: "cv"
401
- }, /*#__PURE__*/_react.default.createElement("div", {
402
- className: "character-viewer__block__name"
403
- }, "Character Variants"), /*#__PURE__*/_react.default.createElement("div", {
404
- className: "character-viewer__block__characters",
405
- style: {
406
- ...style
407
- },
408
- onMouseLeave: handleFeatureCharacterMouseLeave
409
- }, characterVariants.flatMap((_ref10, i) => {
410
- let {
411
- feature,
412
- characters
413
- } = _ref10;
414
- return characters.map((chars, j) => /*#__PURE__*/_react.default.createElement(Character, {
415
- key: `${i}${j}`,
333
+ className: "character-viewer__block__character-list",
416
334
  style: {
417
- fontFeatureSettings: `'${feature}' 1`
418
- },
419
- onClick: () => setSelectedFeatureCharacter([chars, feature]),
420
- onMouseEnter: () => setActiveFeatureCharacter([chars, feature]),
421
- "data-selected": (selectedFeatureCharacter === null || selectedFeatureCharacter === void 0 ? void 0 : selectedFeatureCharacter[0]) === chars && (selectedFeatureCharacter === null || selectedFeatureCharacter === void 0 ? void 0 : selectedFeatureCharacter[1]) === feature
422
- }, chars));
423
- }))) : null)) : null);
335
+ fontFeatureSettings: set.features ? `${set.features.map(feature => `'${feature}' 1`).join(', ')}` : undefined
336
+ }
337
+ }, set.characters.map((chars, k) => {
338
+ const selection = {
339
+ string: chars,
340
+ features: set.features
341
+ };
342
+ return /*#__PURE__*/_react.default.createElement(Character, {
343
+ key: k,
344
+ onClick: () => setSelectedGlyph(selection),
345
+ onMouseEnter: () => setActiveGlyph(selection),
346
+ "data-selected": compareGlyphs(selectedGlyph, selection)
347
+ }, chars);
348
+ })))));
349
+ }))));
424
350
  }
425
- _CharacterViewer_family2.default.hash && _CharacterViewer_family2.default.hash !== "d940cabe9ed658d5cbed547287f2de0e" && console.error("The definition of 'CharacterViewer_family' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewer_family2.default;
426
351
  const idQuery = (_CharacterViewerIDQuery2.default.hash && _CharacterViewerIDQuery2.default.hash !== "f90b09a4df6d95307b0a5d5fda487cdc" && console.error("The definition of 'CharacterViewerIDQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewerIDQuery2.default);
427
- function CharacterViewerIdQueryRenderer(_ref11) {
352
+ function CharacterViewerIdQueryRenderer(_ref7) {
428
353
  let {
429
354
  collectionId
430
- } = _ref11;
355
+ } = _ref7;
431
356
  const data = (0, _reactRelay.useLazyLoadQuery)(idQuery, {
432
357
  collectionId
433
358
  });
@@ -436,11 +361,11 @@ function CharacterViewerIdQueryRenderer(_ref11) {
436
361
  collection: data.node
437
362
  });
438
363
  }
439
- function CharacterViewerPreloadedIDQueryRenderer(_ref12) {
364
+ function CharacterViewerPreloadedIDQueryRenderer(_ref8) {
440
365
  let {
441
366
  preloadedQuery,
442
367
  ...rest
443
- } = _ref12;
368
+ } = _ref8;
444
369
  const queryRef = (0, _useSerializablePreloadedQuery.default)(preloadedQuery);
445
370
  const data = (0, _reactRelay.usePreloadedQuery)(idQuery, queryRef);
446
371
  if (!data.node) return null;
@@ -448,11 +373,11 @@ function CharacterViewerPreloadedIDQueryRenderer(_ref12) {
448
373
  collection: data.node
449
374
  }));
450
375
  }
451
- function CharacterViewerSlugQueryRenderer(_ref13) {
376
+ function CharacterViewerSlugQueryRenderer(_ref9) {
452
377
  var _data$viewer, _data$viewer$slug;
453
378
  let {
454
379
  collectionSlug
455
- } = _ref13;
380
+ } = _ref9;
456
381
  const data = (0, _reactRelay.useLazyLoadQuery)((_CharacterViewerSlugQuery2.default.hash && _CharacterViewerSlugQuery2.default.hash !== "afa08a8f050e0434308892fea6e3c267" && console.error("The definition of 'CharacterViewerSlugQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CharacterViewerSlugQuery2.default), {
457
382
  collectionSlug
458
383
  });
@@ -462,12 +387,12 @@ function CharacterViewerSlugQueryRenderer(_ref13) {
462
387
  collection: collection
463
388
  });
464
389
  }
465
- function CharacterViewerPreloadedSlugQueryRenderer(_ref14) {
390
+ function CharacterViewerPreloadedSlugQueryRenderer(_ref10) {
466
391
  var _data$viewer2, _data$viewer2$slug;
467
392
  let {
468
393
  preloadedQuery,
469
394
  ...rest
470
- } = _ref14;
395
+ } = _ref10;
471
396
  const queryRef = (0, _useSerializablePreloadedQuery.default)(preloadedQuery);
472
397
  const data = (0, _reactRelay.usePreloadedQuery)(idQuery, queryRef);
473
398
  const collection = data === null || data === void 0 ? void 0 : (_data$viewer2 = data.viewer) === null || _data$viewer2 === void 0 ? void 0 : (_data$viewer2$slug = _data$viewer2.slug) === null || _data$viewer2$slug === void 0 ? void 0 : _data$viewer2$slug.fontCollection;
@@ -476,11 +401,11 @@ function CharacterViewerPreloadedSlugQueryRenderer(_ref14) {
476
401
  collection: collection
477
402
  }));
478
403
  }
479
- function CharacterViewer(_ref15) {
404
+ function CharacterViewer(_ref11) {
480
405
  let {
481
406
  collectionId,
482
407
  collectionSlug
483
- } = _ref15;
408
+ } = _ref11;
484
409
  if (collectionId) {
485
410
  return /*#__PURE__*/_react.default.createElement(CharacterViewerIdQueryRenderer, {
486
411
  collectionId: collectionId
@@ -44,14 +44,12 @@ function FamilyButton(_ref) {
44
44
  } = (0, _useTotalStyles.default)({
45
45
  fontCollection: collection
46
46
  });
47
- let label;
48
- if (collection.isVariableFont) {
49
- label = 'Variable font';
50
- } else {
51
- label = (0, _utils.pluralize)(totalStyles, 'style');
52
- if (variableFonts) {
53
- label += ', ' + (0, _utils.pluralize)(variableFonts, 'variable font');
54
- }
47
+ let label = [];
48
+ if (totalStyles > 0) {
49
+ label.push((0, _utils.pluralize)(totalStyles, 'style'));
50
+ }
51
+ if (variableFonts > 0) {
52
+ label.push((0, _utils.pluralize)(variableFonts, 'variable font'));
55
53
  }
56
54
  return /*#__PURE__*/_react.default.createElement(_StoreModalFamilyButton.default, _extends({
57
55
  selected: selected,
@@ -61,7 +59,7 @@ function FamilyButton(_ref) {
61
59
  Component: "span",
62
60
  fontStyle: collection.featureStyle
63
61
  }, collection.name, getSuffix(collection)),
64
- label,
62
+ label: label.join(', '),
65
63
  price: collection.sku && /*#__PURE__*/_react.default.createElement(_SKUPrice.default, {
66
64
  sku: collection.sku,
67
65
  format: _Price.PriceFormat.Truncated
@@ -42,14 +42,12 @@ const StoreModalIndexItem = _ref => {
42
42
  } = (0, _useTotalStyles.default)({
43
43
  fontCollection: data
44
44
  });
45
- let label;
46
- if (data.isVariableFont) {
47
- label = 'Variable font';
48
- } else {
49
- label = (0, _utils.pluralize)(totalStyles, 'style');
50
- if (variableFonts) {
51
- label += ', ' + (0, _utils.pluralize)(variableFonts, 'variable font');
52
- }
45
+ let label = [];
46
+ if (totalStyles > 0) {
47
+ label.push((0, _utils.pluralize)(totalStyles, 'style'));
48
+ }
49
+ if (variableFonts > 0) {
50
+ label.push((0, _utils.pluralize)(variableFonts, 'variable font'));
53
51
  }
54
52
  return /*#__PURE__*/_react.default.createElement(_StoreModalIndexItem.default, {
55
53
  key: data.id,
@@ -65,7 +63,7 @@ const StoreModalIndexItem = _ref => {
65
63
  }), /*#__PURE__*/_react.default.createElement(_FontStyle.default, {
66
64
  fontStyle: data.featureStyle
67
65
  }, data.name)) : data.name,
68
- label
66
+ label: label.join(', ')
69
67
  });
70
68
  };
71
69
  var _default = StoreModalIndexItem;
@@ -4,6 +4,6 @@ interface useTotalStyles_props {
4
4
  }
5
5
  declare const useTotalStyles: ({ fontCollection }: useTotalStyles_props) => {
6
6
  totalStyles: number;
7
- variableFonts: number | undefined;
7
+ variableFonts: number;
8
8
  };
9
9
  export default useTotalStyles;