@operato/font 1.0.0-beta.8 → 1.0.1

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 (46) hide show
  1. package/CHANGELOG.md +367 -0
  2. package/custom-elements.json +855 -0
  3. package/dist/src/font-creation-card.d.ts +18 -0
  4. package/dist/src/font-creation-card.js +258 -0
  5. package/dist/src/font-creation-card.js.map +1 -0
  6. package/dist/src/font-graphql-client.d.ts +20 -0
  7. package/dist/src/font-graphql-client.js +109 -0
  8. package/dist/src/font-graphql-client.js.map +1 -0
  9. package/dist/src/font-selector.d.ts +36 -0
  10. package/dist/src/font-selector.js +285 -0
  11. package/dist/src/font-selector.js.map +1 -0
  12. package/dist/src/index.d.ts +5 -0
  13. package/dist/src/index.js +6 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/src/ox-file-selector.d.ts +12 -0
  16. package/dist/src/ox-file-selector.js +129 -0
  17. package/dist/src/ox-file-selector.js.map +1 -0
  18. package/dist/src/ox-font-selector.d.ts +15 -0
  19. package/dist/src/ox-font-selector.js +88 -0
  20. package/dist/src/ox-font-selector.js.map +1 -0
  21. package/dist/src/ox-property-editor-font-selector.d.ts +8 -0
  22. package/dist/src/ox-property-editor-font-selector.js +13 -0
  23. package/dist/src/ox-property-editor-font-selector.js.map +1 -0
  24. package/dist/src/redux-font-actions.d.ts +7 -0
  25. package/dist/src/redux-font-actions.js +19 -0
  26. package/dist/src/redux-font-actions.js.map +1 -0
  27. package/dist/src/redux-font-reducers.d.ts +12 -0
  28. package/dist/src/redux-font-reducers.js +70 -0
  29. package/dist/src/redux-font-reducers.js.map +1 -0
  30. package/dist/tsconfig.tsbuildinfo +1 -0
  31. package/package.json +65 -20
  32. package/src/font-creation-card.ts +260 -0
  33. package/src/{graphql-client.js → font-graphql-client.ts} +35 -26
  34. package/src/font-selector.ts +284 -0
  35. package/src/index.ts +6 -0
  36. package/src/ox-file-selector.ts +114 -0
  37. package/src/ox-font-selector.ts +94 -0
  38. package/src/ox-property-editor-font-selector.ts +17 -0
  39. package/src/redux-font-actions.ts +21 -0
  40. package/src/redux-font-reducers.ts +88 -0
  41. package/src/font-creation-card.js +0 -311
  42. package/src/font-selector.js +0 -465
  43. package/src/index.js +0 -3
  44. package/src/ox-font-selector.js +0 -102
  45. package/src/ox-property-editor-font-selector.js +0 -25
  46. package/things-factory.config.js +0 -5
@@ -0,0 +1,88 @@
1
+ import { CLEAR_FONT_LIST, UPDATE_FONT_LIST } from './redux-font-actions.js'
2
+
3
+ import { Action } from 'redux'
4
+ import WebFont from 'webfontloader'
5
+
6
+ type Font = {
7
+ name: string
8
+ provider: string
9
+ uri: string
10
+ active: boolean
11
+ files: Array<{ name: string; fullpath: string }>
12
+ }
13
+
14
+ const ReducerFont = (state = [], action: any) => {
15
+ switch (action.type) {
16
+ case UPDATE_FONT_LIST:
17
+ let newState = action.list as Array<Font>
18
+ let activatedFonts = newState.filter(font => font.active)
19
+
20
+ let googles = [] as Array<string>
21
+ let customs = [] as Array<string>
22
+ let customFontCSS = ''
23
+
24
+ activatedFonts.forEach(font => {
25
+ const { name, provider, files, uri } = font
26
+
27
+ if (provider === 'google') {
28
+ googles.push(name)
29
+ } else if (provider === 'custom') {
30
+ customs.push(name)
31
+
32
+ if (files && files.length > 0) {
33
+ customFontCSS += files
34
+ .map(file => {
35
+ const { name: filename, fullpath } = file
36
+ const bold = filename.toUpperCase().indexOf('BOLD') !== -1
37
+
38
+ return `@font-face {
39
+ font-family: '${name}';
40
+ src: local('${name}'), url(${fullpath});
41
+ font-weight: ${bold ? 'bold' : 'normal'};
42
+ }
43
+ `
44
+ })
45
+ .join('\n')
46
+ } else {
47
+ customFontCSS += `@font-face {
48
+ font-family: '${name}';
49
+ src: local('${name}')${uri ? `, url(${uri})` : ''};
50
+ }
51
+ `
52
+ }
53
+ }
54
+ })
55
+
56
+ let style = document.head.querySelector('#custom-fonts') as HTMLStyleElement
57
+ if (!style) {
58
+ style = document.createElement('style')
59
+ style.id = 'custom-fonts'
60
+ document.head.appendChild(style)
61
+ }
62
+ style.innerHTML = customFontCSS
63
+
64
+ // TODO: typekit 등 타 서비스 지원
65
+ let WebFontConfig = {} as any
66
+ if (googles.length) {
67
+ WebFontConfig.google = {
68
+ families: googles
69
+ }
70
+ }
71
+ if (customs.length) {
72
+ WebFontConfig.custom = {
73
+ families: customs
74
+ }
75
+ }
76
+ if (Object.keys(WebFontConfig).length) WebFont.load(WebFontConfig)
77
+
78
+ return newState
79
+
80
+ case CLEAR_FONT_LIST:
81
+ return []
82
+
83
+ default:
84
+ return state
85
+ }
86
+ }
87
+
88
+ export default ReducerFont
@@ -1,311 +0,0 @@
1
- import "@operato/attachment";
2
-
3
- import { LitElement, css, html } from "lit";
4
- import { i18next, localize } from "@operato/i18n";
5
-
6
- import { FileDropHelper } from "@operato/utils";
7
-
8
- export class FontCreationCard extends localize(i18next)(LitElement) {
9
- static get properties() {
10
- return {
11
- provider: {
12
- type: String,
13
- },
14
- googleFonts: {
15
- type: Array,
16
- },
17
- _files: {
18
- type: Array,
19
- },
20
- };
21
- }
22
-
23
- constructor() {
24
- super();
25
- this.provider = "google";
26
- this.providers = [
27
- { value: "google", display: "Google" },
28
- // TODO 구글 외 폰트 서비스 구현
29
- // { value: 'typekit', display: 'Typekit' },
30
- { value: "custom", display: "Custom" },
31
- ];
32
- this.googleFonts = [];
33
- }
34
-
35
- static get styles() {
36
- return [
37
- css`
38
- :host {
39
- position: relative;
40
-
41
- padding: 0;
42
- margin: 0;
43
- height: 100%;
44
-
45
- -webkit-transform-style: preserve-3d;
46
- transform-style: preserve-3d;
47
- -webkit-transition: all 0.5s ease-in-out;
48
- transition: all 0.5s ease-in-out;
49
- }
50
-
51
- :host(.candrop) [front],
52
- :host(.candrop) [back] {
53
- border-width: 2px;
54
- background-color: #fffde9;
55
- }
56
-
57
- :host(.flipped) {
58
- -webkit-transform: var(--card-list-flip-transform);
59
- transform: var(--card-list-flip-transform);
60
- }
61
-
62
- [front],
63
- [back] {
64
- position: absolute;
65
-
66
- width: 100%;
67
- height: 100%;
68
- margin: 0;
69
- padding: 0;
70
-
71
- border: var(--card-list-create-border);
72
- border-radius: var(--card-list-create-border-radius);
73
-
74
- background-color: #fff;
75
-
76
- -webkit-backface-visibility: hidden;
77
- backface-visibility: hidden;
78
- }
79
-
80
- [front] {
81
- display: flex;
82
- flex-direction: column;
83
- align-items: center;
84
- justify-content: center;
85
-
86
- text-align: center;
87
- font-size: 0.8em;
88
- color: var(--card-list-create-color);
89
- text-transform: capitalize;
90
- }
91
-
92
- [front] mwc-icon {
93
- font-size: 3.5em;
94
- color: var(--card-list-create-icon-color);
95
- }
96
-
97
- [back] {
98
- -webkit-transform: var(--card-list-flip-transform);
99
- transform: var(--card-list-flip-transform);
100
- box-sizing: border-box;
101
- display: grid;
102
- }
103
-
104
- [back] form {
105
- padding: var(--card-list-create-form-padding);
106
- width: 100%;
107
- height: 100%;
108
- box-sizing: border-box;
109
- display: grid;
110
- grid-template-columns: 1fr;
111
- grid-template-rows: auto 1fr auto;
112
- justify-content: center;
113
- align-items: center;
114
- }
115
-
116
- [back] form .props {
117
- width: 100%;
118
- height: 100%;
119
- box-sizing: border-box;
120
- display: grid;
121
- grid-template-columns: repeat(10, 1fr);
122
- grid-row-gap: 7px;
123
- justify-content: center;
124
- align-items: center;
125
- }
126
-
127
- [back] form .props label {
128
- grid-column: span 4;
129
- font: var(--card-list-create-label-font);
130
- color: var(--card-list-create-label-color);
131
- }
132
-
133
- [back] form .props input,
134
- [back] form .props select {
135
- grid-column: span 6;
136
- background-color: #fff;
137
- border: var(--card-list-create-input-border);
138
- border-radius: var(--card-list-create-input-border-radius);
139
- font: var(--card-list-create-input-font);
140
- color: var(--card-list-create-input-color);
141
- width: -moz-available;
142
- }
143
-
144
- file-selector {
145
- grid-column: span 6;
146
- font: var(--card-list-create-input-font);
147
- border: none;
148
- box-sizing: border-box;
149
- padding: 0;
150
- }
151
-
152
- [back] input[type="submit"] {
153
- background-color: var(--button-background-color) !important;
154
- font: var(--button-font);
155
- color: var(--button-color) !important;
156
- border-radius: var(--button-radius);
157
- border: var(--button-border);
158
- grid-column: span 10;
159
- grid-row: auto / -1;
160
- }
161
-
162
- .hidden {
163
- display: none !important;
164
- }
165
- `,
166
- ];
167
- }
168
-
169
- async firstUpdated() {
170
- FileDropHelper.set(this);
171
- }
172
-
173
- render() {
174
- let isProviderGoogle =
175
- this.provider == "google" && this.googleFonts.length > 0;
176
- let isFileAttached = this._files.length > 0 ? true : false;
177
- return html`
178
- <div @click=${(e) => this.onClickFlip(e)} front>
179
- <mwc-icon>add_circle_outline</mwc-icon>create font
180
- </div>
181
-
182
- <div @click=${(e) => this.onClickFlip(e)} back>
183
- <form @submit=${(e) => this.onClickSubmit(e)}>
184
- <div class="props">
185
- <label>${i18next.t("label.provider")}</label>
186
- <select
187
- name="provider"
188
- @change=${(e) => {
189
- this.provider = e.target.value;
190
- if (e.target.value === "google") {
191
- fetch(`/all-google-fonts`).then(async (response) => {
192
- if (response.ok) this.googleFonts = await response.json();
193
- else {
194
- console.warn(
195
- `(${response.url}) ${response.status} ${response.statusText}. Could not load Google fonts.`
196
- );
197
- }
198
- });
199
- }
200
- }}
201
- >
202
- ${this.providers.map(
203
- (p) =>
204
- html`
205
- <option
206
- value=${p.value}
207
- ?selected=${this.provider == p.value}
208
- >
209
- ${p.display}
210
- </option>
211
- `
212
- )}
213
- </select>
214
-
215
- <label>${i18next.t("label.name")}</label>
216
- <input
217
- type="text"
218
- name="${isProviderGoogle ? "" : "name"}"
219
- ?hidden=${isProviderGoogle}
220
- />
221
- <select
222
- name="${isProviderGoogle ? "name" : ""}"
223
- ?hidden=${!isProviderGoogle}
224
- >
225
- ${isProviderGoogle &&
226
- this.googleFonts.map(
227
- (f) => html` <option value=${f}>${f}</option> `
228
- )}
229
- </select>
230
-
231
- <label ?hidden=${this.provider != "custom"}
232
- >${i18next.t("label.uri")}</label
233
- >
234
- <input
235
- ?hidden=${this.provider != "custom"}
236
- ?disabled=${isFileAttached}
237
- .value=${isFileAttached ? this._files[0].name : ""}
238
- type="text"
239
- name="uri"
240
- />
241
- <!-- display when attachment module is imported -->
242
- <label ?hidden=${this.provider != "custom"}
243
- >${i18next.t("label.file")}</label
244
- >
245
- <file-selector
246
- class="${this.provider != "custom" ? "hidden" : ""}"
247
- name="file"
248
- label="${i18next.t("label.select file")}"
249
- accept=".ttf,.otf,.woff,.woff2,.eot,.svg,.svgz"
250
- multiple
251
- @file-change=${(e) => {
252
- this._files = Array.from(e.detail.files);
253
- }}
254
- ></file-selector>
255
- <!------------------------------------------------>
256
-
257
- <label for="checkbox-active" @click=${(e) => e.stopPropagation()}>
258
- ${i18next.t("label.active")}
259
- </label>
260
- <input id="checkbox-active" type="checkbox" name="active" checked />
261
- </div>
262
- <div></div>
263
- <input type="submit" value=${i18next.t("button.create")} />
264
- </form>
265
- </div>
266
- `;
267
- }
268
-
269
- onClickFlip(e) {
270
- if (
271
- !["INPUT", "SELECT", "OPTION"].find(
272
- (tagName) => tagName === e.target.tagName
273
- )
274
- ) {
275
- if (e.currentTarget.hasAttribute("front")) this.reset(); // 입력 폼으로 뒤집기 전에 한 번 리셋
276
- this.classList.toggle("flipped");
277
- }
278
- }
279
-
280
- async onClickSubmit(e) {
281
- e.preventDefault();
282
- e.stopPropagation();
283
-
284
- var form = e.target;
285
-
286
- var detail = {};
287
- detail.name = form.elements["name"].value;
288
- detail.provider = form.elements["provider"].value;
289
- detail.active = form.elements["active"].checked;
290
- if (this.provider === "custom") {
291
- detail.uri = form.elements["uri"].value;
292
- if (this._files?.length > 0) {
293
- detail._files = this._files;
294
- }
295
- }
296
-
297
- this.dispatchEvent(new CustomEvent("create-font", { detail }));
298
- }
299
-
300
- reset() {
301
- var form = this.shadowRoot.querySelector("form");
302
- if (form) {
303
- form.reset();
304
- }
305
-
306
- this._files = [];
307
- this.classList.remove("flipped");
308
- }
309
- }
310
-
311
- customElements.define("font-creation-card", FontCreationCard);