@progressive-development/pd-contact 0.9.2 → 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.
package/LICENSE CHANGED
@@ -1,2 +1,21 @@
1
- No License, all rights reserved
2
- @2021 - PD Progressive Development UG
1
+ MIT License
2
+
3
+ Copyright (c) 2021-present PD Progressive Development UG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,76 +1,49 @@
1
- # \<pd-contact>
1
+ # @progressive-development/pd-contact
2
2
 
3
- This webcomponent follows the [open-wc](https://github.com/open-wc/open-wc) recommendation.
3
+ [![npm version](https://img.shields.io/npm/v/@progressive-development/pd-contact.svg)](https://www.npmjs.com/package/@progressive-development/pd-contact)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+
6
+ Contact form and address display component for managing personal and business contacts.
7
+
8
+ ## Features
9
+
10
+ - **Lit 3 & TypeScript** – Modern, type-safe web components
11
+ - **Accessible** – WCAG 2.1 compliant, keyboard navigation, ARIA support
12
+ - **Themeable** – CSS Custom Properties for easy customization
13
+ - **Localized** – Built-in i18n support (EN, DE, BE)
14
+ - **Lightweight** – No heavy dependencies, tree-shakeable
15
+ - **Framework-agnostic** – Works with React, Vue, Angular, or vanilla JS
16
+ - **Dual Contact Types** – Switch between personal and business contacts with automatic field adaptation
17
+ - **Flexible Field Configuration** – Control visible and required fields via simple arrays
18
+ - **Smart Phone Normalization** – Auto-transforms local phone numbers to international format based on country
19
+ - **Edit & View Modes** – Same component for form input and formatted address display with clickable links
4
20
 
5
21
  ## Installation
6
22
 
7
23
  ```bash
8
- npm i pd-contact
24
+ npm install @progressive-development/pd-contact
9
25
  ```
10
26
 
11
- ## Usage
27
+ ## Quick Start
12
28
 
13
29
  ```html
14
30
  <script type="module">
15
- import 'pd-contact/pd-contact.js';
31
+ import '@progressive-development/pd-contact';
16
32
  </script>
17
33
 
18
34
  <pd-contact></pd-contact>
19
35
  ```
20
36
 
21
- ## Linting and formatting
37
+ ## Components
22
38
 
23
- To scan the project for linting and formatting errors, run
39
+ | Component | Description |
40
+ |-----------|-------------|
41
+ | `<pd-contact>` | Contact form with edit and view modes |
24
42
 
25
- ```bash
26
- npm run lint
27
- ```
28
-
29
- To automatically fix linting and formatting errors, run
30
-
31
- ```bash
32
- npm run format
33
- ```
43
+ ## Documentation
34
44
 
35
- ## Testing with Web Test Runner
36
-
37
- To execute a single test run:
38
-
39
- ```bash
40
- npm run test
41
- ```
42
-
43
- To run the tests in interactive watch mode run:
44
-
45
- ```bash
46
- npm run test:watch
47
- ```
45
+ 📖 **Full documentation:** [pd-components.web.app](https://pd-components.web.app/)
48
46
 
49
- ## Demoing with Storybook
50
-
51
- To run a local instance of Storybook for your component, run
52
-
53
- ```bash
54
- npm run storybook
55
- ```
56
-
57
- To build a production version of Storybook, run
58
-
59
- ```bash
60
- npm run storybook:build
61
- ```
62
-
63
-
64
- ## Tooling configs
65
-
66
- For most of the tools, the configuration is in the `package.json` to minimize the amount of files in your project.
67
-
68
- If you customize the configuration a lot, you can consider moving them to individual files.
69
-
70
- ## Local Demo with `web-dev-server`
71
-
72
- ```bash
73
- npm start
74
- ```
47
+ ## License
75
48
 
76
- To run a local development server that serves the basic demo located in `demo/index.html`
49
+ MIT © [PD Progressive Development UG](https://progressive-development.com)
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { PdContact } from './pd-contact/pd-contact.js';
2
- export type { PdContactData, PdContactFormOptions, PdContactMatch, C_ADDITIONAL, C_BTWNR, C_CITY, C_COMPANY, C_EMAIL, C_FIRSTNAME, C_LASTNAME, C_PHONE1, C_PROPERTY_DATE, C_STREET, C_STREET_NR, C_TYPE, C_ZIP, } from './types.js';
2
+ export type { PdContactData, PdContactFormOptions, PdContactMatch, SocialEntry, C_ADDITIONAL, C_BTWNR, C_CITY, C_COMPANY, C_EMAIL, C_FIRSTNAME, C_LASTNAME, C_LOGO, C_PHONE1, C_PROPERTY_DATE, C_SOCIAL_MEDIA, C_STREET, C_STREET_NR, C_TITLE_NAME, C_TYPE, C_WEBSITE, C_ZIP, } from './types.js';
3
3
  export { templates as beTemplates } from './generated/locales/be.js';
4
4
  export { templates as deTemplates } from './generated/locales/de.js';
5
5
  export { templates as enTemplates } from './generated/locales/en.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,OAAO,EACP,MAAM,EACN,SAAS,EACT,OAAO,EACP,WAAW,EACX,UAAU,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,WAAW,EACX,MAAM,EACN,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,OAAO,EACP,MAAM,EACN,SAAS,EACT,OAAO,EACP,WAAW,EACX,UAAU,EACV,MAAM,EACN,QAAQ,EACR,eAAe,EACf,cAAc,EACd,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,MAAM,EACN,SAAS,EACT,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
@@ -1,46 +1,52 @@
1
1
  import { LitElement, PropertyValues, CSSResultGroup } from 'lit';
2
2
  import { PdContactData, PdContactMatch } from '../types';
3
3
  /**
4
+ * Contact component for displaying and editing contact information.
5
+ *
4
6
  * @tagname pd-contact
7
+ * @summary Contact form/view with private/business support and validation.
8
+ *
9
+ * @csspart card-wrapper - Outer container for the card view layout, provides container query context.
10
+ *
11
+ * @cssprop --pd-contact-address-col - Text color for address content. Default: `var(--pd-default-font-content-col)`.
12
+ * @cssprop --pd-contact-address-title-col - Text color for address title. Default: `var(--pd-default-font-title-col)`.
13
+ * @cssprop --pd-contact-icon-col - Icon fill color. Default: `var(--pd-default-col)`.
14
+ * @cssprop --pd-contact-card-bg - Card view background color. Default: `var(--pd-default-bg-col)`.
15
+ * @cssprop --pd-contact-card-divider-col - Card divider line color. Default: `var(--pd-default-disabled-light-col)`.
16
+ * @cssprop --pd-contact-card-padding - Card inner padding. Default: `2rem`.
17
+ * @cssprop --pd-contact-card-radius - Card border radius. Default: `var(--pd-radius-lg)`.
18
+ * @cssprop --pd-contact-card-shadow - Card box shadow. Default: `var(--pd-shadow-xl)`.
19
+ * @cssprop --pd-contact-card-subtitle-col - Card subtitle (real name) text color. Default: `var(--pd-default-font-muted-col)`.
20
+ * @cssprop --pd-contact-card-title-col - Card title (display name) text color. Default: `var(--pd-default-font-title-col)`.
5
21
  */
6
22
  export declare class PdContact extends LitElement {
7
- /**
8
- * Title shown above address block.
9
- */
23
+ /** Title shown above address block. */
10
24
  addressTitle: string;
11
- /**
12
- * If true, phone and email are rendered as clickable links with icons.
13
- */
25
+ /** Render phone and email as clickable links with icons. */
14
26
  phoneMailLink: boolean;
15
- /**
16
- * If true, render only summary view instead of full editable form.
17
- */
27
+ /** Render only summary view instead of full editable form. */
18
28
  summary: boolean;
19
- /**
20
- * Whether the Baujahr / propertyDate should be shown in the form.
29
+ /** View type: 'detail' shows existing behavior, 'card' shows business card. */
30
+ viewType: "detail" | "card";
31
+ /** Layout mode for card view. */
32
+ cardLayout: "auto" | "horizontal" | "vertical";
33
+ /** Show property date selection field.
21
34
  * TODO: Refactor, give selectable property dates from outside, show if set
22
35
  */
23
36
  withPropertyDate: boolean;
24
- /**
25
- * List of required input field keys (optional).
26
- */
37
+ /** List of required input field keys. */
27
38
  requiredFields: string[];
28
- /**
29
- * List of fields to be rendered (optional).
30
- */
39
+ /** List of fields to be rendered (empty = all fields). */
31
40
  inputFields: string[];
32
- /**
33
- * Contact object to show or edit.
34
- */
41
+ /** Contact data object to show or edit. */
35
42
  contact?: PdContactData;
36
- /**
37
- * Optional location match data.
38
- */
43
+ /** Optional location match data for auto-fill. */
39
44
  match?: PdContactMatch;
40
45
  /**
41
46
  * Business or private contact (internal flag).
42
- */
47
+ * @ignore */
43
48
  private _business;
49
+ /** @ignore */
44
50
  private _contactForm;
45
51
  static styles: CSSResultGroup;
46
52
  willUpdate(changedProps: PropertyValues<this>): void;
@@ -48,6 +54,15 @@ export declare class PdContact extends LitElement {
48
54
  private _renderEditContact;
49
55
  private _getRadioValue;
50
56
  private _renderViewContact;
57
+ private _renderCardView;
58
+ private _renderCardLogo;
59
+ private _renderCardNames;
60
+ private _renderCardContactInfo;
61
+ private _renderCardDivider;
62
+ private _renderCardSocialMedia;
63
+ private _hasCardContactInfo;
64
+ private _ensureHttps;
65
+ private _formatWebsiteDisplay;
51
66
  get valid(): boolean;
52
67
  triggerValidate(): Promise<boolean>;
53
68
  getValues(): PdContactData;
@@ -1 +1 @@
1
- {"version":3,"file":"PdContact.d.ts","sourceRoot":"","sources":["../../src/pd-contact/PdContact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAI5E,OAAO,0CAA0C,CAAC;AAGlD,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,4CAA4C,CAAC;AACpD,OAAO,6CAA6C,CAAC;AACrD,OAAO,kDAAkD,CAAC;AAE1D,OAAO,EAaL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAmClB;;GAEG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACvC;;OAEG;IAEH,YAAY,SAAsD;IAElE;;OAEG;IAEH,aAAa,UAAS;IAEtB;;OAEG;IAEH,OAAO,UAAS;IAEhB;;;OAGG;IAEH,gBAAgB,UAAS;IAEzB;;OAEG;IAEH,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B;;OAEG;IAEH,WAAW,EAAE,MAAM,EAAE,CAAM;IAE3B;;OAEG;IAEH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;OAEG;IAEH,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB;;OAEG;IAEH,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,YAAY,CAAmB;IAEvC,OAAgB,MAAM,EAAE,cAAc,CAoEpC;IAEO,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAMpD,MAAM;IAQf,OAAO,CAAC,kBAAkB;IAiP1B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,kBAAkB;IAiF1B,IAAI,KAAK,YAER;IAEY,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC,SAAS,IAAI,aAAa;IAiCjC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,MAAM,CAAC,WAAW;CAG3B"}
1
+ {"version":3,"file":"PdContact.d.ts","sourceRoot":"","sources":["../../src/pd-contact/PdContact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAK5E,OAAO,0CAA0C,CAAC;AAClD,OAAO,iDAAiD,CAAC;AAGzD,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,4CAA4C,CAAC;AACpD,OAAO,6CAA6C,CAAC;AACrD,OAAO,kDAAkD,CAAC;AAE1D,OAAO,EAaL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAmClB;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACvC,uCAAuC;IAEvC,YAAY,SAAsD;IAElE,4DAA4D;IAE5D,aAAa,UAAS;IAEtB,8DAA8D;IAE9D,OAAO,UAAS;IAEhB,+EAA+E;IAE/E,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAY;IAEvC,iCAAiC;IAEjC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAAU;IAExD;;OAEG;IAEH,gBAAgB,UAAS;IAEzB,yCAAyC;IAEzC,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,0DAA0D;IAE1D,WAAW,EAAE,MAAM,EAAE,CAAM;IAE3B,2CAA2C;IAE3C,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,kDAAkD;IAElD,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB;;iBAEa;IAEb,OAAO,CAAC,SAAS,CAAS;IAE1B,cAAc;IAEd,OAAO,CAAC,YAAY,CAAmB;IAEvC,OAAgB,MAAM,EAAE,cAAc,CAuYpC;IAEO,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAMpD,MAAM;IAYf,OAAO,CAAC,kBAAkB;IAwO1B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,kBAAkB;IAgI1B,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,sBAAsB;IAoD9B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,qBAAqB;IAQ7B,IAAI,KAAK,YAER;IAEY,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzC,SAAS,IAAI,aAAa;IAgCjC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,MAAM,CAAC,WAAW;CAG3B"}
@@ -1,7 +1,8 @@
1
- import { LitElement, css, html } from 'lit';
1
+ 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 '@progressive-development/pd-page/pd-socialmedia';
5
6
  import '@progressive-development/pd-forms/pd-checkbox';
6
7
  import '@progressive-development/pd-forms/pd-form-container';
7
8
  import '@progressive-development/pd-forms/pd-form-row';
@@ -59,6 +60,8 @@ const _PdContact = class _PdContact extends LitElement {
59
60
  this.addressTitle = msg("Adresse", { id: "pd.contact.address.title" });
60
61
  this.phoneMailLink = false;
61
62
  this.summary = false;
63
+ this.viewType = "detail";
64
+ this.cardLayout = "auto";
62
65
  this.withPropertyDate = false;
63
66
  this.requiredFields = [];
64
67
  this.inputFields = [];
@@ -132,6 +135,329 @@ const _PdContact = class _PdContact extends LitElement {
132
135
  .link-item:hover {
133
136
  color: var(--pd-default-font-link-col-hover, #451a46);
134
137
  }
138
+
139
+ /* ========================================
140
+ DETAIL VIEW STYLES
141
+ ======================================== */
142
+
143
+ .detail-view {
144
+ display: flex;
145
+ flex-direction: column;
146
+ gap: var(--pd-spacing-md, 1rem);
147
+ }
148
+
149
+ .detail-names {
150
+ display: flex;
151
+ flex-direction: column;
152
+ gap: var(--pd-spacing-xs, 0.25rem);
153
+ }
154
+
155
+ .detail-title {
156
+ margin: 0;
157
+ font-family: var(--pd-default-font-title-family, inherit);
158
+ font-size: 1.25rem;
159
+ font-weight: 700;
160
+ color: var(--pd-default-font-title-col, #0a3a48);
161
+ line-height: 1.3;
162
+ }
163
+
164
+ .detail-company,
165
+ .detail-vat {
166
+ margin: 0;
167
+ color: var(--pd-default-font-content-col, #353738);
168
+ }
169
+
170
+ .detail-name {
171
+ margin: 0;
172
+ color: var(--pd-default-font-muted-col, #6b7280);
173
+ font-weight: 300;
174
+ }
175
+
176
+ .detail-address {
177
+ display: flex;
178
+ flex-direction: column;
179
+ gap: var(--pd-spacing-xs, 0.25rem);
180
+ }
181
+
182
+ .detail-address p {
183
+ margin: 0;
184
+ color: var(--pd-default-font-content-col, #353738);
185
+ line-height: 1.5;
186
+ }
187
+
188
+ .detail-contact-info {
189
+ display: flex;
190
+ flex-direction: column;
191
+ gap: var(--pd-spacing-sm, 0.5rem);
192
+ }
193
+
194
+ .detail-bank {
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: var(--pd-spacing-xs, 0.25rem);
198
+ }
199
+
200
+ .detail-bank p {
201
+ margin: 0;
202
+ color: var(--pd-default-font-content-col, #353738);
203
+ }
204
+
205
+ .detail-label {
206
+ font-weight: 700;
207
+ color: var(--pd-default-font-title-col, #0a3a48) !important;
208
+ padding-top: var(--pd-spacing-sm, 0.5rem);
209
+ }
210
+
211
+ .detail-divider {
212
+ border: none;
213
+ border-top: 1px solid var(--pd-default-disabled-light-col, #e0e0e0);
214
+ margin: var(--pd-spacing-sm, 0.5rem) 0;
215
+ opacity: 0.5;
216
+ }
217
+
218
+ /* ========================================
219
+ CARD VIEW STYLES
220
+ ======================================== */
221
+
222
+ .card-wrapper {
223
+ container-type: inline-size;
224
+ container-name: contact-card;
225
+ }
226
+
227
+ .card {
228
+ display: grid;
229
+ background: var(
230
+ --pd-contact-card-bg,
231
+ var(--pd-default-bg-col, #fefefe)
232
+ );
233
+ border-radius: var(--pd-contact-card-radius, var(--pd-radius-lg, 8px));
234
+ box-shadow: var(
235
+ --pd-contact-card-shadow,
236
+ var(--pd-shadow-xl, 0 8px 16px rgba(0, 0, 0, 0.15))
237
+ );
238
+ padding: var(--pd-contact-card-padding, 2rem);
239
+ overflow: hidden;
240
+ }
241
+
242
+ .card-content {
243
+ display: flex;
244
+ flex-direction: column;
245
+ gap: var(--pd-spacing-md, 1rem);
246
+ }
247
+
248
+ .card-logo {
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ }
253
+
254
+ .card-logo img {
255
+ max-width: 100%;
256
+ max-height: 100%;
257
+ object-fit: contain;
258
+ }
259
+
260
+ .card-names {
261
+ display: flex;
262
+ flex-direction: column;
263
+ gap: var(--pd-spacing-xs, 0.25rem);
264
+ }
265
+
266
+ .title-name {
267
+ margin: 0;
268
+ font-family: var(--pd-default-font-title-family, inherit);
269
+ color: var(
270
+ --pd-contact-card-title-col,
271
+ var(--pd-default-font-title-col, #0a3a48)
272
+ );
273
+ font-weight: 700;
274
+ line-height: 1.2;
275
+ }
276
+
277
+ .real-name {
278
+ margin: 0;
279
+ font-family: var(--pd-default-font-content-family, inherit);
280
+ color: var(
281
+ --pd-contact-card-subtitle-col,
282
+ var(--pd-default-font-muted-col, #6b7280)
283
+ );
284
+ font-weight: 300;
285
+ }
286
+
287
+ .card-contact-info {
288
+ display: flex;
289
+ flex-direction: column;
290
+ gap: var(--pd-spacing-sm, 0.5rem);
291
+ }
292
+
293
+ .contact-item {
294
+ display: flex;
295
+ align-items: center;
296
+ gap: var(--pd-spacing-sm, 0.5rem);
297
+ text-decoration: none;
298
+ color: var(--pd-default-font-content-col, #353738);
299
+ font-size: var(--pd-default-font-content-size, 1rem);
300
+ }
301
+
302
+ .contact-item:hover {
303
+ color: var(--pd-default-font-link-col-hover, #ffc857);
304
+ }
305
+
306
+ .contact-icon {
307
+ --pd-icon-size: 16px;
308
+ --pd-icon-col: var(
309
+ --pd-contact-icon-col,
310
+ var(--pd-default-col, #067394)
311
+ );
312
+ flex-shrink: 0;
313
+ }
314
+
315
+ .card-divider {
316
+ border: none;
317
+ border-top: 1px solid
318
+ var(
319
+ --pd-contact-card-divider-col,
320
+ var(--pd-default-disabled-light-col, #e0e0e0)
321
+ );
322
+ margin: var(--pd-spacing-sm, 0.5rem) 0;
323
+ opacity: 0.5;
324
+ }
325
+
326
+ /* VERTICAL LAYOUT (default for narrow containers) */
327
+ @container contact-card (max-width: 499px) {
328
+ .card:not(.layout-horizontal) {
329
+ grid-template-rows: auto 1fr;
330
+ grid-template-columns: 1fr;
331
+ text-align: center;
332
+ }
333
+
334
+ .card:not(.layout-horizontal) .card-logo {
335
+ width: 100%;
336
+ max-height: 150px;
337
+ padding-bottom: var(--pd-spacing-md, 1rem);
338
+ }
339
+
340
+ .card:not(.layout-horizontal) .card-names {
341
+ align-items: center;
342
+ }
343
+
344
+ .card:not(.layout-horizontal) .title-name {
345
+ font-size: 1.25rem;
346
+ }
347
+
348
+ .card:not(.layout-horizontal) .real-name {
349
+ font-size: 0.9rem;
350
+ }
351
+
352
+ .card:not(.layout-horizontal) .card-contact-info {
353
+ align-items: center;
354
+ }
355
+
356
+ .card:not(.layout-horizontal) .contact-item {
357
+ justify-content: center;
358
+ font-size: 0.85rem;
359
+ }
360
+
361
+ .card:not(.layout-horizontal) pd-socialmedia {
362
+ display: flex;
363
+ justify-content: center;
364
+ }
365
+ }
366
+
367
+ /* HORIZONTAL LAYOUT (for wider containers) */
368
+ @container contact-card (min-width: 500px) {
369
+ .card:not(.layout-vertical) {
370
+ grid-template-columns: 1fr minmax(120px, 200px);
371
+ grid-template-rows: 1fr;
372
+ align-items: start;
373
+ gap: var(--pd-spacing-md, 1rem);
374
+ }
375
+
376
+ .card:not(.layout-vertical) .card-logo {
377
+ order: 2;
378
+ width: 100%;
379
+ }
380
+
381
+ .card:not(.layout-vertical) .card-content {
382
+ order: 1;
383
+ }
384
+
385
+ .card:not(.layout-vertical) .title-name {
386
+ font-size: 1.5rem;
387
+ }
388
+
389
+ .card:not(.layout-vertical) .real-name {
390
+ font-size: 1rem;
391
+ }
392
+
393
+ .card:not(.layout-vertical) .contact-item {
394
+ font-size: 0.9rem;
395
+ }
396
+ }
397
+
398
+ /* FORCED HORIZONTAL LAYOUT */
399
+ .card.layout-horizontal {
400
+ grid-template-columns: 1fr minmax(120px, 200px) !important;
401
+ grid-template-rows: 1fr !important;
402
+ text-align: left !important;
403
+ align-items: start !important;
404
+ gap: var(--pd-spacing-md, 1rem) !important;
405
+ }
406
+
407
+ .card.layout-horizontal .card-logo {
408
+ order: 2 !important;
409
+ width: 100% !important;
410
+ }
411
+
412
+ .card.layout-horizontal .card-content {
413
+ order: 1 !important;
414
+ }
415
+
416
+ .card.layout-horizontal .title-name {
417
+ font-size: 1.5rem;
418
+ }
419
+
420
+ .card.layout-horizontal .real-name {
421
+ font-size: 1rem;
422
+ }
423
+
424
+ /* FORCED VERTICAL LAYOUT */
425
+ .card.layout-vertical {
426
+ grid-template-rows: auto 1fr !important;
427
+ grid-template-columns: 1fr !important;
428
+ text-align: center !important;
429
+ }
430
+
431
+ .card.layout-vertical .card-logo {
432
+ width: 100% !important;
433
+ max-height: 150px !important;
434
+ padding-bottom: var(--pd-spacing-md, 1rem);
435
+ }
436
+
437
+ .card.layout-vertical .card-names {
438
+ align-items: center !important;
439
+ }
440
+
441
+ .card.layout-vertical .card-contact-info {
442
+ align-items: center !important;
443
+ }
444
+
445
+ .card.layout-vertical .contact-item {
446
+ justify-content: center;
447
+ }
448
+
449
+ .card.layout-vertical pd-socialmedia {
450
+ display: flex;
451
+ justify-content: center;
452
+ }
453
+
454
+ .card.layout-vertical .title-name {
455
+ font-size: 1.25rem;
456
+ }
457
+
458
+ .card.layout-vertical .real-name {
459
+ font-size: 0.9rem;
460
+ }
135
461
  `
136
462
  ];
137
463
  }
@@ -143,7 +469,7 @@ const _PdContact = class _PdContact extends LitElement {
143
469
  render() {
144
470
  return html`
145
471
  <div class="contact">
146
- ${this.summary ? this._renderViewContact() : this._renderEditContact()}
472
+ ${this.viewType === "card" && this.summary ? this._renderCardView() : this.summary ? this._renderViewContact() : this._renderEditContact()}
147
473
  </div>
148
474
  `;
149
475
  }
@@ -154,7 +480,6 @@ const _PdContact = class _PdContact extends LitElement {
154
480
  <pd-form-row>
155
481
  <pd-radio-group
156
482
  id="contactTypeRadioId"
157
- class="quarter3"
158
483
  label="${msg("Typ", { id: "pd.contact.label.type" })}"
159
484
  required
160
485
  initValue="${this._getRadioValue()}"
@@ -185,7 +510,6 @@ const _PdContact = class _PdContact extends LitElement {
185
510
  <pd-form-row class="contact-form">
186
511
  <pd-input
187
512
  id="compNameId"
188
- class="quarter3"
189
513
  label="${msg("Name des Unternehmen", {
190
514
  id: "pd.contact.label.company"
191
515
  })}"
@@ -200,7 +524,6 @@ const _PdContact = class _PdContact extends LitElement {
200
524
  <pd-form-row class="contact-form">
201
525
  <pd-input
202
526
  id="vatId"
203
- class="quarter3"
204
527
  label="${msg("USt-IdNr.", {
205
528
  id: "pd.contact.label.btw"
206
529
  })}"
@@ -217,7 +540,6 @@ const _PdContact = class _PdContact extends LitElement {
217
540
  <pd-form-row class="contact-form">
218
541
  <pd-input
219
542
  id="firstNameId"
220
- class="quarter3"
221
543
  label="${msg("Vorname", {
222
544
  id: "pd.contact.label.firstName"
223
545
  })}"
@@ -232,7 +554,6 @@ const _PdContact = class _PdContact extends LitElement {
232
554
  <pd-form-row class="contact-form">
233
555
  <pd-input
234
556
  id="lastNameId"
235
- class="quarter3"
236
557
  label="${msg("Nachname", {
237
558
  id: "pd.contact.label.lastName"
238
559
  })}"
@@ -248,7 +569,7 @@ const _PdContact = class _PdContact extends LitElement {
248
569
  <pd-form-row class="contact-form">
249
570
  <pd-input
250
571
  id="streetId"
251
- class="quarter2"
572
+ span="three-quarters"
252
573
  label="${msg("Strasse", { id: "pd.contact.label.street" })}"
253
574
  valueName="street"
254
575
  initValue="${this.contact?.street || ""}"
@@ -257,7 +578,7 @@ const _PdContact = class _PdContact extends LitElement {
257
578
  ></pd-input>
258
579
  <pd-input
259
580
  id="streetNrId"
260
- class="quarter1"
581
+ span="quarter"
261
582
  label="${msg("Nr.", { id: "pd.contact.label.streetNr" })}"
262
583
  valueName="streetNr"
263
584
  initValue="${this.contact?.streetNr || ""}"
@@ -271,7 +592,7 @@ const _PdContact = class _PdContact extends LitElement {
271
592
  <pd-input
272
593
  readonly
273
594
  id="zipId"
274
- class="quarter1"
595
+ span="third"
275
596
  label="${msg("PLZ", { id: "pd.contact.label.zip" })}"
276
597
  valueName="zip"
277
598
  initValue="${this.match.zip}"
@@ -279,7 +600,7 @@ const _PdContact = class _PdContact extends LitElement {
279
600
  ` : html`
280
601
  <pd-input
281
602
  id="zipId"
282
- class="quarter1"
603
+ span="third"
283
604
  label="${msg("PLZ", { id: "pd.contact.label.zip" })}"
284
605
  fieldType="number"
285
606
  valueName="zip"
@@ -290,7 +611,7 @@ const _PdContact = class _PdContact extends LitElement {
290
611
  `}
291
612
  <pd-input
292
613
  id="cityId"
293
- class="quarter2"
614
+ span="two-thirds"
294
615
  label="${msg("Ort", { id: "pd.contact.label.city" })}"
295
616
  valueName="city"
296
617
  initValue="${this.contact?.city || ""}"
@@ -302,7 +623,6 @@ const _PdContact = class _PdContact extends LitElement {
302
623
  ${this.inputFields.length === 0 || this._showInput(C_ADDITIONAL) ? html`
303
624
  <pd-form-row class="contact-form">
304
625
  <pd-input
305
- class="quarter3"
306
626
  id="additionalHintId"
307
627
  label="${msg("Addresszusatz", {
308
628
  id: "pd.contact.label.additional"
@@ -316,7 +636,6 @@ const _PdContact = class _PdContact extends LitElement {
316
636
  ${this.withPropertyDate ? html`
317
637
  <pd-form-row class="contact-form">
318
638
  <pd-select
319
- class="quarter3"
320
639
  id="propertyDateId"
321
640
  label="${msg("Datum der Immobilie", {
322
641
  id: "pd.contact.label.propertyDate"
@@ -331,7 +650,6 @@ const _PdContact = class _PdContact extends LitElement {
331
650
  <pd-form-row class="contact-form">
332
651
  <pd-input
333
652
  id="phoneId"
334
- class="quarter3"
335
653
  label="${msg("Telefon", { id: "pd.contact.label.phone" })}"
336
654
  name="phone"
337
655
  valueName="phone1"
@@ -346,7 +664,6 @@ const _PdContact = class _PdContact extends LitElement {
346
664
  <pd-form-row class="contact-form">
347
665
  <pd-input
348
666
  id="mailId"
349
- class="quarter3"
350
667
  label="${msg("E-mail", { id: "pd.contact.label.email" })}"
351
668
  fieldType="mail"
352
669
  valueName="email"
@@ -369,66 +686,195 @@ const _PdContact = class _PdContact extends LitElement {
369
686
  if (!this.contact) return html`<p>Contact undefined</p>`;
370
687
  const trPhoneNr = transformPhone(
371
688
  this.contact.phone1 || "",
372
- this.contact.country || "be"
689
+ this.contact.country || "de"
373
690
  );
691
+ const displayTitle = this.contact.titleName || this.addressTitle;
374
692
  return html`
375
- <address>
376
- <dl>
377
- <dt>${this.addressTitle}</dt>
378
- <dd>${this.contact.companyName}</dd>
379
- <dd>${this.contact.vatNr}</dd>
380
- <dd>${this._getFullName()}</dd>
381
- <dd>${this._getFullStreet()}</dd>
382
- <dd>${this._getFullLocation()}</dd>
383
- ${this.contact.additionalHint ? html`<dd>${this.contact.additionalHint}</dd>` : ""}
384
- ${this.contact.propertyDate ? html`<dd>
693
+ <div class="detail-view">
694
+ <div class="detail-names">
695
+ ${displayTitle ? html`<h3 class="detail-title">${displayTitle}</h3>` : nothing}
696
+ ${this.contact.companyName ? html`<p class="detail-company">${this.contact.companyName}</p>` : nothing}
697
+ ${this.contact.vatNr ? html`<p class="detail-vat">${this.contact.vatNr}</p>` : nothing}
698
+ ${this._getFullName() && this._getFullName() !== displayTitle ? html`<p class="detail-name">${this._getFullName()}</p>` : nothing}
699
+ </div>
700
+
701
+ <div class="detail-address">
702
+ ${this._getFullStreet() ? html`<p>${this._getFullStreet()}</p>` : nothing}
703
+ ${this._getFullLocation() ? html`<p>${this._getFullLocation()}</p>` : nothing}
704
+ ${this.contact.additionalHint ? html`<p>${this.contact.additionalHint}</p>` : nothing}
705
+ ${this.contact.country ? html`<p>${this.contact.country}</p>` : nothing}
706
+ ${this.contact.propertyDate ? html`<p>
385
707
  ${msg(str`Baujahr: ${this.contact.propertyDate}`, {
386
708
  id: "pd.contact.label.summary.propertyDate"
387
709
  })}
388
- </dd>` : ""}
389
- <dd>${this.contact.country}</dd>
390
-
391
- ${this.contact.phone1 ? html` <dd class="larger">
392
- ${this.phoneMailLink && trPhoneNr ? html` <a
393
- href="tel:${trPhoneNr}"
394
- aria-label="Phone call: ${this.contact.phone1}"
395
- class="link-item"
396
- >
397
- <span style="margin-right: 8px;"
398
- >${this.contact.phone1}</span
399
- >
400
- <pd-icon
401
- activeIcon
402
- icon="phoneIcon"
403
- class="round link-icon"
404
- ></pd-icon>
405
- </a>` : this.contact.phone1}
406
- </dd>` : ""}
407
- ${this.contact.email ? html` <dd class="larger">
408
- ${this.phoneMailLink ? html` <a
409
- href="mailto:${this.contact.email}"
410
- aria-label="Send mail: ${this.contact.email}"
411
- class="link-item"
412
- >
413
- <span style="margin-right: 8px;"
414
- >${this.contact.email}</span
415
- >
416
- <pd-icon
417
- activeIcon
418
- icon="mailIcon"
419
- class="round link-icon"
420
- ></pd-icon>
421
- </a>` : this.contact.email}
422
- </dd>` : ""}
423
- ${this.contact.btw ? html` <dt>BTW</dt>
424
- <dd>${this.contact.btw}</dd>` : ""}
425
- ${this.contact.kbc ? html` <dt>Bankgegevens</dt>
426
- <dd>${this.contact.kbc}</dd>
427
- <dd>${this.contact.bank}</dd>` : ""}
428
- </dl>
429
- </address>
710
+ </p>` : nothing}
711
+ </div>
712
+
713
+ <div class="detail-contact-info">
714
+ ${this.contact.phone1 ? html`
715
+ <a
716
+ href="tel:${trPhoneNr || this.contact.phone1}"
717
+ class="contact-item"
718
+ aria-label="Phone: ${this.contact.phone1}"
719
+ >
720
+ <pd-icon icon="phoneIcon" class="contact-icon"></pd-icon>
721
+ <span>${this.contact.phone1}</span>
722
+ </a>
723
+ ` : nothing}
724
+ ${this.contact.email ? html`
725
+ <a
726
+ href="mailto:${this.contact.email}"
727
+ class="contact-item"
728
+ aria-label="Email: ${this.contact.email}"
729
+ >
730
+ <pd-icon icon="mailIcon" class="contact-icon"></pd-icon>
731
+ <span>${this.contact.email}</span>
732
+ </a>
733
+ ` : nothing}
734
+ ${this.contact.website ? html`
735
+ <a
736
+ href="${this._ensureHttps(this.contact.website)}"
737
+ target="_blank"
738
+ rel="noopener noreferrer"
739
+ class="contact-item"
740
+ aria-label="Website: ${this.contact.website}"
741
+ >
742
+ <pd-icon icon="circleIcon" class="contact-icon"></pd-icon>
743
+ <span
744
+ >${this._formatWebsiteDisplay(this.contact.website)}</span
745
+ >
746
+ </a>
747
+ ` : nothing}
748
+ </div>
749
+
750
+ ${this.contact.btw || this.contact.kbc ? html`
751
+ <div class="detail-bank">
752
+ ${this.contact.btw ? html`
753
+ <p class="detail-label">BTW</p>
754
+ <p>${this.contact.btw}</p>
755
+ ` : nothing}
756
+ ${this.contact.kbc ? html`
757
+ <p class="detail-label">Bankgegevens</p>
758
+ <p>${this.contact.kbc}</p>
759
+ ${this.contact.bank ? html`<p>${this.contact.bank}</p>` : nothing}
760
+ ` : nothing}
761
+ </div>
762
+ ` : nothing}
763
+ ${this.contact.socialMedia && this.contact.socialMedia.length > 0 ? html`
764
+ <hr class="detail-divider" />
765
+ <pd-socialmedia
766
+ summary
767
+ .initItems="${this.contact.socialMedia}"
768
+ ></pd-socialmedia>
769
+ ` : nothing}
770
+ </div>
771
+ `;
772
+ }
773
+ // ========================================
774
+ // CARD VIEW RENDER METHODS
775
+ // ========================================
776
+ _renderCardView() {
777
+ if (!this.contact) return html`<p>Contact undefined</p>`;
778
+ const layoutClass = this.cardLayout !== "auto" ? `layout-${this.cardLayout}` : "";
779
+ return html`
780
+ <div class="card-wrapper" part="card-wrapper">
781
+ <div class="card ${layoutClass}">
782
+ ${this._renderCardLogo()}
783
+ <div class="card-content">
784
+ ${this._renderCardNames()} ${this._renderCardContactInfo()}
785
+ ${this._hasCardContactInfo() ? this._renderCardDivider() : nothing}
786
+ ${this._renderCardSocialMedia()}
787
+ </div>
788
+ </div>
789
+ </div>
430
790
  `;
431
791
  }
792
+ _renderCardLogo() {
793
+ if (!this.contact?.logo) return nothing;
794
+ return html`
795
+ <div class="card-logo">
796
+ <img
797
+ src="${this.contact.logo}"
798
+ alt="${this.contact.titleName || "Logo"}"
799
+ />
800
+ </div>
801
+ `;
802
+ }
803
+ _renderCardNames() {
804
+ const titleName = this.contact?.titleName;
805
+ const fullName = this._getFullName();
806
+ return html`
807
+ <div class="card-names">
808
+ ${titleName ? html`<h2 class="title-name">${titleName}</h2>` : nothing}
809
+ ${fullName ? html`<p class="real-name">${fullName}</p>` : nothing}
810
+ </div>
811
+ `;
812
+ }
813
+ _renderCardContactInfo() {
814
+ const phone = this.contact?.phone1;
815
+ const email = this.contact?.email;
816
+ const website = this.contact?.website;
817
+ const trPhoneNr = phone ? transformPhone(phone, this.contact?.country || "de") : "";
818
+ return html`
819
+ <div class="card-contact-info">
820
+ ${phone ? html`
821
+ <a
822
+ href="tel:${trPhoneNr || phone}"
823
+ class="contact-item"
824
+ aria-label="Phone: ${phone}"
825
+ >
826
+ <pd-icon icon="phoneIcon" class="contact-icon"></pd-icon>
827
+ <span>${phone}</span>
828
+ </a>
829
+ ` : nothing}
830
+ ${email ? html`
831
+ <a
832
+ href="mailto:${email}"
833
+ class="contact-item"
834
+ aria-label="Email: ${email}"
835
+ >
836
+ <pd-icon icon="mailIcon" class="contact-icon"></pd-icon>
837
+ <span>${email}</span>
838
+ </a>
839
+ ` : nothing}
840
+ ${website ? html`
841
+ <a
842
+ href="${this._ensureHttps(website)}"
843
+ target="_blank"
844
+ rel="noopener noreferrer"
845
+ class="contact-item"
846
+ aria-label="Website: ${website}"
847
+ >
848
+ <pd-icon icon="circleIcon" class="contact-icon"></pd-icon>
849
+ <span>${this._formatWebsiteDisplay(website)}</span>
850
+ </a>
851
+ ` : nothing}
852
+ </div>
853
+ `;
854
+ }
855
+ _renderCardDivider() {
856
+ return html`<hr class="card-divider" />`;
857
+ }
858
+ _renderCardSocialMedia() {
859
+ const socialItems = this.contact?.socialMedia;
860
+ if (!socialItems || socialItems.length === 0) return nothing;
861
+ return html`
862
+ <pd-socialmedia summary .initItems="${socialItems}"></pd-socialmedia>
863
+ `;
864
+ }
865
+ _hasCardContactInfo() {
866
+ return !!(this.contact?.phone1 || this.contact?.email || this.contact?.website);
867
+ }
868
+ _ensureHttps(url) {
869
+ if (!url) return "";
870
+ return /^https?:\/\//i.test(url) ? url : `https://${url}`;
871
+ }
872
+ _formatWebsiteDisplay(url) {
873
+ return url.replace(/^https?:\/\/(www\.)?/i, "").replace(/\/$/, "");
874
+ }
875
+ // ========================================
876
+ // FORM METHODS
877
+ // ========================================
432
878
  get valid() {
433
879
  return this._contactForm?.valid === true;
434
880
  }
@@ -437,7 +883,6 @@ const _PdContact = class _PdContact extends LitElement {
437
883
  }
438
884
  getValues() {
439
885
  const contactFormValues = this._contactForm?.getValues().origin;
440
- console.log("VAlues:", contactFormValues);
441
886
  const commonValues = {
442
887
  business: this._business,
443
888
  street: contactFormValues.street,
@@ -465,7 +910,6 @@ const _PdContact = class _PdContact extends LitElement {
465
910
  };
466
911
  }
467
912
  _switchAddressType(e) {
468
- console.log("Do switch", e);
469
913
  if (e.detail.name === "contactTypeRadioId") {
470
914
  this._business = e.detail.value === "business";
471
915
  }
@@ -520,6 +964,12 @@ __decorateClass([
520
964
  __decorateClass([
521
965
  property({ type: Boolean })
522
966
  ], _PdContact.prototype, "summary");
967
+ __decorateClass([
968
+ property({ type: String, reflect: true, attribute: "view-type" })
969
+ ], _PdContact.prototype, "viewType");
970
+ __decorateClass([
971
+ property({ type: String, reflect: true, attribute: "card-layout" })
972
+ ], _PdContact.prototype, "cardLayout");
523
973
  __decorateClass([
524
974
  property({ type: Boolean })
525
975
  ], _PdContact.prototype, "withPropertyDate");
@@ -1,18 +1,53 @@
1
- import { StoryObj } from '@storybook/web-components';
2
- declare const meta: {
3
- title: string;
4
- render: ({ inputFields, requiredFields, withPropertyDate, contact }: import('@storybook/web-components').Args) => import('lit').TemplateResult<1>;
5
- argTypes: {};
6
- };
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ import { PdContactData } from '../types.js';
3
+ /**
4
+ * Story arguments interface for pd-contact (edit mode).
5
+ * Maps to the component's public API when used as an editable form.
6
+ */
7
+ interface PdContactEditArgs {
8
+ /** List of input fields to display (empty = all fields) */
9
+ inputFields: string[];
10
+ /** List of required field keys for validation */
11
+ requiredFields: string[];
12
+ /** Show property date selection field */
13
+ withPropertyDate: boolean;
14
+ /** Pre-populated contact data */
15
+ contact?: PdContactData;
16
+ }
17
+ /**
18
+ * ## pd-contact (Edit Mode)
19
+ *
20
+ * Contact form component for creating and editing contact information with
21
+ * built-in validation support.
22
+ *
23
+ * ### Features
24
+ * - Private/Business contact type toggle via radio group
25
+ * - Configurable visible fields via `inputFields` array
26
+ * - Required field validation via `requiredFields` array
27
+ * - Optional property/building year selection
28
+ * - Auto-complete hints for browser autofill
29
+ * - Integration with pd-form-container for validation lifecycle
30
+ *
31
+ * ### Form Methods
32
+ * - `triggerValidate()` — triggers validation and returns Promise<boolean>
33
+ * - `getValues()` — returns current form data as PdContactData
34
+ * - `valid` — getter for current validation state
35
+ */
36
+ declare const meta: Meta<PdContactEditArgs>;
7
37
  export default meta;
8
- type Story = StoryObj;
9
- export declare const ContactForm: Story;
10
- export declare const ContactFormRequiredFields: Story;
11
- export declare const ContactFormRequiredFields2: Story;
12
- export declare const ContactFormPropertyDate: Story;
13
- export declare const ContactFormWithInputFields1: Story;
14
- export declare const ContactFormWithInputFields2: Story;
15
- export declare const ContactPreparedForm: Story;
16
- export declare const ContactPreparedFormCompany: Story;
17
- export declare const ContactPreparedFormPropertyDate: Story;
38
+ type Story = StoryObj<PdContactEditArgs>;
39
+ /** Default empty contact form with all fields visible. Interactive via Controls panel. */
40
+ export declare const Default: Story;
41
+ /** Contact form pre-filled with private person data (first name, last name, address). */
42
+ export declare const PrepopulatedPrivate: Story;
43
+ /** Contact form pre-filled with company data (company name, VAT number). */
44
+ export declare const PrepopulatedCompany: Story;
45
+ /** Form with all fields marked as required — shows validation indicators. */
46
+ export declare const AllFieldsRequired: Story;
47
+ /** Demonstrates showing only a subset of fields using the inputFields array. */
48
+ export declare const CustomFieldSelection: Story;
49
+ /** Form with the optional property/building year selection field enabled. */
50
+ export declare const WithPropertyDate: Story;
51
+ /** CSS Custom Properties — Branded and Redesigned variants. */
52
+ export declare const CustomStyling: Story;
18
53
  //# sourceMappingURL=pd-contact-edit.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-contact-edit.stories.d.ts","sourceRoot":"","sources":["../../src/pd-contact/pd-contact-edit.stories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAehE,OAAO,iBAAiB,CAAC;AAGzB,QAAA,MAAM,IAAI;;;;CAmCM,CAAC;AAEjB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AA2BtB,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAevC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAIxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAIrC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAIzC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAIzC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAIjC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAIxC,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,KAQ7C,CAAC"}
1
+ {"version":3,"file":"pd-contact-edit.stories.d.ts","sourceRoot":"","sources":["../../src/pd-contact/pd-contact-edit.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,EAWL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,iBAAiB,CAAC;AACzB,OAAO,6CAA6C,CAAC;AAMrD;;;GAGG;AACH,UAAU,iBAAiB;IACzB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iDAAiD;IACjD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,yCAAyC;IACzC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iCAAiC;IACjC,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAuED;;;;;;;;;;;;;;;;;;GAkBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAmFjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAMzC,0FAA0F;AAC1F,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAMjC,yFAAyF;AACzF,eAAO,MAAM,mBAAmB,EAAE,KAIjC,CAAC;AAMF,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,EAAE,KAIjC,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,EAAE,KAI/B,CAAC;AAMF,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,EAAE,KAoClC,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAMF,+DAA+D;AAC/D,eAAO,MAAM,aAAa,EAAE,KAuE3B,CAAC"}
@@ -1,13 +1,55 @@
1
- import { StoryObj } from '@storybook/web-components';
2
- declare const meta: {
3
- title: string;
4
- render: ({ summary, phoneMailLink, contact, withPropertyDate }: import('@storybook/web-components').Args) => import('lit').TemplateResult<1>;
5
- argTypes: {};
6
- };
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ import { PdContactData } from '../types.js';
3
+ /**
4
+ * Story arguments interface for pd-contact (view mode).
5
+ * Maps to the component's public API when used as a read-only display.
6
+ */
7
+ interface PdContactViewArgs {
8
+ /** Show summary view (read-only display) */
9
+ summary: boolean;
10
+ /** Render phone and email as clickable links */
11
+ phoneMailLink: boolean;
12
+ /** View type: 'detail' or 'card' (business card) */
13
+ viewType: "detail" | "card";
14
+ /** Card layout mode: 'auto', 'horizontal', or 'vertical' */
15
+ cardLayout: "auto" | "horizontal" | "vertical";
16
+ /** Contact data to display */
17
+ contact: PdContactData;
18
+ }
19
+ /**
20
+ * ## pd-contact (View Mode)
21
+ *
22
+ * Contact display component for showing contact information in read-only mode.
23
+ * Supports two view types: detail (structured list) and card (business card layout).
24
+ *
25
+ * ### Features
26
+ * - Detail view with structured address, phone, email, and social media display
27
+ * - Business card view with logo, responsive layout, and social media integration
28
+ * - Private and business contact support (company name, VAT number)
29
+ * - Clickable phone/email links with icons
30
+ * - Card view with container-query-based responsive layout (auto/horizontal/vertical)
31
+ * - CSS custom properties for full visual customization
32
+ * - CSS part `card-wrapper` for external card styling
33
+ *
34
+ * ### View Types
35
+ * - `detail` — Traditional structured contact display (default)
36
+ * - `card` — Business card layout with logo and social media
37
+ */
38
+ declare const meta: Meta<PdContactViewArgs>;
7
39
  export default meta;
8
- type Story = StoryObj;
9
- export declare const ContactView: Story;
10
- export declare const ContactCompanyView: Story;
11
- export declare const ContactViewPropertyDate: Story;
12
- export declare const ContactViewPhone: Story;
40
+ type Story = StoryObj<PdContactViewArgs>;
41
+ /** Default contact view showing a private person. Interactive via Controls panel. */
42
+ export declare const Default: Story;
43
+ /** All detail view variants at a glance: private, company, with title/social media. */
44
+ export declare const AllDetailVariants: Story;
45
+ /** Detail view with titleName as header, website link, and social media integration. */
46
+ export declare const DetailWithTitleAndSocialMedia: Story;
47
+ /** Business card with auto-responsive layout — switches between horizontal (>500px) and vertical (<500px). */
48
+ export declare const CardDefault: Story;
49
+ /** Card view with all three layout modes side by side. */
50
+ export declare const CardLayouts: Story;
51
+ /** Card view with different content configurations: without logo, without social media, minimal. */
52
+ export declare const CardContentVariations: Story;
53
+ /** CSS Custom Properties — Branded and Redesigned card variants. */
54
+ export declare const CustomStyling: Story;
13
55
  //# sourceMappingURL=pd-contact-view.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-contact-view.stories.d.ts","sourceRoot":"","sources":["../../src/pd-contact/pd-contact-view.stories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,iBAAiB,CAAC;AAGzB,QAAA,MAAM,IAAI;;;;CAYM,CAAC;AAEjB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AA2BtB,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAKhC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAQrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC"}
1
+ {"version":3,"file":"pd-contact-view.stories.d.ts","sourceRoot":"","sources":["../../src/pd-contact/pd-contact-view.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,iBAAiB,CAAC;AAMzB;;;GAGG;AACH,UAAU,iBAAiB;IACzB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,aAAa,EAAE,OAAO,CAAC;IACvB,oDAAoD;IACpD,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC;IAC/C,8BAA8B;IAC9B,OAAO,EAAE,aAAa,CAAC;CACxB;AAyED;;;;;;;;;;;;;;;;;;GAkBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAgFjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAMzC,qFAAqF;AACrF,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAMjC,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,EAAE,KA0C/B,CAAC;AAMF,wFAAwF;AACxF,eAAO,MAAM,6BAA6B,EAAE,KAY3C,CAAC;AAMF,8GAA8G;AAC9G,eAAO,MAAM,WAAW,EAAE,KAazB,CAAC;AAMF,0DAA0D;AAC1D,eAAO,MAAM,WAAW,EAAE,KAwCzB,CAAC;AAMF,oGAAoG;AACpG,eAAO,MAAM,qBAAqB,EAAE,KA+CnC,CAAC;AAMF,oEAAoE;AACpE,eAAO,MAAM,aAAa,EAAE,KAuF3B,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SocialEntry } from '@progressive-development/pd-page';
2
+ export type { SocialEntry };
1
3
  export declare const C_TYPE = "type";
2
4
  export declare const C_COMPANY = "companyName";
3
5
  export declare const C_BTWNR = "vatNr";
@@ -11,6 +13,10 @@ export declare const C_ADDITIONAL = "additionalHint";
11
13
  export declare const C_PROPERTY_DATE = "propertyDate";
12
14
  export declare const C_PHONE1 = "phone1";
13
15
  export declare const C_EMAIL = "email";
16
+ export declare const C_TITLE_NAME = "titleName";
17
+ export declare const C_LOGO = "logo";
18
+ export declare const C_WEBSITE = "website";
19
+ export declare const C_SOCIAL_MEDIA = "socialMedia";
14
20
  export interface PdContactData {
15
21
  business?: boolean;
16
22
  companyName?: string;
@@ -29,6 +35,10 @@ export interface PdContactData {
29
35
  btw?: string;
30
36
  kbc?: string;
31
37
  bank?: string;
38
+ titleName?: string;
39
+ logo?: string;
40
+ website?: string;
41
+ socialMedia?: SocialEntry[];
32
42
  }
33
43
  export interface PdContactMatch {
34
44
  zip?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,SAAS,gBAAgB,CAAC;AACvC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,WAAW,aAAa,CAAC;AACtC,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,KAAK,QAAQ,CAAC;AAC3B,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAC9C,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,SAAS,gBAAgB,CAAC;AACvC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,WAAW,aAAa,CAAC;AACtC,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,KAAK,QAAQ,CAAC;AAC3B,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAC9C,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB"}
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@progressive-development/pd-contact",
3
- "version": "0.9.2",
3
+ "version": "1.0.1",
4
4
  "description": "Progressive Development Contact component",
5
5
  "author": "PD Progressive Development",
6
- "license": "SEE LICENSE IN LICENSE",
6
+ "license": "MIT",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
7
10
  "main": "./dist/index.js",
8
11
  "module": "./dist/index.js",
9
12
  "type": "module",
@@ -21,23 +24,6 @@
21
24
  "README.md",
22
25
  "LICENSE"
23
26
  ],
24
- "dependencies": {
25
- "lit": "^3.3.1",
26
- "@lit/localize": "^0.12.2",
27
- "tslib": "^2.8.1",
28
- "@progressive-development/pd-shared-styles": "0.3.0",
29
- "@progressive-development/pd-icon": "0.9.2",
30
- "@progressive-development/pd-forms": "0.9.2"
31
- },
32
- "customElements": "custom-elements.json",
33
- "keywords": [
34
- "pd",
35
- "progressive",
36
- "development",
37
- "contact",
38
- "form",
39
- "view"
40
- ],
41
27
  "scripts": {
42
28
  "analyze": "cem analyze --litelement --exclude dist,demo",
43
29
  "start": "vite",
@@ -51,9 +37,27 @@
51
37
  "test": "vitest run --coverage",
52
38
  "test:watch": "vitest --watch",
53
39
  "check": "pnpm run lint && pnpm run lint:lit && pnpm run build",
40
+ "prepublishOnly": "pnpm run clean && pnpm run check",
54
41
  "localizeExtract": "lit-localize extract",
55
42
  "localizeBuild": "lit-localize build",
56
43
  "storybook": "storybook dev -p 6006",
57
44
  "build-storybook": "storybook build"
58
- }
59
- }
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
+ }