@imposium-hub/components 1.56.0 → 1.57.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 (54) hide show
  1. package/dist/cjs/components/font-picker/FontPicker.d.ts +44 -0
  2. package/dist/cjs/components/font-picker/FontPicker.js +182 -0
  3. package/dist/cjs/components/font-picker/FontPicker.js.map +1 -0
  4. package/dist/cjs/components/font-picker/font-manager/FontManager.d.ts +26 -0
  5. package/dist/cjs/components/font-picker/font-manager/FontManager.js +209 -0
  6. package/dist/cjs/components/font-picker/font-manager/FontManager.js.map +1 -0
  7. package/dist/cjs/components/font-picker/font-manager/constants.d.ts +4 -0
  8. package/dist/cjs/components/font-picker/font-manager/constants.js +8 -0
  9. package/dist/cjs/components/font-picker/font-manager/constants.js.map +1 -0
  10. package/dist/cjs/components/font-picker/font-manager/fontStyle.d.ts +1 -0
  11. package/dist/cjs/components/font-picker/font-manager/fontStyle.js +61 -0
  12. package/dist/cjs/components/font-picker/font-manager/fontStyle.js.map +1 -0
  13. package/dist/cjs/components/font-picker/font-manager/types.d.ts +25 -0
  14. package/dist/cjs/components/font-picker/font-manager/types.js +12 -0
  15. package/dist/cjs/components/font-picker/font-manager/types.js.map +1 -0
  16. package/dist/cjs/components/font-picker/font-manager/utils.d.ts +3 -0
  17. package/dist/cjs/components/font-picker/font-manager/utils.js +42 -0
  18. package/dist/cjs/components/font-picker/font-manager/utils.js.map +1 -0
  19. package/dist/cjs/index.d.ts +2 -1
  20. package/dist/cjs/index.js +3 -1
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/esm/components/font-picker/FontPicker.d.ts +44 -0
  23. package/dist/esm/components/font-picker/FontPicker.js +134 -0
  24. package/dist/esm/components/font-picker/FontPicker.js.map +1 -0
  25. package/dist/esm/components/font-picker/font-manager/FontManager.d.ts +26 -0
  26. package/dist/esm/components/font-picker/font-manager/FontManager.js +105 -0
  27. package/dist/esm/components/font-picker/font-manager/FontManager.js.map +1 -0
  28. package/dist/esm/components/font-picker/font-manager/constants.d.ts +4 -0
  29. package/dist/esm/components/font-picker/font-manager/constants.js +5 -0
  30. package/dist/esm/components/font-picker/font-manager/constants.js.map +1 -0
  31. package/dist/esm/components/font-picker/font-manager/fontStyle.d.ts +1 -0
  32. package/dist/esm/components/font-picker/font-manager/fontStyle.js +65 -0
  33. package/dist/esm/components/font-picker/font-manager/fontStyle.js.map +1 -0
  34. package/dist/esm/components/font-picker/font-manager/types.d.ts +25 -0
  35. package/dist/esm/components/font-picker/font-manager/types.js +9 -0
  36. package/dist/esm/components/font-picker/font-manager/types.js.map +1 -0
  37. package/dist/esm/components/font-picker/font-manager/utils.d.ts +3 -0
  38. package/dist/esm/components/font-picker/font-manager/utils.js +36 -0
  39. package/dist/esm/components/font-picker/font-manager/utils.js.map +1 -0
  40. package/dist/esm/index.d.ts +2 -1
  41. package/dist/esm/index.js +2 -1
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/styles.css +107 -0
  44. package/dist/styles.less +132 -0
  45. package/less/components/font-picker.less +131 -0
  46. package/less/entry.less +2 -1
  47. package/package.json +1 -1
  48. package/src/components/font-picker/FontPicker.tsx +222 -0
  49. package/src/components/font-picker/font-manager/FontManager.ts +138 -0
  50. package/src/components/font-picker/font-manager/constants.ts +7 -0
  51. package/src/components/font-picker/font-manager/fontStyle.ts +78 -0
  52. package/src/components/font-picker/font-manager/types.ts +83 -0
  53. package/src/components/font-picker/font-manager/utils.ts +36 -0
  54. package/src/index.ts +3 -1
@@ -0,0 +1,138 @@
1
+ import { Font, FontList, Options, OPTIONS_DEFAULTS, Script } from './types';
2
+ import { FONT_FAMILY_DEFAULT, LIST_BASE_URL } from './constants';
3
+ import { getFontId, get } from './utils';
4
+
5
+ interface FontResponse extends Font {
6
+ subsets: Script[];
7
+ }
8
+
9
+ export default class FontManager {
10
+ private readonly apiKey: string;
11
+
12
+ private readonly options: Options;
13
+
14
+ private onChange: (font: string) => void;
15
+
16
+ private fonts: FontList = new Map<string, Font>();
17
+
18
+ constructor(
19
+ apiKey: string,
20
+ defaultFamily: string = FONT_FAMILY_DEFAULT,
21
+ {
22
+ families = OPTIONS_DEFAULTS.families,
23
+ categories = OPTIONS_DEFAULTS.categories,
24
+ scripts = OPTIONS_DEFAULTS.scripts,
25
+ variants = OPTIONS_DEFAULTS.variants,
26
+ filter = OPTIONS_DEFAULTS.filter,
27
+ limit = OPTIONS_DEFAULTS.limit
28
+ }: Options,
29
+
30
+ onChange: (font: string) => void
31
+ ) {
32
+ // Save parameters as class variables
33
+ this.apiKey = apiKey;
34
+ this.options = {
35
+ families,
36
+ categories,
37
+ scripts,
38
+ variants,
39
+ filter,
40
+ limit
41
+ };
42
+ this.onChange = onChange;
43
+
44
+ // Download default font and add it to the empty font list
45
+ this.addFont(defaultFamily);
46
+ this.setActiveFont(defaultFamily);
47
+ }
48
+
49
+ /**
50
+ * Fetch list of all fonts from Google Fonts API, filter it according to the class parameters and
51
+ * save them to the font map
52
+ */
53
+ public async init(): Promise<FontList> {
54
+ // Get list of all fonts
55
+ const fonts = await this.getFontList(this.apiKey);
56
+ // Save desired fonts in the font map
57
+ for (const font of fonts) {
58
+ // const font = fonts[i];
59
+ // Exit once specified limit of number of fonts is reached
60
+ if (this.fonts.size >= this.options.limit) {
61
+ break;
62
+ }
63
+
64
+ if (
65
+ // Skip default font if it is also contained in the list
66
+ !this.fonts.has(font.family) &&
67
+ // `families` parameter: Only keep fonts whose names are included in the provided array
68
+ (this.options.families.length === 0 ||
69
+ this.options.families.includes(font.family)) &&
70
+ // `categories` parameter: only keep fonts in categories from the provided array
71
+ (this.options.categories.length === 0 ||
72
+ this.options.categories.includes(font.category)) &&
73
+ // `scripts` parameter: Only keep fonts which are available in all specified scripts
74
+ this.options.scripts.every((script): boolean => font.scripts.includes(script)) &&
75
+ // `variants` parameter: Only keep fonts which contain all specified variants
76
+ this.options.variants.every((variant): boolean =>
77
+ font.variants.includes(variant)
78
+ ) &&
79
+ // `filter` parameter: Only keep fonts for which the `filter` function evaluates to `true`
80
+ this.options.filter(font) === true
81
+ ) {
82
+ // Font fulfils all requirements: Add it to font map
83
+ this.fonts.set(font.family, font);
84
+ }
85
+ }
86
+
87
+ return this.fonts;
88
+ }
89
+
90
+ private async getFontList(apiKey: string): Promise<Font[]> {
91
+ const url = new URL(LIST_BASE_URL);
92
+ url.searchParams.append('sort', 'popularity');
93
+ url.searchParams.append('key', apiKey);
94
+ const response = await get(url.href);
95
+ const fontsOriginal = JSON.parse(response).items;
96
+ return fontsOriginal.map((fontOriginal: FontResponse): Font => {
97
+ const { family, subsets, ...others } = fontOriginal;
98
+ return {
99
+ ...others,
100
+ family,
101
+ id: getFontId(family),
102
+ scripts: subsets
103
+ };
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Add a new font to the font map and download its preview characters
109
+ */
110
+ private addFont(fontFamily: string): void {
111
+ const font: Font = {
112
+ family: fontFamily,
113
+ id: getFontId(fontFamily),
114
+ variants: [],
115
+ category: 'display',
116
+ scripts: []
117
+ };
118
+ this.fonts.set(fontFamily, font);
119
+ }
120
+
121
+ /**
122
+ * Set the specified font as the active font and download it
123
+ */
124
+ public setActiveFont(fontFamily: string): void {
125
+ const runOnChange = fontFamily !== 'Font not found';
126
+
127
+ if (runOnChange) {
128
+ this.onChange(fontFamily);
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Update the onChange function (executed when changing the active font)
134
+ */
135
+ public setOnChange(onChange: (font: string) => void): void {
136
+ this.onChange = onChange;
137
+ }
138
+ }
@@ -0,0 +1,7 @@
1
+ export const FONT_BASE_URL = 'https://fonts.googleapis.com/css2';
2
+
3
+ export const LIST_BASE_URL = 'https://www.googleapis.com/webfonts/v1/webfonts';
4
+
5
+ export const FONT_FACE_REGEX = /@font-face {([\s\S]*?)}/gm;
6
+
7
+ export const FONT_FAMILY_DEFAULT = 'Open Sans';
@@ -0,0 +1,78 @@
1
+ import { FONT_BASE_URL, FONT_FACE_REGEX } from './constants';
2
+ import { get, getMatches } from './utils';
3
+
4
+ export const createFontStyleSheets = (
5
+ defaultFonts: any,
6
+ uniqueFonts: any,
7
+ availableFonts?: any
8
+ ): void => {
9
+ defaultFonts.map((font: any) => {
10
+ const fonts = uniqueFonts.find((f: any) => f.family === font.family);
11
+ const fontId = font.name.toLowerCase().split(' ').join('-');
12
+
13
+ // non Google Font style
14
+ if (fonts?.file) {
15
+ fillFontStyleSheets(fontId, font);
16
+ }
17
+
18
+ // google font style
19
+ if (fonts?.files) {
20
+ const fontURL = new URL(FONT_BASE_URL);
21
+ fontURL.searchParams.append('family', `${font.family}:wght@${font.weight}`);
22
+ fontURL.searchParams.append('text', font.name);
23
+ fontURL.searchParams.append('font-display', 'swap');
24
+ get(fontURL.href)
25
+ .then((res) => {
26
+ const rule = getMatches(FONT_FACE_REGEX, res);
27
+ const updateFont = rule[rule.length - 1].replace(font.family, font.name);
28
+ fillFontStyleSheets(fontId, updateFont, font.name);
29
+ })
30
+ .catch((e) => console.error(e));
31
+ }
32
+ });
33
+
34
+ // custom font style
35
+ if (availableFonts) {
36
+ availableFonts.map((font: any) => {
37
+ const fontId = font.name.toLowerCase();
38
+ fillFontStyleSheets(fontId, font);
39
+ });
40
+ }
41
+ };
42
+
43
+ const fillFontStyleSheets = (fontId: string, font: any, fontName?: any) => {
44
+ let stylesheetNode = document.getElementById(`font-${fontId}`);
45
+ const { weight, file, url, name, family } = font;
46
+
47
+ const fontFamily = name !== family ? name : family;
48
+ const fontWeight = weight ? `font-weight: ${weight};` : '';
49
+ const fontUrl = file ? `fonts/${file}` : `${url}`;
50
+
51
+ if (stylesheetNode === null) {
52
+ stylesheetNode = stylesheetNode;
53
+ stylesheetNode = document.createElement('style');
54
+ if (stylesheetNode !== null) {
55
+ stylesheetNode.id = `font-${fontId}`;
56
+ stylesheetNode.setAttribute('data-is-preview', 'true');
57
+
58
+ // non-google and custom fonts style
59
+ if (fontFamily && fontFamily && fontUrl) {
60
+ stylesheetNode.textContent = `
61
+ @font-face {
62
+ font-family: ${fontFamily};
63
+ ${fontWeight}
64
+ src: url(${fontUrl});
65
+ }`;
66
+ }
67
+
68
+ if (fontName) {
69
+ stylesheetNode.textContent = `
70
+ @font-face {
71
+ ${font.replace(`'${fontName}'`, fontName)}
72
+ }`;
73
+ }
74
+
75
+ document.head.appendChild(stylesheetNode);
76
+ }
77
+ }
78
+ };
@@ -0,0 +1,83 @@
1
+ export type Category = 'sans-serif' | 'serif' | 'display' | 'handwriting' | 'monospace';
2
+
3
+ export type Script =
4
+ | 'arabic'
5
+ | 'bengali'
6
+ | 'chinese-simplified'
7
+ | 'chinese-traditional'
8
+ | 'cyrillic'
9
+ | 'cyrillic-ext'
10
+ | 'devanagari'
11
+ | 'greek'
12
+ | 'greek-ext'
13
+ | 'gujarati'
14
+ | 'gurmukhi'
15
+ | 'hebrew'
16
+ | 'japanese'
17
+ | 'kannada'
18
+ | 'khmer'
19
+ | 'korean'
20
+ | 'latin'
21
+ | 'latin-ext'
22
+ | 'malayalam'
23
+ | 'myanmar'
24
+ | 'oriya'
25
+ | 'sinhala'
26
+ | 'tamil'
27
+ | '​telugu'
28
+ | 'thai'
29
+ | 'vietnamese';
30
+
31
+ export type SortOption = 'alphabet' | 'popularity';
32
+
33
+ export type Variant =
34
+ | '100'
35
+ | '100italic'
36
+ | '200'
37
+ | '200italic'
38
+ | '300'
39
+ | '300italic'
40
+ | 'regular'
41
+ | 'italic'
42
+ | '500'
43
+ | '500italic'
44
+ | '600'
45
+ | '600italic'
46
+ | '700'
47
+ | '700italic'
48
+ | '800'
49
+ | '800italic'
50
+ | '900'
51
+ | '900italic';
52
+
53
+ export interface Font {
54
+ family: string;
55
+ id: string;
56
+ category: Category;
57
+ scripts: Script[];
58
+ variants: Variant[];
59
+ kind?: string;
60
+ version?: string;
61
+ lastModified?: string;
62
+ files?: Record<Variant, string>;
63
+ }
64
+
65
+ export type FontList = Map<string, Font>;
66
+
67
+ export interface Options {
68
+ families: string[];
69
+ categories: Category[];
70
+ scripts: Script[];
71
+ variants: Variant[];
72
+ filter: (font: Font) => boolean;
73
+ limit: number;
74
+ }
75
+
76
+ export const OPTIONS_DEFAULTS: Options = {
77
+ families: [],
78
+ categories: [],
79
+ scripts: ['latin'],
80
+ variants: ['regular'],
81
+ filter: () => true,
82
+ limit: 50
83
+ };
@@ -0,0 +1,36 @@
1
+ export const getFontId = (fontFamily: string): string => {
2
+ return fontFamily.replace(/\s+/g, '-').toLowerCase();
3
+ };
4
+
5
+ export const get = (url: string): Promise<string> => {
6
+ return new Promise((resolve, reject): void => {
7
+ const request = new XMLHttpRequest();
8
+ request.overrideMimeType('application/json');
9
+ request.open('GET', url, true);
10
+ request.onreadystatechange = (): void => {
11
+ // Request has completed
12
+ if (request.readyState === 4) {
13
+ if (request.status !== 200) {
14
+ // On error
15
+ reject(new Error(`Response has status code ${request.status}`));
16
+ } else {
17
+ // On success
18
+ resolve(request.responseText);
19
+ }
20
+ }
21
+ };
22
+ request.send();
23
+ });
24
+ };
25
+
26
+ export const getMatches = (regex: RegExp, str: string): string[] => {
27
+ const matches: string[] = [];
28
+ let match;
29
+ do {
30
+ match = regex.exec(str);
31
+ if (match) {
32
+ matches.push(match[1]);
33
+ }
34
+ } while (match);
35
+ return matches;
36
+ };
package/src/index.ts CHANGED
@@ -142,6 +142,7 @@ import {
142
142
  import PublishStatusIndicator from './components/publish-wizard/publish/PublishStatusIndicator';
143
143
  import { getMediaPreviewStyle } from './utils/assets';
144
144
  import AdvancedNumberField from './components/advanced-number-field/AdvancedNumberField';
145
+ import FontPicker from './components/font-picker/FontPicker';
145
146
 
146
147
  export {
147
148
  AppWrapper,
@@ -276,5 +277,6 @@ export {
276
277
  getMediaPreviewStyle,
277
278
  HEADER_HEIGHT,
278
279
  decoupleAssets,
279
- updateAssetStory
280
+ updateAssetStory,
281
+ FontPicker
280
282
  };