profile-pane 3.2.0 → 3.2.2-test.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/README.md +50 -0
  2. package/icons-png/discord.png +0 -0
  3. package/icons-png/dribbble.png +0 -0
  4. package/icons-png/facebook.png +0 -0
  5. package/icons-png/instagram.png +0 -0
  6. package/icons-png/linkedin.png +0 -0
  7. package/icons-png/pinterest.png +0 -0
  8. package/icons-png/sharechat.png +0 -0
  9. package/icons-png/signup.png +0 -0
  10. package/icons-png/snapchat.png +0 -0
  11. package/icons-png/spotify.png +0 -0
  12. package/icons-png/telegram.png +0 -0
  13. package/icons-png/tiktok.png +0 -0
  14. package/icons-png/whatsapp.png +0 -0
  15. package/icons-png/x.png +0 -0
  16. package/icons-png/youtube.png +0 -0
  17. package/lib/303.profile-pane.js +1362 -0
  18. package/lib/303.profile-pane.js.map +1 -0
  19. package/lib/303.profile-pane.min.js +2 -0
  20. package/lib/303.profile-pane.min.js.map +1 -0
  21. package/lib/ProfileView.css +1090 -0
  22. package/lib/ProfileView.d.ts +2 -1
  23. package/lib/ProfileView.d.ts.map +1 -1
  24. package/lib/ProfileView.js +64 -36
  25. package/lib/buttonsHelper.d.ts +1 -1
  26. package/lib/buttonsHelper.d.ts.map +1 -1
  27. package/lib/buttonsHelper.js +2 -1
  28. package/lib/editProfilePane/EditCVCard.js +1 -1
  29. package/lib/editProfilePane/EditCommunitiesCard.js +1 -1
  30. package/lib/editProfilePane/EditFriendsCard.js +1 -1
  31. package/lib/editProfilePane/EditProfileView.d.ts +1 -1
  32. package/lib/editProfilePane/EditProfileView.d.ts.map +1 -1
  33. package/lib/editProfilePane/EditProfileView.js +4 -5
  34. package/lib/editProfilePane/editProfilePresenter.d.ts.map +1 -1
  35. package/lib/editProfilePane/editProfilePresenter.js +5 -4
  36. package/lib/icons-svg/profileIcons.d.ts +1 -1
  37. package/lib/icons-svg/profileIcons.d.ts.map +1 -1
  38. package/lib/icons-svg/profileIcons.js +9 -17
  39. package/lib/index.d.ts +1 -8
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js +74 -40
  42. package/lib/ontology/otherPreferencesForm.ttl +32 -0
  43. package/lib/ontology/resumeForm.ttl +349 -0
  44. package/lib/ontology/socialMedia.ttl +433 -0
  45. package/lib/profile-pane.js +32266 -13247
  46. package/lib/profile-pane.js.map +1 -1
  47. package/lib/profile-pane.min.js +2315 -935
  48. package/lib/profile-pane.min.js.map +1 -1
  49. package/lib/rdfFormsHelper.d.ts +13 -1
  50. package/lib/rdfFormsHelper.d.ts.map +1 -1
  51. package/lib/rdfFormsHelper.js +13 -1
  52. package/lib/sections/bio/BioEditDialog.d.ts.map +1 -1
  53. package/lib/sections/bio/BioEditDialog.js +7 -7
  54. package/lib/sections/bio/BioSection.css +300 -0
  55. package/lib/sections/bio/BioSection.d.ts +3 -2
  56. package/lib/sections/bio/BioSection.d.ts.map +1 -1
  57. package/lib/sections/bio/BioSection.js +26 -19
  58. package/lib/sections/bio/mutations.d.ts.map +1 -1
  59. package/lib/sections/bio/mutations.js +14 -3
  60. package/lib/sections/contactInfo/ContactInfoEditDialog.css +354 -0
  61. package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts +3 -1
  62. package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts.map +1 -1
  63. package/lib/sections/contactInfo/ContactInfoEditDialog.js +183 -98
  64. package/lib/sections/contactInfo/ContactInfoSection.css +125 -0
  65. package/lib/sections/contactInfo/ContactInfoSection.d.ts +2 -0
  66. package/lib/sections/contactInfo/ContactInfoSection.d.ts.map +1 -1
  67. package/lib/sections/contactInfo/ContactInfoSection.js +64 -41
  68. package/lib/sections/contactInfo/mutations.d.ts.map +1 -1
  69. package/lib/sections/contactInfo/mutations.js +51 -16
  70. package/lib/sections/education/EducationEditDialog.d.ts +3 -1
  71. package/lib/sections/education/EducationEditDialog.d.ts.map +1 -1
  72. package/lib/sections/education/EducationEditDialog.js +170 -92
  73. package/lib/sections/education/EducationSection.css +133 -0
  74. package/lib/sections/education/EducationSection.d.ts +3 -2
  75. package/lib/sections/education/EducationSection.d.ts.map +1 -1
  76. package/lib/sections/education/EducationSection.js +32 -25
  77. package/lib/sections/education/mutations.d.ts.map +1 -1
  78. package/lib/sections/education/mutations.js +14 -3
  79. package/lib/sections/heading/HeadingEditDialog.d.ts +4 -1
  80. package/lib/sections/heading/HeadingEditDialog.d.ts.map +1 -1
  81. package/lib/sections/heading/HeadingEditDialog.js +287 -162
  82. package/lib/sections/heading/HeadingSection.css +862 -0
  83. package/lib/sections/heading/HeadingSection.d.ts +3 -2
  84. package/lib/sections/heading/HeadingSection.d.ts.map +1 -1
  85. package/lib/sections/heading/HeadingSection.js +63 -32
  86. package/lib/sections/heading/imageHelpers.d.ts +1 -0
  87. package/lib/sections/heading/imageHelpers.d.ts.map +1 -1
  88. package/lib/sections/heading/imageHelpers.js +40 -1
  89. package/lib/sections/heading/mutations.d.ts.map +1 -1
  90. package/lib/sections/heading/mutations.js +86 -23
  91. package/lib/sections/heading/selectors.d.ts.map +1 -1
  92. package/lib/sections/heading/selectors.js +14 -3
  93. package/lib/sections/heading/types.d.ts +1 -2
  94. package/lib/sections/heading/types.d.ts.map +1 -1
  95. package/lib/sections/languages/LanguageEditDialog.d.ts +3 -1
  96. package/lib/sections/languages/LanguageEditDialog.d.ts.map +1 -1
  97. package/lib/sections/languages/LanguageEditDialog.js +202 -119
  98. package/lib/sections/languages/LanguageSection.css +53 -0
  99. package/lib/sections/languages/LanguageSection.d.ts +2 -0
  100. package/lib/sections/languages/LanguageSection.d.ts.map +1 -1
  101. package/lib/sections/languages/LanguageSection.js +42 -31
  102. package/lib/sections/languages/mutations.d.ts.map +1 -1
  103. package/lib/sections/languages/mutations.js +60 -161
  104. package/lib/sections/languages/selectors.d.ts.map +1 -1
  105. package/lib/sections/languages/selectors.js +1 -2
  106. package/lib/sections/projects/ProjectEditDialog.d.ts +2 -1
  107. package/lib/sections/projects/ProjectEditDialog.d.ts.map +1 -1
  108. package/lib/sections/projects/ProjectEditDialog.js +13 -24
  109. package/lib/sections/projects/ProjectSection.css +368 -0
  110. package/lib/sections/projects/ProjectSection.d.ts +2 -1
  111. package/lib/sections/projects/ProjectSection.d.ts.map +1 -1
  112. package/lib/sections/projects/ProjectSection.js +116 -34
  113. package/lib/sections/projects/mutations.d.ts.map +1 -1
  114. package/lib/sections/projects/mutations.js +109 -132
  115. package/lib/sections/projects/selectors.d.ts.map +1 -1
  116. package/lib/sections/projects/selectors.js +4 -45
  117. package/lib/{QRCodeCard.d.ts → sections/qrcode/QRCodeCard.d.ts} +2 -1
  118. package/lib/sections/qrcode/QRCodeCard.d.ts.map +1 -0
  119. package/lib/{QRCodeCard.js → sections/qrcode/QRCodeCard.js} +59 -11
  120. package/lib/sections/qrcode/QRCodeSection.css +108 -0
  121. package/lib/sections/qrcode/QRCodeSection.d.ts +4 -0
  122. package/lib/sections/qrcode/QRCodeSection.d.ts.map +1 -0
  123. package/lib/sections/qrcode/QRCodeSection.js +17 -0
  124. package/lib/sections/resume/ResumeEditDialog.d.ts +10 -1
  125. package/lib/sections/resume/ResumeEditDialog.d.ts.map +1 -1
  126. package/lib/sections/resume/ResumeEditDialog.js +531 -149
  127. package/lib/sections/resume/ResumeSection.css +350 -0
  128. package/lib/sections/resume/ResumeSection.d.ts +3 -2
  129. package/lib/sections/resume/ResumeSection.d.ts.map +1 -1
  130. package/lib/sections/resume/ResumeSection.js +78 -49
  131. package/lib/sections/resume/mutations.d.ts.map +1 -1
  132. package/lib/sections/resume/mutations.js +17 -3
  133. package/lib/sections/resume/selectors.d.ts.map +1 -1
  134. package/lib/sections/resume/selectors.js +1 -0
  135. package/lib/sections/resume/types.d.ts +1 -0
  136. package/lib/sections/resume/types.d.ts.map +1 -1
  137. package/lib/sections/shared/collapsibleSection.d.ts.map +1 -1
  138. package/lib/sections/shared/collapsibleSection.js +1 -0
  139. package/lib/sections/shared/phoneCountries.d.ts +1 -1
  140. package/lib/sections/shared/phoneCountries.d.ts.map +1 -1
  141. package/lib/sections/shared/phoneCountries.js +2 -2
  142. package/lib/sections/shared/projectCommunityNodes.d.ts +6 -0
  143. package/lib/sections/shared/projectCommunityNodes.d.ts.map +1 -0
  144. package/lib/sections/shared/projectCommunityNodes.js +56 -0
  145. package/lib/sections/shared/rdfMutationHelpers.d.ts +35 -2
  146. package/lib/sections/shared/rdfMutationHelpers.d.ts.map +1 -1
  147. package/lib/sections/shared/rdfMutationHelpers.js +290 -14
  148. package/lib/sections/shared/sectionCardHelpers.d.ts.map +1 -1
  149. package/lib/sections/shared/sectionCardHelpers.js +80 -11
  150. package/lib/sections/shared/types.d.ts +24 -0
  151. package/lib/sections/shared/types.d.ts.map +1 -1
  152. package/lib/sections/skills/SkillsEditDialog.d.ts +3 -1
  153. package/lib/sections/skills/SkillsEditDialog.d.ts.map +1 -1
  154. package/lib/sections/skills/SkillsEditDialog.js +136 -115
  155. package/lib/sections/skills/SkillsSection.css +173 -0
  156. package/lib/sections/skills/SkillsSection.d.ts +2 -0
  157. package/lib/sections/skills/SkillsSection.d.ts.map +1 -1
  158. package/lib/sections/skills/SkillsSection.js +107 -47
  159. package/lib/sections/skills/mutations.d.ts.map +1 -1
  160. package/lib/sections/skills/mutations.js +25 -21
  161. package/lib/sections/skills/selectors.d.ts.map +1 -1
  162. package/lib/sections/skills/selectors.js +5 -3
  163. package/lib/sections/social/SocialEditDialog.d.ts +3 -1
  164. package/lib/sections/social/SocialEditDialog.d.ts.map +1 -1
  165. package/lib/sections/social/SocialEditDialog.js +170 -62
  166. package/lib/sections/social/SocialSection.css +194 -0
  167. package/lib/sections/social/SocialSection.d.ts +4 -3
  168. package/lib/sections/social/SocialSection.d.ts.map +1 -1
  169. package/lib/sections/social/SocialSection.js +59 -43
  170. package/lib/sections/social/mutations.d.ts.map +1 -1
  171. package/lib/sections/social/mutations.js +23 -132
  172. package/lib/specialButtons/AddMeToYourFriends.css +54 -0
  173. package/lib/specialButtons/addContact/AddMeToYourContacts.css +1118 -0
  174. package/lib/specialButtons/addContact/ContactCreationDialog.d.ts +10 -0
  175. package/lib/specialButtons/addContact/ContactCreationDialog.d.ts.map +1 -0
  176. package/lib/specialButtons/addContact/ContactCreationDialog.js +1123 -0
  177. package/lib/specialButtons/addContact/addMeToYourContacts.d.ts +16 -0
  178. package/lib/specialButtons/addContact/addMeToYourContacts.d.ts.map +1 -0
  179. package/lib/specialButtons/addContact/addMeToYourContacts.js +136 -0
  180. package/lib/specialButtons/addContact/contactsErrors.d.ts +8 -0
  181. package/lib/specialButtons/addContact/contactsErrors.d.ts.map +1 -0
  182. package/lib/specialButtons/addContact/contactsErrors.js +106 -0
  183. package/lib/specialButtons/addContact/contactsTypes.d.ts +43 -0
  184. package/lib/specialButtons/addContact/contactsTypes.d.ts.map +1 -0
  185. package/lib/specialButtons/addContact/contactsTypes.js +5 -0
  186. package/lib/specialButtons/addContact/helpers.d.ts +7 -0
  187. package/lib/specialButtons/addContact/helpers.d.ts.map +1 -0
  188. package/lib/specialButtons/addContact/helpers.js +103 -0
  189. package/lib/specialButtons/addContact/mutations.d.ts +16 -0
  190. package/lib/specialButtons/addContact/mutations.d.ts.map +1 -0
  191. package/lib/specialButtons/addContact/mutations.js +300 -0
  192. package/lib/specialButtons/addContact/selectors.d.ts +10 -0
  193. package/lib/specialButtons/addContact/selectors.d.ts.map +1 -0
  194. package/lib/specialButtons/addContact/selectors.js +163 -0
  195. package/lib/{addMeToYourFriends.d.ts → specialButtons/addMeToYourFriends.d.ts} +6 -4
  196. package/lib/specialButtons/addMeToYourFriends.d.ts.map +1 -0
  197. package/lib/{addMeToYourFriends.js → specialButtons/addMeToYourFriends.js} +46 -11
  198. package/lib/styles/CollapsibleSection.css +519 -0
  199. package/lib/styles/EditDialogs.css +506 -686
  200. package/lib/styles/EditDialogs.responsive.css +989 -0
  201. package/lib/texts/buttonTexts.d.ts +9 -0
  202. package/lib/texts/buttonTexts.d.ts.map +1 -0
  203. package/lib/texts/buttonTexts.js +14 -0
  204. package/lib/texts/dialogTexts.d.ts +14 -0
  205. package/lib/texts/dialogTexts.d.ts.map +1 -0
  206. package/lib/texts/dialogTexts.js +19 -0
  207. package/lib/texts/messageTexts.d.ts +42 -0
  208. package/lib/texts/messageTexts.d.ts.map +1 -0
  209. package/lib/texts/messageTexts.js +47 -0
  210. package/lib/texts/profileTexts.d.ts +14 -0
  211. package/lib/texts/profileTexts.d.ts.map +1 -0
  212. package/lib/texts/profileTexts.js +19 -0
  213. package/lib/texts/qrCodeTexts.d.ts +2 -0
  214. package/lib/texts/qrCodeTexts.d.ts.map +1 -0
  215. package/lib/texts/qrCodeTexts.js +7 -0
  216. package/lib/texts.d.ts +5 -60
  217. package/lib/texts.d.ts.map +1 -1
  218. package/lib/texts.js +55 -70
  219. package/lib/ui/dialog.css +233 -0
  220. package/lib/ui/dialog.d.ts +15 -1
  221. package/lib/ui/dialog.d.ts.map +1 -1
  222. package/lib/ui/dialog.js +245 -45
  223. package/lib/ui/dialog.responsive.css +195 -0
  224. package/lib/ui/errors.d.ts.map +1 -1
  225. package/lib/ui/errors.js +2 -1
  226. package/lib/ui/spinner.d.ts +3 -0
  227. package/lib/ui/spinner.d.ts.map +1 -0
  228. package/lib/ui/spinner.js +13 -0
  229. package/lib/utils/debug.d.ts +5 -0
  230. package/lib/utils/debug.d.ts.map +1 -0
  231. package/lib/utils/debug.js +23 -0
  232. package/lib/utils/errorDisplay.d.ts +2 -0
  233. package/lib/utils/errorDisplay.d.ts.map +1 -0
  234. package/lib/utils/errorDisplay.js +19 -0
  235. package/package.json +34 -26
  236. package/lib/ChatWithMe.d.ts +0 -7
  237. package/lib/ChatWithMe.d.ts.map +0 -1
  238. package/lib/ChatWithMe.js +0 -90
  239. package/lib/QRCodeCard.d.ts.map +0 -1
  240. package/lib/addMeToYourFriends.d.ts.map +0 -1
  241. package/lib/sections/heading/camera.d.ts +0 -19
  242. package/lib/sections/heading/camera.d.ts.map +0 -1
  243. package/lib/sections/heading/camera.js +0 -199
  244. package/lib/styles/BioSection.css +0 -77
  245. package/lib/styles/CVCard.css +0 -142
  246. package/lib/styles/ChatWithMe.css +0 -6
  247. package/lib/styles/ContactInfoEditDialog.css +0 -153
  248. package/lib/styles/EducationCard.css +0 -103
  249. package/lib/styles/HeadingSection.css +0 -309
  250. package/lib/styles/ProfileCard.css +0 -66
  251. package/lib/styles/ProfileView.css +0 -65
  252. package/lib/styles/ProjectsCard.css +0 -206
  253. package/lib/styles/QRCodeCard.css +0 -43
  254. package/lib/styles/SocialCard.css +0 -89
  255. package/lib/styles/dialog.css +0 -209
  256. package/lib/styles/utilities.css +0 -740
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createSocialEditDialog = createSocialEditDialog;
7
7
  var _dialog = require("../../ui/dialog");
8
8
  var _litHtml = require("lit-html");
9
- require("../../styles/ContactInfoEditDialog.css");
9
+ require("solid-ui/components/actions/button");
10
+ require("solid-ui/components/forms/select");
11
+ require("../contactInfo/ContactInfoEditDialog.css");
10
12
  require("../../styles/EditDialogs.css");
11
13
  var _rowState = require("../shared/rowState");
12
14
  var _textUtils = require("../../textUtils");
@@ -21,22 +23,64 @@ on the row, you should be able to drag this button around and it should allow yo
21
23
  to change the order of the rows and that should change the order in the mutations
22
24
  that happen for this data. */
23
25
 
26
+ function toSocialAccountSelectOptions(options) {
27
+ return options.map(option => ({
28
+ label: option.label,
29
+ value: option.label
30
+ }));
31
+ }
32
+ function getSocialAccountSelectValue(row, options) {
33
+ const selected = (0, _helpers.findSocialAccountOption)(options, row?.name || '');
34
+ return selected?.label || '';
35
+ }
36
+ function readSocialAccountTypeChange(event) {
37
+ const customEvent = event;
38
+ if (typeof customEvent.detail?.value === 'string') {
39
+ return customEvent.detail.value;
40
+ }
41
+ const target = event.target;
42
+ return typeof target?.value === 'string' ? target.value : '';
43
+ }
44
+ function initializeSocialAccountSelects(form, rows, options) {
45
+ const selectOptions = toSocialAccountSelectOptions(options);
46
+ const selectElements = form.querySelectorAll('solid-ui-select[data-social-account-row-index]');
47
+ selectElements.forEach(selectElement => {
48
+ const rowIndex = Number(selectElement.dataset.socialAccountRowIndex);
49
+ if (Number.isNaN(rowIndex)) return;
50
+ const row = rows[rowIndex];
51
+ if (!row) return;
52
+ selectElement.options = selectOptions;
53
+ selectElement.value = getSocialAccountSelectValue(row, options);
54
+ selectElement.label = '';
55
+ });
56
+ }
57
+ function focusSocialField(form, selector) {
58
+ const nextField = form.querySelector(selector);
59
+ if (!nextField) return;
60
+ if (typeof nextField.scrollIntoView === 'function') {
61
+ nextField.scrollIntoView({
62
+ block: 'start',
63
+ behavior: 'auto'
64
+ });
65
+ }
66
+ const view = form.ownerDocument.defaultView;
67
+ const shouldAvoidFocus = Boolean(view?.matchMedia && (view.matchMedia('(pointer: coarse)').matches || view.matchMedia('(max-width: 640px)').matches));
68
+ if (shouldAvoidFocus) return;
69
+ if (nextField.tagName === 'SOLID-UI-SELECT') {
70
+ const triggerButton = nextField.shadowRoot?.querySelector('button');
71
+ triggerButton?.focus();
72
+ return;
73
+ }
74
+ if (typeof nextField.focus === 'function') {
75
+ nextField.focus();
76
+ }
77
+ }
24
78
  function sanitizeSocialFieldValue(value) {
25
79
  return (0, _textUtils.sanitizeTextValue)(value);
26
80
  }
27
81
  function sanitizeUrlFieldValue(value) {
28
82
  return (0, _textUtils.sanitizeTextValue)(value).replace(/\s+/g, '');
29
83
  }
30
- function isValidProfileUrl(value) {
31
- const normalized = (value || '').trim();
32
- if (!normalized) return false;
33
- try {
34
- const parsed = new URL(normalized);
35
- return parsed.protocol === 'http:' || parsed.protocol === 'https:';
36
- } catch {
37
- return false;
38
- }
39
- }
40
84
  function rowHasContent(row) {
41
85
  // A social account is considered meaningful only when a personal profile URL is set.
42
86
  return (0, _textUtils.hasNonEmptyText)(row.homepage);
@@ -68,11 +112,7 @@ function hasOrderChanged(rows, initialExistingOrder) {
68
112
  }
69
113
  return false;
70
114
  }
71
- function validateSocialBeforeSave(rows, initialExistingOrder) {
72
- const ops = (0, _rowState.summarizeRowOps)(rows, rowHasContent);
73
- const hasChanges = ops.create.length > 0 || ops.update.length > 0 || ops.remove.length > 0;
74
- const orderChanged = hasOrderChanged(rows, initialExistingOrder);
75
- if (!hasChanges && !orderChanged) return 'No social changes detected.';
115
+ function validateSocialBeforeSave(rows) {
76
116
  for (let i = 0; i < rows.length; i++) {
77
117
  const row = rows[i];
78
118
  if (!row || row.status === 'deleted') continue;
@@ -84,28 +124,22 @@ function validateSocialBeforeSave(rows, initialExistingOrder) {
84
124
  if (!(0, _textUtils.hasNonEmptyText)(row.homepage)) {
85
125
  return `Social account ${i + 1}: please enter your personal profile link.`;
86
126
  }
87
- if (!isValidProfileUrl(row.homepage || '')) {
88
- return `Social account ${i + 1}: profile link must be a valid http(s) URL.`;
89
- }
90
127
  }
91
128
  return null;
92
129
  }
93
130
  function renderSocialAccountInputSelect(row, rowIndex, options, onChange) {
94
- const selected = (0, _helpers.findSocialAccountOption)(options, row?.name || '');
95
- const selectedLabel = selected?.label || '';
131
+ const selectedLabel = getSocialAccountSelectValue(row, options);
96
132
  return (0, _litHtml.html)`
97
- <select
133
+ <solid-ui-select
98
134
  class="profile-edit-dialog__social-account-select"
99
135
  name=${`social-account-type-${rowIndex}`}
100
- data-row-index=${String(rowIndex)}
136
+ data-social-account-row-index=${String(rowIndex)}
101
137
  autocomplete="off"
138
+ .options=${toSocialAccountSelectOptions(options)}
139
+ .value=${selectedLabel}
140
+ .label=${''}
102
141
  @change=${onChange}
103
- >
104
- <option value="">Select</option>
105
- ${options.map(option => (0, _litHtml.html)`
106
- <option value=${option.label} ?selected=${option.label === selectedLabel}>${option.label}</option>
107
- `)}
108
- </select>
142
+ ></solid-ui-select>
109
143
  `;
110
144
  }
111
145
  function renderSocialInputRow({
@@ -116,9 +150,14 @@ function renderSocialInputRow({
116
150
  onChange,
117
151
  options,
118
152
  onDragStart,
153
+ onDragEnter,
119
154
  onDragOver,
120
155
  onDrop,
121
156
  onDragEnd,
157
+ onPointerDown,
158
+ onPointerMove,
159
+ onPointerUp,
160
+ onPointerCancel,
122
161
  isDropTarget
123
162
  }) {
124
163
  const row = rows[index];
@@ -133,8 +172,7 @@ function renderSocialInputRow({
133
172
  }
134
173
  };
135
174
  const handleAccountTypeInput = event => {
136
- const target = event.target;
137
- const selected = (0, _helpers.findSocialAccountOption)(options, target.value);
175
+ const selected = (0, _helpers.findSocialAccountOption)(options, readSocialAccountTypeChange(event));
138
176
  if (!rows[index]) return;
139
177
  if (!selected) {
140
178
  (0, _rowState.applyRowFieldChange)(rows[index], 'name', '', rowHasContent);
@@ -153,20 +191,28 @@ function renderSocialInputRow({
153
191
  return (0, _litHtml.html)`
154
192
  <div
155
193
  class="profile-edit-dialog__row profile-edit-dialog__row--social ${isDropTarget ? 'profile-edit-dialog__row--drop-target' : ''}"
156
- @dragover=${event => onDragOver(event)}
157
- @drop=${() => onDrop(index)}
194
+ data-social-reorder-index=${String(index)}
195
+ @dragenter=${() => onDragEnter(index)}
196
+ @dragover=${event => onDragOver(event, index)}
197
+ @drop=${event => onDrop(event, index)}
158
198
  >
159
- <button
199
+ <solid-ui-button
160
200
  type="button"
161
201
  class="profile-edit-dialog__drag-handle"
202
+ variant="icon"
203
+ size="md"
162
204
  aria-label=${`Reorder social account ${displayIndex + 1}`}
163
205
  title="Drag to reorder"
164
206
  draggable="true"
165
- @dragstart=${() => onDragStart(index)}
207
+ @dragstart=${event => onDragStart(event, index)}
166
208
  @dragend=${() => onDragEnd()}
209
+ @pointerdown=${event => onPointerDown(event, index)}
210
+ @pointermove=${event => onPointerMove(event)}
211
+ @pointerup=${event => onPointerUp(event)}
212
+ @pointercancel=${event => onPointerCancel(event)}
167
213
  >
168
- ${_profileIcons.bentoIcon}
169
- </button>
214
+ <span slot="icon" class="profile-edit-dialog__drag-handle-icon" aria-hidden="true">${_profileIcons.bentoIcon}</span>
215
+ </solid-ui-button>
170
216
  <img
171
217
  class="profile-edit-dialog__social-icon"
172
218
  src="${row?.icon || _constants.DEFAULT_ICON_URI}"
@@ -181,30 +227,32 @@ function renderSocialInputRow({
181
227
  <label aria-label=${homepageLabel} class="label profile-edit-dialog__field profile-edit-dialog__field--social-url">
182
228
  <input
183
229
  class="input"
184
- type="url"
230
+ type="text"
185
231
  name=${`social-homepage-${index}`}
186
232
  .value=${row?.homepage || ''}
187
233
  data-contact-field="homepage"
188
234
  data-entry-node=${row?.entryNode || ''}
189
235
  data-row-status=${row?.status || 'n/a'}
190
- placeholder="Profile URL"
191
- autocomplete="url"
192
- inputmode="url"
236
+ placeholder="Profile link or handle"
237
+ autocomplete="off"
238
+ inputmode="text"
193
239
  required
194
240
  @input=${handleTextInput('homepage')}
195
241
  />
196
- <small class="profile-edit-dialog__input-help-text">Paste your full profile URL (for example: https://example.com/username)</small>
242
+ <small class="profile-edit-dialog__input-help-text">Enter your profile link, handle, or username.</small>
197
243
  </label>
198
244
  <div class="profile-edit-dialog__actions profile-edit-dialog__actions--edge">
199
- <button
245
+ <solid-ui-button
200
246
  type="button"
247
+ variant="icon"
248
+ size="md"
201
249
  class="profile-edit-dialog__delete-button"
202
250
  aria-label=${`Delete social account ${displayIndex + 1}`}
203
251
  title=${_texts.deleteEntryButtonTitleText}
204
252
  @click=${handleDelete}
205
253
  >
206
- <span class="profile-edit-dialog__delete-icon" aria-hidden="true">${_profileIcons.trashIcon}</span>
207
- </button>
254
+ <span slot="icon" class="profile-edit-dialog__delete-icon" aria-hidden="true">${_profileIcons.trashIcon}</span>
255
+ </solid-ui-button>
208
256
  </div>
209
257
  </div>
210
258
  `;
@@ -212,6 +260,7 @@ function renderSocialInputRow({
212
260
  function renderSocialSection(rows, options, onRerender) {
213
261
  let dragSourceIndex = null;
214
262
  let dropTargetIndex = null;
263
+ let touchPointerId = null;
215
264
  const reorderRows = (from, to) => {
216
265
  if (from === to) return;
217
266
  const row = rows[from];
@@ -219,19 +268,33 @@ function renderSocialSection(rows, options, onRerender) {
219
268
  rows.splice(from, 1);
220
269
  rows.splice(to, 0, row);
221
270
  };
222
- const handleDragStart = index => {
271
+ const handleDragStart = (event, index) => {
223
272
  dragSourceIndex = index;
224
273
  dropTargetIndex = index;
274
+ if (event.dataTransfer) {
275
+ event.dataTransfer.effectAllowed = 'move';
276
+ event.dataTransfer.setData('text/plain', String(index));
277
+ }
278
+ };
279
+ const handleDragEnter = index => {
280
+ if (dragSourceIndex === null) return;
281
+ dropTargetIndex = index;
225
282
  };
226
- const handleDragOver = event => {
283
+ const handleDragOver = (event, index) => {
227
284
  event.preventDefault();
285
+ if (dragSourceIndex !== null) {
286
+ dropTargetIndex = index;
287
+ }
228
288
  if (event.dataTransfer) {
229
289
  event.dataTransfer.dropEffect = 'move';
230
290
  }
231
291
  };
232
- const handleDrop = index => {
233
- if (dragSourceIndex === null) return;
234
- reorderRows(dragSourceIndex, index);
292
+ const handleDrop = (event, index) => {
293
+ event.preventDefault();
294
+ const transferIndex = event.dataTransfer?.getData('text/plain');
295
+ const sourceIndex = dragSourceIndex ?? (transferIndex ? Number(transferIndex) : null);
296
+ if (sourceIndex === null || Number.isNaN(sourceIndex)) return;
297
+ reorderRows(sourceIndex, index);
235
298
  dragSourceIndex = null;
236
299
  dropTargetIndex = null;
237
300
  onRerender();
@@ -240,6 +303,49 @@ function renderSocialSection(rows, options, onRerender) {
240
303
  dragSourceIndex = null;
241
304
  dropTargetIndex = null;
242
305
  };
306
+ const updateTouchDropTarget = event => {
307
+ const dom = event.currentTarget?.ownerDocument || document;
308
+ const target = dom.elementFromPoint(event.clientX, event.clientY)?.closest('[data-social-reorder-index]');
309
+ if (!target) return;
310
+ const nextIndex = Number(target.dataset.socialReorderIndex);
311
+ if (!Number.isNaN(nextIndex)) {
312
+ dropTargetIndex = nextIndex;
313
+ }
314
+ };
315
+ const handlePointerDown = (event, index) => {
316
+ if (event.pointerType !== 'touch') return;
317
+ event.preventDefault();
318
+ dragSourceIndex = index;
319
+ dropTargetIndex = index;
320
+ touchPointerId = event.pointerId;
321
+ event.currentTarget?.setPointerCapture?.(event.pointerId);
322
+ };
323
+ const handlePointerMove = event => {
324
+ if (event.pointerType !== 'touch' || touchPointerId !== event.pointerId || dragSourceIndex === null) return;
325
+ event.preventDefault();
326
+ updateTouchDropTarget(event);
327
+ };
328
+ const handlePointerUp = event => {
329
+ if (event.pointerType !== 'touch' || touchPointerId !== event.pointerId) return;
330
+ event.preventDefault();
331
+ updateTouchDropTarget(event);
332
+ const sourceIndex = dragSourceIndex;
333
+ const targetIndex = dropTargetIndex;
334
+ event.currentTarget?.releasePointerCapture?.(event.pointerId);
335
+ touchPointerId = null;
336
+ dragSourceIndex = null;
337
+ dropTargetIndex = null;
338
+ if (sourceIndex === null || targetIndex === null || sourceIndex === targetIndex) return;
339
+ reorderRows(sourceIndex, targetIndex);
340
+ onRerender();
341
+ };
342
+ const handlePointerCancel = event => {
343
+ if (event.pointerType !== 'touch' || touchPointerId !== event.pointerId) return;
344
+ event.currentTarget?.releasePointerCapture?.(event.pointerId);
345
+ touchPointerId = null;
346
+ dragSourceIndex = null;
347
+ dropTargetIndex = null;
348
+ };
243
349
  const visibleRows = rows.map((row, index) => ({
244
350
  row,
245
351
  index
@@ -263,24 +369,20 @@ function renderSocialSection(rows, options, onRerender) {
263
369
  onChange: onRerender,
264
370
  options,
265
371
  onDragStart: handleDragStart,
372
+ onDragEnter: handleDragEnter,
266
373
  onDragOver: handleDragOver,
267
374
  onDrop: handleDrop,
268
375
  onDragEnd: handleDragEnd,
376
+ onPointerDown: handlePointerDown,
377
+ onPointerMove: handlePointerMove,
378
+ onPointerUp: handlePointerUp,
379
+ onPointerCancel: handlePointerCancel,
269
380
  isDropTarget: dropTargetIndex === index
270
381
  }))}
271
382
  </fieldset>
272
383
  </section>
273
384
  `;
274
385
  }
275
- function focusSocialField(form, selector) {
276
- const nextField = form.querySelector(selector);
277
- if (!nextField || typeof nextField.focus !== 'function') return;
278
- nextField.scrollIntoView({
279
- block: 'start',
280
- behavior: 'auto'
281
- });
282
- nextField.focus();
283
- }
284
386
  function renderSocialEditTemplate(form, formState, store, viewerMode, rerenderOptions = {}) {
285
387
  const rerender = (nextOptions = {}) => renderSocialEditTemplate(form, formState, store, viewerMode, nextOptions);
286
388
  const socialOptions = (0, _helpers.getSocialAccountOptions)(store);
@@ -288,6 +390,7 @@ function renderSocialEditTemplate(form, formState, store, viewerMode, rerenderOp
288
390
  ${renderSocialSection(formState.socialAccounts, socialOptions, rerender)}
289
391
  ${viewerMode !== 'owner' ? (0, _litHtml.html)`<p class="profile-edit-dialog__login-message">${_texts.ownerLoginRequiredDialogMessageText}</p>` : null}
290
392
  `, form);
393
+ initializeSocialAccountSelects(form, formState.socialAccounts, socialOptions);
291
394
  if (rerenderOptions.focusSelector) {
292
395
  focusSocialField(form, rerenderOptions.focusSelector);
293
396
  }
@@ -327,6 +430,12 @@ async function createSocialEditDialog(event, store, subject, socialAccounts, vie
327
430
  title: _texts.editSocialDialogTitleText,
328
431
  dom,
329
432
  form,
433
+ onOpen: () => focusSocialField(form, '[name="social-account-type-0"]'),
434
+ shouldCloseWithoutSave: () => {
435
+ const ops = (0, _rowState.summarizeRowOps)(formState.socialAccounts, rowHasContent);
436
+ const orderChanged = hasOrderChanged(formState.socialAccounts, formState.initialExistingOrder);
437
+ return ops.create.length === 0 && ops.update.length === 0 && ops.remove.length === 0 && !orderChanged;
438
+ },
330
439
  headerAction: {
331
440
  type: 'button',
332
441
  label: '+ Add More',
@@ -339,7 +448,7 @@ async function createSocialEditDialog(event, store, subject, socialAccounts, vie
339
448
  if (viewerMode !== 'owner') {
340
449
  return _texts.ownerLoginRequiredDialogMessageText;
341
450
  }
342
- return validateSocialBeforeSave(formState.socialAccounts, formState.initialExistingOrder);
451
+ return validateSocialBeforeSave(formState.socialAccounts);
343
452
  },
344
453
  onSave: async () => {
345
454
  const socialOps = (0, _rowState.summarizeRowOps)(formState.socialAccounts, rowHasContent);
@@ -351,8 +460,7 @@ async function createSocialEditDialog(event, store, subject, socialAccounts, vie
351
460
  await (0, _mutations.processSocialMutations)(store, subject, plan, formState.socialAccounts);
352
461
  },
353
462
  formatSaveError: error => {
354
- const message = error instanceof Error ? error.message : String(error);
355
- return message.startsWith(_texts.saveSocialUpdatesFailedPrefixText) ? message : `${_texts.saveSocialUpdatesFailedPrefixText} ${message}`;
463
+ return error instanceof Error ? error.message : _texts.saveSocialUpdatesFailedMessageText;
356
464
  }
357
465
  });
358
466
  if (!result) return;
@@ -0,0 +1,194 @@
1
+ /* Social section styles. */
2
+
3
+ .profile__section[data-profile-section='social'],
4
+ .profile__section--empty[data-profile-section='social'] {
5
+ --social-card-collapsed-columns: repeat(5, max-content);
6
+ --social-card-expanded-columns: repeat(3, max-content);
7
+ --social-card-icon-size: var(--icon-base, 2rem);
8
+ --social-card-list-display: flex;
9
+ --social-card-list-columns: none;
10
+ --social-card-list-gap: var(--spacing-xxs, 0.3125rem);
11
+ --social-card-link-gap: var(--spacing-xs, 0.75rem);
12
+ --social-card-link-padding: var(--spacing-xs, 0.75rem);
13
+ --social-card-link-hover-background: var(--color-surface-accent-subtle, var(--lavender-300, #e6dcff));
14
+ --social-card-hidden-item-display: flex;
15
+ --social-card-more-button-display: none;
16
+ --social-card-more-button-margin-top: var(--spacing-xs, 0.75rem);
17
+ border: var(--border-width-thin, 1px) solid var(--color-border-lighter, #D1D5DB);
18
+ }
19
+
20
+ .profile__section--empty[data-profile-section='social'] {
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ }
25
+
26
+ /* Card and list */
27
+ .social-card,
28
+ .social-card__list {
29
+ width: 100%;
30
+ max-width: 100%;
31
+ min-width: 0;
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ .social-card__list {
36
+ display: var(--social-card-list-display);
37
+ grid-template-columns: var(--social-card-list-columns);
38
+ flex-wrap: wrap;
39
+ justify-content: flex-start;
40
+ gap: var(--social-card-list-gap);
41
+ margin: 0;
42
+ padding: 0;
43
+ list-style: none;
44
+ }
45
+
46
+ .social-card__item,
47
+ .social-card__link,
48
+ .profile__section--empty[data-profile-section='social'] .profile__empty-state-content {
49
+ display: flex;
50
+ align-items: center;
51
+ }
52
+
53
+ .profile__section--empty[data-profile-section='social'] .profile__empty-state-content {
54
+ flex-direction: column;
55
+ gap: var(--spacing-2xs, 0.625rem);
56
+ }
57
+
58
+ .social__empty-icon {
59
+ display: inline-flex;
60
+ }
61
+
62
+ /* Links */
63
+ .social-card__link {
64
+ color: var(--color-primary, #7C4DFF);
65
+ text-decoration: none;
66
+ gap: var(--social-card-link-gap);
67
+ padding: var(--social-card-link-padding);
68
+ border-radius: var(--border-radius-base, 0.3125rem);
69
+ transition: background-color var(--animation-duration, 0.2s) ease;
70
+ position: relative;
71
+ flex: 1;
72
+ min-width: 0;
73
+ }
74
+
75
+ .social-card__link:hover,
76
+ .social-card__link:focus {
77
+ text-decoration: underline;
78
+ background-color: var(--social-card-link-hover-background);
79
+ }
80
+
81
+ .social-card__link[href^="http"]:after {
82
+ content: " (external link)";
83
+ position: absolute;
84
+ left: -10000px;
85
+ width: 1px;
86
+ height: 1px;
87
+ overflow: hidden;
88
+ }
89
+
90
+ .social-card__icon {
91
+ width: var(--social-card-icon-size);
92
+ height: var(--social-card-icon-size);
93
+ border-radius: var(--border-radius-base, 0.3125rem);
94
+ background: var(--color-card-bg, #FFFFFF);
95
+ flex-shrink: 0;
96
+ }
97
+
98
+ /* Toggle button */
99
+
100
+ solid-ui-button.social-card__more-button {
101
+ --button-height-sm: 0;
102
+ --button-padding-x-sm: 0;
103
+ --button-background: transparent;
104
+ --button-border: transparent;
105
+ --button-text: var(--color-primary, #7C4DFF);
106
+ --button-hover-background: transparent;
107
+ --button-hover-border: transparent;
108
+ --button-hover-text: var(--color-primary, #7C4DFF);
109
+ }
110
+
111
+ .social-card__more-button,
112
+ solid-ui-button.social-card__more-button::part(button) {
113
+ display: var(--social-card-more-button-display);
114
+ padding: 0;
115
+ border: 0;
116
+ background: transparent;
117
+ color: var(--color-primary, #7C4DFF);
118
+ font: inherit;
119
+ font-weight: var(--font-weight-bold, 600);
120
+ cursor: var(--profile-interactive-cursor, pointer);
121
+ }
122
+
123
+ .social-card[data-mobile-expanded="false"] .social-card__item:nth-child(n + 11) {
124
+ display: var(--social-card-hidden-item-display);
125
+ }
126
+
127
+ .social-card[data-mobile-expanded="true"] {
128
+ --social-card-list-columns: var(--social-card-expanded-columns);
129
+ --social-card-hidden-item-display: flex;
130
+ --social-card-more-button-display: none;
131
+ }
132
+
133
+ /* Compact layout */
134
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .profile__section[data-profile-section='social'],
135
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .profile__section--empty[data-profile-section='social'] {
136
+ --social-card-list-display: grid;
137
+ --social-card-list-columns: var(--social-card-collapsed-columns);
138
+ --social-card-hidden-item-display: none;
139
+ --social-card-more-button-display: inline-flex;
140
+ }
141
+
142
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .social-card .social-card__list {
143
+ justify-content: flex-start;
144
+ }
145
+
146
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .profile__section[data-profile-section='social'] .profile-section-collapsible__toggle-button,
147
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .profile__section--empty[data-profile-section='social'] .profile-section-collapsible__toggle-button {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ }
152
+
153
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] .social-card__more-button,
154
+ :is(.profile-pane-host, .profile-pane-root)[data-layout='mobile'] solid-ui-button.social-card__more-button::part(button) {
155
+ margin-top: var(--social-card-more-button-margin-top);
156
+ }
157
+
158
+ @media (max-width: 768px) {
159
+ .profile__section[data-profile-section='social'],
160
+ .profile__section--empty[data-profile-section='social'] {
161
+ --social-card-list-display: grid;
162
+ --social-card-list-columns: var(--social-card-collapsed-columns);
163
+ --social-card-hidden-item-display: none;
164
+ --social-card-more-button-display: inline-flex;
165
+ }
166
+
167
+ .social-card .social-card__list {
168
+ justify-content: flex-start;
169
+ }
170
+
171
+ .social-card__more-button,
172
+ solid-ui-button.social-card__more-button::part(button) {
173
+ margin-top: var(--social-card-more-button-margin-top);
174
+ }
175
+ }
176
+
177
+ @container profile-pane (max-width: 768px) {
178
+ .profile__section[data-profile-section='social'],
179
+ .profile__section--empty[data-profile-section='social'] {
180
+ --social-card-list-display: grid;
181
+ --social-card-list-columns: var(--social-card-collapsed-columns);
182
+ --social-card-hidden-item-display: none;
183
+ --social-card-more-button-display: inline-flex;
184
+ }
185
+
186
+ .social-card .social-card__list {
187
+ justify-content: flex-start;
188
+ }
189
+
190
+ .social-card__more-button,
191
+ solid-ui-button.social-card__more-button::part(button) {
192
+ margin-top: var(--social-card-more-button-margin-top);
193
+ }
194
+ }
@@ -1,8 +1,9 @@
1
1
  import { TemplateResult } from 'lit-html';
2
+ import 'solid-ui/components/actions/button';
2
3
  import { SocialPresentation } from './types';
3
4
  import { ViewerMode } from '../../types';
4
- import '../../styles/SocialCard.css';
5
+ import './SocialSection.css';
5
6
  import { LiveStore, NamedNode } from 'rdflib';
6
- export declare const SocialCard: (SocialData: SocialPresentation, viewerMode: ViewerMode) => TemplateResult;
7
- export declare function renderSocialAccounts(store: LiveStore, subject: NamedNode, socialData: SocialPresentation, viewerMode: ViewerMode, onSaved?: () => Promise<void> | void): TemplateResult<1> | "";
7
+ export declare const SocialCard: (SocialData: SocialPresentation, _viewerMode: ViewerMode) => TemplateResult;
8
+ export declare function renderSocialSection(store: LiveStore, subject: NamedNode, socialData: SocialPresentation, viewerMode: ViewerMode, onSaved?: () => Promise<void> | void): TemplateResult<1> | "";
8
9
  //# sourceMappingURL=SocialSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SocialSection.d.ts","sourceRoot":"","sources":["../../../src/sections/social/SocialSection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAW,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,6BAA6B,CAAA;AAGpC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAoB7C,eAAO,MAAM,UAAU,GACrB,YAAY,kBAAkB,EAC9B,YAAY,UAAU,KACrB,cA6DF,CAAA;AAwJD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,0BAYrC"}
1
+ {"version":3,"file":"SocialSection.d.ts","sourceRoot":"","sources":["../../../src/sections/social/SocialSection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,EAAW,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,qBAAqB,CAAA;AAG5B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAoB7C,eAAO,MAAM,UAAU,GACrB,YAAY,kBAAkB,EAC9B,aAAa,UAAU,KACtB,cA+DF,CAAA;AAoKD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,0BAYrC"}