@operato/contact 1.1.52

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 (56) hide show
  1. package/.editorconfig +29 -0
  2. package/.storybook/main.js +3 -0
  3. package/.storybook/server.mjs +8 -0
  4. package/CHANGELOG.md +11 -0
  5. package/README.md +76 -0
  6. package/demo/index.html +79 -0
  7. package/dist/src/OxContact copy.d.ts +38 -0
  8. package/dist/src/OxContact copy.js +194 -0
  9. package/dist/src/OxContact copy.js.map +1 -0
  10. package/dist/src/OxContact.d.ts +38 -0
  11. package/dist/src/OxContact.js +67 -0
  12. package/dist/src/OxContact.js.map +1 -0
  13. package/dist/src/OxContactEdit.d.ts +18 -0
  14. package/dist/src/OxContactEdit.js +235 -0
  15. package/dist/src/OxContactEdit.js.map +1 -0
  16. package/dist/src/OxContactView copy.d.ts +35 -0
  17. package/dist/src/OxContactView copy.js +143 -0
  18. package/dist/src/OxContactView copy.js.map +1 -0
  19. package/dist/src/OxContactView.d.ts +7 -0
  20. package/dist/src/OxContactView.js +138 -0
  21. package/dist/src/OxContactView.js.map +1 -0
  22. package/dist/src/index.d.ts +1 -0
  23. package/dist/src/index.js +2 -0
  24. package/dist/src/index.js.map +1 -0
  25. package/dist/src/ox-contact copy.d.ts +1 -0
  26. package/dist/src/ox-contact copy.js +3 -0
  27. package/dist/src/ox-contact copy.js.map +1 -0
  28. package/dist/src/ox-contact-edit copy.d.ts +1 -0
  29. package/dist/src/ox-contact-edit copy.js +3 -0
  30. package/dist/src/ox-contact-edit copy.js.map +1 -0
  31. package/dist/src/ox-contact-edit.d.ts +18 -0
  32. package/dist/src/ox-contact-edit.js +245 -0
  33. package/dist/src/ox-contact-edit.js.map +1 -0
  34. package/dist/src/ox-contact-view.d.ts +7 -0
  35. package/dist/src/ox-contact-view.js +142 -0
  36. package/dist/src/ox-contact-view.js.map +1 -0
  37. package/dist/src/ox-contact.d.ts +38 -0
  38. package/dist/src/ox-contact.js +67 -0
  39. package/dist/src/ox-contact.js.map +1 -0
  40. package/dist/stories/index.stories.d.ts +24 -0
  41. package/dist/stories/index.stories.js +79 -0
  42. package/dist/stories/index.stories.js.map +1 -0
  43. package/dist/test/ox-contact.test.d.ts +1 -0
  44. package/dist/test/ox-contact.test.js +24 -0
  45. package/dist/test/ox-contact.test.js.map +1 -0
  46. package/dist/tsconfig.tsbuildinfo +1 -0
  47. package/package.json +79 -0
  48. package/src/index.ts +1 -0
  49. package/src/ox-contact-edit.ts +261 -0
  50. package/src/ox-contact-view.ts +146 -0
  51. package/src/ox-contact.ts +69 -0
  52. package/stories/index.stories.ts +92 -0
  53. package/test/ox-contact.test.ts +32 -0
  54. package/tsconfig.json +23 -0
  55. package/web-dev-server.config.mjs +27 -0
  56. package/web-test-runner.config.mjs +41 -0
@@ -0,0 +1,245 @@
1
+ import { __decorate } from "tslib";
2
+ import '@material/mwc-icon-button';
3
+ import { html, css, LitElement } from 'lit';
4
+ import { customElement, property, state, query, queryAll } from 'lit/decorators.js';
5
+ import { ContactField } from './ox-contact';
6
+ import { ScrollbarStyles } from '@operato/styles';
7
+ let OxContactEdit = class OxContactEdit extends LitElement {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.contact = {};
11
+ this.stageContact = JSON.parse(JSON.stringify(this.contact));
12
+ }
13
+ render() {
14
+ var _a;
15
+ const { items = [], note } = this.stageContact || {};
16
+ var sorted = {};
17
+ items.forEach(item => {
18
+ if (!sorted[item.type]) {
19
+ sorted[item.type] = [item];
20
+ }
21
+ else {
22
+ sorted[item.type].push(item);
23
+ }
24
+ });
25
+ const names = [...(sorted[ContactField.Name] || [{ type: ContactField.Name, label: 'name', value: '' }])];
26
+ const companies = [
27
+ ...(sorted[ContactField.Company] || [{ type: ContactField.Company, label: 'company', value: '' }])
28
+ ];
29
+ return html `
30
+ <div name>
31
+ <div monogram>${(_a = names[0]) === null || _a === void 0 ? void 0 : _a.value.replace(/\s/g, '').slice(0, 2)}</div>
32
+ <div name-content>
33
+ ${names.map(item => html `<div @change=${(e) => this.onChangeItem(e, item)} .item=${item} field>
34
+ <span>name</span>
35
+ <input type="hidden" .value=${item.label} data-item="label" disabled />
36
+ <input type="text" .value=${item.value} data-item="value" />
37
+ </div>`)}
38
+ ${companies.map(item => html `<div @change=${(e) => this.onChangeItem(e, item)} .item=${item} field>
39
+ <span>company</span>
40
+ <input type="hidden" .value=${item.label} data-item="label" disabled />
41
+ <input type="text" .value=${item.value} data-item="value" />
42
+ </div>`)}
43
+ </div>
44
+ </div>
45
+ ${['email', 'phone', 'address'].map(type => {
46
+ var items = [...(sorted[type] || []), { type: type, label: 'work', value: '' }];
47
+ return html `
48
+ <div data-type=${type}>
49
+ ${type}
50
+ ${items.map(item => html `<div @change=${(e) => this.onChangeItem(e, item)} .item=${item} field>
51
+ ${item.value
52
+ ? html `<mwc-icon-button
53
+ icon="cancel"
54
+ @click=${() => {
55
+ item.value = '';
56
+ this.buildStageContact();
57
+ }}
58
+ ></mwc-icon-button>`
59
+ : html `<mwc-icon-button></mwc-icon-button>`}
60
+ <select .value=${item.label} data-item="label">
61
+ ${['home', 'work', 'other', 'mobile'].map(option => html ` <option value=${option} ?selected=${option === item.label}>${option}</option>`)}
62
+ </select>
63
+ <input type="text" .value=${item.value} data-item="value" />
64
+ </div>`)}
65
+ </div>
66
+ `;
67
+ })}
68
+ <div note>
69
+ note
70
+ <textarea id="note" .value=${note || ''} @change=${() => this.buildStageContact()}></textarea>
71
+ </div>
72
+
73
+ <div buttons>
74
+ <button value="Done" @click=${() => this.onSave()}>Done</button>
75
+ <button value="Cancel" @click=${() => this.onCancel()}>Cancel</button>
76
+ <button value="Reset" @click=${() => this.onReset()}>Reset</button>
77
+ </div>
78
+ `;
79
+ }
80
+ updated(changes) {
81
+ if (changes.has('contact')) {
82
+ this.stageContact = JSON.parse(JSON.stringify(this.contact));
83
+ }
84
+ }
85
+ buildItems() {
86
+ const items = [];
87
+ this.fields.forEach(fieldElement => {
88
+ const item = fieldElement.item;
89
+ if (item.value) {
90
+ items.push(item);
91
+ }
92
+ });
93
+ return items;
94
+ }
95
+ buildStageContact() {
96
+ this.stageContact = {
97
+ ...this.stageContact,
98
+ note: this.note.value,
99
+ items: this.buildItems()
100
+ };
101
+ }
102
+ onChangeItem(e, item) {
103
+ const target = e.currentTarget;
104
+ const labelElement = target.querySelector('[data-item="label"');
105
+ const valueElement = target.querySelector('[data-item="value"');
106
+ item.label = labelElement.value;
107
+ item.value = valueElement.value;
108
+ if (e.target === valueElement || item.value) {
109
+ this.buildStageContact();
110
+ }
111
+ }
112
+ onSave() {
113
+ this.buildStageContact();
114
+ this.dispatchEvent(new CustomEvent('edit-done', {
115
+ detail: this.stageContact
116
+ }));
117
+ }
118
+ onCancel() {
119
+ this.dispatchEvent(new CustomEvent('edit-cancel', {
120
+ detail: this.stageContact
121
+ }));
122
+ }
123
+ onReset() {
124
+ this.buildStageContact();
125
+ this.stageContact = JSON.parse(JSON.stringify(this.contact));
126
+ }
127
+ };
128
+ OxContactEdit.styles = [
129
+ ScrollbarStyles,
130
+ css `
131
+ :host {
132
+ display: block;
133
+ padding: 25px;
134
+
135
+ --mdc-icon-button-size: 16px;
136
+ --mdc-icon-size: 16px;
137
+ }
138
+
139
+ :host > div {
140
+ padding: 10px 0;
141
+ display: block;
142
+ border-bottom: 1px solid blue;
143
+ }
144
+
145
+ :host > div > div {
146
+ padding: 4px 0;
147
+ box-sizing: border-box;
148
+
149
+ display: flex;
150
+ flex-direction: row;
151
+ gap: 10px;
152
+ }
153
+
154
+ :host > div > div:hover {
155
+ position: relative;
156
+ }
157
+
158
+ [data-item='label'] {
159
+ width: 100px;
160
+ text-align: right;
161
+ }
162
+
163
+ [data-item='value'] {
164
+ flex: 1;
165
+ }
166
+
167
+ :host > div[name] {
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 10px;
171
+ font-weight: bold;
172
+ font-size: 1.4em;
173
+ }
174
+
175
+ :host > div[name] > [monogram] {
176
+ display: inline-block;
177
+ width: 100px;
178
+ height: 100px;
179
+ line-height: 100px;
180
+ border-radius: 999px;
181
+ border: 1px solid darkgray;
182
+ box-sizing: border-box;
183
+ padding: 0;
184
+ font-size: 40px;
185
+ font-family: system-ui;
186
+ overflow: hidden;
187
+ text-align: center;
188
+ vertical-align: center;
189
+ background-color: gray;
190
+ color: white;
191
+ text-transform: uppercase;
192
+ }
193
+
194
+ :host > div[name] > div[name-content] {
195
+ flex: 1;
196
+
197
+ display: flex;
198
+ flex-direction: column;
199
+ }
200
+
201
+ div[field] {
202
+ display: flex;
203
+ flex-direction: row;
204
+ align-items: center;
205
+ gap: 10px;
206
+ }
207
+
208
+ div[field] > span {
209
+ width: 100px;
210
+ text-align: right;
211
+ }
212
+
213
+ div[field] > input {
214
+ flex: 1;
215
+ }
216
+
217
+ textarea {
218
+ width: 100%;
219
+ height: 100px;
220
+ }
221
+
222
+ div[buttons] {
223
+ display: flex;
224
+ flex-direction: row-reverse;
225
+ gap: 10px;
226
+ }
227
+ `
228
+ ];
229
+ __decorate([
230
+ property({ type: Object })
231
+ ], OxContactEdit.prototype, "contact", void 0);
232
+ __decorate([
233
+ state()
234
+ ], OxContactEdit.prototype, "stageContact", void 0);
235
+ __decorate([
236
+ query('#note')
237
+ ], OxContactEdit.prototype, "note", void 0);
238
+ __decorate([
239
+ queryAll('[field]')
240
+ ], OxContactEdit.prototype, "fields", void 0);
241
+ OxContactEdit = __decorate([
242
+ customElement('ox-contact-edit')
243
+ ], OxContactEdit);
244
+ export { OxContactEdit };
245
+ //# sourceMappingURL=ox-contact-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-contact-edit.js","sourceRoot":"","sources":["../../src/ox-contact-edit.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-icon-button'\n\nimport { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state, query, queryAll } from 'lit/decorators.js'\nimport { Contact, ContactField, ContactItem } from './ox-contact'\nimport { ScrollbarStyles } from '@operato/styles'\n\n@customElement('ox-contact-edit')\nexport class OxContactEdit extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: block;\n padding: 25px;\n\n --mdc-icon-button-size: 16px;\n --mdc-icon-size: 16px;\n }\n\n :host > div {\n padding: 10px 0;\n display: block;\n border-bottom: 1px solid blue;\n }\n\n :host > div > div {\n padding: 4px 0;\n box-sizing: border-box;\n\n display: flex;\n flex-direction: row;\n gap: 10px;\n }\n\n :host > div > div:hover {\n position: relative;\n }\n\n [data-item='label'] {\n width: 100px;\n text-align: right;\n }\n\n [data-item='value'] {\n flex: 1;\n }\n\n :host > div[name] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: bold;\n font-size: 1.4em;\n }\n\n :host > div[name] > [monogram] {\n display: inline-block;\n width: 100px;\n height: 100px;\n line-height: 100px;\n border-radius: 999px;\n border: 1px solid darkgray;\n box-sizing: border-box;\n padding: 0;\n font-size: 40px;\n font-family: system-ui;\n overflow: hidden;\n text-align: center;\n vertical-align: center;\n background-color: gray;\n color: white;\n text-transform: uppercase;\n }\n\n :host > div[name] > div[name-content] {\n flex: 1;\n\n display: flex;\n flex-direction: column;\n }\n\n div[field] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 10px;\n }\n\n div[field] > span {\n width: 100px;\n text-align: right;\n }\n\n div[field] > input {\n flex: 1;\n }\n\n textarea {\n width: 100%;\n height: 100px;\n }\n\n div[buttons] {\n display: flex;\n flex-direction: row-reverse;\n gap: 10px;\n }\n `\n ]\n\n @property({ type: Object }) contact: Contact = {}\n\n @state() private stageContact: Contact = JSON.parse(JSON.stringify(this.contact))\n\n @query('#note') note!: HTMLTextAreaElement\n @queryAll('[field]') fields!: NodeListOf<HTMLDivElement>\n\n render() {\n const { items = [], note } = this.stageContact || {}\n var sorted: { [type: string]: ContactItem[] } = {}\n\n items.forEach(item => {\n if (!sorted[item.type as string]) {\n sorted[item.type] = [item]\n } else {\n sorted[item.type as string].push(item)\n }\n })\n\n const names = [...(sorted[ContactField.Name] || [{ type: ContactField.Name, label: 'name', value: '' }])]\n const companies = [\n ...(sorted[ContactField.Company] || [{ type: ContactField.Company, label: 'company', value: '' }])\n ]\n\n return html`\n <div name>\n <div monogram>${names[0]?.value.replace(/\\s/g, '').slice(0, 2)}</div>\n <div name-content>\n ${names.map(\n item => html`<div @change=${(e: Event) => this.onChangeItem(e, item)} .item=${item} field>\n <span>name</span>\n <input type=\"hidden\" .value=${item.label} data-item=\"label\" disabled />\n <input type=\"text\" .value=${item.value} data-item=\"value\" />\n </div>`\n )}\n ${companies.map(\n item => html`<div @change=${(e: Event) => this.onChangeItem(e, item)} .item=${item} field>\n <span>company</span>\n <input type=\"hidden\" .value=${item.label} data-item=\"label\" disabled />\n <input type=\"text\" .value=${item.value} data-item=\"value\" />\n </div>`\n )}\n </div>\n </div>\n ${['email', 'phone', 'address'].map(type => {\n var items = [...(sorted[type] || []), { type: type as ContactField, label: 'work', value: '' }]\n\n return html`\n <div data-type=${type}>\n ${type}\n ${items.map(\n item =>\n html`<div @change=${(e: Event) => this.onChangeItem(e, item)} .item=${item} field>\n ${item.value\n ? html`<mwc-icon-button\n icon=\"cancel\"\n @click=${() => {\n item.value = ''\n this.buildStageContact()\n }}\n ></mwc-icon-button>`\n : html`<mwc-icon-button></mwc-icon-button>`}\n <select .value=${item.label} data-item=\"label\">\n ${['home', 'work', 'other', 'mobile'].map(\n option => html` <option value=${option} ?selected=${option === item.label}>${option}</option>`\n )}\n </select>\n <input type=\"text\" .value=${item.value} data-item=\"value\" />\n </div>`\n )}\n </div>\n `\n })}\n <div note>\n note\n <textarea id=\"note\" .value=${note || ''} @change=${() => this.buildStageContact()}></textarea>\n </div>\n\n <div buttons>\n <button value=\"Done\" @click=${() => this.onSave()}>Done</button>\n <button value=\"Cancel\" @click=${() => this.onCancel()}>Cancel</button>\n <button value=\"Reset\" @click=${() => this.onReset()}>Reset</button>\n </div>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('contact')) {\n this.stageContact = JSON.parse(JSON.stringify(this.contact))\n }\n }\n\n buildItems() {\n const items: ContactItem[] = []\n\n this.fields.forEach(fieldElement => {\n const item = (fieldElement as any).item\n if (item.value) {\n items.push(item)\n }\n })\n\n return items\n }\n\n buildStageContact() {\n this.stageContact = {\n ...this.stageContact,\n note: this.note.value,\n items: this.buildItems()\n }\n }\n\n onChangeItem(e: Event, item: ContactItem) {\n const target = e.currentTarget as HTMLElement\n const labelElement = target.querySelector('[data-item=\"label\"') as HTMLSelectElement\n const valueElement = target.querySelector('[data-item=\"value\"') as HTMLInputElement\n\n item.label = labelElement.value\n item.value = valueElement.value\n\n if (e.target === valueElement || item.value) {\n this.buildStageContact()\n }\n }\n\n onSave() {\n this.buildStageContact()\n\n this.dispatchEvent(\n new CustomEvent('edit-done', {\n detail: this.stageContact\n })\n )\n }\n\n onCancel() {\n this.dispatchEvent(\n new CustomEvent('edit-cancel', {\n detail: this.stageContact\n })\n )\n }\n\n onReset() {\n this.buildStageContact()\n\n this.stageContact = JSON.parse(JSON.stringify(this.contact))\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { LitElement } from 'lit';
2
+ import { Contact } from './ox-contact';
3
+ export declare class OxContactView extends LitElement {
4
+ static styles: import("lit").CSSResult;
5
+ contact: Contact;
6
+ render(): import("lit-html").TemplateResult<1>;
7
+ }
@@ -0,0 +1,142 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, property } from 'lit/decorators.js';
4
+ import { ContactField } from './ox-contact';
5
+ let OxContactView = class OxContactView extends LitElement {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.contact = {};
9
+ }
10
+ render() {
11
+ var _a;
12
+ const { items = [], note } = this.contact || {};
13
+ var sorted = {};
14
+ items.forEach(item => {
15
+ if (!sorted[item.type]) {
16
+ sorted[item.type] = [item];
17
+ }
18
+ else {
19
+ sorted[item.type].push(item);
20
+ }
21
+ });
22
+ const names = sorted[ContactField.Name] || [];
23
+ const companies = sorted[ContactField.Company] || [];
24
+ return html `
25
+ <div name>
26
+ <div monogram>${(_a = names[0]) === null || _a === void 0 ? void 0 : _a.value.replace(/\s/g, '').slice(0, 2)}</div>
27
+ <div name-content>
28
+ ${names.map(item => html `<div>
29
+ <span data-item="value">${item.value}</span>
30
+ </div>`)}
31
+ ${companies.map(item => html `<div>
32
+ <span data-item="value">${item.value}</span>
33
+ </div>`)}
34
+ </div>
35
+ </div>
36
+ ${['email', 'phone', 'address', 'company', 'etc']
37
+ .map(type => sorted[type])
38
+ .filter(items => items && items.length > 0)
39
+ .map(items => html `<div data-type=${items[0].type}>
40
+ ${items[0].type}
41
+ ${items.map(item => html `<div>
42
+ <label data-item="label">${item.label}</label>
43
+ <span data-item="value">${item.value}</span>
44
+ </div>`)}
45
+ </div>`)}
46
+ <div note>
47
+ note
48
+ <div>${note || ''}</div>
49
+ </div>
50
+ `;
51
+ }
52
+ };
53
+ OxContactView.styles = css `
54
+ :host {
55
+ display: block;
56
+ }
57
+
58
+ :host > div {
59
+ padding: 10px 0;
60
+ display: block;
61
+ border-bottom: 1px solid blue;
62
+ }
63
+
64
+ :host > div > div {
65
+ padding: 4px 0;
66
+ box-sizing: border-box;
67
+
68
+ display: flex;
69
+ flex-direction: row;
70
+ gap: 10px;
71
+ }
72
+
73
+ :host > div > div:hover {
74
+ position: relative;
75
+ }
76
+
77
+ :host > div > div:hover::before {
78
+ content: '';
79
+ display: block;
80
+ position: absolute;
81
+ text-align: left;
82
+ line-height: 24px;
83
+ top: 0;
84
+ right: 0;
85
+ width: 100%;
86
+ height: 100%;
87
+ opacity: 0.3;
88
+ background-image: linear-gradient(var(--primary-color, gray), var(--primary-color, gray));
89
+ z-index: -1;
90
+ }
91
+
92
+ [data-item='label'] {
93
+ width: 100px;
94
+ text-align: right;
95
+ }
96
+
97
+ [data-item='value'] {
98
+ flex: 1;
99
+ }
100
+
101
+ :host > div[name] {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 10px;
105
+ font-weight: bold;
106
+ font-size: 1.4em;
107
+ }
108
+
109
+ :host > div[name] > [monogram] {
110
+ display: inline-block;
111
+ width: 100px;
112
+ height: 100px;
113
+ line-height: 100px;
114
+ border-radius: 999px;
115
+ border: 1px solid darkgray;
116
+ box-sizing: border-box;
117
+ padding: 0;
118
+ font-size: 40px;
119
+ font-family: system-ui;
120
+ overflow: hidden;
121
+ text-align: center;
122
+ vertical-align: center;
123
+ background-color: gray;
124
+ color: white;
125
+ text-transform: uppercase;
126
+ }
127
+
128
+ :host > div[name] > div[name-content] {
129
+ flex: 1;
130
+
131
+ display: flex;
132
+ flex-direction: column;
133
+ }
134
+ `;
135
+ __decorate([
136
+ property({ type: Object })
137
+ ], OxContactView.prototype, "contact", void 0);
138
+ OxContactView = __decorate([
139
+ customElement('ox-contact-view')
140
+ ], OxContactView);
141
+ export { OxContactView };
142
+ //# sourceMappingURL=ox-contact-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-contact-view.js","sourceRoot":"","sources":["../../src/ox-contact-view.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAW,YAAY,EAAe,MAAM,cAAc,CAAA;AAG1D,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,UAAU;IAAtC;;QAoFuB,YAAO,GAAY,EAAE,CAAA;IAwDnD,CAAC;IAtDC,MAAM;;QACJ,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAC/C,IAAI,MAAM,GAAsC,EAAE,CAAA;QAElD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAc,CAAC,EAAE;gBAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;aAC3B;iBAAM;gBACL,MAAM,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;aACvC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QAEpD,OAAO,IAAI,CAAA;;wBAES,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;;YAE1D,KAAK,CAAC,GAAG,CACT,IAAI,CAAC,EAAE,CACL,IAAI,CAAA;0CACwB,IAAI,CAAC,KAAK;qBAC/B,CACV;YACC,SAAS,CAAC,GAAG,CACb,IAAI,CAAC,EAAE,CACL,IAAI,CAAA;0CACwB,IAAI,CAAC,KAAK;qBAC/B,CACV;;;QAGH,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;aAC9C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aACzB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;aAC1C,GAAG,CACF,KAAK,CAAC,EAAE,CAAC,IAAI,CAAA,kBAAkB,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;cACxC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;cACb,KAAK,CAAC,GAAG,CACT,IAAI,CAAC,EAAE,CACL,IAAI,CAAA;6CACyB,IAAI,CAAC,KAAK;4CACX,IAAI,CAAC,KAAK;uBAC/B,CACV;iBACI,CACR;;;eAGM,IAAI,IAAI,EAAE;;KAEpB,CAAA;IACH,CAAC;;AA1IM,oBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFlB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAsB;AApFtC,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CA4IzB;SA5IY,aAAa","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { Contact, ContactField, ContactItem } from './ox-contact'\n\n@customElement('ox-contact-view')\nexport class OxContactView extends LitElement {\n static styles = css`\n :host {\n display: block;\n }\n\n :host > div {\n padding: 10px 0;\n display: block;\n border-bottom: 1px solid blue;\n }\n\n :host > div > div {\n padding: 4px 0;\n box-sizing: border-box;\n\n display: flex;\n flex-direction: row;\n gap: 10px;\n }\n\n :host > div > div:hover {\n position: relative;\n }\n\n :host > div > div:hover::before {\n content: '';\n display: block;\n position: absolute;\n text-align: left;\n line-height: 24px;\n top: 0;\n right: 0;\n width: 100%;\n height: 100%;\n opacity: 0.3;\n background-image: linear-gradient(var(--primary-color, gray), var(--primary-color, gray));\n z-index: -1;\n }\n\n [data-item='label'] {\n width: 100px;\n text-align: right;\n }\n\n [data-item='value'] {\n flex: 1;\n }\n\n :host > div[name] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-weight: bold;\n font-size: 1.4em;\n }\n\n :host > div[name] > [monogram] {\n display: inline-block;\n width: 100px;\n height: 100px;\n line-height: 100px;\n border-radius: 999px;\n border: 1px solid darkgray;\n box-sizing: border-box;\n padding: 0;\n font-size: 40px;\n font-family: system-ui;\n overflow: hidden;\n text-align: center;\n vertical-align: center;\n background-color: gray;\n color: white;\n text-transform: uppercase;\n }\n\n :host > div[name] > div[name-content] {\n flex: 1;\n\n display: flex;\n flex-direction: column;\n }\n `\n\n @property({ type: Object }) contact: Contact = {}\n\n render() {\n const { items = [], note } = this.contact || {}\n var sorted: { [type: string]: ContactItem[] } = {}\n\n items.forEach(item => {\n if (!sorted[item.type as string]) {\n sorted[item.type] = [item]\n } else {\n sorted[item.type as string].push(item)\n }\n })\n\n const names = sorted[ContactField.Name] || []\n const companies = sorted[ContactField.Company] || []\n\n return html`\n <div name>\n <div monogram>${names[0]?.value.replace(/\\s/g, '').slice(0, 2)}</div>\n <div name-content>\n ${names.map(\n item =>\n html`<div>\n <span data-item=\"value\">${item.value}</span>\n </div>`\n )}\n ${companies.map(\n item =>\n html`<div>\n <span data-item=\"value\">${item.value}</span>\n </div>`\n )}\n </div>\n </div>\n ${['email', 'phone', 'address', 'company', 'etc']\n .map(type => sorted[type])\n .filter(items => items && items.length > 0)\n .map(\n items => html`<div data-type=${items[0].type}>\n ${items[0].type}\n ${items.map(\n item =>\n html`<div>\n <label data-item=\"label\">${item.label}</label>\n <span data-item=\"value\">${item.value}</span>\n </div>`\n )}\n </div>`\n )}\n <div note>\n note\n <div>${note || ''}</div>\n </div>\n `\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { LitElement } from 'lit';
2
+ import './ox-contact-edit';
3
+ import './ox-contact-view';
4
+ export declare enum ContactField {
5
+ Name = "name",
6
+ JobTitle = "job-title",
7
+ Phone = "phone",
8
+ Address = "address",
9
+ Email = "email",
10
+ Birthday = "birthday",
11
+ Profile = "profile",
12
+ Picture = "picture",
13
+ Department = "department",
14
+ Company = "company",
15
+ Homepage = "homepage"
16
+ }
17
+ export declare enum ContactLabel {
18
+ home = "home",
19
+ work = "work",
20
+ other = "other",
21
+ mobile = "mobile"
22
+ }
23
+ export type ContactItem = {
24
+ id?: string;
25
+ type: ContactField;
26
+ label: string;
27
+ value: string;
28
+ };
29
+ export type Contact = {
30
+ items?: ContactItem[];
31
+ note?: string;
32
+ };
33
+ export declare class OxContact extends LitElement {
34
+ static styles: import("lit").CSSResult;
35
+ contact: Contact;
36
+ editMode?: boolean;
37
+ render(): import("lit-html").TemplateResult<1>;
38
+ }
@@ -0,0 +1,67 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, property, state } from 'lit/decorators.js';
4
+ import './ox-contact-edit';
5
+ import './ox-contact-view';
6
+ export var ContactField;
7
+ (function (ContactField) {
8
+ ContactField["Name"] = "name";
9
+ ContactField["JobTitle"] = "job-title";
10
+ ContactField["Phone"] = "phone";
11
+ ContactField["Address"] = "address";
12
+ ContactField["Email"] = "email";
13
+ ContactField["Birthday"] = "birthday";
14
+ ContactField["Profile"] = "profile";
15
+ ContactField["Picture"] = "picture";
16
+ ContactField["Department"] = "department";
17
+ ContactField["Company"] = "company";
18
+ ContactField["Homepage"] = "homepage";
19
+ })(ContactField || (ContactField = {}));
20
+ export var ContactLabel;
21
+ (function (ContactLabel) {
22
+ ContactLabel["home"] = "home";
23
+ ContactLabel["work"] = "work";
24
+ ContactLabel["other"] = "other";
25
+ ContactLabel["mobile"] = "mobile";
26
+ })(ContactLabel || (ContactLabel = {}));
27
+ let OxContact = class OxContact extends LitElement {
28
+ constructor() {
29
+ super(...arguments);
30
+ this.contact = {};
31
+ this.editMode = false;
32
+ }
33
+ render() {
34
+ return html `${this.editMode
35
+ ? html `<ox-contact-edit
36
+ .contact=${this.contact}
37
+ @edit-cancel=${() => (this.editMode = false)}
38
+ @edit-done=${(e) => {
39
+ this.contact = e.detail;
40
+ this.editMode = false;
41
+ }}
42
+ ></ox-contact-edit>`
43
+ : html ` <ox-contact-view .contact=${this.contact}></ox-contact-view>
44
+ <button value="Edit" @click=${() => (this.editMode = true)}>Edit</button>`} `;
45
+ }
46
+ };
47
+ OxContact.styles = css `
48
+ :host {
49
+ display: block;
50
+ }
51
+
52
+ button {
53
+ display: block;
54
+ margin-left: auto;
55
+ }
56
+ `;
57
+ __decorate([
58
+ property({ type: Object })
59
+ ], OxContact.prototype, "contact", void 0);
60
+ __decorate([
61
+ state()
62
+ ], OxContact.prototype, "editMode", void 0);
63
+ OxContact = __decorate([
64
+ customElement('ox-contact')
65
+ ], OxContact);
66
+ export { OxContact };
67
+ //# sourceMappingURL=ox-contact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-contact.js","sourceRoot":"","sources":["../../src/ox-contact.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,mBAAmB,CAAA;AAC1B,OAAO,mBAAmB,CAAA;AAE1B,MAAM,CAAN,IAAY,YAYX;AAZD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,sCAAsB,CAAA;IACtB,+BAAe,CAAA;IACf,mCAAmB,CAAA;IACnB,+BAAe,CAAA;IACf,qCAAqB,CAAA;IACrB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,yCAAyB,CAAA;IACzB,mCAAmB,CAAA;IACnB,qCAAqB,CAAA;AACvB,CAAC,EAZW,YAAY,KAAZ,YAAY,QAYvB;AAED,MAAM,CAAN,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,6BAAa,CAAA;IACb,+BAAe,CAAA;IACf,iCAAiB,CAAA;AACnB,CAAC,EALW,YAAY,KAAZ,YAAY,QAKvB;AAeM,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAYuB,YAAO,GAAY,EAAE,CAAA;QAExC,aAAQ,GAAa,KAAK,CAAA;IAerC,CAAC;IAbC,MAAM;QACJ,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,QAAQ;YACzB,CAAC,CAAC,IAAI,CAAA;qBACS,IAAI,CAAC,OAAO;yBACR,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;uBAC/B,CAAC,CAAc,EAAE,EAAE;gBAC9B,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAA;gBACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;YACvB,CAAC;4BACiB;YACtB,CAAC,CAAC,IAAI,CAAA,8BAA8B,IAAI,CAAC,OAAO;wCACd,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,GAAG,CAAA;IACrF,CAAC;;AA3BM,gBAAM,GAAG,GAAG,CAAA;;;;;;;;;GASlB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAsB;AAExC;IAAR,KAAK,EAAE;2CAA2B;AAdxB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CA6BrB;SA7BY,SAAS","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport './ox-contact-edit'\nimport './ox-contact-view'\n\nexport enum ContactField {\n Name = 'name',\n JobTitle = 'job-title',\n Phone = 'phone',\n Address = 'address',\n Email = 'email',\n Birthday = 'birthday',\n Profile = 'profile',\n Picture = 'picture',\n Department = 'department',\n Company = 'company',\n Homepage = 'homepage'\n}\n\nexport enum ContactLabel {\n home = 'home',\n work = 'work',\n other = 'other',\n mobile = 'mobile'\n}\n\nexport type ContactItem = {\n id?: string\n type: ContactField\n label: string\n value: string\n}\n\nexport type Contact = {\n items?: ContactItem[]\n note?: string\n}\n\n@customElement('ox-contact')\nexport class OxContact extends LitElement {\n static styles = css`\n :host {\n display: block;\n }\n\n button {\n display: block;\n margin-left: auto;\n }\n `\n\n @property({ type: Object }) contact: Contact = {}\n\n @state() editMode?: boolean = false\n\n render() {\n return html`${this.editMode\n ? html`<ox-contact-edit\n .contact=${this.contact}\n @edit-cancel=${() => (this.editMode = false)}\n @edit-done=${(e: CustomEvent) => {\n this.contact = e.detail\n this.editMode = false\n }}\n ></ox-contact-edit>`\n : html` <ox-contact-view .contact=${this.contact}></ox-contact-view>\n <button value=\"Edit\" @click=${() => (this.editMode = true)}>Edit</button>`} `\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { TemplateResult } from 'lit';
2
+ import '@material/mwc-icon';
3
+ import '@material/mwc-icon-button';
4
+ import '../src/ox-contact.js';
5
+ import { Contact } from '../src/ox-contact.js';
6
+ declare const _default: {
7
+ title: string;
8
+ component: string;
9
+ argTypes: {
10
+ contact: {
11
+ control: string;
12
+ };
13
+ };
14
+ };
15
+ export default _default;
16
+ interface Story<T> {
17
+ (args: T): TemplateResult;
18
+ args?: Partial<T>;
19
+ argTypes?: Record<string, unknown>;
20
+ }
21
+ interface ArgTypes {
22
+ contact?: Contact;
23
+ }
24
+ export declare const Regular: Story<ArgTypes>;
@@ -0,0 +1,79 @@
1
+ import { html } from 'lit';
2
+ import '@material/mwc-icon';
3
+ import '@material/mwc-icon-button';
4
+ import '../src/ox-contact.js';
5
+ import { ContactField } from '../src/ox-contact.js';
6
+ export default {
7
+ title: 'OxContact',
8
+ component: 'ox-contact',
9
+ argTypes: {
10
+ contact: { control: 'object' }
11
+ }
12
+ };
13
+ const Template = ({ contact }) => html `
14
+ <link href="/themes/app-theme.css" rel="stylesheet" />
15
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
16
+ <style>
17
+ body {
18
+ }
19
+ </style>
20
+
21
+ <ox-contact .contact=${contact}> </ox-contact>
22
+ `;
23
+ export const Regular = Template.bind({});
24
+ Regular.args = {
25
+ contact: {
26
+ note: 'abcdefg',
27
+ items: [
28
+ {
29
+ id: '1',
30
+ type: ContactField.Name,
31
+ label: 'name',
32
+ value: '남 상혁'
33
+ },
34
+ {
35
+ id: '2',
36
+ type: ContactField.Phone,
37
+ label: 'home',
38
+ value: '010-1223-3443'
39
+ },
40
+ {
41
+ id: '3',
42
+ type: ContactField.Phone,
43
+ label: 'mobile',
44
+ value: '010-1122-3344'
45
+ },
46
+ {
47
+ id: '4',
48
+ type: ContactField.Email,
49
+ label: 'work',
50
+ value: 'heartyoh@hatiolab.com'
51
+ },
52
+ {
53
+ id: '5',
54
+ type: ContactField.Email,
55
+ label: 'home',
56
+ value: 'shnam2k@gmail.com'
57
+ },
58
+ {
59
+ id: '6',
60
+ type: ContactField.Address,
61
+ label: 'home',
62
+ value: '경기도 성남시 분당구 123'
63
+ },
64
+ {
65
+ id: '7',
66
+ type: ContactField.Address,
67
+ label: 'work',
68
+ value: '경기도 성남시 분당구 234'
69
+ },
70
+ {
71
+ id: '8',
72
+ type: ContactField.Address,
73
+ label: 'work',
74
+ value: '서울특별시 종로구 123'
75
+ }
76
+ ]
77
+ }
78
+ };
79
+ //# sourceMappingURL=index.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.stories.js","sourceRoot":"","sources":["../../stories/index.stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC1C,OAAO,oBAAoB,CAAA;AAC3B,OAAO,2BAA2B,CAAA;AAClC,OAAO,sBAAsB,CAAA;AAE7B,OAAO,EAAW,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAE5D,eAAe;IACb,KAAK,EAAE,WAAW;IAClB,SAAS,EAAE,YAAY;IACvB,QAAQ,EAAE;QACR,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE;KAC/B;CACF,CAAA;AAYD,MAAM,QAAQ,GAAoB,CAAC,EAAE,OAAO,EAAY,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;;;;yBAQxC,OAAO;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACxC,OAAO,CAAC,IAAI,GAAG;IACb,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,KAAK,EAAE;YACL;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,MAAM;aACd;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,eAAe;aACvB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,eAAe;aACvB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,uBAAuB;aAC/B;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,mBAAmB;aAC3B;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,OAAO;gBAC1B,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,iBAAiB;aACzB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,OAAO;gBAC1B,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,iBAAiB;aACzB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,YAAY,CAAC,OAAO;gBAC1B,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,eAAe;aACvB;SACF;KACF;CACF,CAAA","sourcesContent":["import { html, TemplateResult } from 'lit'\nimport '@material/mwc-icon'\nimport '@material/mwc-icon-button'\nimport '../src/ox-contact.js'\n\nimport { Contact, ContactField } from '../src/ox-contact.js'\n\nexport default {\n title: 'OxContact',\n component: 'ox-contact',\n argTypes: {\n contact: { control: 'object' }\n }\n}\n\ninterface Story<T> {\n (args: T): TemplateResult\n args?: Partial<T>\n argTypes?: Record<string, unknown>\n}\n\ninterface ArgTypes {\n contact?: Contact\n}\n\nconst Template: Story<ArgTypes> = ({ contact }: ArgTypes) => html`\n <link href=\"/themes/app-theme.css\" rel=\"stylesheet\" />\n <link href=\"https://fonts.googleapis.com/css?family=Material+Icons&display=block\" rel=\"stylesheet\" />\n <style>\n body {\n }\n </style>\n\n <ox-contact .contact=${contact}> </ox-contact>\n`\n\nexport const Regular = Template.bind({})\nRegular.args = {\n contact: {\n note: 'abcdefg',\n items: [\n {\n id: '1',\n type: ContactField.Name,\n label: 'name',\n value: '남 상혁'\n },\n {\n id: '2',\n type: ContactField.Phone,\n label: 'home',\n value: '010-1223-3443'\n },\n {\n id: '3',\n type: ContactField.Phone,\n label: 'mobile',\n value: '010-1122-3344'\n },\n {\n id: '4',\n type: ContactField.Email,\n label: 'work',\n value: 'heartyoh@hatiolab.com'\n },\n {\n id: '5',\n type: ContactField.Email,\n label: 'home',\n value: 'shnam2k@gmail.com'\n },\n {\n id: '6',\n type: ContactField.Address,\n label: 'home',\n value: '경기도 성남시 분당구 123'\n },\n {\n id: '7',\n type: ContactField.Address,\n label: 'work',\n value: '경기도 성남시 분당구 234'\n },\n {\n id: '8',\n type: ContactField.Address,\n label: 'work',\n value: '서울특별시 종로구 123'\n }\n ]\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ import '../src/ox-contact.js';