@pontive/pontkit-core 1.1.3 → 1.1.4

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.
@@ -42,6 +42,27 @@ export declare class PontWatermark extends LitElement implements Props {
42
42
  get labelId(): string;
43
43
  get logoId(): string;
44
44
  private _renderLabel;
45
+ /**
46
+ * The Pontive lockup: the mark, then the wordmark.
47
+ *
48
+ * This replaced a square 800x800 tile — a rounded indigo rect with a white
49
+ * glyph knocked out of it — and the two recolour hooks had to change with it.
50
+ * `.pontive-logo-rect` has nothing to fill any more, and `.pontive-logo-path`
51
+ * was white only because it sat on that coloured tile; white letterforms on a
52
+ * page background would be invisible.
53
+ *
54
+ * So: `.pontive-logo-mark` carries the brand colour the tile used to, and
55
+ * `.pontive-logo-wordmark` follows the label's own colour, which keeps
56
+ * "Powered by" and "Pontive" reading as one line and keeps the theme and
57
+ * muted variants meaning something.
58
+ *
59
+ * The supplied artwork puts two greys on the mark. They are flattened to one
60
+ * fill deliberately: this renders 16px tall, where a two-tone split is noise,
61
+ * and the brief was to keep the colours the watermark already used.
62
+ *
63
+ * No width/height attributes — the lockup is roughly 5:1 and the CSS sizes it
64
+ * by height, so it cannot be squeezed into the square slot the tile left.
65
+ */
45
66
  private _renderLogo;
46
67
  render(): import('lit-html').TemplateResult<1>;
47
68
  }
@@ -3,4 +3,4 @@ export * from './pont-member-management';
3
3
  export * from './pont-preview/pont-preview';
4
4
  export * from './pont-signin/pont-signin';
5
5
  export * from './pont-signup/pont-signup';
6
- export * from './pont-nav-user';
6
+ export * from './pont-account-menu';
@@ -0,0 +1 @@
1
+ export * from './pont-account-menu';
@@ -1,5 +1,11 @@
1
1
  import { LitElement, PropertyValues, TemplateResult } from 'lit';
2
2
  import { AuthState } from '../../../context';
3
+ /** The three fields this menu shows for whoever is signed in. */
4
+ export type MenuUser = {
5
+ name?: string;
6
+ email?: string;
7
+ avatar_url?: string;
8
+ };
3
9
  type MenuItem = {
4
10
  id?: string;
5
11
  label: string;
@@ -19,10 +25,10 @@ type MenuItem = {
19
25
  export declare class PontUserSnippet extends LitElement {
20
26
  protected createRenderRoot(): HTMLElement | DocumentFragment;
21
27
  isTrigger: boolean;
22
- user: {};
28
+ user: MenuUser;
23
29
  render(): TemplateResult<1>;
24
30
  }
25
- export declare class PontNavUser extends LitElement {
31
+ export declare class PontAccountMenu extends LitElement {
26
32
  protected createRenderRoot(): HTMLElement | DocumentFragment;
27
33
  accountSettingsPath: string;
28
34
  menuItems: MenuItem[];
@@ -53,7 +59,34 @@ export declare class PontNavUser extends LitElement {
53
59
  private _renderToggleItem;
54
60
  private _renderSelectItem;
55
61
  render(): TemplateResult<1>;
62
+ /**
63
+ * Leaves for `path`, but only as a last resort.
64
+ *
65
+ * `window.location.href` is a full document navigation. Inside a SPA that
66
+ * discards every bit of client state and re-runs the whole boot, including
67
+ * the session restore round trip — so choosing "Account settings" reloaded
68
+ * the page, blanked the settings widget while it re-fetched, and silently
69
+ * dropped whatever the user had half-typed into a card. When the menu points
70
+ * at the page it is already on, the reload bought nothing at all.
71
+ *
72
+ * So: nothing to do if we are already there, and the host gets first refusal
73
+ * (see _handleAccountSettings) so a client-side router can move without a
74
+ * reload. This stays as the fallback for a plain multi-page site.
75
+ */
56
76
  private _navigate;
77
+ /**
78
+ * The `account-settings` event is cancelable, and that is the point.
79
+ *
80
+ * A host with a client-side router calls preventDefault() and does its own
81
+ * push — the difference between a reload and a transition. Without that hook
82
+ * this element's only move was a hard navigation, and a custom element cannot
83
+ * know about next/router or any other.
84
+ *
85
+ * With no path configured and nobody cancelling, fall back to asking a
86
+ * modal-mode pont-account-settings to open: the same event the SDK's own
87
+ * openAccountSettingsModal() sends. If nothing is mounted to hear that
88
+ * either, say so once rather than appearing to do nothing.
89
+ */
57
90
  private _handleAccountSettings;
58
91
  private _handleLogout;
59
92
  private _handleMenuItemClick;
@@ -56,6 +56,18 @@ export declare class PontAccountSettings extends LitElement {
56
56
  private renderWatermark;
57
57
  private renderMainContent;
58
58
  private renderTabContent;
59
+ /**
60
+ * What the widget occupies while the profile is on its way.
61
+ *
62
+ * It used to render nothing at all until `_userLoaded`, so a page that
63
+ * embeds it showed a hole for the length of the /mgmt/v1/me round trip and
64
+ * then jumped when the real content arrived. A skeleton of the same shape
65
+ * costs nothing and keeps the page's layout still.
66
+ *
67
+ * Only page mode needs this: a modal is not on screen until someone opens
68
+ * it, and by then the fetch has almost always settled.
69
+ */
70
+ private renderLoadingSkeleton;
59
71
  render(): import('lit-html/directive.js').DirectiveResult<{
60
72
  new (_partInfo: import('lit-html/directive.js').PartInfo): import('lit-html/directives/keyed.js').Keyed<import('lit-html').TemplateResult<1>>;
61
73
  }>;
@@ -7,3 +7,12 @@ export declare const CARD_EDITABLE_INPUT_CLASS = "pont-account-settings-card-edi
7
7
  export declare const CARD_DEFAULT_BUTTON = "pont-account-settings-card-button-full";
8
8
  export declare const CARD_OUTLINE_BUTTON = "pont-account-settings-card-button-full";
9
9
  export declare const CARD_EDIT_BUTTON = "pont-account-settings-card-edit-button pont-text-muted-foreground pont-flex pont-items-center";
10
+ /**
11
+ * The "Not Added" placeholder every card shows for an empty field.
12
+ *
13
+ * It used to be a raw `<p class="…label…">` nested INSIDE a
14
+ * `<pont-typography-p>`, which itself renders a `<p>` — a paragraph inside a
15
+ * paragraph, four cards over. pont-typography-muted is the design system's own
16
+ * element for exactly this: de-emphasised text that is not a value.
17
+ */
18
+ export declare const notAddedPlaceholder: () => import('lit-html').TemplateResult<1>;
@@ -13,13 +13,7 @@ export declare class PontAccountInfo extends LitElement {
13
13
  onAvatarRemove: () => void;
14
14
  showIcons: boolean;
15
15
  content: IProfileWidgetCustomization | null;
16
- otpVariant: "simple" | "with_spacing" | "with_separator" | "digits_only";
17
- otpLength: number;
18
16
  layout: USER_ACCOUNT_SETTINGS_WIDGETS_LAYOUT;
19
- private isEditingEmail;
20
- private isVerifyingEmail;
21
- private isEditingPhone;
22
- private isVerifyingPhone;
23
17
  private isUploadingImage;
24
18
  private isEditingAvatarMobile;
25
19
  private isMobile;
@@ -28,7 +22,6 @@ export declare class PontAccountInfo extends LitElement {
28
22
  private _intentionalClose;
29
23
  private avatarDraft;
30
24
  private _committedAvatar;
31
- private formData;
32
25
  private userContextValue;
33
26
  private _mobileQuery;
34
27
  private _onMobileChange;
@@ -45,10 +38,40 @@ export declare class PontAccountInfo extends LitElement {
45
38
  private handleAvatarInput;
46
39
  private handleCancelAvatar;
47
40
  private handleSaveAvatar;
41
+ /**
42
+ * One label/value row, whatever the value happens to be.
43
+ *
44
+ * Photo, Email and Phone all go through here, which is what keeps this card's
45
+ * label column at the same x as Personal Info, Location and Links. It was
46
+ * previously inlined per field, so the avatar could quietly grow its own
47
+ * column and take Email and Phone with it.
48
+ */
49
+ private renderRow;
50
+ /** A read-only value row. See renderEmailSection for why there is no edit. */
48
51
  private renderDisplayRow;
49
- private renderEditForm;
50
- private renderVerificationForm;
51
- private updateField;
52
+ /**
53
+ * Email and phone are READ-ONLY, deliberately.
54
+ *
55
+ * Both are login identifiers and must stay verified. Letting someone change
56
+ * one in place would change what they sign in with while the new value is
57
+ * still unproven, which can lock a user out of their own account — so the
58
+ * Login Info card renders values and no edit affordance, and is the only card
59
+ * here without an Edit button.
60
+ *
61
+ * This is a product decision, not an unfinished one. An earlier draft carried
62
+ * an inline edit form and a six-digit OTP verification form for each field,
63
+ * but nothing ever rendered the button that would reach them: the row's
64
+ * action cell is empty, so `isEditingEmail` and `isEditingPhone` could never
65
+ * become true. Roughly 120 lines of form and OTP markup sat here looking like
66
+ * a feature someone forgot to finish, which is an invitation to "fix" it by
67
+ * wiring a button up — exactly the change that would be unsafe.
68
+ *
69
+ * The forms are gone rather than commented out; git history has them for
70
+ * whenever the real flow is built. DO NOT reintroduce an edit affordance here
71
+ * until there is an update flow that asks the user to verify the new address
72
+ * or number AFTER the change, and that keeps the old identifier usable until
73
+ * they do.
74
+ */
52
75
  private renderEmailSection;
53
76
  private renderPhoneSection;
54
77
  private renderAvatarFooter;
@@ -59,8 +82,32 @@ export declare class PontAccountInfo extends LitElement {
59
82
  * keystroke and restored on cancel.
60
83
  */
61
84
  private renderAvatarFormBody;
62
- private renderAvatarDesktop;
63
- private renderAvatarMobile;
85
+ /**
86
+ * Initials for the image-less case.
87
+ *
88
+ * The fallback used to be rendered childless — `<pont-avatar-fallback>` puts
89
+ * its children in the slot and has nothing of its own to show — so every user
90
+ * without a photo got a blank 148px disc. pont-account-menu has always passed
91
+ * initials through the same helper; this is the header avatar's own rule,
92
+ * applied to the one place that skipped it, so the two agree.
93
+ */
94
+ private get avatarInitials();
95
+ /** The disc itself: photo when there is one, initials when there is not. */
96
+ private renderAvatarVisual;
97
+ /**
98
+ * The avatar as a field of this card rather than a column beside it.
99
+ *
100
+ * It used to sit in a flex row next to the whole details block, so the
101
+ * avatar's own width pushed Email and Phone 180px to the right of where every
102
+ * other card on the page starts its labels — Login Info was the one card that
103
+ * did not line up with the rest. Rendering it through the same row helper as
104
+ * the other fields makes that alignment structural instead of something to
105
+ * keep re-tuning, and collapses the desktop and mobile trees into one shape.
106
+ *
107
+ * Desktop opens the editor in a popover, mobile inline underneath: that split
108
+ * is a real input-modality difference and stays.
109
+ */
110
+ private renderPhotoRow;
64
111
  private renderHeader;
65
112
  private renderAccountDetails;
66
113
  render(): TemplateResult<1>;
@@ -18,8 +18,21 @@ export declare class PontLocationInfo extends LitElement {
18
18
  private handleEdit;
19
19
  private handleCancel;
20
20
  private updateField;
21
+ /** See personal-info.validate for why this stopped being a no-op. */
21
22
  private validate;
22
23
  private handleSave;
24
+ private fieldId;
25
+ /**
26
+ * Zone Info is an IANA timezone name, not free text.
27
+ *
28
+ * It goes straight to the OIDC `zoneinfo` claim, which is defined as an IANA
29
+ * Time Zone Database name ("Australia/Sydney"). As a text box it collected
30
+ * whatever people typed — "GMT+3", "AEST", "Sydney" — none of which any
31
+ * consumer of that claim can resolve. The list comes from the browser's own
32
+ * tz database rather than a hardcoded copy that would rot.
33
+ */
34
+ private get timeZones();
35
+ private renderControl;
23
36
  private renderField;
24
37
  private renderFooter;
25
38
  render(): TemplateResult<1>;
@@ -22,9 +22,28 @@ export declare class PontPersonalInfo extends LitElement {
22
22
  private handleEdit;
23
23
  private handleCancel;
24
24
  private updateField;
25
+ /**
26
+ * These are the rules the server will apply anyway; running them here is what
27
+ * turns a rejected save into a message beside the offending field instead of
28
+ * a toast that does not say which one.
29
+ *
30
+ * Everything is optional — this card has no required field — so a rule only
31
+ * fires on a value the user actually typed. It used to build an empty object
32
+ * and return true, which left the pont-field `invalid` / pont-field-error
33
+ * wiring below permanently unreachable.
34
+ */
25
35
  private validate;
26
36
  private handleSave;
27
37
  createRenderRoot(): this;
38
+ /**
39
+ * Ids are namespaced rather than the bare field key.
40
+ *
41
+ * A `<label for>` needs an id that is unique in the DOCUMENT, and these used
42
+ * to be "username", "bio", "first" — names any host page might already use,
43
+ * and which collide with themselves the moment the widget is mounted twice
44
+ * (a page instance and a modal instance both exist in the supported setup).
45
+ */
46
+ private fieldId;
28
47
  private renderControl;
29
48
  private renderField;
30
49
  private renderFooter;
@@ -17,8 +17,14 @@ export declare class PontUrlsInfo extends LitElement {
17
17
  private handleEdit;
18
18
  private handleCancel;
19
19
  private updateField;
20
+ /**
21
+ * Website took any string at all. "not a url", a javascript: URI, a bare
22
+ * "example.com" that no consumer can link to — all saved happily, because
23
+ * this returned true without looking. See personal-info.validate.
24
+ */
20
25
  private validate;
21
26
  private handleSave;
27
+ private fieldId;
22
28
  private renderField;
23
29
  private renderFooter;
24
30
  private handleLinkClick;
@@ -4,6 +4,5 @@ export declare const SIDEBAR_CONTAINER_CLASSES: {
4
4
  horizontalBurger: string;
5
5
  };
6
6
  export declare const BURGER_BUTTON_CLASSES = "pont-account-settings-sidebar-burger-button pont-rounded-lg pont-cursor-pointer";
7
- export declare const BURGER_LABEL_CLASSES = "pont-account-settings-sidebar-burger-label pont-font-medium";
8
7
  export declare const MOBILE_DRAWER_CLASSES = "mobile-sidebar-drawer pont-account-settings-sidebar-mobile-drawer pont-transform pont-transition-all pont-duration-300 pont-ease-in-out";
9
8
  export declare const MOBILE_OVERLAY_CLASSES = "mobile-sidebar-overlay pont-account-settings-sidebar-mobile-overlay pont-transition-opacity pont-duration-300 pont-ease-in-out";
@@ -1,4 +1,5 @@
1
1
  import { PontAccountInfo } from './components/widgets/pont-account-settings/profile/components/account-info';
2
+ import { PontAccountMenu, PontUserSnippet } from './components/widgets/pont-account-menu/pont-account-menu';
2
3
  import { PontAccountSettings } from './components/widgets/pont-account-settings/pont-account-settings';
3
4
  import { PontAlert } from './components/renderers/feedback/alert/_alert';
4
5
  import { AuthStateElement } from './components/wrappers/pont-auth-state/pont-auth-state';
@@ -20,7 +21,6 @@ import { PontLink } from './components/renderers/navigation/link/_link';
20
21
  import { PontLogo } from './components/renderers/visuals/logo/_logo';
21
22
  import { PontModal } from './components/ui/modal/index';
22
23
  import { PontNameField } from './components/renderers/auth/field/_name-field';
23
- import { PontNavUser, PontUserSnippet } from './components/widgets/pont-nav-user/pont-nav-user';
24
24
  import { PontOtp } from './components/renderers/auth/otp/_otp';
25
25
  import { PontOtpResend } from './components/renderers/auth/otp/_otp-resend';
26
26
  import { PontPasskeyButton } from './components/renderers/auth/button/_passkey-button';
@@ -45,6 +45,7 @@ import { PontWatermark } from './components/renderers/visuals/watermark/_waterma
45
45
  declare global {
46
46
  interface HTMLElementTagNameMap {
47
47
  "pont-account-info": PontAccountInfo;
48
+ "pont-account-menu": PontAccountMenu;
48
49
  "pont-account-settings": PontAccountSettings;
49
50
  "pont-alert": PontAlert;
50
51
  "pont-auth-state": AuthStateElement;
@@ -66,7 +67,6 @@ declare global {
66
67
  "pont-logo": PontLogo;
67
68
  "pont-modal": PontModal;
68
69
  "pont-name-field": PontNameField;
69
- "pont-nav-user": PontNavUser;
70
70
  "pont-otp": PontOtp;
71
71
  "pont-otp-resend": PontOtpResend;
72
72
  "pont-passkey-button": PontPasskeyButton;