@progressive-development/pd-contact 1.0.0 → 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.
@@ -2,7 +2,7 @@ import { LitElement, css, html, nothing } from 'lit';
2
2
  import { property, state, query } from 'lit/decorators.js';
3
3
  import { msg, str } from '@lit/localize';
4
4
  import '@progressive-development/pd-icon/pd-icon';
5
- import '../pd-page/dist/pd-socialmedia.js';
5
+ import '@progressive-development/pd-page/pd-socialmedia';
6
6
  import '@progressive-development/pd-forms/pd-checkbox';
7
7
  import '@progressive-development/pd-forms/pd-form-container';
8
8
  import '@progressive-development/pd-forms/pd-form-row';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progressive-development/pd-contact",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Progressive Development Contact component",
5
5
  "author": "PD Progressive Development",
6
6
  "license": "MIT",
@@ -24,23 +24,6 @@
24
24
  "README.md",
25
25
  "LICENSE"
26
26
  ],
27
- "dependencies": {
28
- "lit": "^3.3.1",
29
- "@lit/localize": "^0.12.2",
30
- "tslib": "^2.8.1",
31
- "@progressive-development/pd-icon": "1.0.0",
32
- "@progressive-development/pd-shared-styles": "0.3.1",
33
- "@progressive-development/pd-forms": "1.0.0"
34
- },
35
- "customElements": "custom-elements.json",
36
- "keywords": [
37
- "pd",
38
- "progressive",
39
- "development",
40
- "contact",
41
- "form",
42
- "view"
43
- ],
44
27
  "scripts": {
45
28
  "analyze": "cem analyze --litelement --exclude dist,demo",
46
29
  "start": "vite",
@@ -54,9 +37,27 @@
54
37
  "test": "vitest run --coverage",
55
38
  "test:watch": "vitest --watch",
56
39
  "check": "pnpm run lint && pnpm run lint:lit && pnpm run build",
40
+ "prepublishOnly": "pnpm run clean && pnpm run check",
57
41
  "localizeExtract": "lit-localize extract",
58
42
  "localizeBuild": "lit-localize build",
59
43
  "storybook": "storybook dev -p 6006",
60
44
  "build-storybook": "storybook build"
61
- }
62
- }
45
+ },
46
+ "dependencies": {
47
+ "lit": "^3.3.1",
48
+ "@lit/localize": "^0.12.2",
49
+ "@progressive-development/pd-shared-styles": "workspace:*",
50
+ "@progressive-development/pd-icon": "workspace:*",
51
+ "@progressive-development/pd-forms": "workspace:*",
52
+ "tslib": "^2.8.1"
53
+ },
54
+ "customElements": "custom-elements.json",
55
+ "keywords": [
56
+ "pd",
57
+ "progressive",
58
+ "development",
59
+ "contact",
60
+ "form",
61
+ "view"
62
+ ]
63
+ }
@@ -1,426 +0,0 @@
1
- import { css, LitElement, html, nothing } from 'lit';
2
- import { property, state, query } from 'lit/decorators.js';
3
- import { localized, msg } from '@lit/localize';
4
- import '@progressive-development/pd-forms/pd-suggestion-box';
5
- import '@progressive-development/pd-forms/pd-form-row';
6
- import '@progressive-development/pd-forms/pd-button';
7
- import '@progressive-development/pd-forms/pd-input';
8
- import '@progressive-development/pd-icon/pd-icon';
9
- import { SOCIAL_PROVIDERS } from './pd-socialmedia-model.js';
10
- import { pdIcons } from '@progressive-development/pd-icon';
11
-
12
- var __defProp = Object.defineProperty;
13
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
14
- var __decorateClass = (decorators, target, key, kind) => {
15
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
16
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
17
- if (decorator = decorators[i])
18
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
19
- if (kind && result) __defProp(target, key, result);
20
- return result;
21
- };
22
- let PdSocialmedia = class extends LitElement {
23
- constructor() {
24
- super(...arguments);
25
- this.summary = false;
26
- this.initItems = [];
27
- this.providers = SOCIAL_PROVIDERS;
28
- this.showLabelBelowIcon = false;
29
- this.openLinksInSameTab = false;
30
- this._pendingAddProvider = null;
31
- this._currentInputValue = null;
32
- this._editItems = [];
33
- this._openAddSuggestItem = (e) => {
34
- const metaProvider = e.detail;
35
- const providerId = metaProvider?.id;
36
- if (!providerId) return;
37
- this._pendingAddProvider = metaProvider;
38
- this._currentInputValue = null;
39
- };
40
- this._closeAddSuggestedItem = (_e) => {
41
- this._pendingAddProvider = null;
42
- this._currentInputValue = null;
43
- };
44
- }
45
- willUpdate(_changedProperties) {
46
- if (_changedProperties.has("initItems")) {
47
- this._editItems = [...this.initItems || []];
48
- }
49
- }
50
- // --- Public API helpers ---
51
- addItem(entry) {
52
- const next = [...this._editItems, entry];
53
- this._editItems = next;
54
- this.emitChange();
55
- }
56
- removeIndex(index) {
57
- const next = this._editItems.slice();
58
- next.splice(index, 1);
59
- this._editItems = next;
60
- this.emitChange();
61
- }
62
- get value() {
63
- return this._editItems;
64
- }
65
- // --- Render ---
66
- render() {
67
- return this.summary ? this.renderView() : this.renderEdit();
68
- }
69
- renderView() {
70
- const items = this._editItems ?? [];
71
- const empty = items.length === 0;
72
- return html`
73
- <ul
74
- class="view-list"
75
- aria-label="${msg("Social-Media-Profile", {
76
- id: "pd.socialmedia.aria.label"
77
- })}"
78
- >
79
- ${empty ? html`<li>
80
- <span
81
- >${msg("Keine Einträge", { id: "pd.socialmedia.empty" })}</span
82
- >
83
- </li>` : items.map((item) => {
84
- const provider = this._findProvider(item.providerId);
85
- const label = provider?.label ?? item.label ?? item.providerId;
86
- const href = this._toUrl(provider, item.value);
87
- const title = `${label}: ${href}`;
88
- const content = html`
89
- <div class="icon-tile" title=${title}>
90
- ${provider?.icon ?? "link"}
91
- ${this.showLabelBelowIcon ? html`<div class="icon-label">${label}</div>` : nothing}
92
- </div>
93
- `;
94
- return html` <li>
95
- ${href ? html` <a
96
- href=${href}
97
- target=${this.openLinksInSameTab ? "_self" : "_blank"}
98
- rel="noopener noreferrer"
99
- aria-label=${label}
100
- >${content}</a
101
- >` : html`<div class="icon-tile" aria-label=${label}>
102
- ${content}
103
- </div>`}
104
- </li>`;
105
- })}
106
- </ul>
107
- `;
108
- }
109
- renderEdit() {
110
- return html`
111
- <div class="edit">
112
- <div>
113
- <pd-form-row>
114
- <pd-suggestion-box
115
- id="suggesBoxId"
116
- span="full"
117
- label="${msg("Neuer Eintrag", {
118
- id: "pd.socialmedia.new.entry"
119
- })}"
120
- minCharsToSearch="1"
121
- placeholder="${msg("Socialmedia eingeben...", {
122
- id: "pd.socialmedia.placeholder"
123
- })}"
124
- .callFunction="${this._searchSocialProviders.bind(this)}"
125
- @element-selected="${this._openAddSuggestItem}"
126
- @element-unselected="${this._closeAddSuggestedItem}"
127
- @pd-form-element-change="${(e) => e.stopPropagation()}"
128
- @pd-form-element-register="${(e) => e.stopPropagation()}"
129
- @pd-form-element-unregister="${(e) => e.stopPropagation()}"
130
- ></pd-suggestion-box>
131
- </pd-form-row>
132
- ${this._pendingAddProvider !== null ? this._renderAddRow() : ""}
133
- </div>
134
-
135
- <div class="edit-list">
136
- ${this._editItems?.map((item, i) => {
137
- const meta = this._findProvider(item.providerId);
138
- const label = meta?.label ?? item.providerId;
139
- return html`
140
- <div class="row">
141
- <div class="provider">
142
- ${meta?.icon ?? "link"}<span>${label}</span>
143
- </div>
144
- <div class="value">${item.value}</div>
145
- <button
146
- class="btn-icon danger"
147
- @click=${() => this.removeIndex(i)}
148
- aria-label="${msg("Eintrag löschen", {
149
- id: "pd.socialmedia.delete"
150
- })}"
151
- >
152
- <pd-icon icon="${pdIcons.ICON_DELETE_NEW}"></pd-icon>
153
- </button>
154
- </div>
155
- `;
156
- })}
157
- </div>
158
- </div>
159
- `;
160
- }
161
- _renderAddRow() {
162
- const provider = this._pendingAddProvider;
163
- if (!provider) return html`<p>! Missing Provider !</p>`;
164
- return html`
165
- <pd-form-row class="no-padding">
166
- <pd-input
167
- id="scValueId"
168
- maxlength="250"
169
- span="full"
170
- label="${`${provider.icon} ${provider.label}`}"
171
- helperTxt="${`Pattern: ${provider.pattern}`}"
172
- placeholder="${provider.placeholder || `Eingabe ${provider.inputKind}`}"
173
- valueName="providerValue"
174
- @pd-form-element-change="${(e) => {
175
- this._currentInputValue = e.detail.value;
176
- e.stopPropagation();
177
- }}"
178
- @pd-form-element-register="${(e) => e.stopPropagation()}"
179
- @pd-form-element-unregister="${(e) => e.stopPropagation()}"
180
- required
181
- ></pd-input>
182
- </pd-form-row>
183
- <div class="current-input-url">
184
- URL:
185
- <a
186
- target="_blank"
187
- href="${this._toUrl(provider, this._currentInputValue || "") || ""}"
188
- >${this._toUrl(provider, this._currentInputValue || "")}</a
189
- >
190
- </div>
191
-
192
- <div class="add-button-group">
193
- <pd-button
194
- icon="${pdIcons.ICON_CLOSE}"
195
- text="${msg("Abbrechen", { id: "pd.socialmedia.cancel" })}"
196
- @button-clicked="${() => {
197
- this._currentInputValue = null;
198
- this._pendingAddProvider = null;
199
- this._suggestForm?.reset();
200
- }}"
201
- ></pd-button>
202
- <pd-button
203
- icon="${pdIcons.ICON_SYNC}"
204
- text="${msg("Speichern", { id: "pd.socialmedia.save" })}"
205
- @button-clicked="${() => {
206
- this.addItem({
207
- providerId: this._pendingAddProvider?.id || "",
208
- value: this._currentInputValue || ""
209
- });
210
- this._currentInputValue = null;
211
- this._pendingAddProvider = null;
212
- this._suggestForm?.reset();
213
- }}"
214
- ></pd-button>
215
- </div>
216
- `;
217
- }
218
- // --- Suggest Box Helper
219
- async _searchSocialProviders(input) {
220
- const includedIds = this._editItems.map((item) => item.providerId);
221
- return Promise.resolve(
222
- SOCIAL_PROVIDERS.filter(
223
- (v) => !includedIds.includes(v.id) && (v.label.toLowerCase().includes(input.toLowerCase()) || v.category.toLowerCase().includes(input.toLowerCase()) || v.aliases?.join()?.toLowerCase().includes(input.toLowerCase()))
224
- ).map((e) => ({
225
- id: e.id,
226
- name: `${e.icon || ""} ${e.label || "--"}`,
227
- subInfo: html`<b><em>${e.category || "--"}:</em></b> ${e.aliases?.join(
228
- ","
229
- ) || e.id}`,
230
- objectValue: e
231
- }))
232
- );
233
- }
234
- // --- Private helpers ---
235
- _findProvider(id) {
236
- if (!id) return void 0;
237
- return this.providers?.find((p) => p.id === id);
238
- }
239
- _toUrl(meta, raw) {
240
- const v = raw?.trim();
241
- if (!v) return null;
242
- if (meta?.toUrl) return meta.toUrl(v);
243
- if (/^https?:\/\//i.test(v)) return v;
244
- return null;
245
- }
246
- emitChange() {
247
- this.dispatchEvent(
248
- new CustomEvent("items-change", {
249
- detail: { items: this._editItems },
250
- bubbles: true,
251
- composed: true
252
- })
253
- );
254
- }
255
- };
256
- PdSocialmedia.styles = css`
257
- :host {
258
- display: block;
259
- }
260
-
261
- /* View: icons row */
262
- .view-list {
263
- display: flex;
264
- flex-wrap: wrap;
265
- gap: var(--pd-gap, 0.5rem);
266
- align-items: center;
267
- list-style: none;
268
- padding: 0;
269
- margin: 0;
270
- }
271
-
272
- .view-list li:hover .icon-tile .icon-label {
273
- color: var(--pd-default-hover-col);
274
- }
275
-
276
- .icon-tile {
277
- display: inline-flex;
278
- flex-direction: column;
279
- align-items: center;
280
- justify-content: center;
281
- gap: 0.25rem;
282
- padding: 0.25rem;
283
- min-width: 2.25rem;
284
- }
285
-
286
- .icon-tile a,
287
- .icon-tile button[role="link"] {
288
- display: inline-flex;
289
- align-items: center;
290
- justify-content: center;
291
- text-decoration: none;
292
- outline: none;
293
- border: none;
294
- background: none;
295
- cursor: pointer;
296
- }
297
-
298
- .icon-label {
299
- font-size: 0.75rem;
300
- line-height: 1;
301
- color: var(--pd-sc-text-muted, var(--pd-default-disabled-col));
302
- text-align: center;
303
- max-width: 6rem;
304
- }
305
-
306
- /* Edit: list */
307
- .edit {
308
- display: flex;
309
- flex-direction: column;
310
- gap: 1rem;
311
- }
312
-
313
- .edit-list {
314
- display: flex;
315
- flex-direction: column;
316
- gap: 0.1rem;
317
- }
318
-
319
- .row {
320
- display: grid;
321
- grid-template-columns: auto 1fr auto;
322
- align-items: center;
323
- gap: 0;
324
- padding: 0 var(--pd-spacing-xs);
325
- border-radius: var(--pd-radius-md);
326
- max-width: 500px;
327
- }
328
-
329
- .edit-list > .row:nth-child(odd) {
330
- background: var(--pd-sc-row-bg-odd-col, var(--pd-default-bg-light-col));
331
- }
332
-
333
- .edit-list > .row:nth-child(even) {
334
- background: var(--pd-sc-row-bg-even-col, var(--pd-default-bg-dark-col));
335
- }
336
-
337
- .edit-list > .row:hover {
338
- background: var(--pd-sc-row-bg-col-hover, var(--pd-default-lightest-col));
339
- }
340
-
341
- .provider {
342
- font-family: var(--pd-default-font-title-family);
343
- color: var(--pd-sc-edit-provider-col, var(--pd-default-font-title-col));
344
- display: inline-flex;
345
- align-items: center;
346
- gap: 0.5rem;
347
- min-width: 10rem;
348
- }
349
-
350
- .value {
351
- font-family: var(--pd-default-font-input-family);
352
- font-size: 0.95rem;
353
- color: var(--pd-sc-edit-value-col, var(--pd-default-font-input-col));
354
- overflow: hidden;
355
- text-overflow: ellipsis;
356
- white-space: nowrap;
357
- }
358
-
359
- .btn-icon {
360
- display: inline-flex;
361
- align-items: center;
362
- justify-content: center;
363
- width: 2rem;
364
- height: 2rem;
365
- border: none;
366
- background: none;
367
- border-radius: 0.5rem;
368
- cursor: pointer;
369
- }
370
-
371
- .btn-icon:hover {
372
- background: var(--pd-surface-200, rgba(0, 0, 0, 0.05));
373
- }
374
-
375
- .danger {
376
- --pd-icon-col: var(--pd-default-error-col, #c0392b);
377
- }
378
-
379
- .btn-icon:focus-visible {
380
- outline: 2px solid var(--pd-focus-ring-col, var(--pd-default-col));
381
- outline-offset: 2px;
382
- }
383
-
384
- .current-input-url {
385
- color: var(--pd-sc-text-muted, var(--pd-default-disabled-col));
386
- padding-top: 0.2rem;
387
- font-size: 1rem;
388
- }
389
-
390
- .add-button-group {
391
- padding-top: 0.5rem;
392
- --pd-button-font-size: 1rem;
393
- }
394
- `;
395
- __decorateClass([
396
- property({ type: Boolean, reflect: true })
397
- ], PdSocialmedia.prototype, "summary", 2);
398
- __decorateClass([
399
- property({ type: Array })
400
- ], PdSocialmedia.prototype, "initItems", 2);
401
- __decorateClass([
402
- property({ type: Array })
403
- ], PdSocialmedia.prototype, "providers", 2);
404
- __decorateClass([
405
- property({ type: Boolean })
406
- ], PdSocialmedia.prototype, "showLabelBelowIcon", 2);
407
- __decorateClass([
408
- property({ type: Boolean })
409
- ], PdSocialmedia.prototype, "openLinksInSameTab", 2);
410
- __decorateClass([
411
- state()
412
- ], PdSocialmedia.prototype, "_pendingAddProvider", 2);
413
- __decorateClass([
414
- state()
415
- ], PdSocialmedia.prototype, "_currentInputValue", 2);
416
- __decorateClass([
417
- state()
418
- ], PdSocialmedia.prototype, "_editItems", 2);
419
- __decorateClass([
420
- query("#suggesBoxId")
421
- ], PdSocialmedia.prototype, "_suggestForm", 2);
422
- PdSocialmedia = __decorateClass([
423
- localized()
424
- ], PdSocialmedia);
425
-
426
- export { PdSocialmedia };
@@ -1,240 +0,0 @@
1
- const trim = (s) => s.trim();
2
- const stripAt = (s) => s.replace(/^@/, "");
3
- const ensureHttps = (url) => /^https?:\/\//i.test(url) ? url : `https://${url}`;
4
- const SOCIAL_PROVIDERS = [
5
- // --- Social ---
6
- {
7
- id: "instagram",
8
- label: "Instagram",
9
- aliases: ["insta", "ig"],
10
- category: "Social",
11
- icon: "📸",
12
- brandColor: "#E4405F",
13
- inputKind: "username",
14
- placeholder: "@deinname",
15
- pattern: /^[A-Za-z0-9._]{1,30}$/,
16
- normalize: (raw) => stripAt(trim(raw)),
17
- toUrl: (input) => `https://instagram.com/${stripAt(trim(input))}`
18
- },
19
- {
20
- id: "tiktok",
21
- label: "TikTok",
22
- aliases: ["tiktok"],
23
- category: "Social",
24
- icon: "🎵",
25
- brandColor: "#000000",
26
- inputKind: "username",
27
- placeholder: "@deinname",
28
- pattern: /^[A-Za-z0-9._]{2,24}$/,
29
- normalize: (raw) => stripAt(trim(raw)),
30
- toUrl: (input) => `https://www.tiktok.com/@${stripAt(trim(input))}`
31
- },
32
- {
33
- id: "facebook",
34
- label: "Facebook",
35
- aliases: ["fb", "facebook page"],
36
- category: "Social",
37
- icon: "📘",
38
- brandColor: "#1877F2",
39
- inputKind: "url",
40
- placeholder: "facebook.com/deinprofil",
41
- pattern: /^https?:\/\/(www\.)?facebook\.com\/.+/i,
42
- toUrl: (input) => ensureHttps(trim(input))
43
- },
44
- {
45
- id: "x",
46
- label: "X (Twitter)",
47
- aliases: ["twitter"],
48
- category: "Social",
49
- icon: "X",
50
- brandColor: "#000000",
51
- inputKind: "username",
52
- placeholder: "@deinname",
53
- pattern: /^[A-Za-z0-9_]{1,15}$/,
54
- normalize: (raw) => stripAt(trim(raw)),
55
- toUrl: (input) => `https://x.com/${stripAt(trim(input))}`
56
- },
57
- {
58
- id: "youtube",
59
- label: "YouTube",
60
- aliases: ["yt", "youtube channel"],
61
- category: "Streaming",
62
- icon: "▶️",
63
- brandColor: "#FF0000",
64
- inputKind: "url",
65
- placeholder: "youtube.com/@deinname oder Kanal-URL",
66
- pattern: /^https?:\/\/(www\.)?youtube\.com\/.+/i,
67
- toUrl: (input) => ensureHttps(trim(input))
68
- },
69
- {
70
- id: "twitch",
71
- label: "Twitch",
72
- aliases: ["twitch tv"],
73
- category: "Streaming",
74
- icon: "🎮",
75
- brandColor: "#9146FF",
76
- inputKind: "username",
77
- placeholder: "deinname",
78
- pattern: /^[A-Za-z0-9_]{4,25}$/,
79
- normalize: (raw) => trim(raw),
80
- toUrl: (input) => `https://twitch.tv/${trim(input)}`
81
- },
82
- // --- Music / DJ ---
83
- {
84
- id: "soundcloud",
85
- label: "SoundCloud",
86
- aliases: ["sc"],
87
- category: "Music",
88
- icon: "☁️",
89
- brandColor: "#FF5500",
90
- inputKind: "username",
91
- placeholder: "deinname",
92
- pattern: /^[A-Za-z0-9-_.]{3,40}$/,
93
- normalize: (raw) => trim(raw).replace(/^https?:\/\/(www\.)?soundcloud\.com\//i, ""),
94
- toUrl: (input) => `https://soundcloud.com/${trim(input)}`
95
- },
96
- {
97
- id: "mixcloud",
98
- label: "Mixcloud",
99
- aliases: ["mix cloud"],
100
- category: "Music",
101
- icon: "📻",
102
- brandColor: "#5000FF",
103
- inputKind: "username",
104
- placeholder: "deinname",
105
- pattern: /^[A-Za-z0-9-_.]{3,40}$/,
106
- normalize: (raw) => trim(raw).replace(/^https?:\/\/(www\.)?mixcloud\.com\//i, ""),
107
- toUrl: (input) => `https://www.mixcloud.com/${trim(input)}/`
108
- },
109
- {
110
- id: "hearthis",
111
- label: "HearThis.at",
112
- aliases: ["hearthis"],
113
- category: "Music",
114
- icon: "🔊",
115
- brandColor: "#D61C1C",
116
- inputKind: "username",
117
- placeholder: "deinname",
118
- pattern: /^[A-Za-z0-9-_.]{3,40}$/,
119
- normalize: (raw) => trim(raw).replace(/^https?:\/\/(www\.)?hearthis\.at\//i, ""),
120
- toUrl: (input) => `https://hearthis.at/${trim(input)}/`
121
- },
122
- {
123
- id: "beatport",
124
- label: "Beatport (Artist)",
125
- aliases: ["beat port"],
126
- category: "DJ/Booking",
127
- icon: "🎧",
128
- brandColor: "#A8E00F",
129
- inputKind: "url",
130
- placeholder: "beatport.com/artist/... oder /profile/...",
131
- pattern: /^https?:\/\/(www\.)?beatport\.com\/(artist|profile)\/.+/i,
132
- toUrl: (input) => ensureHttps(trim(input))
133
- },
134
- {
135
- id: "residentadvisor",
136
- label: "Resident Advisor",
137
- aliases: ["ra", "ra.co"],
138
- category: "DJ/Booking",
139
- icon: "🟢",
140
- brandColor: "#BADA55",
141
- inputKind: "url",
142
- placeholder: "ra.co/dj/deinname",
143
- pattern: /^https?:\/\/(www\.)?ra\.co\/dj\/.+/i,
144
- toUrl: (input) => ensureHttps(trim(input))
145
- },
146
- {
147
- id: "spotify",
148
- label: "Spotify (Artist)",
149
- aliases: ["spotify artist"],
150
- category: "Music",
151
- icon: "🟢",
152
- brandColor: "#1DB954",
153
- inputKind: "id",
154
- placeholder: "Artist-ID oder vollständige URL",
155
- pattern: /^[0-9A-Za-z]{22}$|^https?:\/\/open\.spotify\.com\/artist\/[0-9A-Za-z]{22}/i,
156
- normalize: (raw) => {
157
- const s = trim(raw);
158
- const m = s.match(/artist\/([0-9A-Za-z]{22})/);
159
- return m ? m[1] : s;
160
- },
161
- toUrl: (input) => {
162
- const id = trim(input).match(/^[0-9A-Za-z]{22}$/) ? input : input.match(/artist\/([0-9A-Za-z]{22})/)?.[1] ?? input;
163
- return `https://open.spotify.com/artist/${id}`;
164
- }
165
- },
166
- {
167
- id: "applemusic",
168
- label: "Apple Music",
169
- aliases: ["itunes", "apple music artist"],
170
- category: "Music",
171
- icon: "🎵",
172
- brandColor: "#FA2D48",
173
- inputKind: "url",
174
- placeholder: "music.apple.com/... (Artist-Link)",
175
- pattern: /^https?:\/\/music\.apple\.com\/.+/i,
176
- toUrl: (input) => ensureHttps(trim(input))
177
- },
178
- {
179
- id: "deezer",
180
- label: "Deezer (Artist)",
181
- aliases: ["deezer"],
182
- category: "Music",
183
- icon: "🎶",
184
- brandColor: "#00C7F2",
185
- inputKind: "url",
186
- placeholder: "deezer.com/artist/...",
187
- pattern: /^https?:\/\/(www\.)?deezer\.com\/.+/i,
188
- toUrl: (input) => ensureHttps(trim(input))
189
- },
190
- {
191
- id: "bandcamp",
192
- label: "Bandcamp",
193
- aliases: ["band camp"],
194
- category: "Music",
195
- icon: "💿",
196
- brandColor: "#629AA9",
197
- inputKind: "url",
198
- placeholder: "deinname.bandcamp.com",
199
- pattern: /^https?:\/\/[A-Za-z0-9-]+\.bandcamp\.com(\/.*)?$/i,
200
- toUrl: (input) => ensureHttps(trim(input))
201
- },
202
- {
203
- id: "discogs",
204
- label: "Discogs",
205
- aliases: ["disc ogs"],
206
- category: "Catalog",
207
- icon: "📀",
208
- brandColor: "#333333",
209
- inputKind: "url",
210
- placeholder: "discogs.com/artist/... oder /user/...",
211
- pattern: /^https?:\/\/(www\.)?discogs\.com\/(artist|user)\/.+/i,
212
- toUrl: (input) => ensureHttps(trim(input))
213
- },
214
- {
215
- id: "mixesdb",
216
- label: "MixesDB",
217
- aliases: ["mixes db"],
218
- category: "Catalog",
219
- icon: "📂",
220
- brandColor: "#FFB000",
221
- inputKind: "url",
222
- placeholder: "mixesdb.com/... (Profil-URL)",
223
- pattern: /^https?:\/\/(www\.)?mixesdb\.com\/.+/i,
224
- toUrl: (input) => ensureHttps(trim(input))
225
- },
226
- {
227
- id: "linkedin",
228
- label: "LinkedIn",
229
- aliases: ["li"],
230
- category: "Social",
231
- icon: "🔗",
232
- brandColor: "#0A66C2",
233
- inputKind: "url",
234
- placeholder: "linkedin.com/in/deinname",
235
- pattern: /^https?:\/\/(www\.)?linkedin\.com\/.+/i,
236
- toUrl: (input) => ensureHttps(trim(input))
237
- }
238
- ];
239
-
240
- export { SOCIAL_PROVIDERS };
@@ -1,7 +0,0 @@
1
- import { PdSocialmedia } from './pd-socialmedia/PdSocialmedia.js';
2
-
3
- if (!customElements.get("pd-socialmedia")) {
4
- customElements.define("pd-socialmedia", PdSocialmedia);
5
- }
6
-
7
- export { PdSocialmedia };