Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
64617df
docs(feedback): Add more themeables + improve/fix inconsistencies
billyvg Nov 1, 2023
493992c
wip: initial widget api
billyvg Oct 6, 2023
9f81fda
wip: refactor to functions
billyvg Oct 6, 2023
916bb62
lint
billyvg Oct 10, 2023
5f5479e
ref: move css into separate fns
billyvg Oct 10, 2023
a75e600
ref: move Actor into sep file
billyvg Oct 10, 2023
3e71020
ref: use FeedbackComponent and rename methods
billyvg Oct 10, 2023
9cd810b
feat: add success message, error message, move submit logic up into i…
billyvg Oct 10, 2023
bbc26dc
dont typecheck callback fns
billyvg Oct 13, 2023
4097e4b
some svg refactors
billyvg Oct 13, 2023
6a91be8
WIP: Add attachTo configuration
billyvg Oct 16, 2023
fbf4e30
fix cENS
billyvg Oct 16, 2023
fde0896
try/catch all the things, fix dialog not opening, add autoInject option
billyvg Oct 17, 2023
cd8b208
move feedback class to integration.ts, make isAnonymous work, hide fa…
billyvg Oct 17, 2023
725a42f
ref(Form): destructure options in params
billyvg Oct 17, 2023
9e2ce65
ref: move theme/text labels to constants, fix dark mode for svgs
billyvg Oct 17, 2023
9925a87
ref: change/add some callbacks
billyvg Oct 17, 2023
80294ad
ref: fix onDialogOpened, add option for host id
billyvg Oct 17, 2023
e4904d8
feat: change positioning css to use css vars
billyvg Oct 17, 2023
9b94658
meta: lint fixes
billyvg Oct 17, 2023
c5821d9
use isBrowser
billyvg Oct 25, 2023
ff14e8e
ref(feedback): Refactor to better support multiple dialogs (#9305)
billyvg Oct 25, 2023
fc5568e
refactor shadow/host creation
billyvg Oct 25, 2023
6dfc0b5
remove $ prefix, change h to createElement
billyvg Oct 25, 2023
30596d6
createElementNS
billyvg Oct 25, 2023
1a85ce6
test feedback in size limit
billyvg Oct 26, 2023
3b5bc77
v0.0.1-alpha.5
billyvg Oct 26, 2023
d14ae45
export Form props + add Form test
billyvg Oct 26, 2023
6c532d0
test when message turns empty
billyvg Oct 27, 2023
f41ffd1
add actor test + slight refactor, add text label test for form
billyvg Oct 27, 2023
8a820c6
remove referrer
billyvg Oct 27, 2023
3eb963a
explicit props instead of passing options
billyvg Oct 27, 2023
edd2a90
add dialog test
billyvg Oct 27, 2023
e6c09d2
add submit button test
billyvg Oct 27, 2023
5497c1c
add test for SuccessMessage
billyvg Oct 27, 2023
6bfdbf9
lint
billyvg Oct 30, 2023
02d17c9
add createWidget test, refactor
billyvg Oct 30, 2023
9456f37
ref: remove disabled button, instead add better a11y for required field
billyvg Oct 30, 2023
97ca405
update aria attributes + elements should be in getter
billyvg Oct 30, 2023
6b6ca10
fix type for attachTo
billyvg Oct 30, 2023
03d10cd
missing callback
billyvg Oct 30, 2023
99ef589
update tests
billyvg Oct 30, 2023
c488fcd
lint
billyvg Oct 30, 2023
c97d3bb
bump sentry version
billyvg Oct 31, 2023
0897a26
v0.0.1-alpha.6
billyvg Oct 31, 2023
6a951bd
fix(types): Fix optional types for theme
billyvg Oct 31, 2023
5b12a2f
submit/cancel
billyvg Nov 1, 2023
2b12c96
refactor theme names to be even more consistent, add input styles
billyvg Nov 1, 2023
5230bf6
v0.0.1-alpha.7
billyvg Nov 1, 2023
fda4cb2
feat: Add Sentry branding
billyvg Nov 1, 2023
7942039
fix outline
billyvg Nov 2, 2023
6d439d5
fix branding
billyvg Nov 2, 2023
5c2682f
fix darkmode firefox
billyvg Nov 2, 2023
b9a3c9c
v0.0.1-alpha.8
billyvg Nov 2, 2023
9c02d47
v0.0.1-alpha.9
billyvg Nov 2, 2023
cc43a04
review fixes
billyvg Nov 6, 2023
aa31d8d
prettier
billyvg Nov 6, 2023
78e6b60
fix ts
billyvg Nov 6, 2023
ee46ff4
more ts
billyvg Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
explicit props instead of passing options
  • Loading branch information
billyvg committed Nov 6, 2023
commit 3eb963a8412716bdc90c532a5953346d9c7d657c
23 changes: 17 additions & 6 deletions packages/feedback/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
SUBMIT_BUTTON_LABEL,
SUCCESS_MESSAGE_TEXT,
} from './constants';
import type { CreateWidgetOptionOverrides, FeedbackConfigurationWithDefaults, Widget } from './types';
import type {
CreateWidgetOptionOverrides,
FeedbackConfigurationWithDefaults,
FeedbackInternalOptions,
Widget,
} from './types';
import { createActorStyles } from './widget/Actor.css';
import { createShadowHost } from './widget/createShadowHost';
import { createWidget } from './widget/createWidget';
Expand Down Expand Up @@ -44,7 +49,7 @@ export class Feedback implements Integration {
/**
* Feedback configuration options
*/
public options: FeedbackConfigurationWithDefaults;
public options: FeedbackInternalOptions;

/**
* Reference to widget element that is created when autoInject is true
Expand Down Expand Up @@ -187,7 +192,10 @@ export class Feedback implements Integration {
*/
public attachTo(el: Node | string, optionOverrides: CreateWidgetOptionOverrides): Widget | null {
try {
const options = Object.assign({}, this.options, optionOverrides);
const options = {
...this.options,
...optionOverrides,
};

return this._ensureShadowHost<Widget | null>(options, ({ shadow }) => {
const targetEl =
Expand All @@ -213,7 +221,10 @@ export class Feedback implements Integration {
*/
public createWidget(optionOverrides: CreateWidgetOptionOverrides): Widget | null {
try {
return this._createWidget(Object.assign({}, this.options, optionOverrides));
return this._createWidget({
...this.options,
...optionOverrides,
});
} catch (err) {
logger.error(err);
return null;
Expand Down Expand Up @@ -266,7 +277,7 @@ export class Feedback implements Integration {
/**
* Creates a new widget, after ensuring shadow DOM exists
*/
protected _createWidget(options: FeedbackConfigurationWithDefaults): Widget | null {
protected _createWidget(options: FeedbackInternalOptions): Widget | null {
return this._ensureShadowHost<Widget>(options, ({ shadow }) => {
const widget = createWidget({ shadow, options });

Expand All @@ -284,7 +295,7 @@ export class Feedback implements Integration {
* Ensures that shadow DOM exists and is added to the DOM
*/
protected _ensureShadowHost<T>(
options: FeedbackConfigurationWithDefaults,
options: FeedbackInternalOptions,
cb: (createShadowHostResult: ReturnType<typeof createShadowHost>) => T,
): T | null {
let needsAppendHost = false;
Expand Down
39 changes: 31 additions & 8 deletions packages/feedback/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ export interface FeedbackFormData {
name?: string;
}

export interface FeedbackConfigurationWithDefaults {
/**
* General feedback configuration
*/
export interface FeedbackGeneralConfiguration {
/**
* id to use for the main widget container (this will host the shadow DOM)
*/
Expand Down Expand Up @@ -92,8 +95,12 @@ export interface FeedbackConfigurationWithDefaults {
email: string;
name: string;
};
}

// * Color theme customization * //
/**
* Theme-related configuration
*/
export interface FeedbackThemeConfiguration {
/**
* The colorscheme to use. "system" will choose the scheme based on the user's system settings
*/
Expand All @@ -107,9 +114,12 @@ export interface FeedbackConfigurationWithDefaults {
* Dark theme customization, will be merged with default theme values.
*/
themeDark: FeedbackTheme;
// * End of Color theme customization * //
}

// * Text customization * //
/**
* All of the different text labels that can be customized
*/
export interface FeedbackTextConfiguration {
/**
* The label for the Feedback widget button that opens the dialog
*/
Expand Down Expand Up @@ -154,9 +164,12 @@ export interface FeedbackConfigurationWithDefaults {
* Message after feedback was sent successfully
*/
successMessageText: string;
// * End of text customization * //
}

// * Start of Callbacks * //
/**
* The public callbacks available for the feedback integration
*/
export interface FeedbackCallbacks {
/**
* Callback when dialog is closed
*/
Expand All @@ -181,9 +194,19 @@ export interface FeedbackConfigurationWithDefaults {
* Callback when feedback is unsuccessfully submitted
*/
onSubmitError?: () => void;
// * End of Callbacks * //
}

export interface FeedbackConfigurationWithDefaults
extends FeedbackGeneralConfiguration,
FeedbackThemeConfiguration,
FeedbackTextConfiguration,
FeedbackCallbacks {}

/**
* The integration's internal `options` member
*/
export type FeedbackInternalOptions = FeedbackConfigurationWithDefaults;

export interface FeedbackTheme {
/**
* Font family for widget
Expand Down Expand Up @@ -223,7 +246,7 @@ export interface FeedbackTheme {
error: string;
}

export interface CreateWidgetOptionOverrides extends Partial<FeedbackConfigurationWithDefaults> {}
export type CreateWidgetOptionOverrides = Partial<FeedbackConfigurationWithDefaults>;

export interface FeedbackThemes {
dark: FeedbackTheme;
Expand Down
25 changes: 15 additions & 10 deletions packages/feedback/src/widget/Dialog.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import type { FeedbackComponent, FeedbackConfigurationWithDefaults, FeedbackFormData } from '../types';
import type { FeedbackComponent } from '../types';
import type { FormComponentProps } from './Form';
import { Form } from './Form';
import { createElement } from './util/createElement';

interface DialogProps {
defaultName: string;
defaultEmail: string;
onCancel?: (e: Event) => void;
export interface DialogProps extends FormComponentProps {
formTitle: string;
onClosed?: () => void;
onSubmit?: (feedback: FeedbackFormData) => void;
options: FeedbackConfigurationWithDefaults;
}

export interface DialogComponent extends FeedbackComponent<HTMLDialogElement> {
Expand Down Expand Up @@ -52,12 +49,16 @@ export interface DialogComponent extends FeedbackComponent<HTMLDialogElement> {
* Feedback dialog component that has the form
*/
export function Dialog({
formTitle,
showName,
showEmail,
isAnonymous,
defaultName,
defaultEmail,
onClosed,
onCancel,
onSubmit,
options,
...textLabels
}: DialogProps): DialogComponent {
let el: HTMLDialogElement | null = null;

Expand Down Expand Up @@ -106,11 +107,15 @@ export function Dialog({
showError,
hideError,
} = Form({
showEmail,
showName,
isAnonymous,

defaultName,
defaultEmail,
options,
onSubmit,
onCancel,
...textLabels,
});

el = createElement(
Expand All @@ -129,7 +134,7 @@ export function Dialog({
e.stopPropagation();
},
},
createElement('h2', { className: 'dialog__header' }, options.formTitle),
createElement('h2', { className: 'dialog__header' }, formTitle),
formEl,
),
);
Expand Down
51 changes: 21 additions & 30 deletions packages/feedback/src/widget/Form.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { FeedbackComponent, FeedbackConfigurationWithDefaults, FeedbackFormData } from '../types';
import type { FeedbackComponent, FeedbackFormData, FeedbackInternalOptions, FeedbackTextConfiguration } from '../types';
import { SubmitButton } from './SubmitButton';
import { createElement } from './util/createElement';

export interface FormComponentProps {
export interface FormComponentProps
extends Pick<
FeedbackInternalOptions,
| 'showName'
| 'showEmail'
| 'isAnonymous'
| Exclude<keyof FeedbackTextConfiguration, 'buttonLabel' | 'formTitle' | 'successMessageText'>
> {
/**
* A default name value to render the input with. Empty strings are ok.
*/
Expand All @@ -11,20 +18,6 @@ export interface FormComponentProps {
* A default email value to render the input with. Empty strings are ok.
*/
defaultEmail: string;
options: Pick<
FeedbackConfigurationWithDefaults,
| 'showName'
| 'showEmail'
| 'isAnonymous'
| 'nameLabel'
| 'namePlaceholder'
| 'emailLabel'
| 'emailPlaceholder'
| 'messageLabel'
| 'messagePlaceholder'
| 'cancelButtonLabel'
| 'submitButtonLabel'
>;
onCancel?: (e: Event) => void;
onSubmit?: (feedback: FeedbackFormData) => void;
}
Expand Down Expand Up @@ -63,20 +56,18 @@ function retrieveStringValue(formData: FormData, key: string): string {
* Creates the form element
*/
export function Form({
options: {
showName,
showEmail,
isAnonymous,

nameLabel,
namePlaceholder,
emailLabel,
emailPlaceholder,
messageLabel,
messagePlaceholder,
cancelButtonLabel,
submitButtonLabel,
},
nameLabel,
namePlaceholder,
emailLabel,
emailPlaceholder,
messageLabel,
messagePlaceholder,
cancelButtonLabel,
submitButtonLabel,

showName,
showEmail,
isAnonymous,

defaultName,
defaultEmail,
Expand Down
4 changes: 2 additions & 2 deletions packages/feedback/src/widget/createShadowHost.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { WINDOW } from '@sentry/browser';
import { logger } from '@sentry/utils';

import type { FeedbackConfigurationWithDefaults } from '../types';
import type { FeedbackInternalOptions } from '../types';
import { createDialogStyles } from './Dialog.css';
import { createMainStyles } from './Main.css';

interface CreateShadowHostParams {
options: FeedbackConfigurationWithDefaults;
options: FeedbackInternalOptions;
}

/**
Expand Down
17 changes: 14 additions & 3 deletions packages/feedback/src/widget/createWidget.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getCurrentHub } from '@sentry/core';
import { logger } from '@sentry/utils';

import type { FeedbackConfigurationWithDefaults, FeedbackFormData, Widget } from '../types';
import type { FeedbackFormData, FeedbackInternalOptions, Widget } from '../types';
import { handleFeedbackSubmit } from '../util/handleFeedbackSubmit';
import type { ActorComponent } from './Actor';
import { Actor } from './Actor';
Expand All @@ -11,7 +11,7 @@ import { SuccessMessage } from './SuccessMessage';

interface CreateWidgetParams {
shadow: ShadowRoot;
options: FeedbackConfigurationWithDefaults;
options: FeedbackInternalOptions;
attachTo?: Node;
}

Expand Down Expand Up @@ -124,6 +124,18 @@ export function createWidget({ shadow, options, attachTo }: CreateWidgetParams):
const user = scope && scope.getUser();

dialog = Dialog({
showName: options.showName,
showEmail: options.showEmail,
isAnonymous: options.isAnonymous,
formTitle: options.formTitle,
cancelButtonLabel: options.cancelButtonLabel,
submitButtonLabel: options.submitButtonLabel,
emailLabel: options.emailLabel,
emailPlaceholder: options.emailPlaceholder,
messageLabel: options.messageLabel,
messagePlaceholder: options.messagePlaceholder,
nameLabel: options.nameLabel,
namePlaceholder: options.namePlaceholder,
defaultName: (userKey && user && user[userKey.name]) || '',
defaultEmail: (userKey && user && user[userKey.email]) || '',
onClosed: () => {
Expand All @@ -135,7 +147,6 @@ export function createWidget({ shadow, options, attachTo }: CreateWidgetParams):
showActor();
},
onSubmit: _handleFeedbackSubmit,
options,
});

shadow.appendChild(dialog.el);
Expand Down
Loading