@operato/contact 8.0.0-alpha.50 → 8.0.0-beta.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.
@@ -1,155 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { css, LitElement } from 'lit';
3
- import { customElement, property, state } from 'lit/decorators.js';
4
- function getPoint(e) {
5
- var _a;
6
- if (e.button == 0) {
7
- return {
8
- x: e.clientX,
9
- y: e.clientY
10
- };
11
- }
12
- else if (((_a = e.touches) === null || _a === void 0 ? void 0 : _a.length) == 1) {
13
- const touch = e.touches[0];
14
- return {
15
- x: touch.clientX,
16
- y: touch.clientY
17
- };
18
- }
19
- else {
20
- return;
21
- }
22
- }
23
- let OxZoomableImage = class OxZoomableImage extends LitElement {
24
- constructor() {
25
- super(...arguments);
26
- this.zoom = 1;
27
- this.left = 0;
28
- this.top = 0;
29
- this.dragEndHandler = this.onDragEnd.bind(this);
30
- this.dragMoveHandler = this.onDragMove.bind(this);
31
- this.dragStartHandler = this.onDragStart.bind(this);
32
- this.wheelEventHandler = this.onWheelEvent.bind(this);
33
- this.resetHandler = this.onReset.bind(this);
34
- }
35
- connectedCallback() {
36
- super.connectedCallback();
37
- this.addEventListener('mousewheel', this.wheelEventHandler, false);
38
- this.addEventListener('mousedown', this.dragStartHandler);
39
- this.addEventListener('touchstart', this.dragStartHandler);
40
- this.addEventListener('dblclick', this.resetHandler);
41
- document.addEventListener('mouseup', this.dragEndHandler);
42
- document.addEventListener('touchend', this.dragEndHandler);
43
- document.addEventListener('touchcancel', this.dragEndHandler);
44
- document.addEventListener('mousemove', this.dragMoveHandler);
45
- document.addEventListener('touchmove', this.dragMoveHandler);
46
- }
47
- disconnectedCallback() {
48
- this.removeEventListener('mousewheel', this.wheelEventHandler, false);
49
- this.removeEventListener('mousedown', this.dragStartHandler);
50
- this.removeEventListener('touchstart', this.dragStartHandler);
51
- this.removeEventListener('dblclick', this.resetHandler);
52
- document.removeEventListener('mouseup', this.dragEndHandler);
53
- document.removeEventListener('touchend', this.dragEndHandler);
54
- document.removeEventListener('touchcancel', this.dragEndHandler);
55
- document.removeEventListener('mousemove', this.dragMoveHandler);
56
- document.removeEventListener('touchmove', this.dragMoveHandler);
57
- super.disconnectedCallback();
58
- }
59
- updated(changes) {
60
- const style = this.style;
61
- if (changes.has('src') && this.src) {
62
- style.setProperty('--background-image', `url('${this.src}')`);
63
- }
64
- style.setProperty('--image-transform', `translate(${this.left}%, ${this.top}%) scale(${this.zoom}, ${this.zoom})`);
65
- }
66
- onWheelEvent(e) {
67
- e.preventDefault();
68
- var delta = Math.max(-1, Math.min(1, e.deltaY || -e.detail));
69
- this.zoom *= 1 - delta / 20;
70
- }
71
- onDragStart(e) {
72
- const point = getPoint(e);
73
- if (point) {
74
- this.dragStart = point;
75
- e.stopPropagation();
76
- return false;
77
- }
78
- }
79
- onDragMove(e) {
80
- if (!this.dragStart) {
81
- return false;
82
- }
83
- const point = getPoint(e);
84
- if (!point) {
85
- return false;
86
- }
87
- e.stopPropagation();
88
- e.preventDefault();
89
- const dragStart = point;
90
- var { x, y } = point;
91
- x -= this.dragStart.x;
92
- y -= this.dragStart.y;
93
- this.dragStart = dragStart;
94
- const { offsetHeight, offsetWidth } = this;
95
- this.top += (y / offsetHeight) * 100;
96
- this.left += (x / offsetWidth) * 100;
97
- return false;
98
- }
99
- onDragEnd(e) {
100
- if (this.dragStart) {
101
- e.stopPropagation();
102
- e.preventDefault();
103
- delete this.dragStart;
104
- }
105
- }
106
- onReset(e) {
107
- this.zoom = 1;
108
- this.left = 0;
109
- this.top = 0;
110
- }
111
- };
112
- OxZoomableImage.styles = css `
113
- :host {
114
- display: block;
115
- position: relative;
116
- width: 100%;
117
- height: 100%;
118
- overflow: hidden;
119
- }
120
-
121
- :host::before {
122
- content: '';
123
- display: block;
124
-
125
- position: absolute;
126
- top: 0;
127
- right: 0;
128
- width: 100%;
129
- height: 100%;
130
-
131
- background-image: var(
132
- --background-image,
133
- linear-gradient(var(--primary-color, lightgray), var(--primary-color, lightgray))
134
- );
135
- transform: var(--image-transform, '');
136
- background-size: 100% 100%;
137
- }
138
- `;
139
- __decorate([
140
- property({ type: String })
141
- ], OxZoomableImage.prototype, "src", void 0);
142
- __decorate([
143
- state()
144
- ], OxZoomableImage.prototype, "zoom", void 0);
145
- __decorate([
146
- state()
147
- ], OxZoomableImage.prototype, "left", void 0);
148
- __decorate([
149
- state()
150
- ], OxZoomableImage.prototype, "top", void 0);
151
- OxZoomableImage = __decorate([
152
- customElement('ox-zoomable-image')
153
- ], OxZoomableImage);
154
- export { OxZoomableImage };
155
- //# sourceMappingURL=ox-zoomable-image.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ox-zoomable-image.js","sourceRoot":"","sources":["../../src/ox-zoomable-image.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nfunction getPoint(e: Event): { x: number; y: number } | undefined {\n if ((e as MouseEvent).button == 0) {\n return {\n x: (e as MouseEvent).clientX,\n y: (e as MouseEvent).clientY\n }\n } else if ((e as TouchEvent).touches?.length == 1) {\n const touch = (e as TouchEvent).touches[0]\n return {\n x: touch.clientX,\n y: touch.clientY\n }\n } else {\n return\n }\n}\n\n@customElement('ox-zoomable-image')\nexport class OxZoomableImage extends LitElement {\n static styles = css`\n :host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n :host::before {\n content: '';\n display: block;\n\n position: absolute;\n top: 0;\n right: 0;\n width: 100%;\n height: 100%;\n\n background-image: var(\n --background-image,\n linear-gradient(var(--primary-color, lightgray), var(--primary-color, lightgray))\n );\n transform: var(--image-transform, '');\n background-size: 100% 100%;\n }\n `\n\n @property({ type: String }) src?: string\n\n @state() zoom: number = 1\n @state() left: number = 0\n @state() top: number = 0\n\n private dragStart?: { x: number; y: number }\n\n private dragEndHandler = this.onDragEnd.bind(this) as EventListener\n private dragMoveHandler = this.onDragMove.bind(this) as EventListener\n private dragStartHandler = this.onDragStart.bind(this) as EventListener\n private wheelEventHandler = this.onWheelEvent.bind(this) as EventListener\n private resetHandler = this.onReset.bind(this) as EventListener\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.addEventListener('mousewheel', this.wheelEventHandler, false)\n\n this.addEventListener('mousedown', this.dragStartHandler)\n this.addEventListener('touchstart', this.dragStartHandler)\n this.addEventListener('dblclick', this.resetHandler)\n\n document.addEventListener('mouseup', this.dragEndHandler)\n document.addEventListener('touchend', this.dragEndHandler)\n document.addEventListener('touchcancel', this.dragEndHandler)\n document.addEventListener('mousemove', this.dragMoveHandler)\n document.addEventListener('touchmove', this.dragMoveHandler)\n }\n\n disconnectedCallback() {\n this.removeEventListener('mousewheel', this.wheelEventHandler, false)\n\n this.removeEventListener('mousedown', this.dragStartHandler!)\n this.removeEventListener('touchstart', this.dragStartHandler!)\n this.removeEventListener('dblclick', this.resetHandler!)\n\n document.removeEventListener('mouseup', this.dragEndHandler!)\n document.removeEventListener('touchend', this.dragEndHandler!)\n document.removeEventListener('touchcancel', this.dragEndHandler!)\n document.removeEventListener('mousemove', this.dragMoveHandler!)\n document.removeEventListener('touchmove', this.dragMoveHandler!)\n\n super.disconnectedCallback()\n }\n\n updated(changes: PropertyValues<this>) {\n const style = this.style\n\n if (changes.has('src') && this.src) {\n style.setProperty('--background-image', `url('${this.src}')`)\n }\n\n style.setProperty('--image-transform', `translate(${this.left}%, ${this.top}%) scale(${this.zoom}, ${this.zoom})`)\n }\n\n onWheelEvent(e: MouseEvent) {\n e.preventDefault()\n\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n\n this.zoom *= 1 - delta / 20\n }\n\n onDragStart(e: Event) {\n const point = getPoint(e)\n\n if (point) {\n this.dragStart = point\n e.stopPropagation()\n return false\n }\n }\n\n onDragMove(e: Event) {\n if (!this.dragStart) {\n return false\n }\n\n const point = getPoint(e)\n\n if (!point) {\n return false\n }\n\n e.stopPropagation()\n e.preventDefault()\n\n const dragStart = point\n var { x, y } = point\n\n x -= this.dragStart.x\n y -= this.dragStart.y\n\n this.dragStart = dragStart\n\n const { offsetHeight, offsetWidth } = this\n\n this.top += (y / offsetHeight) * 100\n this.left += (x / offsetWidth) * 100\n\n return false\n }\n\n onDragEnd(e: Event) {\n if (this.dragStart) {\n e.stopPropagation()\n e.preventDefault()\n\n delete this.dragStart\n }\n }\n\n onReset(e: Event) {\n this.zoom = 1\n this.left = 0\n this.top = 0\n }\n}\n"]}
@@ -1,22 +0,0 @@
1
- import '@operato/i18n';
2
- import '../src/ox-zoomable-image.js';
3
- import { TemplateResult } from 'lit';
4
- declare const _default: {
5
- title: string;
6
- component: string;
7
- argTypes: {
8
- src: {
9
- control: string;
10
- };
11
- };
12
- };
13
- export default _default;
14
- interface Story<T> {
15
- (args: T): TemplateResult;
16
- args?: Partial<T>;
17
- argTypes?: Record<string, unknown>;
18
- }
19
- interface ArgTypes {
20
- src?: string;
21
- }
22
- export declare const Regular: Story<ArgTypes>;
@@ -1,27 +0,0 @@
1
- import '@operato/i18n';
2
- import '../src/ox-zoomable-image.js';
3
- import { html } from 'lit';
4
- export default {
5
- title: 'ox-zoomable-image',
6
- component: 'ox-zoomable-image',
7
- argTypes: {
8
- src: { control: 'text' }
9
- }
10
- };
11
- const Template = ({ src = '' }) => html `
12
- <link href="/themes/app-theme.css" rel="stylesheet" />
13
- <link href="/themes/light.css" rel="stylesheet" />
14
- <link href="/themes/dark.css" rel="stylesheet" />
15
- <link href="/themes/spacing.css" rel="stylesheet" />
16
- <link href="/themes/grist-theme.css" rel="stylesheet" />
17
- <link href="/themes/form-theme.css" rel="stylesheet" />
18
-
19
- <div style="height: 300px">
20
- <ox-zoomable-image src=${src} style="width: 300px; height: 300px"> </ox-zoomable-image>
21
- </div>
22
- `;
23
- export const Regular = Template.bind({});
24
- Regular.args = {
25
- src: '/assets/sample-image.png'
26
- };
27
- //# sourceMappingURL=ox-zoomable-image.stories.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ox-zoomable-image.stories.js","sourceRoot":"","sources":["../../stories/ox-zoomable-image.stories.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AACtB,OAAO,6BAA6B,CAAA;AAEpC,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAE1C,eAAe;IACb,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,mBAAmB;IAC9B,QAAQ,EAAE;QACR,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;KACzB;CACF,CAAA;AAYD,MAAM,QAAQ,GAAoB,CAAC,EAAE,GAAG,GAAG,EAAE,EAAY,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;;;;;6BASrC,GAAG;;CAE/B,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACxC,OAAO,CAAC,IAAI,GAAG;IACb,GAAG,EAAE,0BAA0B;CAChC,CAAA","sourcesContent":["import '@operato/i18n'\nimport '../src/ox-zoomable-image.js'\n\nimport { html, TemplateResult } from 'lit'\n\nexport default {\n title: 'ox-zoomable-image',\n component: 'ox-zoomable-image',\n argTypes: {\n src: { control: 'text' }\n }\n}\n\ninterface Story<T> {\n (args: T): TemplateResult\n args?: Partial<T>\n argTypes?: Record<string, unknown>\n}\n\ninterface ArgTypes {\n src?: string\n}\n\nconst Template: Story<ArgTypes> = ({ src = '' }: ArgTypes) => html`\n <link href=\"/themes/app-theme.css\" rel=\"stylesheet\" />\n <link href=\"/themes/light.css\" rel=\"stylesheet\" />\n <link href=\"/themes/dark.css\" rel=\"stylesheet\" />\n <link href=\"/themes/spacing.css\" rel=\"stylesheet\" />\n <link href=\"/themes/grist-theme.css\" rel=\"stylesheet\" />\n <link href=\"/themes/form-theme.css\" rel=\"stylesheet\" />\n\n <div style=\"height: 300px\">\n <ox-zoomable-image src=${src} style=\"width: 300px; height: 300px\"> </ox-zoomable-image>\n </div>\n`\n\nexport const Regular = Template.bind({})\nRegular.args = {\n src: '/assets/sample-image.png'\n}\n"]}
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export { OxContact } from './ox-contact.js'
2
- export { OxPfp } from './ox-pfp.js'
3
- export { OxPfpView } from './ox-pfp-view.js'
@@ -1,260 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import './ox-pfp.js'
3
-
4
- import { html, css, LitElement, PropertyValues } from 'lit'
5
- import { customElement, property, state, query, queryAll } from 'lit/decorators.js'
6
- import { Contact, ContactField, ContactItem } from './ox-contact'
7
- import { ScrollbarStyles } from '@operato/styles'
8
- import { i18next } from '@operato/i18n'
9
- import { OxPfp } from './ox-pfp.js'
10
-
11
- @customElement('ox-contact-edit')
12
- export class OxContactEdit extends LitElement {
13
- static styles = [
14
- ScrollbarStyles,
15
- css`
16
- :host {
17
- display: block;
18
- padding: 25px;
19
- }
20
-
21
- input,
22
- select,
23
- textarea {
24
- padding: 8px;
25
- border-radius: 4px;
26
- border: 1px solid var(--md-sys-color-outline, #ccc);
27
- background-color: #fff;
28
- color: var(--md-sys-color-on-surface);
29
- font-size: 16px; /* for iPhone */
30
- box-shadow: 0 1px 1px 0px rgba(0, 0, 0, 0.1);
31
- transition:
32
- border-color 0.3s ease,
33
- box-shadow 0.3s ease;
34
- }
35
-
36
- input:focus,
37
- select:focus,
38
- textarea:focus {
39
- border-color: var(--md-sys-color-primary, #6200ea);
40
- box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
41
- outline: none;
42
- }
43
-
44
- :host > div {
45
- padding: 10px 0;
46
- display: block;
47
- border-bottom: 1px solid blue;
48
- }
49
-
50
- :host > div > div {
51
- padding: 4px 0;
52
- box-sizing: border-box;
53
-
54
- display: flex;
55
- flex-direction: row;
56
- gap: 10px;
57
- align-items: center;
58
- }
59
-
60
- :host > div > div:hover {
61
- position: relative;
62
- }
63
-
64
- [data-item='label'] {
65
- width: 100px;
66
- text-align: right;
67
- }
68
-
69
- [data-item='value'] {
70
- flex: 1;
71
- }
72
-
73
- :host > div[name] {
74
- display: flex;
75
- align-items: center;
76
- gap: 10px;
77
- font-weight: bold;
78
- font-size: 1.4em;
79
- }
80
-
81
- :host ox-pfp {
82
- display: inline-block;
83
- width: 100px;
84
- height: 100px;
85
- }
86
-
87
- :host > div[name] > div[name-content] {
88
- flex: 1;
89
-
90
- display: grid;
91
- grid-template-columns: minmax(auto, 160px) 1fr;
92
- gap: var(--spacing-medium);
93
- align-items: center;
94
-
95
- span {
96
- text-align: right;
97
- }
98
- }
99
-
100
- div[field] {
101
- display: flex;
102
- flex-direction: row;
103
- align-items: center;
104
- gap: 10px;
105
- }
106
-
107
- div[field] > span {
108
- width: 100px;
109
- text-align: right;
110
- }
111
-
112
- div[field] > input {
113
- flex: 1;
114
- }
115
-
116
- textarea {
117
- width: 100%;
118
- min-height: 100px;
119
- box-sizing: border-box;
120
- resize: none;
121
- }
122
- `
123
- ]
124
-
125
- @property({ type: Object }) contact: Contact = {}
126
-
127
- @state() private stageContact: Contact = JSON.parse(JSON.stringify(this.contact))
128
-
129
- @query('#name') name!: HTMLTextAreaElement
130
- @query('#company') company!: HTMLTextAreaElement
131
- @query('#note') note!: HTMLTextAreaElement
132
- @query('ox-pfp') pfp!: OxPfp
133
- @queryAll('[item-field]') fields!: NodeListOf<HTMLDivElement>
134
-
135
- render() {
136
- const { profile, items = [], name, company, note } = this.stageContact || {}
137
- var sorted: { [type: string]: ContactItem[] } = {}
138
-
139
- items.forEach(item => {
140
- if (!sorted[item.type as string]) {
141
- sorted[item.type] = [item]
142
- } else {
143
- sorted[item.type as string].push(item)
144
- }
145
- })
146
-
147
- return html`
148
- <div name>
149
- <ox-pfp .profile=${profile} .name=${name}></ox-pfp>
150
-
151
- <div name-content>
152
- <span>${i18next.t('label.name')}</span>
153
- <input type="text" id="name" .value=${name ?? ''} @change=${(e: Event) => this.buildStageContact()} />
154
- <span>${i18next.t('label.company')}</span>
155
- <input type="text" id="company" .value=${company ?? ''} @change=${(e: Event) => this.buildStageContact()} />
156
- </div>
157
- </div>
158
- ${['department', 'email', 'phone', 'address'].map(type => {
159
- var items = [...(sorted[type] || []), { type: type as ContactField, label: 'work', value: '' }]
160
-
161
- return html`
162
- <div data-type=${type}>
163
- ${type}
164
- ${items.map(
165
- item =>
166
- html`<div @change=${(e: Event) => this.onChangeItem(e, item)} .item=${item} item-field>
167
- ${item.value
168
- ? html`<md-icon
169
- @click=${() => {
170
- item.value = ''
171
- this.buildStageContact()
172
- }}
173
- >cancel</md-icon
174
- >`
175
- : html`<md-icon></md-icon>`}
176
- <select .value=${item.label} data-item="label">
177
- ${['home', 'work', 'other', 'mobile'].map(
178
- option => html` <option value=${option} ?selected=${option === item.label}>${option}</option>`
179
- )}
180
- </select>
181
- <input type="text" .value=${item.value} data-item="value" />
182
- </div>`
183
- )}
184
- </div>
185
- `
186
- })}
187
- <div note>
188
- note
189
- <textarea id="note" .value=${note || ''} @change=${() => this.buildStageContact()}></textarea>
190
- </div>
191
- `
192
- }
193
-
194
- updated(changes: PropertyValues<this>) {
195
- if (changes.has('contact')) {
196
- this.stageContact = JSON.parse(JSON.stringify(this.contact))
197
- }
198
- }
199
-
200
- buildItems() {
201
- const items: ContactItem[] = []
202
-
203
- this.fields.forEach(fieldElement => {
204
- const item = (fieldElement as any).item
205
- if (item.value) {
206
- items.push(item)
207
- }
208
- })
209
-
210
- return items
211
- }
212
-
213
- buildStageContact() {
214
- this.stageContact = {
215
- ...this.stageContact,
216
- profile: this.pfp.profile,
217
- name: this.name.value,
218
- company: this.company.value,
219
- note: this.note.value,
220
- items: this.buildItems()
221
- }
222
- }
223
-
224
- onChangeItem(e: Event, item: ContactItem) {
225
- const target = e.currentTarget as HTMLElement
226
- const labelElement = target.querySelector('[data-item="label"]') as HTMLSelectElement
227
- const valueElement = target.querySelector('[data-item="value"]') as HTMLInputElement
228
-
229
- item.label = labelElement.value
230
- item.value = valueElement.value
231
-
232
- if (e.target === valueElement || item.value) {
233
- this.buildStageContact()
234
- }
235
- }
236
-
237
- save() {
238
- this.buildStageContact()
239
-
240
- this.dispatchEvent(
241
- new CustomEvent('edit-done', {
242
- detail: this.stageContact
243
- })
244
- )
245
- }
246
-
247
- cancel() {
248
- this.dispatchEvent(
249
- new CustomEvent('edit-cancel', {
250
- detail: this.stageContact
251
- })
252
- )
253
- }
254
-
255
- reset() {
256
- this.buildStageContact()
257
-
258
- this.stageContact = JSON.parse(JSON.stringify(this.contact))
259
- }
260
- }
@@ -1,189 +0,0 @@
1
- import './ox-pfp-view.js'
2
-
3
- import { html, css, LitElement } from 'lit'
4
- import { customElement, property } from 'lit/decorators.js'
5
- import { Contact, ContactField, ContactItem } from './ox-contact'
6
-
7
- @customElement('ox-contact-view')
8
- export class OxContactView extends LitElement {
9
- static styles = css`
10
- :host {
11
- display: block;
12
- --md-icon-size: 16px;
13
-
14
- color: var(--md-sys-color-on-surface);
15
- background-color: var(--md-sys-color-surface);
16
- }
17
-
18
- :host > div {
19
- padding: var(--spacing-medium, 8px);
20
- display: block;
21
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
22
- font-size: 0.9em;
23
- text-transform: capitalize;
24
- }
25
-
26
- :host > div > div {
27
- padding: 4px 0;
28
- box-sizing: border-box;
29
-
30
- display: flex;
31
- flex-direction: row;
32
- gap: 10px;
33
- }
34
-
35
- :host > div > div:hover {
36
- position: relative;
37
- }
38
-
39
- :host > div > div:hover::before {
40
- content: '';
41
- display: block;
42
- position: absolute;
43
- text-align: left;
44
- line-height: 24px;
45
- top: 0;
46
- right: 0;
47
- width: 100%;
48
- height: 100%;
49
- opacity: 0.15;
50
- background-image: linear-gradient(var(--md-sys-color-primary, gray), var(--md-sys-color-primary, gray));
51
- }
52
-
53
- [data-item='label'] {
54
- width: 80px;
55
- text-align: right;
56
- color: var(--md-sys-color-primary, #017e7f);
57
- }
58
-
59
- [data-item='value'] {
60
- flex: 1;
61
- text-transform: none;
62
- }
63
-
64
- :host > div[name] {
65
- display: flex;
66
- align-items: center;
67
- gap: 15px;
68
- font-weight: bold;
69
- font-size: 1.4em;
70
- }
71
-
72
- :host ox-pfp-view {
73
- display: inline-block;
74
-
75
- --ox-pfp-size: 75px;
76
- }
77
-
78
- :host > div[name] > div[name-content] {
79
- flex: 1;
80
-
81
- display: flex;
82
- flex-direction: column;
83
- }
84
-
85
- div[data-type='email'] md-icon::before {
86
- content: 'mail_outline';
87
- }
88
-
89
- div[data-type='phone'] md-icon::before {
90
- content: 'phone';
91
- }
92
-
93
- div[data-type='address'] md-icon::before {
94
- content: 'place';
95
- }
96
-
97
- div[data-type='department'] md-icon::before {
98
- content: 'diversity_3';
99
- }
100
-
101
- div[data-type='company'] md-icon::before {
102
- content: 'business';
103
- }
104
-
105
- div[data-type='etc'] md-icon::before {
106
- content: 'feed';
107
- }
108
-
109
- div[note] md-icon::before {
110
- content: 'subject';
111
- }
112
-
113
- :host > div > [name-content] {
114
- gap: 3px;
115
- }
116
-
117
- div md-icon {
118
- position: relative;
119
- top: 3px;
120
- margin-right: 3px;
121
- opacity: 0.5;
122
- color: var(--md-sys-color-on-primary-container, #333);
123
- }
124
-
125
- [name-content] div {
126
- color: var(--md-sys-color-on-primary-container, #333);
127
- font-size: 1.2em;
128
- }
129
-
130
- [name-content] [company] {
131
- color: var(--md-sys-color-on-secondary-container, #666);
132
- font-weight: normal;
133
- font-size: 0.9em;
134
- }
135
- `
136
-
137
- @property({ type: Object }) contact: Contact = {}
138
-
139
- render() {
140
- const { profile, items = [], name, company, note } = this.contact || {}
141
- var sorted: { [type: string]: ContactItem[] } = {}
142
-
143
- items.forEach(item => {
144
- if (!sorted[item.type as string]) {
145
- sorted[item.type] = [item]
146
- } else {
147
- sorted[item.type as string].push(item)
148
- }
149
- })
150
-
151
- return html`
152
- <div name>
153
- <ox-pfp-view .profile=${profile} .name=${name}></ox-pfp-view>
154
-
155
- <div name-content>
156
- <div>
157
- <span data-item="value">${name}</span>
158
- </div>
159
- <div company>
160
- <span data-item="value">${company}</span>
161
- </div>
162
- </div>
163
- </div>
164
-
165
- ${['department', 'email', 'phone', 'address', 'company', 'etc']
166
- .map(type => sorted[type])
167
- .filter(items => items && items.length > 0)
168
- .map(
169
- items =>
170
- html`<div data-type=${items[0].type}>
171
- <md-icon></md-icon>
172
- ${items[0].type}
173
- ${items.map(
174
- item =>
175
- html`<div>
176
- <label data-item="label"> ${item.label}</label>
177
- <span data-item="value">${item.value}</span>
178
- </div>`
179
- )}
180
- </div>`
181
- )}
182
- <div note>
183
- <md-icon></md-icon>
184
- note
185
- <div>${note || ''}</div>
186
- </div>
187
- `
188
- }
189
- }