@progressive-development/pd-page 0.9.1 → 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 -134
  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 -74
  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 -276
  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 +14 -8
@@ -1,28 +1,111 @@
1
- import { LitElement, css, nothing, html } from 'lit';
1
+ import { css, LitElement, nothing, html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
- import { PdColorStyles, PdFontStyles } from '@progressive-development/pd-shared-styles';
3
+ import { localized, msg } from '@lit/localize';
4
4
 
5
5
  var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
7
  var __decorateClass = (decorators, target, key, kind) => {
7
- var result = void 0 ;
8
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
8
9
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
9
10
  if (decorator = decorators[i])
10
- result = (decorator(target, key, result) ) || result;
11
- if (result) __defProp(target, key, result);
11
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
12
+ if (kind && result) __defProp(target, key, result);
12
13
  return result;
13
14
  };
14
- class PdFooter extends LitElement {
15
+ let PdFooter = class extends LitElement {
15
16
  constructor() {
16
17
  super(...arguments);
17
18
  this.copyright = "";
18
19
  this.version = "";
19
20
  this.footerLinks = [];
20
21
  }
21
- static {
22
- this.styles = [
23
- PdColorStyles,
24
- PdFontStyles,
25
- css`
22
+ render() {
23
+ return html`
24
+ <nav
25
+ class="footer-links"
26
+ aria-label="${msg("Footer Navigation", { id: "pd.footer.nav.aria" })}"
27
+ >
28
+ <ul role="list">
29
+ ${this.footerLinks?.map(
30
+ (link) => html`
31
+ <li
32
+ role="button"
33
+ tabindex="0"
34
+ data-link="${link.key}"
35
+ @click="${this._footerLinkClicked}"
36
+ @keydown="${this._handleLinkKeydown}"
37
+ >
38
+ ${link.name}
39
+ </li>
40
+ `
41
+ )}
42
+ </ul>
43
+ </nav>
44
+
45
+ <div class="bottom-line">
46
+ <div>
47
+ ${this.copyright ? html`<span class="copyright">© ${this.copyright}, </span>` : nothing}
48
+ ${this.version ? html`<span class="version">${this.version}</span>` : nothing}
49
+ </div>
50
+
51
+ ${this.madeBy ? html`<span
52
+ class="made-by"
53
+ role="button"
54
+ tabindex="0"
55
+ @click="${this._clickMadeBy}"
56
+ @keydown="${this._handleMadeByKeydown}"
57
+ >${this.madeBy.txt}</span
58
+ >` : nothing}
59
+ </div>
60
+ `;
61
+ }
62
+ /**
63
+ * Handles keyboard events on footer links.
64
+ * Activates on Enter or Space key.
65
+ */
66
+ _handleLinkKeydown(e) {
67
+ if (e.key === "Enter" || e.key === " ") {
68
+ e.preventDefault();
69
+ this._footerLinkClicked(e);
70
+ }
71
+ }
72
+ /**
73
+ * Handles keyboard events on madeBy element.
74
+ * Activates on Enter or Space key.
75
+ */
76
+ _handleMadeByKeydown(e) {
77
+ if (e.key === "Enter" || e.key === " ") {
78
+ e.preventDefault();
79
+ this._clickMadeBy();
80
+ }
81
+ }
82
+ _clickMadeBy() {
83
+ if (this.madeBy?.email) {
84
+ window.location.href = `mailto:${this.madeBy.email}`;
85
+ } else if (this.madeBy?.link) {
86
+ const url = this.madeBy.link;
87
+ if (url.startsWith("https://") || url.startsWith("http://")) {
88
+ window.open(url, "_blank", "noopener,noreferrer");
89
+ }
90
+ }
91
+ }
92
+ _footerLinkClicked(e) {
93
+ const target = e.currentTarget;
94
+ const linkKey = target.dataset.link;
95
+ const linkObj = this.footerLinks?.find((fl) => fl.key === linkKey);
96
+ if (linkObj) {
97
+ this.dispatchEvent(
98
+ new CustomEvent("footer-link", {
99
+ detail: { linkObj },
100
+ bubbles: true,
101
+ composed: true
102
+ })
103
+ );
104
+ }
105
+ }
106
+ };
107
+ PdFooter.styles = [
108
+ css`
26
109
  :host {
27
110
  display: flex;
28
111
  flex-flow: column;
@@ -37,7 +120,7 @@ class PdFooter extends LitElement {
37
120
  align-items: center;
38
121
  justify-content: right;
39
122
  height: 100%;
40
- color: var(--pd-footer-font-col, var(--pd-default-bg-col));
123
+ color: var(--pd-footer-font-col, var(--pd-on-primary-col));
41
124
  font-family: var(
42
125
  --pd-footer-font-family,
43
126
  var(--pd-default-font-link-family)
@@ -49,9 +132,9 @@ class PdFooter extends LitElement {
49
132
  display: flex;
50
133
  flex-wrap: wrap;
51
134
  list-style: none;
52
- gap: 2em;
135
+ gap: var(--pd-spacing-lg);
53
136
  margin: 0;
54
- padding: 2em 2.5em;
137
+ padding: var(--pd-spacing-lg);
55
138
  }
56
139
 
57
140
  .footer-links li {
@@ -62,6 +145,12 @@ class PdFooter extends LitElement {
62
145
  color: var(--pd-default-hover-col);
63
146
  }
64
147
 
148
+ .footer-links li:focus-visible {
149
+ outline: 2px solid var(--pd-focus-ring-col, var(--pd-default-col));
150
+ outline-offset: 2px;
151
+ border-radius: var(--pd-radius-sm);
152
+ }
153
+
65
154
  .bottom-line {
66
155
  background-color: var(
67
156
  --pd-footer-bottom-col,
@@ -69,9 +158,9 @@ class PdFooter extends LitElement {
69
158
  );
70
159
  font-size: var(--pd-footer-bottom-font-size, 0.9em);
71
160
  color: var(--pd-footer-bottom-font-col, var(--pd-default-dark-col));
72
- padding: 0.5em;
161
+ padding: var(--pd-spacing-sm);
73
162
  display: flex;
74
- gap: 1em;
163
+ gap: var(--pd-spacing-md);
75
164
  flex-wrap: wrap;
76
165
  justify-content: space-between;
77
166
  align-items: center;
@@ -85,78 +174,37 @@ class PdFooter extends LitElement {
85
174
  font-weight: normal;
86
175
  }
87
176
 
88
- .madeBy {
177
+ .made-by {
89
178
  cursor: pointer;
90
179
  font-style: italic;
180
+ white-space: normal;
91
181
  }
92
182
 
93
- .madeBy:hover {
183
+ .made-by:hover {
94
184
  color: var(--pd-default-col);
95
185
  }
96
- `
97
- ];
98
- }
99
- render() {
100
- return html`
101
- <div class="footer-links">
102
- <ul>
103
- ${this.footerLinks?.map(
104
- (link) => html`
105
- <li>
106
- <a @click=${this._footerLinkClicked} data-link=${link.key}
107
- >${link.name}</a
108
- >
109
- </li>
110
- `
111
- )}
112
- </ul>
113
- </div>
114
186
 
115
- <div class="bottom-line">
116
- <div>
117
- ${this.copyright ? html`<span class="copyright">© ${this.copyright}, </span>` : nothing}
118
- ${this.version ? html`<span class="version">${this.version}</span>` : nothing}
119
- </div>
120
-
121
- ${this.madeBy ? html`<span class="madeBy" @click=${this._clickMadeBy}
122
- >${this.madeBy.txt}</span
123
- >` : nothing}
124
- </div>
125
- `;
126
- }
127
- _clickMadeBy() {
128
- if (this.madeBy?.email) {
129
- window.location.href = `mailto:${this.madeBy.email}`;
130
- } else if (this.madeBy?.link) {
131
- window.open(this.madeBy.link, "_blank");
132
- }
133
- }
134
- _footerLinkClicked(e) {
135
- const target = e.currentTarget;
136
- const linkKey = target.dataset.link;
137
- const linkObj = this.footerLinks?.find((fl) => fl.key === linkKey);
138
- if (linkObj) {
139
- this.dispatchEvent(
140
- new CustomEvent("footer-link", {
141
- detail: { linkObj },
142
- bubbles: true,
143
- composed: true
144
- })
145
- );
146
- }
147
- }
148
- }
187
+ .made-by:focus-visible {
188
+ outline: 2px solid var(--pd-focus-ring-col, var(--pd-default-col));
189
+ outline-offset: 2px;
190
+ border-radius: var(--pd-radius-sm);
191
+ }
192
+ `
193
+ ];
149
194
  __decorateClass([
150
195
  property({ type: String })
151
- ], PdFooter.prototype, "copyright");
196
+ ], PdFooter.prototype, "copyright", 2);
152
197
  __decorateClass([
153
198
  property({ type: String })
154
- ], PdFooter.prototype, "version");
199
+ ], PdFooter.prototype, "version", 2);
155
200
  __decorateClass([
156
201
  property({ type: Object })
157
- ], PdFooter.prototype, "madeBy");
202
+ ], PdFooter.prototype, "madeBy", 2);
158
203
  __decorateClass([
159
204
  property({ type: Array })
160
- ], PdFooter.prototype, "footerLinks");
205
+ ], PdFooter.prototype, "footerLinks", 2);
206
+ PdFooter = __decorateClass([
207
+ localized()
208
+ ], PdFooter);
161
209
 
162
210
  export { PdFooter };
@@ -1,8 +1,48 @@
1
- import { Meta, StoryFn } from '@storybook/web-components';
2
- declare const _default: Meta;
3
- export default _default;
4
- export declare const Default: StoryFn;
5
- export declare const OhneVersionUndMadeBy: StoryFn;
6
- export declare const NurLinks: StoryFn;
7
- export declare const NurMadeByMitLink: StoryFn;
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ import { PdFooterLink, PdFooterMadeBy } from '../types.js';
3
+ /**
4
+ * Story arguments interface for pd-footer component.
5
+ * Maps to the component's public API.
6
+ */
7
+ interface PdFooterArgs {
8
+ /** Footer navigation links */
9
+ footerLinks: PdFooterLink[];
10
+ /** Copyright text */
11
+ copyright: string;
12
+ /** Version string */
13
+ version: string;
14
+ /** Developer/agency reference */
15
+ madeBy?: PdFooterMadeBy;
16
+ }
17
+ /**
18
+ * ## pd-footer
19
+ *
20
+ * Application footer with navigation links, copyright info, version display, and developer reference.
21
+ *
22
+ * ### Features
23
+ * - Configurable footer links with click events
24
+ * - Copyright text and version string display
25
+ * - Developer/agency reference with email (mailto:) or external link
26
+ * - Responsive layout with flex-wrap for links
27
+ * - Full keyboard accessibility (Tab, Enter, Space on links and madeBy)
28
+ *
29
+ * ### Accessibility
30
+ * - Uses `<nav>` element with `aria-label` for footer navigation landmark
31
+ * - Footer links use `role="button"` and `tabindex="0"`
32
+ * - Focus-visible styling for keyboard users
33
+ * - Made-by link opens in new tab with noopener,noreferrer for security
34
+ */
35
+ declare const meta: Meta<PdFooterArgs>;
36
+ export default meta;
37
+ type Story = StoryObj<PdFooterArgs>;
38
+ /** Default footer with links, copyright, and version. Interactive via Controls panel. */
39
+ export declare const Default: Story;
40
+ /** Footer with developer/agency reference — email opens mailto:, link opens in new tab. */
41
+ export declare const WithMadeBy: Story;
42
+ /** Minimal footer configurations — different content combinations. */
43
+ export declare const MinimalConfigurations: Story;
44
+ /** Overview of all footer configurations at a glance. */
45
+ export declare const AllVariants: Story;
46
+ /** CSS Custom Properties -- Branded and Redesigned variants. */
47
+ export declare const CustomStyling: Story;
8
48
  //# sourceMappingURL=pd-footer.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-footer.stories.d.ts","sourceRoot":"","sources":["../../src/pd-footer/pd-footer.stories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAI/D,OAAO,gBAAgB,CAAC;wBAcnB,IAAI;AAZT,wBAYU;AAuBV,eAAO,MAAM,OAAO,EAAE,OAA2B,CAAC;AAQlD,eAAO,MAAM,oBAAoB,EAAE,OAA2B,CAAC;AAM/D,eAAO,MAAM,QAAQ,EAAE,OAA2B,CAAC;AAKnD,eAAO,MAAM,gBAAgB,EAAE,OAA2B,CAAC"}
1
+ {"version":3,"file":"pd-footer.stories.d.ts","sourceRoot":"","sources":["../../src/pd-footer/pd-footer.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,gBAAgB,CAAC;AAMxB;;;GAGG;AACH,UAAU,YAAY;IACpB,8BAA8B;IAC9B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AA+BD;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,CA8E5B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;AAMpC,yFAAyF;AACzF,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAMjC,2FAA2F;AAC3F,eAAO,MAAM,UAAU,EAAE,KA0CxB,CAAC;AAMF,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,EAAE,KAkCnC,CAAC;AAMF,yDAAyD;AACzD,eAAO,MAAM,WAAW,EAAE,KA8CzB,CAAC;AAMF,gEAAgE;AAChE,eAAO,MAAM,aAAa,EAAE,KAgF3B,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { LitElement, CSSResultGroup } from 'lit';
2
+ /**
3
+ * Login form component for email/password authentication.
4
+ *
5
+ * This is a pure UI component that emits events for login attempts.
6
+ * The actual authentication logic should be handled by the parent component.
7
+ *
8
+ * Supports two views:
9
+ * - **login**: Default login form with email and password fields.
10
+ * - **forgot-password**: Password reset request form with email field only.
11
+ *
12
+ * @summary Login form with email and password fields, including forgot password flow.
13
+ *
14
+ * @tagname pd-login
15
+ *
16
+ * @event login-attempt - Fired when user submits valid credentials. Detail: `LoginAttemptDetail`.
17
+ * @event forgot-password-attempt - Fired when user requests password reset. Detail: `ForgotPasswordAttemptDetail`.
18
+ *
19
+ * @cssprop --pd-login-bg-color - Form background color. Default: `var(--pd-default-bg-light-col)`.
20
+ * @cssprop --pd-login-border-radius - Form border radius. Default: `var(--pd-radius-md)`.
21
+ * @cssprop --pd-login-max-width - Maximum width of the form. Default: `500px`.
22
+ * @cssprop --pd-login-padding - Form padding. Default: `1rem 0 1rem 1rem`.
23
+ */
24
+ export declare class PdLogin extends LitElement {
25
+ /** Shows loading state on the submit button. */
26
+ loading: boolean;
27
+ /** Error message to display. */
28
+ errorMessage: string;
29
+ /** Success message to display (e.g., after password reset request). */
30
+ successMessage: string;
31
+ /** Hide the forgot password link. */
32
+ hideForgotPassword: boolean;
33
+ /** Current view: login form or forgot password form (internal). */
34
+ private _view;
35
+ private _validForm;
36
+ private _forgotPasswordValidForm;
37
+ private _prefillEmail;
38
+ /** @ignore */
39
+ private _formElement;
40
+ /** @ignore */
41
+ private _forgotPasswordFormElement;
42
+ static styles: CSSResultGroup;
43
+ render(): import('lit').TemplateResult<1>;
44
+ private _renderLoginView;
45
+ private _renderForgotPasswordView;
46
+ /** Clears the form and resets validation state. */
47
+ clear(): void;
48
+ private _handleFormChange;
49
+ private _handleSubmit;
50
+ private _handleForgotPassword;
51
+ private _handleForgotPasswordFormChange;
52
+ private _handleForgotPasswordSubmit;
53
+ private _handleBackToLogin;
54
+ /** Switch to forgot password view. */
55
+ showForgotPassword(): void;
56
+ /** Switch back to login view. */
57
+ showLogin(): void;
58
+ }
59
+ //# sourceMappingURL=PdLogin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PdLogin.d.ts","sourceRoot":"","sources":["../../src/pd-login/PdLogin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAI5D,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,4CAA4C,CAAC;AACpD,OAAO,mDAAmD,CAAC;AAC3D,OAAO,mDAAmD,CAAC;AAS3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACrC,gDAAgD;IAEhD,OAAO,UAAS;IAEhB,gCAAgC;IAEhC,YAAY,SAAM;IAElB,uEAAuE;IAEvE,cAAc,SAAM;IAEpB,qCAAqC;IAErC,kBAAkB,UAAS;IAE3B,mEAAmE;IAEnE,OAAO,CAAC,KAAK,CAAwC;IAGrD,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,wBAAwB,CAAS;IAGzC,OAAO,CAAC,aAAa,CAAM;IAE3B,cAAc;IAEd,OAAO,CAAC,YAAY,CAAmB;IAEvC,cAAc;IAEd,OAAO,CAAC,0BAA0B,CAAmB;IAErD,OAAgB,MAAM,EAAE,cAAc,CA0CpC;IAEF,MAAM;IAMN,OAAO,CAAC,gBAAgB;IAgExB,OAAO,CAAC,yBAAyB;IAqDjC,mDAAmD;IACnD,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,+BAA+B;IAKvC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,kBAAkB;IAK1B,sCAAsC;IACtC,kBAAkB,IAAI,IAAI;IAM1B,iCAAiC;IACjC,SAAS,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,292 @@
1
+ import { css, LitElement, html } from 'lit';
2
+ import { localized, msg } from '@lit/localize';
3
+ import { property, state, query } from 'lit/decorators.js';
4
+ import '@progressive-development/pd-forms/pd-form-container';
5
+ import '@progressive-development/pd-forms/pd-form-row';
6
+ import '@progressive-development/pd-forms/pd-input';
7
+ import '@progressive-development/pd-forms/pd-panel-button';
8
+ import '../pd-content/dist/pd-notice-box/pd-notice-box.js';
9
+ import { pdIcons } from '@progressive-development/pd-icon';
10
+
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __decorateClass = (decorators, target, key, kind) => {
14
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
15
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
16
+ if (decorator = decorators[i])
17
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
18
+ if (kind && result) __defProp(target, key, result);
19
+ return result;
20
+ };
21
+ let PdLogin = class extends LitElement {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.loading = false;
25
+ this.errorMessage = "";
26
+ this.successMessage = "";
27
+ this.hideForgotPassword = false;
28
+ this._view = "login";
29
+ this._validForm = false;
30
+ this._forgotPasswordValidForm = false;
31
+ this._prefillEmail = "";
32
+ }
33
+ render() {
34
+ return this._view === "login" ? this._renderLoginView() : this._renderForgotPasswordView();
35
+ }
36
+ _renderLoginView() {
37
+ return html`
38
+ <div class="login-form">
39
+ ${this.successMessage ? html`<pd-notice-box type="success" variant="sidebar"
40
+ >${this.successMessage}</pd-notice-box
41
+ >` : ""}
42
+
43
+ <pd-form-container
44
+ id="loginFormId"
45
+ @pd-form-change="${this._handleFormChange}"
46
+ commonError="${this.errorMessage}"
47
+ >
48
+ <pd-form-row>
49
+ <pd-input
50
+ id="eMail"
51
+ maxlength="250"
52
+ fieldType="mail"
53
+ valueName="email"
54
+ label="${msg("E-Mail", { id: "pd.login.email.label" })}"
55
+ autoCompleteName="email"
56
+ required
57
+ @enter-pressed="${this._handleSubmit}"
58
+ ></pd-input>
59
+ </pd-form-row>
60
+
61
+ <pd-form-row>
62
+ <pd-input
63
+ id="pWord"
64
+ secret
65
+ maxlength="30"
66
+ label="${msg("Passwort", { id: "pd.login.password.label" })}"
67
+ valueName="password"
68
+ autoCompleteName="current-password"
69
+ required
70
+ @enter-pressed="${this._handleSubmit}"
71
+ ></pd-input>
72
+
73
+ ${!this.hideForgotPassword ? html`<span class="pwd-link"
74
+ ><a href="#" @click="${this._handleForgotPassword}"
75
+ >${msg("Passwort vergessen?", {
76
+ id: "pd.login.forgot.password"
77
+ })}</a
78
+ ></span
79
+ >` : ""}
80
+ </pd-form-row>
81
+ </pd-form-container>
82
+
83
+ <pd-form-row>
84
+ <pd-button
85
+ text="${msg("Anmelden", { id: "pd.login.submit" })}"
86
+ icon="${pdIcons.ICON_USER}"
87
+ ?disabled="${!this._validForm || this.loading}"
88
+ ?loading="${this.loading}"
89
+ @button-clicked="${this._handleSubmit}"
90
+ ></pd-button>
91
+ </pd-form-row>
92
+ </div>
93
+ `;
94
+ }
95
+ _renderForgotPasswordView() {
96
+ return html`
97
+ <div class="login-form">
98
+ <pd-notice-box type="info" variant="sidebar">
99
+ ${msg(
100
+ "Geben Sie Ihre E-Mail-Adresse ein. Sie erhalten einen Link zum Zurücksetzen Ihres Passworts.",
101
+ {
102
+ id: "pd.login.forgot.info"
103
+ }
104
+ )}
105
+ </pd-notice-box>
106
+
107
+ <pd-form-container
108
+ id="forgotPasswordFormId"
109
+ @pd-form-change="${this._handleForgotPasswordFormChange}"
110
+ commonError="${this.errorMessage}"
111
+ >
112
+ <pd-form-row>
113
+ <pd-input
114
+ id="forgotEmail"
115
+ maxlength="250"
116
+ fieldType="mail"
117
+ valueName="email"
118
+ label="${msg("E-Mail", { id: "pd.login.email.label" })}"
119
+ autoCompleteName="email"
120
+ .value="${this._prefillEmail}"
121
+ required
122
+ @enter-pressed="${this._handleForgotPasswordSubmit}"
123
+ ></pd-input>
124
+
125
+ <span class="pwd-link">
126
+ <a href="#" @click="${this._handleBackToLogin}"
127
+ >${msg("Zurück zur Anmeldung", {
128
+ id: "pd.login.forgot.back"
129
+ })}</a
130
+ >
131
+ </span>
132
+ </pd-form-row>
133
+ </pd-form-container>
134
+
135
+ <pd-form-row>
136
+ <pd-button
137
+ text="${msg("Link anfordern", { id: "pd.login.forgot.submit" })}"
138
+ icon="${pdIcons.ICON_MAIL}"
139
+ ?disabled="${!this._forgotPasswordValidForm || this.loading}"
140
+ ?loading="${this.loading}"
141
+ @button-clicked="${this._handleForgotPasswordSubmit}"
142
+ ></pd-button>
143
+ </pd-form-row>
144
+ </div>
145
+ `;
146
+ }
147
+ /** Clears the form and resets validation state. */
148
+ clear() {
149
+ this._formElement?.clear();
150
+ this._validForm = false;
151
+ }
152
+ _handleFormChange(e) {
153
+ this._validForm = e.detail.overallValidity;
154
+ e.stopPropagation();
155
+ }
156
+ _handleSubmit() {
157
+ if (!this._formElement?.valid || this.loading) {
158
+ return;
159
+ }
160
+ const formValues = this._formElement.getValues().origin;
161
+ const detail = {
162
+ email: formValues.email,
163
+ password: formValues.password
164
+ };
165
+ this.dispatchEvent(
166
+ new CustomEvent("login-attempt", {
167
+ detail,
168
+ bubbles: true,
169
+ composed: true
170
+ })
171
+ );
172
+ }
173
+ _handleForgotPassword(e) {
174
+ e.preventDefault();
175
+ const formValues = this._formElement?.getValues()?.origin;
176
+ this._prefillEmail = formValues?.email || "";
177
+ this._view = "forgot-password";
178
+ }
179
+ _handleForgotPasswordFormChange(e) {
180
+ this._forgotPasswordValidForm = e.detail.overallValidity;
181
+ e.stopPropagation();
182
+ }
183
+ _handleForgotPasswordSubmit() {
184
+ if (!this._forgotPasswordFormElement?.valid || this.loading) {
185
+ return;
186
+ }
187
+ const formValues = this._forgotPasswordFormElement.getValues().origin;
188
+ const detail = {
189
+ email: formValues.email
190
+ };
191
+ this.dispatchEvent(
192
+ new CustomEvent("forgot-password-attempt", {
193
+ detail,
194
+ bubbles: true,
195
+ composed: true
196
+ })
197
+ );
198
+ this._view = "login";
199
+ }
200
+ _handleBackToLogin(e) {
201
+ e.preventDefault();
202
+ this.showLogin();
203
+ }
204
+ /** Switch to forgot password view. */
205
+ showForgotPassword() {
206
+ const formValues = this._formElement?.getValues()?.origin;
207
+ this._prefillEmail = formValues?.email || "";
208
+ this._view = "forgot-password";
209
+ }
210
+ /** Switch back to login view. */
211
+ showLogin() {
212
+ this._view = "login";
213
+ }
214
+ };
215
+ PdLogin.styles = [
216
+ css`
217
+ :host {
218
+ display: flex;
219
+ justify-content: center;
220
+ width: 100%;
221
+ }
222
+
223
+ .login-form {
224
+ display: flex;
225
+ flex-flow: column;
226
+ justify-content: center;
227
+ background-color: var(
228
+ --pd-login-bg-color,
229
+ var(--pd-default-bg-light-col)
230
+ );
231
+ padding: var(--pd-login-padding, 1rem 0 1rem 1rem);
232
+ border-radius: var(--pd-login-border-radius, var(--pd-radius-md));
233
+ max-width: var(--pd-login-max-width, 500px);
234
+ width: 100%;
235
+ }
236
+
237
+ .pwd-link {
238
+ display: block;
239
+ padding-bottom: 0.5em;
240
+ text-align: right;
241
+ font-size: 0.8em;
242
+ }
243
+
244
+ .pwd-link a {
245
+ color: var(--pd-default-link-col, inherit);
246
+ text-decoration: none;
247
+ }
248
+
249
+ .pwd-link a:hover {
250
+ text-decoration: underline;
251
+ }
252
+
253
+ pd-notice-box {
254
+ margin-bottom: var(--pd-spacing-md, 1rem);
255
+ }
256
+ `
257
+ ];
258
+ __decorateClass([
259
+ property({ type: Boolean })
260
+ ], PdLogin.prototype, "loading", 2);
261
+ __decorateClass([
262
+ property({ type: String })
263
+ ], PdLogin.prototype, "errorMessage", 2);
264
+ __decorateClass([
265
+ property({ type: String })
266
+ ], PdLogin.prototype, "successMessage", 2);
267
+ __decorateClass([
268
+ property({ type: Boolean })
269
+ ], PdLogin.prototype, "hideForgotPassword", 2);
270
+ __decorateClass([
271
+ state()
272
+ ], PdLogin.prototype, "_view", 2);
273
+ __decorateClass([
274
+ state()
275
+ ], PdLogin.prototype, "_validForm", 2);
276
+ __decorateClass([
277
+ state()
278
+ ], PdLogin.prototype, "_forgotPasswordValidForm", 2);
279
+ __decorateClass([
280
+ state()
281
+ ], PdLogin.prototype, "_prefillEmail", 2);
282
+ __decorateClass([
283
+ query("#loginFormId")
284
+ ], PdLogin.prototype, "_formElement", 2);
285
+ __decorateClass([
286
+ query("#forgotPasswordFormId")
287
+ ], PdLogin.prototype, "_forgotPasswordFormElement", 2);
288
+ PdLogin = __decorateClass([
289
+ localized()
290
+ ], PdLogin);
291
+
292
+ export { PdLogin };
@@ -0,0 +1,3 @@
1
+ import { PdLogin } from './PdLogin.js';
2
+ export { PdLogin };
3
+ //# sourceMappingURL=pd-login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-login.d.ts","sourceRoot":"","sources":["../../src/pd-login/pd-login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAOvC,OAAO,EAAE,OAAO,EAAE,CAAC"}