diff --git a/apps/web/package.json b/apps/web/package.json index 5543aede43f..d9ef0a3e66d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -61,6 +61,7 @@ "@mantine/spotlight": "^5.7.1", "@monaco-editor/react": "^4.6.0", "@novu/design-system": "workspace:*", + "@novu/js": "workspace:*", "@novu/notification-center": "workspace:*", "@novu/novui": "workspace:*", "@novu/shared": "workspace:*", diff --git a/apps/web/src/components/workflow/preview/in-app/v2/InboxPreviewContent.tsx b/apps/web/src/components/workflow/preview/in-app/v2/InboxPreviewContent.tsx index 5e7be6f7a85..87084311a6e 100644 --- a/apps/web/src/components/workflow/preview/in-app/v2/InboxPreviewContent.tsx +++ b/apps/web/src/components/workflow/preview/in-app/v2/InboxPreviewContent.tsx @@ -2,6 +2,7 @@ import { Text, Title } from '@novu/novui'; import { css, cva } from '@novu/novui/css'; import { IconArrowDropDown, IconMoreHoriz, IconSettings } from '@novu/novui/icons'; import { Center, Flex, HStack, Stack } from '@novu/novui/jsx'; +import { parseMarkdownIntoTokens } from '@novu/js/internal'; import { ParsedPreviewStateType } from '../../../../../pages/templates/hooks/usePreviewInAppTemplate'; import { SkeletonStyled } from '../Content.styles'; import { InboxAvatar } from './InboxAvatar'; @@ -22,6 +23,31 @@ export const INBOX_TOKENS = { 'Inbox/margin/message/txt/buttons': '1rem', } as const; +const renderText = (text?: string) => { + if (!text) { + return null; + } + + const tokens = parseMarkdownIntoTokens(text); + + return tokens.map((token, index) => { + if (token.type === 'bold') { + return ( + + ); + } + + return token.content; + }); +}; + export function InboxPreviewContent({ isPreviewLoading, parsedPreviewState, @@ -158,17 +184,13 @@ export function InboxPreviewContent({ - - {parsedPreviewState.subject} - + {renderText(parsedPreviewState.subject)} 5 min - - {parsedPreviewState.content} - + {renderText(parsedPreviewState.content)} {/* Actions Section */} diff --git a/packages/js/internal/package.json b/packages/js/internal/package.json new file mode 100644 index 00000000000..5f199a72b2f --- /dev/null +++ b/packages/js/internal/package.json @@ -0,0 +1,5 @@ +{ + "main": "../dist/cjs/internal/index.cjs", + "module": "../dist/esm/internal/index.mjs", + "types": "../dist/cjs/internal/index.d.ts" +} diff --git a/packages/js/package.json b/packages/js/package.json index a28bd70741c..ef495a9ca5e 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -38,6 +38,16 @@ "types": "./dist/cjs/themes/index.js", "default": "./dist/cjs/themes/index.d.ts" } + }, + "./internal": { + "import": { + "types": "./dist/esm/internal/index.d.mts", + "default": "./dist/esm/internal/index.mjs" + }, + "require": { + "types": "./dist/cjs/internal/index.js", + "default": "./dist/cjs/internal/index.d.ts" + } } }, "files": [ @@ -47,7 +57,8 @@ "dist/novu.min.js", "dist/novu.min.js.gz", "ui/**/*", - "themes/**/*" + "themes/**/*", + "internal/**/*" ], "sideEffects": false, "private": false, diff --git a/packages/js/src/ui/components/elements/Markdown.tsx b/packages/js/src/ui/components/elements/Markdown.tsx index 237ebd7115e..59fb136e78b 100644 --- a/packages/js/src/ui/components/elements/Markdown.tsx +++ b/packages/js/src/ui/components/elements/Markdown.tsx @@ -1,44 +1,8 @@ import { createMemo, For, JSX } from 'solid-js'; import { useStyle } from '../../helpers'; +import { parseMarkdownIntoTokens } from '../../internal'; import { AppearanceKey } from '../../types'; -interface Token { - type: 'bold' | 'text'; - content: string; -} - -const parseMarkdownIntoTokens = (text: string): Token[] => { - const tokens: Token[] = []; - let buffer = ''; - let inBold = false; - - for (let i = 0; i < text.length; i += 1) { - // Check if it's an escaped character - if (text[i] === '\\' && text[i + 1] === '*') { - buffer += '*'; - i += 1; - } - // Check for bold marker ** - else if (text[i] === '*' && text[i + 1] === '*') { - if (buffer) { - tokens.push({ type: inBold ? 'bold' : 'text', content: buffer }); - buffer = ''; - } - inBold = !inBold; - i += 1; - } else { - buffer += text[i]; - } - } - - // Push any remaining buffered text as a token - if (buffer) { - tokens.push({ type: inBold ? 'bold' : 'text', content: buffer }); - } - - return tokens; -}; - const Bold = (props: { children?: JSX.Element; appearanceKey?: AppearanceKey }) => { const style = useStyle(); diff --git a/packages/js/src/ui/internal/index.ts b/packages/js/src/ui/internal/index.ts new file mode 100644 index 00000000000..76947b3dda3 --- /dev/null +++ b/packages/js/src/ui/internal/index.ts @@ -0,0 +1 @@ +export * from './parseMarkdown'; diff --git a/packages/js/src/ui/internal/parseMarkdown.tsx b/packages/js/src/ui/internal/parseMarkdown.tsx new file mode 100644 index 00000000000..a5056d19796 --- /dev/null +++ b/packages/js/src/ui/internal/parseMarkdown.tsx @@ -0,0 +1,36 @@ +export interface Token { + type: 'bold' | 'text'; + content: string; +} + +export const parseMarkdownIntoTokens = (text: string): Token[] => { + const tokens: Token[] = []; + let buffer = ''; + let inBold = false; + + for (let i = 0; i < text.length; i += 1) { + // Check if it's an escaped character + if (text[i] === '\\' && text[i + 1] === '*') { + buffer += '*'; + i += 1; + } + // Check for bold marker ** + else if (text[i] === '*' && text[i + 1] === '*') { + if (buffer) { + tokens.push({ type: inBold ? 'bold' : 'text', content: buffer }); + buffer = ''; + } + inBold = !inBold; + i += 1; + } else { + buffer += text[i]; + } + } + + // Push any remaining buffered text as a token + if (buffer) { + tokens.push({ type: inBold ? 'bold' : 'text', content: buffer }); + } + + return tokens; +}; diff --git a/packages/js/tsup.config.ts b/packages/js/tsup.config.ts index 31a189edca2..fb8fb5b7274 100644 --- a/packages/js/tsup.config.ts +++ b/packages/js/tsup.config.ts @@ -48,6 +48,7 @@ const baseModuleConfig: Options = { index: './src/index.ts', 'ui/index': './src/ui/index.ts', 'themes/index': './src/ui/themes/index.ts', + 'internal/index': './src/ui/internal/index.ts', }, }; diff --git a/playground/nextjs/src/pages/index.tsx b/playground/nextjs/src/pages/index.tsx index 65c2e92f77f..bd366d430f8 100644 --- a/playground/nextjs/src/pages/index.tsx +++ b/playground/nextjs/src/pages/index.tsx @@ -1,6 +1,7 @@ +import { Inbox } from '@novu/react'; +import { dark } from '@novu/react/themes'; import Title from '@/components/Title'; import { novuConfig } from '@/utils/config'; -import { Inbox } from '@novu/react'; export default function Home() { return ( @@ -14,6 +15,9 @@ export default function Home() { '6697c185607852e9104daf33': 'My workflow in other language', // key is workflow id }, }} + appearance={{ + baseTheme: dark, + }} /> ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e124b9fb374..fe21848e7cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -969,6 +969,9 @@ importers: '@novu/design-system': specifier: workspace:* version: link:../../libs/design-system + '@novu/js': + specifier: workspace:* + version: link:../../packages/js '@novu/notification-center': specifier: workspace:* version: link:../../packages/notification-center @@ -34012,8 +34015,8 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.575.0(@aws-sdk/client-sts@3.575.0) - '@aws-sdk/client-sts': 3.575.0 + '@aws-sdk/client-sso-oidc': 3.575.0 + '@aws-sdk/client-sts': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) '@aws-sdk/core': 3.575.0 '@aws-sdk/credential-provider-node': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0)(@aws-sdk/client-sts@3.575.0) '@aws-sdk/middleware-host-header': 3.575.0 @@ -34214,8 +34217,8 @@ snapshots: '@aws-crypto/sha1-browser': 3.0.0 '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.575.0(@aws-sdk/client-sts@3.575.0) - '@aws-sdk/client-sts': 3.575.0 + '@aws-sdk/client-sso-oidc': 3.575.0 + '@aws-sdk/client-sts': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) '@aws-sdk/core': 3.575.0 '@aws-sdk/credential-provider-node': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0)(@aws-sdk/client-sts@3.575.0) '@aws-sdk/middleware-bucket-endpoint': 3.575.0 @@ -34441,11 +34444,11 @@ snapshots: - aws-crt optional: true - '@aws-sdk/client-sso-oidc@3.575.0(@aws-sdk/client-sts@3.575.0)': + '@aws-sdk/client-sso-oidc@3.575.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.575.0 + '@aws-sdk/client-sts': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) '@aws-sdk/core': 3.575.0 '@aws-sdk/credential-provider-node': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0)(@aws-sdk/client-sts@3.575.0) '@aws-sdk/middleware-host-header': 3.575.0 @@ -34484,7 +34487,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.7.0 transitivePeerDependencies: - - '@aws-sdk/client-sts' - aws-crt '@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)': @@ -34869,11 +34871,11 @@ snapshots: - aws-crt optional: true - '@aws-sdk/client-sts@3.575.0': + '@aws-sdk/client-sts@3.575.0(@aws-sdk/client-sso-oidc@3.575.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.575.0(@aws-sdk/client-sts@3.575.0) + '@aws-sdk/client-sso-oidc': 3.575.0 '@aws-sdk/core': 3.575.0 '@aws-sdk/credential-provider-node': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0)(@aws-sdk/client-sts@3.575.0) '@aws-sdk/middleware-host-header': 3.575.0 @@ -34912,6 +34914,7 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.7.0 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt '@aws-sdk/client-sts@3.637.0': @@ -35141,7 +35144,7 @@ snapshots: '@aws-sdk/credential-provider-ini@3.575.0(@aws-sdk/client-sso-oidc@3.575.0)(@aws-sdk/client-sts@3.575.0)': dependencies: - '@aws-sdk/client-sts': 3.575.0 + '@aws-sdk/client-sts': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) '@aws-sdk/credential-provider-env': 3.575.0 '@aws-sdk/credential-provider-process': 3.575.0 '@aws-sdk/credential-provider-sso': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) @@ -35452,7 +35455,7 @@ snapshots: '@aws-sdk/credential-provider-web-identity@3.575.0(@aws-sdk/client-sts@3.575.0)': dependencies: - '@aws-sdk/client-sts': 3.575.0 + '@aws-sdk/client-sts': 3.575.0(@aws-sdk/client-sso-oidc@3.575.0) '@aws-sdk/types': 3.575.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 @@ -35973,7 +35976,7 @@ snapshots: '@aws-sdk/token-providers@3.575.0(@aws-sdk/client-sso-oidc@3.575.0)': dependencies: - '@aws-sdk/client-sso-oidc': 3.575.0(@aws-sdk/client-sts@3.575.0) + '@aws-sdk/client-sso-oidc': 3.575.0 '@aws-sdk/types': 3.575.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 @@ -35982,7 +35985,7 @@ snapshots: '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.575.0)': dependencies: - '@aws-sdk/client-sso-oidc': 3.575.0(@aws-sdk/client-sts@3.575.0) + '@aws-sdk/client-sso-oidc': 3.575.0 '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4