@progressive-development/pd-page 0.9.2 → 1.0.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 (69) hide show
  1. package/LICENSE +21 -2
  2. package/README.md +34 -57
  3. package/dist/generated/locales/be.d.ts +19 -1
  4. package/dist/generated/locales/be.d.ts.map +1 -1
  5. package/dist/generated/locales/de.d.ts +19 -1
  6. package/dist/generated/locales/de.d.ts.map +1 -1
  7. package/dist/generated/locales/en.d.ts +19 -1
  8. package/dist/generated/locales/en.d.ts.map +1 -1
  9. package/dist/index.d.ts +6 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +7 -0
  12. package/dist/locales/be.js +19 -1
  13. package/dist/locales/de.js +19 -1
  14. package/dist/locales/en.js +19 -1
  15. package/dist/pd-contact-us/PdContactUs.d.ts +15 -5
  16. package/dist/pd-contact-us/PdContactUs.d.ts.map +1 -1
  17. package/dist/pd-contact-us/PdContactUs.js +94 -131
  18. package/dist/pd-contact-us/pd-contact-us.stories.d.ts +36 -5
  19. package/dist/pd-contact-us/pd-contact-us.stories.d.ts.map +1 -1
  20. package/dist/pd-content/dist/pd-notice-box/PdNoticeBox.js +224 -0
  21. package/dist/pd-content/dist/pd-notice-box/pd-notice-box.js +8 -0
  22. package/dist/pd-footer/PdFooter.d.ts +27 -15
  23. package/dist/pd-footer/PdFooter.d.ts.map +1 -1
  24. package/dist/pd-footer/PdFooter.js +122 -71
  25. package/dist/pd-footer/pd-footer.stories.d.ts +47 -7
  26. package/dist/pd-footer/pd-footer.stories.d.ts.map +1 -1
  27. package/dist/pd-login/PdLogin.d.ts +59 -0
  28. package/dist/pd-login/PdLogin.d.ts.map +1 -0
  29. package/dist/pd-login/PdLogin.js +292 -0
  30. package/dist/pd-login/pd-login.d.ts +3 -0
  31. package/dist/pd-login/pd-login.d.ts.map +1 -0
  32. package/dist/pd-login/pd-login.stories.d.ts +55 -0
  33. package/dist/pd-login/pd-login.stories.d.ts.map +1 -0
  34. package/dist/pd-login.d.ts +2 -0
  35. package/dist/pd-login.js +8 -0
  36. package/dist/pd-menu/PdMenu.d.ts +72 -40
  37. package/dist/pd-menu/PdMenu.d.ts.map +1 -1
  38. package/dist/pd-menu/PdMenu.js +384 -273
  39. package/dist/pd-menu/pd-menu.stories.d.ts +59 -17
  40. package/dist/pd-menu/pd-menu.stories.d.ts.map +1 -1
  41. package/dist/pd-socialmedia/PdSocialmedia.d.ts +56 -0
  42. package/dist/pd-socialmedia/PdSocialmedia.d.ts.map +1 -0
  43. package/dist/pd-socialmedia/PdSocialmedia.js +426 -0
  44. package/dist/pd-socialmedia/pd-socialmedia-model.d.ts +16 -0
  45. package/dist/pd-socialmedia/pd-socialmedia-model.d.ts.map +1 -0
  46. package/dist/pd-socialmedia/pd-socialmedia-model.js +240 -0
  47. package/dist/pd-socialmedia/pd-socialmedia.d.ts +3 -0
  48. package/dist/pd-socialmedia/pd-socialmedia.d.ts.map +1 -0
  49. package/dist/pd-socialmedia/pd-socialmedia.stories.d.ts +53 -0
  50. package/dist/pd-socialmedia/pd-socialmedia.stories.d.ts.map +1 -0
  51. package/dist/pd-socialmedia.d.ts +2 -0
  52. package/dist/pd-socialmedia.js +7 -0
  53. package/dist/pd-toast/PdToast.d.ts +23 -0
  54. package/dist/pd-toast/PdToast.d.ts.map +1 -0
  55. package/dist/pd-toast/PdToast.js +222 -0
  56. package/dist/pd-toast/pd-toast.d.ts +3 -0
  57. package/dist/pd-toast/pd-toast.d.ts.map +1 -0
  58. package/dist/pd-toast/pd-toast.stories.d.ts +47 -0
  59. package/dist/pd-toast/pd-toast.stories.d.ts.map +1 -0
  60. package/dist/pd-toast.d.ts +2 -0
  61. package/dist/pd-toast.js +8 -0
  62. package/dist/stories/01_index.stories.d.ts +36 -4
  63. package/dist/stories/01_index.stories.d.ts.map +1 -1
  64. package/dist/toast-bus/toast-bus.d.ts +61 -0
  65. package/dist/toast-bus/toast-bus.d.ts.map +1 -0
  66. package/dist/toast-bus/toast-bus.js +42 -0
  67. package/dist/types.d.ts +18 -0
  68. package/dist/types.d.ts.map +1 -1
  69. package/package.json +13 -7
@@ -1,20 +1,62 @@
1
1
  import { TemplateResult } from 'lit';
2
- import { Meta, StoryFn } from '@storybook/web-components';
3
- import { PdMenu } from './pd-menu.js';
2
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
3
+ import { PdMenuItem } from '../types.js';
4
+ import { ButtonData } from '@progressive-development/pd-forms';
5
+ /**
6
+ * Story arguments interface for pd-menu component.
7
+ * Maps to the component's public API.
8
+ */
9
+ interface PdMenuArgs {
10
+ /** Main menu items */
11
+ menuItems: PdMenuItem[];
12
+ /** Top menu items (profile, settings, etc.) */
13
+ topMenuItems: PdMenuItem[];
14
+ /** Available language options (ButtonData with text and value) */
15
+ locales: ButtonData[];
16
+ /** Currently selected language (value from ButtonData) */
17
+ selectedLocale: string;
18
+ /** Disable responsive burger menu */
19
+ noBurgerMenu: boolean;
20
+ /** Custom logo slot content */
21
+ logo?: TemplateResult;
22
+ }
4
23
  export declare const ticomiLogo: TemplateResult<1>;
5
- declare const _default: Meta<PdMenu>;
6
- export default _default;
7
- type PdMenuArgs = Partial<PdMenu> & {
8
- color?: string;
9
- logo?: TemplateResult<1>;
10
- menuColor: string;
11
- noBurger: boolean;
12
- menuHeight: number;
13
- };
14
- export declare const BasicColor1: StoryFn<PdMenuArgs>;
15
- export declare const BasicColor2: StoryFn<PdMenuArgs>;
16
- export declare const WithLogo: StoryFn<PdMenuArgs>;
17
- export declare const WithTopItems: StoryFn<PdMenuArgs>;
18
- export declare const WithoutBurger: StoryFn<PdMenuArgs>;
19
- export declare const SmallTopMenuWithoutBurger: StoryFn<PdMenuArgs>;
24
+ /**
25
+ * ## pd-menu
26
+ *
27
+ * Responsive application navigation menu with burger menu, language selector, and scroll-to-section support.
28
+ *
29
+ * ### Features
30
+ * - Configurable main menu items with scroll-to-section navigation
31
+ * - Top menu bar for secondary actions (profile, settings)
32
+ * - Responsive burger menu for mobile devices (collapses below 768px)
33
+ * - Built-in language selector via pd-button-select-group
34
+ * - Logo slot with click-to-navigate support
35
+ * - Active section highlighting based on scroll position
36
+ * - Full keyboard accessibility (Tab, Enter, Space, Escape)
37
+ *
38
+ * ### Accessibility
39
+ * - Uses `<nav>` with `aria-label` for navigation landmark
40
+ * - Menu items have `role="menuitem"` and `tabindex="0"`
41
+ * - Burger menu button has `aria-expanded` and `aria-controls`
42
+ * - Escape key closes the burger menu
43
+ * - Focus-visible styling for keyboard users
44
+ */
45
+ declare const meta: Meta<PdMenuArgs>;
46
+ export default meta;
47
+ type Story = StoryObj<PdMenuArgs>;
48
+ /** Default menu with basic navigation items. Interactive via Controls panel. */
49
+ export declare const Default: Story;
50
+ /** Menu with a custom logo in the slotLogo slot. */
51
+ export declare const WithLogo: Story;
52
+ /** Menu with logo, top items (profile), and language selector. */
53
+ export declare const FullFeatured: Story;
54
+ /** Menu with noBurgerMenu — always shows full desktop layout regardless of screen width. */
55
+ export declare const WithoutBurger: Story;
56
+ /** Compact top-only menu without main navigation — useful for secondary page headers. */
57
+ export declare const CompactTopMenu: Story;
58
+ /** Overview of different menu configurations at a glance. */
59
+ export declare const AllVariants: Story;
60
+ /** CSS Custom Properties -- Branded and Redesigned variants. */
61
+ export declare const CustomStyling: Story;
20
62
  //# sourceMappingURL=pd-menu.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-menu.stories.d.ts","sourceRoot":"","sources":["../../src/pd-menu/pd-menu.stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,cAAc,CAAC;AAEtB,eAAO,MAAM,UAAU,mBAsEtB,CAAC;wBAYG,IAAI,CAAC,MAAM,CAAC;AAVjB,wBAUkB;AAElB,KAAK,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA8BF,eAAO,MAAM,WAAW,qBAAoB,CAAC;AAW7C,eAAO,MAAM,WAAW,qBAAoB,CAAC;AAM7C,eAAO,MAAM,QAAQ,qBAAoB,CAAC;AAO1C,eAAO,MAAM,YAAY,qBAAoB,CAAC;AAU9C,eAAO,MAAM,aAAa,qBAAoB,CAAC;AAM/C,eAAO,MAAM,yBAAyB,qBAAoB,CAAC"}
1
+ {"version":3,"file":"pd-menu.stories.d.ts","sourceRoot":"","sources":["../../src/pd-menu/pd-menu.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,cAAc,CAAC;AAMtB;;;GAGG;AACH,UAAU,UAAU;IAClB,sBAAsB;IACtB,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,+CAA+C;IAC/C,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,kEAAkE;IAClE,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAMD,eAAO,MAAM,UAAU,mBAiEtB,CAAC;AAiCF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAAU,CA4E1B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;AAMlC,gFAAgF;AAChF,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAMF,oDAAoD;AACpD,eAAO,MAAM,QAAQ,EAAE,KA6BtB,CAAC;AAMF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KA2B1B,CAAC;AAMF,4FAA4F;AAC5F,eAAO,MAAM,aAAa,EAAE,KA+B3B,CAAC;AAMF,yFAAyF;AACzF,eAAO,MAAM,cAAc,EAAE,KA6B5B,CAAC;AAMF,6DAA6D;AAC7D,eAAO,MAAM,WAAW,EAAE,KAmDzB,CAAC;AAMF,gEAAgE;AAChE,eAAO,MAAM,aAAa,EAAE,KA2F3B,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { LitElement, TemplateResult, PropertyValues } from 'lit';
2
+ import { SocialProvider } from './pd-socialmedia-model';
3
+ import { SocialEntry } from '../types';
4
+ /**
5
+ * Social media profiles display and editor component.
6
+ *
7
+ * @summary Social media display (icons) and editor (add/remove) component.
8
+ *
9
+ * @tagname pd-socialmedia
10
+ *
11
+ * @event items-change - Fired when items are added or removed.
12
+ *
13
+ * @cssprop --pd-gap - Icon spacing. Default: `0.5rem`.
14
+ * @cssprop --pd-sc-text-muted - Muted text color. Default: `var(--pd-default-disabled-col)`.
15
+ * @cssprop --pd-sc-row-bg-odd-col - Odd row background. Default: `var(--pd-default-bg-light-col)`.
16
+ * @cssprop --pd-sc-row-bg-even-col - Even row background. Default: `var(--pd-default-bg-dark-col)`.
17
+ * @cssprop --pd-sc-row-bg-col-hover - Row hover background. Default: `var(--pd-default-lightest-col)`.
18
+ * @cssprop --pd-sc-edit-provider-col - Provider label color. Default: `var(--pd-default-font-title-col)`.
19
+ * @cssprop --pd-sc-edit-value-col - Value text color. Default: `var(--pd-default-font-input-col)`.
20
+ */
21
+ export declare class PdSocialmedia extends LitElement {
22
+ /** View mode (true) shows icons, edit mode (false) shows add/remove list. */
23
+ summary: boolean;
24
+ /** Initial social media entries. */
25
+ initItems: SocialEntry[];
26
+ /** Provider metadata definitions (injectable from outside). */
27
+ providers: SocialProvider[];
28
+ /** Show provider label below icon in view mode. */
29
+ showLabelBelowIcon: boolean;
30
+ /** Open links in same tab instead of new tab. */
31
+ openLinksInSameTab: boolean;
32
+ /** @ignore */
33
+ private _pendingAddProvider;
34
+ /** @ignore */
35
+ private _currentInputValue;
36
+ /** @ignore */
37
+ _editItems: SocialEntry[];
38
+ /** @ignore */
39
+ private _suggestForm;
40
+ static styles: import('lit').CSSResult;
41
+ protected willUpdate(_changedProperties: PropertyValues): void;
42
+ addItem(entry: SocialEntry): void;
43
+ removeIndex(index: number): void;
44
+ get value(): SocialEntry[];
45
+ protected render(): TemplateResult<1>;
46
+ protected renderView(): TemplateResult<1>;
47
+ protected renderEdit(): TemplateResult<1>;
48
+ private _renderAddRow;
49
+ private _searchSocialProviders;
50
+ private _openAddSuggestItem;
51
+ private _closeAddSuggestedItem;
52
+ private _findProvider;
53
+ private _toUrl;
54
+ private emitChange;
55
+ }
56
+ //# sourceMappingURL=PdSocialmedia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PdSocialmedia.d.ts","sourceRoot":"","sources":["../../src/pd-socialmedia/PdSocialmedia.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,UAAU,EAIV,cAAc,EACd,cAAc,EACf,MAAM,KAAK,CAAC;AAIb,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,6CAA6C,CAAC;AACrD,OAAO,4CAA4C,CAAC;AACpD,OAAO,0CAA0C,CAAC;AAElD,OAAO,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,6EAA6E;IAE7E,OAAO,UAAS;IAEhB,oCAAoC;IAEpC,SAAS,EAAE,WAAW,EAAE,CAAM;IAE9B,+DAA+D;IAE/D,SAAS,EAAE,cAAc,EAAE,CAAoB;IAE/C,mDAAmD;IAEnD,kBAAkB,UAAS;IAE3B,iDAAiD;IAEjD,kBAAkB,UAAS;IAE3B,cAAc;IAEd,OAAO,CAAC,mBAAmB,CAA+B;IAE1D,cAAc;IAEd,OAAO,CAAC,kBAAkB,CAAuB;IAEjD,cAAc;IAEd,UAAU,EAAE,WAAW,EAAE,CAAM;IAE/B,cAAc;IAEd,OAAO,CAAC,YAAY,CAAmC;IAEvD,MAAM,CAAC,MAAM,0BA0IX;IAEF,SAAS,CAAC,UAAU,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAOvD,OAAO,CAAC,KAAK,EAAE,WAAW;IAM1B,WAAW,CAAC,KAAK,EAAE,MAAM;IAOhC,IAAI,KAAK,kBAER;IAGD,SAAS,CAAC,MAAM;IAIhB,SAAS,CAAC,UAAU;IA+CpB,SAAS,CAAC,UAAU;IAwDpB,OAAO,CAAC,aAAa;YA+DP,sBAAsB;IAoBpC,OAAO,CAAC,mBAAmB,CASzB;IAEF,OAAO,CAAC,sBAAsB,CAG5B;IAGF,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,UAAU;CASnB"}
@@ -0,0 +1,426 @@
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 };
@@ -0,0 +1,16 @@
1
+ export type ProviderInputKind = "username" | "url" | "id";
2
+ export interface SocialProvider {
3
+ id: string;
4
+ label: string;
5
+ aliases?: string[];
6
+ category: "Social" | "Music" | "Streaming" | "DJ/Booking" | "Catalog";
7
+ icon: string;
8
+ brandColor?: string;
9
+ inputKind: ProviderInputKind;
10
+ placeholder?: string;
11
+ pattern?: RegExp;
12
+ toUrl: (input: string) => string;
13
+ normalize?: (raw: string) => string;
14
+ }
15
+ export declare const SOCIAL_PROVIDERS: SocialProvider[];
16
+ //# sourceMappingURL=pd-socialmedia-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-socialmedia-model.d.ts","sourceRoot":"","sources":["../../src/pd-socialmedia/pd-socialmedia-model.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,KAAK,GAAG,IAAI,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAEjC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAiP5C,CAAC"}