@operato/contact 1.1.52 → 1.1.53

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/CHANGELOG.md +11 -0
  2. package/demo/ox-pfp.html +45 -0
  3. package/demo/pfp-edit.html +59 -0
  4. package/demo/pfp-view.html +46 -0
  5. package/dist/src/index.d.ts +2 -0
  6. package/dist/src/index.js +2 -0
  7. package/dist/src/index.js.map +1 -1
  8. package/dist/src/ox-contact copy.d.ts +38 -1
  9. package/dist/src/ox-contact copy.js +66 -2
  10. package/dist/src/ox-contact copy.js.map +1 -1
  11. package/dist/src/ox-contact-edit.d.ts +3 -0
  12. package/dist/src/ox-contact-edit.js +9 -16
  13. package/dist/src/ox-contact-edit.js.map +1 -1
  14. package/dist/src/ox-contact-view.d.ts +1 -0
  15. package/dist/src/ox-contact-view.js +5 -16
  16. package/dist/src/ox-contact-view.js.map +1 -1
  17. package/dist/src/ox-contact.d.ts +2 -0
  18. package/dist/src/ox-contact.js.map +1 -1
  19. package/dist/src/ox-pfp-edit.d.ts +28 -0
  20. package/dist/src/ox-pfp-edit.js +314 -0
  21. package/dist/src/ox-pfp-edit.js.map +1 -0
  22. package/dist/src/ox-pfp-editor copy.d.ts +11 -0
  23. package/dist/src/ox-pfp-editor copy.js +71 -0
  24. package/dist/src/ox-pfp-editor copy.js.map +1 -0
  25. package/dist/src/ox-pfp-editor.d.ts +20 -0
  26. package/dist/src/ox-pfp-editor.js +165 -0
  27. package/dist/src/ox-pfp-editor.js.map +1 -0
  28. package/dist/src/ox-pfp-view.d.ts +15 -0
  29. package/dist/src/ox-pfp-view.js +100 -0
  30. package/dist/src/ox-pfp-view.js.map +1 -0
  31. package/dist/src/ox-pfp-viewer.d.ts +14 -0
  32. package/dist/src/ox-pfp-viewer.js +63 -0
  33. package/dist/src/ox-pfp-viewer.js.map +1 -0
  34. package/dist/src/ox-pfp.d.ts +14 -0
  35. package/dist/src/ox-pfp.js +104 -0
  36. package/dist/src/ox-pfp.js.map +1 -0
  37. package/dist/stories/index.stories copy.d.ts +24 -0
  38. package/dist/stories/index.stories copy.js +79 -0
  39. package/dist/stories/index.stories copy.js.map +1 -0
  40. package/dist/stories/ox-contact.stories.d.ts +24 -0
  41. package/dist/stories/ox-contact.stories.js +79 -0
  42. package/dist/stories/ox-contact.stories.js.map +1 -0
  43. package/dist/stories/ox-pfp.stories.d.ts +28 -0
  44. package/dist/stories/ox-pfp.stories.js +37 -0
  45. package/dist/stories/ox-pfp.stories.js.map +1 -0
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +14 -5
  48. package/src/index.ts +2 -0
  49. package/src/ox-contact-edit.ts +8 -16
  50. package/src/ox-contact-view.ts +6 -16
  51. package/src/ox-contact.ts +2 -0
  52. package/src/ox-pfp-edit.ts +351 -0
  53. package/src/ox-pfp-view.ts +98 -0
  54. package/src/ox-pfp.ts +97 -0
  55. package/stories/{index.stories.ts → ox-contact.stories.ts} +0 -0
  56. package/stories/ox-pfp.stories.ts +53 -0
@@ -1,4 +1,5 @@
1
1
  import { __decorate } from "tslib";
2
+ import './ox-pfp-view.js';
2
3
  import { html, css, LitElement } from 'lit';
3
4
  import { customElement, property } from 'lit/decorators.js';
4
5
  import { ContactField } from './ox-contact';
@@ -9,7 +10,7 @@ let OxContactView = class OxContactView extends LitElement {
9
10
  }
10
11
  render() {
11
12
  var _a;
12
- const { items = [], note } = this.contact || {};
13
+ const { profile, items = [], note } = this.contact || {};
13
14
  var sorted = {};
14
15
  items.forEach(item => {
15
16
  if (!sorted[item.type]) {
@@ -23,7 +24,8 @@ let OxContactView = class OxContactView extends LitElement {
23
24
  const companies = sorted[ContactField.Company] || [];
24
25
  return html `
25
26
  <div name>
26
- <div monogram>${(_a = names[0]) === null || _a === void 0 ? void 0 : _a.value.replace(/\s/g, '').slice(0, 2)}</div>
27
+ <ox-pfp-view .profile=${profile} .name=${(_a = names[0]) === null || _a === void 0 ? void 0 : _a.value}></ox-pfp-view>
28
+
27
29
  <div name-content>
28
30
  ${names.map(item => html `<div>
29
31
  <span data-item="value">${item.value}</span>
@@ -106,23 +108,10 @@ OxContactView.styles = css `
106
108
  font-size: 1.4em;
107
109
  }
108
110
 
109
- :host > div[name] > [monogram] {
111
+ :host ox-pfp-view {
110
112
  display: inline-block;
111
113
  width: 100px;
112
114
  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
115
  }
127
116
 
128
117
  :host > div[name] > div[name-content] {
@@ -1 +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"]}
1
+ {"version":3,"file":"ox-contact-view.js","sourceRoot":"","sources":["../../src/ox-contact-view.ts"],"names":[],"mappings":";AAAA,OAAO,kBAAkB,CAAA;AAEzB,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;;QAuEuB,YAAO,GAAY,EAAE,CAAA;IAyDnD,CAAC;IAvDC,MAAM;;QACJ,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QACxD,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;;gCAEiB,OAAO,UAAU,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,KAAK;;;YAGpD,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;;AA9HM,oBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoElB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAsB;AAvEtC,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CAgIzB;SAhIY,aAAa","sourcesContent":["import './ox-pfp-view.js'\n\nimport { 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 ox-pfp-view {\n display: inline-block;\n width: 100px;\n height: 100px;\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 { profile, 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 <ox-pfp-view .profile=${profile} .name=${names[0]?.value}></ox-pfp-view>\n\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"]}
@@ -1,6 +1,7 @@
1
1
  import { LitElement } from 'lit';
2
2
  import './ox-contact-edit';
3
3
  import './ox-contact-view';
4
+ import { Profile } from './ox-pfp-view.js';
4
5
  export declare enum ContactField {
5
6
  Name = "name",
6
7
  JobTitle = "job-title",
@@ -27,6 +28,7 @@ export type ContactItem = {
27
28
  value: string;
28
29
  };
29
30
  export type Contact = {
31
+ profile?: Profile;
30
32
  items?: ContactItem[];
31
33
  note?: string;
32
34
  };
@@ -1 +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"]}
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;AAG1B,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;AAgBM,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'\nimport { Profile } from './ox-pfp-view.js'\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 profile?: Profile\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,28 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ import { Profile } from './ox-pfp-view';
3
+ export declare class OxPfpEdit extends LitElement {
4
+ static styles: import("lit").CSSResult;
5
+ profile: Profile;
6
+ name?: string;
7
+ circle: HTMLDivElement;
8
+ private dragStart?;
9
+ private dragEndHandler;
10
+ private dragMoveHandler;
11
+ private dragStartHandler;
12
+ private wheelEventHandler;
13
+ private dropFileHandler;
14
+ connectedCallback(): void;
15
+ disconnectedCallback(): void;
16
+ render(): import("lit-html").TemplateResult<1>;
17
+ updated(changes: PropertyValues<this>): void;
18
+ get value(): Profile;
19
+ set value(value: Profile);
20
+ onWheelEvent(e: Event): void;
21
+ onDragStart(e: Event): false | undefined;
22
+ onDragMove(e: Event): boolean;
23
+ onDragEnd(e: Event): void;
24
+ onDropFile(e: Event): void;
25
+ onChangeFile(e: Event): void;
26
+ fit(): void;
27
+ clear(): void;
28
+ }
@@ -0,0 +1,314 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, property, query } from 'lit/decorators.js';
4
+ import { FileDropHelper } from '@operato/utils';
5
+ function getPoint(e) {
6
+ var _a;
7
+ if (e.button == 0) {
8
+ return {
9
+ x: e.clientX,
10
+ y: e.clientY
11
+ };
12
+ }
13
+ else if (((_a = e.touches) === null || _a === void 0 ? void 0 : _a.length) == 1) {
14
+ const touch = e.touches[0];
15
+ return {
16
+ x: touch.clientX,
17
+ y: touch.clientY
18
+ };
19
+ }
20
+ else {
21
+ return;
22
+ }
23
+ }
24
+ let OxPfpEdit = class OxPfpEdit extends LitElement {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.profile = {};
28
+ this.dragEndHandler = this.onDragEnd.bind(this);
29
+ this.dragMoveHandler = this.onDragMove.bind(this);
30
+ this.dragStartHandler = this.onDragStart.bind(this);
31
+ this.wheelEventHandler = this.onWheelEvent.bind(this);
32
+ this.dropFileHandler = this.onDropFile.bind(this);
33
+ }
34
+ connectedCallback() {
35
+ super.connectedCallback();
36
+ FileDropHelper.set(this);
37
+ this.addEventListener('mousewheel', this.wheelEventHandler, false);
38
+ this.addEventListener('mousedown', this.dragStartHandler);
39
+ this.addEventListener('touchstart', this.dragStartHandler);
40
+ document.addEventListener('mouseup', this.dragEndHandler);
41
+ document.addEventListener('touchend', this.dragEndHandler);
42
+ document.addEventListener('touchcancel', this.dragEndHandler);
43
+ document.addEventListener('mousemove', this.dragMoveHandler);
44
+ document.addEventListener('touchmove', this.dragMoveHandler);
45
+ this.addEventListener('file-drop', this.dropFileHandler);
46
+ }
47
+ disconnectedCallback() {
48
+ this.removeEventListener('mousewheel', this.wheelEventHandler, false);
49
+ this.removeEventListener('mousedown', this.dragStartHandler);
50
+ this.removeEventListener('touchstart', this.dragStartHandler);
51
+ document.removeEventListener('mouseup', this.dragEndHandler);
52
+ document.removeEventListener('touchend', this.dragEndHandler);
53
+ document.removeEventListener('touchcancel', this.dragEndHandler);
54
+ document.removeEventListener('mousemove', this.dragMoveHandler);
55
+ document.removeEventListener('touchmove', this.dragMoveHandler);
56
+ this.removeEventListener('file-drop', this.dropFileHandler);
57
+ super.disconnectedCallback();
58
+ }
59
+ render() {
60
+ var _a, _b;
61
+ return html `
62
+ <div content>
63
+ ${((_a = this.profile) === null || _a === void 0 ? void 0 : _a.picture)
64
+ ? html `<div circle></div>`
65
+ : html `<div monogram><div>${(_b = this.name) === null || _b === void 0 ? void 0 : _b.replace(/\s/g, '').slice(0, 2)}</div></div>`}
66
+ </div>
67
+
68
+ <div file-load>
69
+ <label>
70
+ <input
71
+ id="input-file"
72
+ type="file"
73
+ accept="image/*"
74
+ hidden
75
+ capture="environment"
76
+ @change=${(e) => this.onChangeFile(e)}
77
+ />
78
+ <mwc-icon>image_search</mwc-icon>
79
+ </label>
80
+ </div>
81
+
82
+ <slot></slot>
83
+ `;
84
+ }
85
+ updated(changes) {
86
+ const { picture, zoom = 1, left = 0, top = 0 } = this.profile;
87
+ if (picture) {
88
+ const style = this.style;
89
+ style.setProperty('--background-image', `url(${picture})`);
90
+ style.setProperty('--image-transform', `translate(${left}%, ${top}%) scale(${zoom}, ${zoom})`);
91
+ }
92
+ }
93
+ get value() {
94
+ return this.profile;
95
+ }
96
+ set value(value) {
97
+ this.profile = value;
98
+ }
99
+ onWheelEvent(e) {
100
+ e.preventDefault();
101
+ var delta = Math.max(-1, Math.min(1, e.deltaY || -e.detail));
102
+ const { top = 0, left = 0, zoom = 1, picture } = this.profile;
103
+ this.profile = {
104
+ top,
105
+ left,
106
+ zoom: zoom * (1 - delta / 20),
107
+ picture
108
+ };
109
+ this.dispatchEvent(new CustomEvent('change', {
110
+ detail: this.profile
111
+ }));
112
+ }
113
+ onDragStart(e) {
114
+ const point = getPoint(e);
115
+ if (point) {
116
+ this.dragStart = point;
117
+ e.stopPropagation();
118
+ return false;
119
+ }
120
+ }
121
+ onDragMove(e) {
122
+ if (!this.dragStart) {
123
+ return false;
124
+ }
125
+ const point = getPoint(e);
126
+ if (!point) {
127
+ return false;
128
+ }
129
+ e.stopPropagation();
130
+ e.preventDefault();
131
+ const dragStart = point;
132
+ var { x, y } = point;
133
+ x -= this.dragStart.x;
134
+ y -= this.dragStart.y;
135
+ this.dragStart = dragStart;
136
+ const { top = 0, left = 0, zoom = 1, picture } = this.profile;
137
+ const { offsetHeight, offsetWidth } = this;
138
+ this.profile = {
139
+ top: top + (y / offsetHeight) * 100,
140
+ left: left + (x / offsetWidth) * 100,
141
+ zoom,
142
+ picture
143
+ };
144
+ this.dispatchEvent(new CustomEvent('change', {
145
+ detail: this.profile
146
+ }));
147
+ return false;
148
+ }
149
+ onDragEnd(e) {
150
+ if (this.dragStart) {
151
+ e.stopPropagation();
152
+ e.preventDefault();
153
+ delete this.dragStart;
154
+ }
155
+ }
156
+ onDropFile(e) {
157
+ const dropFiles = e.detail;
158
+ const imageFile = dropFiles[0];
159
+ if (!imageFile) {
160
+ return;
161
+ }
162
+ const picture = URL.createObjectURL(imageFile);
163
+ this.profile = {
164
+ left: 0,
165
+ top: 0,
166
+ zoom: 1,
167
+ picture
168
+ };
169
+ }
170
+ onChangeFile(e) {
171
+ const fileInput = e.currentTarget;
172
+ const imageFile = [...Array.from(fileInput.files)][0];
173
+ if (!imageFile) {
174
+ return;
175
+ }
176
+ const picture = URL.createObjectURL(imageFile);
177
+ this.profile = {
178
+ left: 0,
179
+ top: 0,
180
+ zoom: 1,
181
+ picture
182
+ };
183
+ fileInput.files = null;
184
+ }
185
+ fit() {
186
+ this.profile = {
187
+ ...this.profile,
188
+ left: 0,
189
+ top: 0,
190
+ zoom: 1
191
+ };
192
+ }
193
+ clear() {
194
+ this.profile = {};
195
+ }
196
+ };
197
+ OxPfpEdit.styles = css `
198
+ :host {
199
+ display: inline-block;
200
+ overflow: hidden;
201
+ }
202
+
203
+ [content] {
204
+ display: flex;
205
+ align-items: center;
206
+ justify-content: center;
207
+ width: 100%;
208
+ height: 100%;
209
+ }
210
+
211
+ [circle] {
212
+ width: 90%;
213
+ height: 90%;
214
+ position: relative;
215
+ }
216
+
217
+ [circle]::after {
218
+ position: absolute;
219
+ content: '';
220
+ width: 100%;
221
+ height: 100%;
222
+ box-shadow: 0 0 0 1000px lightgray;
223
+ border-radius: 50%;
224
+ opacity: 0.9;
225
+ }
226
+
227
+ [circle]::before {
228
+ content: '';
229
+ display: block;
230
+ position: absolute;
231
+ text-align: left;
232
+ line-height: 24px;
233
+ top: 0;
234
+ right: 0;
235
+ width: 100%;
236
+ height: 100%;
237
+ z-index: -1;
238
+ background-repeat: no-repeat;
239
+ background-image: var(
240
+ --background-image,
241
+ linear-gradient(var(--primary-color, lightgray), var(--primary-color, lightgray))
242
+ );
243
+ transform: var(--image-transform, '');
244
+ background-size: 100% 100%;
245
+ }
246
+
247
+ [monogram] {
248
+ width: 100%;
249
+ height: 100%;
250
+ border-radius: 50%;
251
+ border: 1px solid darkgray;
252
+ box-sizing: border-box;
253
+ padding: 0;
254
+ overflow: hidden;
255
+ background-color: gray;
256
+ color: white;
257
+
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ }
262
+
263
+ [monogram] div {
264
+ flex: 1;
265
+ text-transform: uppercase;
266
+ font-size: 2em;
267
+ font-family: system-ui;
268
+ text-align: center;
269
+ vertical-align: center;
270
+ }
271
+
272
+ [file-load] {
273
+ position: absolute;
274
+ left: 0;
275
+ top: 0;
276
+
277
+ display: flex;
278
+ place-content: center;
279
+ }
280
+
281
+ [file-load]:hover {
282
+ opacity: 50%;
283
+ }
284
+
285
+ #input-file {
286
+ display: none;
287
+ }
288
+
289
+ label {
290
+ display: flex;
291
+ align-content: center;
292
+ }
293
+
294
+ mwc-icon {
295
+ align-self: center;
296
+
297
+ color: var(--file-uploader-icon-color, black);
298
+ --mdc-icon-size: var(--file-uploader-icon-size, 20px);
299
+ }
300
+ `;
301
+ __decorate([
302
+ property({ type: Object })
303
+ ], OxPfpEdit.prototype, "profile", void 0);
304
+ __decorate([
305
+ property({ type: String })
306
+ ], OxPfpEdit.prototype, "name", void 0);
307
+ __decorate([
308
+ query('[circle]')
309
+ ], OxPfpEdit.prototype, "circle", void 0);
310
+ OxPfpEdit = __decorate([
311
+ customElement('ox-pfp-edit')
312
+ ], OxPfpEdit);
313
+ export { OxPfpEdit };
314
+ //# sourceMappingURL=ox-pfp-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-pfp-edit.js","sourceRoot":"","sources":["../../src/ox-pfp-edit.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { Profile } from './ox-pfp-view'\nimport { FileDropHelper } from '@operato/utils'\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-pfp-edit')\nexport class OxPfpEdit extends LitElement {\n static styles = css`\n :host {\n display: inline-block;\n overflow: hidden;\n }\n\n [content] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }\n\n [circle] {\n width: 90%;\n height: 90%;\n position: relative;\n }\n\n [circle]::after {\n position: absolute;\n content: '';\n width: 100%;\n height: 100%;\n box-shadow: 0 0 0 1000px lightgray;\n border-radius: 50%;\n opacity: 0.9;\n }\n\n [circle]::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 z-index: -1;\n background-repeat: no-repeat;\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 [monogram] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 1px solid darkgray;\n box-sizing: border-box;\n padding: 0;\n overflow: hidden;\n background-color: gray;\n color: white;\n\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n [monogram] div {\n flex: 1;\n text-transform: uppercase;\n font-size: 2em;\n font-family: system-ui;\n text-align: center;\n vertical-align: center;\n }\n\n [file-load] {\n position: absolute;\n left: 0;\n top: 0;\n\n display: flex;\n place-content: center;\n }\n\n [file-load]:hover {\n opacity: 50%;\n }\n\n #input-file {\n display: none;\n }\n\n label {\n display: flex;\n align-content: center;\n }\n\n mwc-icon {\n align-self: center;\n\n color: var(--file-uploader-icon-color, black);\n --mdc-icon-size: var(--file-uploader-icon-size, 20px);\n }\n `\n\n @property({ type: Object }) profile: Profile = {}\n @property({ type: String }) name?: string\n\n @query('[circle]') circle!: HTMLDivElement\n\n private dragStart?: { x: number; y: number }\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 dropFileHandler = this.onDropFile.bind(this) as EventListener\n\n connectedCallback(): void {\n super.connectedCallback()\n\n FileDropHelper.set(this)\n\n this.addEventListener('mousewheel', this.wheelEventHandler, false)\n\n this.addEventListener('mousedown', this.dragStartHandler)\n this.addEventListener('touchstart', this.dragStartHandler)\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 this.addEventListener('file-drop', this.dropFileHandler)\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\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 this.removeEventListener('file-drop', this.dropFileHandler)\n\n super.disconnectedCallback()\n }\n\n render() {\n return html`\n <div content>\n ${this.profile?.picture\n ? html`<div circle></div>`\n : html`<div monogram><div>${this.name?.replace(/\\s/g, '').slice(0, 2)}</div></div>`}\n </div>\n\n <div file-load>\n <label>\n <input\n id=\"input-file\"\n type=\"file\"\n accept=\"image/*\"\n hidden\n capture=\"environment\"\n @change=${(e: Event) => this.onChangeFile(e)}\n />\n <mwc-icon>image_search</mwc-icon>\n </label>\n </div>\n\n <slot></slot>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n const { picture, zoom = 1, left = 0, top = 0 } = this.profile\n\n if (picture) {\n const style = this.style\n\n style.setProperty('--background-image', `url(${picture})`)\n style.setProperty('--image-transform', `translate(${left}%, ${top}%) scale(${zoom}, ${zoom})`)\n }\n }\n\n get value() {\n return this.profile\n }\n\n set value(value: Profile) {\n this.profile = value\n }\n\n onWheelEvent(e: Event) {\n e.preventDefault()\n\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n\n const { top = 0, left = 0, zoom = 1, picture } = this.profile\n this.profile = {\n top,\n left,\n zoom: zoom * (1 - delta / 20),\n picture\n }\n\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: this.profile\n })\n )\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 { top = 0, left = 0, zoom = 1, picture } = this.profile\n const { offsetHeight, offsetWidth } = this\n\n this.profile = {\n top: top + (y / offsetHeight) * 100,\n left: left + (x / offsetWidth) * 100,\n zoom,\n picture\n }\n\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: this.profile\n })\n )\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 onDropFile(e: Event) {\n const dropFiles = (e as CustomEvent).detail\n const imageFile = dropFiles[0]\n if (!imageFile) {\n return\n }\n\n const picture = URL.createObjectURL(imageFile)\n\n this.profile = {\n left: 0,\n top: 0,\n zoom: 1,\n picture\n }\n }\n\n onChangeFile(e: Event) {\n const fileInput = e.currentTarget as HTMLInputElement\n const imageFile = [...Array.from(fileInput.files as FileList)][0]\n if (!imageFile) {\n return\n }\n\n const picture = URL.createObjectURL(imageFile)\n\n this.profile = {\n left: 0,\n top: 0,\n zoom: 1,\n picture\n }\n\n fileInput.files = null\n }\n\n fit() {\n this.profile = {\n ...this.profile,\n left: 0,\n top: 0,\n zoom: 1\n }\n }\n\n clear() {\n this.profile = {}\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ export declare class OxPfpEditor extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ picture?: string;
5
+ zoom: number;
6
+ left: number;
7
+ top: number;
8
+ container: HTMLDivElement;
9
+ render(): import("lit-html").TemplateResult<1>;
10
+ updated(changes: PropertyValues<this>): void;
11
+ }
@@ -0,0 +1,71 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, property, query, state } from 'lit/decorators.js';
4
+ let OxPfpEditor = class OxPfpEditor extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.zoom = 1;
8
+ this.left = 0;
9
+ this.top = 0;
10
+ }
11
+ render() {
12
+ return html ` <div container style="background-image: url(${this.picture})"></div> `;
13
+ }
14
+ updated(changes) {
15
+ if (changes.has('picture')) {
16
+ const style = this.container.style;
17
+ style.backgroundImage = `url($this.picture})`;
18
+ style.backgroundPositionX = `${this.left}px`;
19
+ style.backgroundPositionY = `${this.top}px`;
20
+ }
21
+ }
22
+ };
23
+ OxPfpEditor.styles = css `
24
+ :host {
25
+ display: block;
26
+ background-color: black;
27
+ }
28
+
29
+ [container] {
30
+ width: 200px;
31
+ height: 250px;
32
+ margin: 1em auto;
33
+ -webkit-filter: drop-shadow(0px -4px 4px black);
34
+ filter: drop-shadow(0px -4px 4px black);
35
+ overflow: hidden;
36
+ position: relative;
37
+ background-repeat: no-repeat;
38
+ }
39
+
40
+ [container]:after {
41
+ position: absolute;
42
+ content: '';
43
+ width: 100px;
44
+ height: 100px;
45
+ box-shadow: 0 0 0 1000px #fff7;
46
+ border-radius: 50%;
47
+ left: 50px;
48
+ top: 35px;
49
+ opacity: 0.5;
50
+ }
51
+ `;
52
+ __decorate([
53
+ property({ type: String })
54
+ ], OxPfpEditor.prototype, "picture", void 0);
55
+ __decorate([
56
+ state()
57
+ ], OxPfpEditor.prototype, "zoom", void 0);
58
+ __decorate([
59
+ state()
60
+ ], OxPfpEditor.prototype, "left", void 0);
61
+ __decorate([
62
+ state()
63
+ ], OxPfpEditor.prototype, "top", void 0);
64
+ __decorate([
65
+ query('[container]')
66
+ ], OxPfpEditor.prototype, "container", void 0);
67
+ OxPfpEditor = __decorate([
68
+ customElement('ox-pfp-edit')
69
+ ], OxPfpEditor);
70
+ export { OxPfpEditor };
71
+ //# sourceMappingURL=ox-pfp-edit%20copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-pfp-edit copy.js","sourceRoot":"","sources":["../../src/ox-pfp-edit copy.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGlE,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IAApC;;QAiCI,SAAI,GAAW,CAAC,CAAA;QAChB,SAAI,GAAW,CAAC,CAAA;QAChB,QAAG,GAAW,CAAC,CAAA;IAgB1B,CAAC;IAZC,MAAM;QACJ,OAAO,IAAI,CAAA,gDAAgD,IAAI,CAAC,OAAO,YAAY,CAAA;IACrF,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;YAClC,KAAK,CAAC,eAAe,GAAG,qBAAqB,CAAA;YAC7C,KAAK,CAAC,mBAAmB,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,CAAA;YAC5C,KAAK,CAAC,mBAAmB,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;SAC5C;IACH,CAAC;;AAjDM,kBAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BlB,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAiB;AAEnC;IAAR,KAAK,EAAE;yCAAiB;AAChB;IAAR,KAAK,EAAE;yCAAiB;AAChB;IAAR,KAAK,EAAE;wCAAgB;AAEF;IAArB,KAAK,CAAC,aAAa,CAAC;8CAA2B;AArCrC,WAAW;IADvB,aAAa,CAAC,eAAe,CAAC;GAClB,WAAW,CAmDvB;SAnDY,WAAW","sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\n@customElement('ox-pfp-edit')\nexport class OxPfpEditor extends LitElement {\n static styles = css`\n :host {\n display: block;\n background-color: black;\n }\n\n [container] {\n width: 200px;\n height: 250px;\n margin: 1em auto;\n -webkit-filter: drop-shadow(0px -4px 4px black);\n filter: drop-shadow(0px -4px 4px black);\n overflow: hidden;\n position: relative;\n background-repeat: no-repeat;\n }\n\n [container]:after {\n position: absolute;\n content: '';\n width: 100px;\n height: 100px;\n box-shadow: 0 0 0 1000px #fff7;\n border-radius: 50%;\n left: 50px;\n top: 35px;\n opacity: 0.5;\n }\n `\n\n @property({ type: String }) picture?: string\n\n @state() zoom: number = 1\n @state() left: number = 0\n @state() top: number = 0\n\n @query('[container]') container!: HTMLDivElement\n\n render() {\n return html` <div container style=\"background-image: url(${this.picture})\"></div> `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('picture')) {\n const style = this.container.style\n style.backgroundImage = `url($this.picture})`\n style.backgroundPositionX = `${this.left}px`\n style.backgroundPositionY = `${this.top}px`\n }\n }\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ import { Profile } from './ox-pfp-viewer';
3
+ export declare class OxPfpEditor extends LitElement {
4
+ static styles: import("lit").CSSResult;
5
+ profile: Profile;
6
+ circle: HTMLDivElement;
7
+ private dragStart?;
8
+ private dragEndHandler;
9
+ private dragMoveHandler;
10
+ private dragStartHandler;
11
+ private wheelEventHandler;
12
+ connectedCallback(): void;
13
+ disconnectedCallback(): void;
14
+ render(): import("lit-html").TemplateResult<1>;
15
+ onWheelEvent(e: Event): void;
16
+ onDragStart(e: Event): false | undefined;
17
+ onDragMove(e: Event): boolean;
18
+ onDragEnd(e: Event): void;
19
+ updated(changes: PropertyValues<this>): void;
20
+ }