Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sendbird/react-uikit-message-template-view

Package Overview
Dependencies
Maintainers
0
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sendbird/react-uikit-message-template-view - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

dist/components/RMTCarousel/index.d.ts

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

## [0.0.3](https://github.com/sendbird/sendbird-uikit-core-ts/compare/v0.0.2...v0.0.3) (2024-10-08)
### Features
* added highlight interface to MessageProvider ([9b9abd0](https://github.com/sendbird/sendbird-uikit-core-ts/commit/9b9abd0a4d39d72beda8a88f4f2b543b4bbd764d))
## [0.0.2](https://github.com/sendbird/sendbird-uikit-core-ts/compare/v0.0.1-alpha.79...v0.0.2) (2024-09-20)

@@ -8,0 +19,0 @@

13

dist/context/MessageContextProvider.d.ts
import React from 'react';
import type { BaseMessage } from '@sendbird/chat/message';
import type { Action } from '@sendbird/uikit-message-template';
import type { Action, ComponentsUnion } from '@sendbird/uikit-message-template';
export type MessageContextProps = React.PropsWithChildren<{

@@ -9,6 +9,15 @@ message: BaseMessage;

handlePredefinedAction?(event: React.SyntheticEvent, action: Action, message: BaseMessage): null;
/**
* @internal DO NOT USE THIS, this is for internal use only.
* This interface allows for detecting and injecting highlight styles into areas that include variables.
*/
highlight?: {
getContainerClassName?(raw: ComponentsUnion['properties']): string;
getContainerInlineStyle?(raw: ComponentsUnion['properties']): React.CSSProperties;
renderText?(text: string): React.ReactNode;
};
}>;
export type MessageContextInterface = Omit<MessageContextProps, 'children'>;
declare const MessageProvider: (props: MessageContextProps) => React.JSX.Element;
declare const MessageProvider: ({ message, handleWebAction, handleCustomAction, handlePredefinedAction, highlight, children, }: MessageContextProps) => React.JSX.Element;
declare const useMessageContext: () => MessageContextInterface;
export { MessageProvider, useMessageContext };

6

dist/context/MessageContextProvider.js

@@ -5,4 +5,3 @@ // create a context provider for MessageComponent

const MessageContext = React.createContext(null);
const MessageProvider = (props) => {
const { message, handleWebAction, handleCustomAction, handlePredefinedAction, children } = props;
const MessageProvider = ({ message, handleWebAction, handleCustomAction, handlePredefinedAction, highlight, children, }) => {
const value = React.useMemo(() => ({

@@ -13,3 +12,4 @@ message,

handlePredefinedAction,
}), [message === null || message === void 0 ? void 0 : message.updatedAt]);
highlight,
}), [message === null || message === void 0 ? void 0 : message.updatedAt, highlight === null || highlight === void 0 ? void 0 : highlight.getContainerClassName, highlight === null || highlight === void 0 ? void 0 : highlight.getContainerInlineStyle, highlight === null || highlight === void 0 ? void 0 : highlight.renderText]);
return React.createElement(MessageContext.Provider, { value: value }, children);

@@ -16,0 +16,0 @@ };

@@ -49,2 +49,5 @@ import { ComponentType, FlexSizeSpecValue, Layout, MediaContentMode, alignInFlex, defaultProperties, } from '@sendbird/uikit-message-template';

else if (width.type === 'fixed' && width.value >= 0) {
if (parentLayout === Layout.Row) {
style['flexShrink'] = 0;
}
style['width'] = width.value;

@@ -59,2 +62,5 @@ }

else if (height.type === 'fixed' && height.value >= 0) {
if (parentLayout === Layout.Column) {
style['flexShrink'] = 0;
}
style['height'] = height.value;

@@ -61,0 +67,0 @@ }

@@ -10,3 +10,4 @@ import React from 'react';

elementId?: string;
inlineStyle?: React.CSSProperties;
}>;
export declare const ActionHandler: ({ children, props, className, style }: ActionHandlerProps) => React.JSX.Element;
export declare const ActionHandler: ({ children, props, className, style, inlineStyle }: ActionHandlerProps) => React.JSX.Element;

@@ -16,20 +16,5 @@ var __rest = (this && this.__rest) || function (s, e) {

import { useRecalculateWidth } from '../hook/useRecalculationSize';
const hasValidUrlProtocol = (url = '') => ['http://', 'https://', 'ftp://'].some((protocol) => url.startsWith(protocol));
/**
* @param url - url to be checked
* @returns url with http:// protocol if it doesn't have any protocol
* @example
* returnUrl('www.sendbird.com') // returns 'http://www.sendbird.com'
* returnUrl('https://www.sendbird.com') // returns 'https://www.sendbird.com'
* returnUrl('ftp://www.sendbird.com') // returns 'ftp://www.sendbird.com'
* returnUrl('sendbird.com') // returns 'https://sendbird.com'
**/
const returnUrl = (url = '') => {
if (hasValidUrlProtocol(url)) {
return url;
}
return `https://${url}`;
};
import { clx, getValidURL } from '../util';
// todo: semantic html here is not perfect, need to revisit. Same for Button
export const ActionHandler = ({ children, props, className, style }) => {
export const ActionHandler = ({ children, props, className, style, inlineStyle }) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;

@@ -52,3 +37,3 @@ const { recalculatedStyle, elemRef } = useRecalculateWidth({ style, props });

else {
(_c = window === null || window === void 0 ? void 0 : window.open(returnUrl((_b = props === null || props === void 0 ? void 0 : props.action) === null || _b === void 0 ? void 0 : _b.data), '_blank', 'noopener noreferrer')) === null || _c === void 0 ? void 0 : _c.focus();
(_c = window === null || window === void 0 ? void 0 : window.open(getValidURL((_b = props === null || props === void 0 ? void 0 : props.action) === null || _b === void 0 ? void 0 : _b.data), '_blank', 'noopener noreferrer')) === null || _c === void 0 ? void 0 : _c.focus();
}

@@ -61,3 +46,3 @@ }

else {
(_f = window === null || window === void 0 ? void 0 : window.open(returnUrl((_e = props === null || props === void 0 ? void 0 : props.action) === null || _e === void 0 ? void 0 : _e.data), '_blank', 'noopener noreferrer')) === null || _f === void 0 ? void 0 : _f.focus();
(_f = window === null || window === void 0 ? void 0 : window.open(getValidURL((_e = props === null || props === void 0 ? void 0 : props.action) === null || _e === void 0 ? void 0 : _e.data), '_blank', 'noopener noreferrer')) === null || _f === void 0 ? void 0 : _f.focus();
}

@@ -70,6 +55,6 @@ }

if (props.type === ComponentType.TextButton) {
return (React.createElement("button", { className: clx(className, borderClass), "data-sb-template-id": props.elementId, style: Object.assign(Object.assign({}, style), paddingStyles), onClick: onClick }, children));
return (React.createElement("button", { className: clx(className, borderClass), "data-sb-template-id": props.elementId, style: Object.assign(Object.assign(Object.assign({}, style), paddingStyles), inlineStyle), onClick: onClick }, children));
}
const { display, flexDirection, justifyContent, alignItems, objectFit } = recalculatedStyle, wrapperStyles = __rest(recalculatedStyle, ["display", "flexDirection", "justifyContent", "alignItems", "objectFit"]);
return (React.createElement("div", { ref: elemRef, className: clx(className, borderClass, props.action && 'sb-message-template__action'), "data-sb-template-id": props.elementId, style: wrapperStyles, onClick: onClick },
return (React.createElement("div", { ref: elemRef, className: clx(className, borderClass, props.action && 'sb-message-template__action'), "data-sb-template-id": props.elementId, style: Object.assign(Object.assign({}, wrapperStyles), inlineStyle), onClick: onClick },
React.createElement("div", { style: Object.assign({ display,

@@ -81,4 +66,1 @@ flexDirection,

};
function clx(...names) {
return names.filter((it) => !!it).join(' ');
}
import React from 'react';
import { type MessageTemplateProps } from '@sendbird/uikit-message-template';
import '../index.css';
import { ReactParsedProperties } from '../styles';
export declare const renderer: import("@sendbird/uikit-message-template").Renderer<ReactParsedProperties>;
export declare const parser: import("@sendbird/uikit-message-template").Parser<ReactParsedProperties>;
export declare const MessageTemplate: ({ templateVersion, templateItems, parentLayout, }: MessageTemplateProps) => React.JSX.Element;
export { parser } from './parser';
export { renderer } from './renderer';
export declare const MessageTemplate: ({ templateVersion, templateItems, parentLayout, }: import("@sendbird/uikit-message-template").MessageTemplateProps) => React.JSX.Element;
import React from 'react';
import { FlexSizeSpecValue, Layout, createMessageTemplate, createParser, createRenderer, defaultProperties, } from '@sendbird/uikit-message-template';
import { Carousel } from '../components/Carousel';
import ReactMessageTemplateImage from '../components/ReactMessageTemplateImage';
import { createMessageTemplate } from '@sendbird/uikit-message-template';
import '../index.css';
import { getDefaultStyles, setAlign, setImageAspectRatio, setImageStyle, setTextAlign, setTextStyle, setViewProps, webkitLineClampStyles, } from '../styles';
import { ActionHandler } from './ActionHandler';
/**
* Text that is fixed or fill parent should be wrapped in a div with max-width: 100% and max-height: 100%
* This is to prevent text from overflowing the padding of the container
*/
function isFixedOrFill(view) {
var _a, _b, _c, _d;
const heightType = (_a = view === null || view === void 0 ? void 0 : view.height) === null || _a === void 0 ? void 0 : _a.type;
const widthType = (_b = view === null || view === void 0 ? void 0 : view.width) === null || _b === void 0 ? void 0 : _b.type;
const isFixedDiamension = heightType === 'fixed' || widthType === 'fixed';
const isFill = (heightType === 'flex' && ((_c = view === null || view === void 0 ? void 0 : view.height) === null || _c === void 0 ? void 0 : _c.value) === FlexSizeSpecValue.FillParent) ||
(widthType === 'flex' && ((_d = view === null || view === void 0 ? void 0 : view.width) === null || _d === void 0 ? void 0 : _d.value) === FlexSizeSpecValue.FillParent);
return isFixedDiamension || isFill;
}
function convertNewlinesToBr(text) {
return text.split('\n').map((line, index) => (React.createElement(React.Fragment, { key: index },
line,
React.createElement("br", null))));
}
function renderText(view) {
const { text, maxTextLines } = view;
const isToBeWrapped = isFixedOrFill(view);
const hasMaxLines = typeof maxTextLines === 'number' && maxTextLines > 0;
const convertedText = convertNewlinesToBr(text);
if (hasMaxLines || isToBeWrapped) {
const wrapperStyling = Object.assign(Object.assign({}, ((hasMaxLines || isToBeWrapped) && { maxWidth: '100%' })), (isToBeWrapped && { maxHeight: '100%', overflow: 'hidden' }));
return (React.createElement("div", { style: wrapperStyling }, hasMaxLines ? React.createElement("div", { style: webkitLineClampStyles(maxTextLines) }, convertedText) : convertedText));
}
return hasMaxLines ? React.createElement("div", { style: webkitLineClampStyles(maxTextLines) }, convertedText) : convertedText;
}
export const renderer = createRenderer({
views: {
box(props) {
return (React.createElement(ActionHandler, { className: "sb-message-template__box", elementId: props.elementId, style: props.parsedProperties, props: props }, props.children));
},
text(props) {
return (React.createElement(ActionHandler, { className: "sb-message-template__text", elementId: props.elementId, style: props.parsedProperties, props: props }, renderText(props)));
},
image(props) {
var _a;
// todo: add image backup
return (React.createElement(ActionHandler, { className: "sb-message-template__image-container", elementId: props.elementId, style: props.parsedProperties, props: props },
React.createElement(ReactMessageTemplateImage, { className: "sb-message-template__image", alt: "image", src: props.imageUrl, style: { width: '100%', height: '100%', aspectRatio: 'inherit', objectFit: 'inherit' }, tintColor: (_a = props.imageStyle) === null || _a === void 0 ? void 0 : _a.tintColor, metaData: props.metaData })));
},
textButton(props) {
return (React.createElement(ActionHandler, { className: "sb-message-template__text-button", elementId: props.elementId, style: props.parsedProperties, props: props }, renderText(Object.assign({ maxTextLines: defaultProperties.textButton.maxTextLines }, props))));
},
imageButton(props) {
var _a;
return (React.createElement(ActionHandler, { className: "sb-message-template__image-container sb-message-template__image-button", elementId: props.elementId, style: props.parsedProperties, props: props },
React.createElement(ReactMessageTemplateImage, { className: "sb-message-template__image", alt: "image-button", src: props.imageUrl, style: { width: '100%', height: '100%', aspectRatio: 'inherit', objectFit: 'inherit' }, tintColor: (_a = props.imageStyle) === null || _a === void 0 ? void 0 : _a.tintColor, metaData: props.metaData })));
},
carouselView(props) {
var _a, _b;
return (React.createElement(Carousel, { maxChildWidth: (_a = props.carouselStyle) === null || _a === void 0 ? void 0 : _a.maxChildWidth, spacing: (_b = props.carouselStyle) === null || _b === void 0 ? void 0 : _b.spacing, style: props.parsedProperties }, props.children));
},
},
});
export const parser = createParser({
mapBoxProps(props, options) {
const styles = getDefaultStyles();
setViewProps(styles, props, options);
setAlign(styles, props.layout, props.align);
return styles;
},
mapTextProps(props, options) {
var _a;
const styles = getDefaultStyles({ whiteSpace: 'pre-line', wordBreak: 'break-word' });
// Better not set flex 1 to text
setViewProps(styles, props, options);
setTextStyle(styles, props, options);
setAlign(styles, Layout.Row, props.align);
setTextAlign(styles, (_a = props.align) === null || _a === void 0 ? void 0 : _a.horizontal);
return styles;
},
mapImageProps(props, options) {
const styles = getDefaultStyles();
setViewProps(styles, props, options);
setImageStyle(styles, props.imageStyle);
setImageAspectRatio(styles, props);
return styles;
},
mapTextButtonProps(props, options) {
const styles = getDefaultStyles({ whiteSpace: 'pre-line', alignItems: 'center', justifyContent: 'center' });
setViewProps(styles, props, options);
setTextStyle(styles, props, options);
return styles;
},
mapImageButtonProps(props, options) {
const styles = getDefaultStyles();
setViewProps(styles, props, options);
setImageStyle(styles, props.imageStyle);
setImageAspectRatio(styles, props);
return styles;
},
mapCarouselProps(props, options) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const styles = getDefaultStyles();
setViewProps(styles, props, options);
styles['paddingBlockStart'] = (_b = (_a = props.viewStyle) === null || _a === void 0 ? void 0 : _a.padding) === null || _b === void 0 ? void 0 : _b.top;
styles['paddingBlockEnd'] = (_d = (_c = props.viewStyle) === null || _c === void 0 ? void 0 : _c.padding) === null || _d === void 0 ? void 0 : _d.bottom;
styles['paddingInlineStart'] = (_f = (_e = props.viewStyle) === null || _e === void 0 ? void 0 : _e.padding) === null || _f === void 0 ? void 0 : _f.left;
styles['paddingInlineEnd'] = (_h = (_g = props.viewStyle) === null || _g === void 0 ? void 0 : _g.padding) === null || _h === void 0 ? void 0 : _h.right;
return styles;
},
});
import { parser } from './parser';
import { renderer } from './renderer';
export { parser } from './parser';
export { renderer } from './renderer';
export const { MessageTemplate } = createMessageTemplate({

@@ -117,9 +12,4 @@ renderer,

Container: ({ children, className }) => {
return (React.createElement("div", { className: `sb-message-template__parent ${className}`, style: {
display: 'flex',
flexDirection: 'column',
maxWidth: 400,
marginBlockEnd: 24,
} }, children));
return (React.createElement("div", { className: `sb-message-template__parent ${className}`, style: { display: 'flex', flexDirection: 'column', maxWidth: 400, marginBlockEnd: 24 } }, children));
},
});

@@ -9,1 +9,13 @@ import { SizeSpec, View } from '@sendbird/uikit-message-template';

export declare const isNumber: (val?: string | number | null) => val is number;
export declare const clx: (...names: (undefined | string)[]) => string;
export declare const hasValidURLProtocol: (url?: string) => boolean;
/**
* @param url - url to be checked
* @returns url with http:// protocol if it doesn't have any protocol
* @example
* returnUrl('www.sendbird.com') // returns 'http://www.sendbird.com'
* returnUrl('https://www.sendbird.com') // returns 'https://www.sendbird.com'
* returnUrl('ftp://www.sendbird.com') // returns 'ftp://www.sendbird.com'
* returnUrl('sendbird.com') // returns 'https://sendbird.com'
**/
export declare const getValidURL: (url?: string) => string;

@@ -29,1 +29,21 @@ import { ComponentType, FlexSizeSpecValue } from '@sendbird/uikit-message-template';

};
export const clx = (...names) => {
return names.filter((it) => !!it).join(' ');
};
export const hasValidURLProtocol = (url = '') => {
return ['http://', 'https://', 'ftp://'].some((protocol) => url.startsWith(protocol));
};
/**
* @param url - url to be checked
* @returns url with http:// protocol if it doesn't have any protocol
* @example
* returnUrl('www.sendbird.com') // returns 'http://www.sendbird.com'
* returnUrl('https://www.sendbird.com') // returns 'https://www.sendbird.com'
* returnUrl('ftp://www.sendbird.com') // returns 'ftp://www.sendbird.com'
* returnUrl('sendbird.com') // returns 'https://sendbird.com'
**/
export const getValidURL = (url = '') => {
if (hasValidURLProtocol(url))
return url;
return `https://${url}`;
};
{
"name": "@sendbird/react-uikit-message-template-view",
"version": "0.0.2",
"version": "0.0.3",
"publishConfig": {

@@ -43,5 +43,5 @@ "registry": "https://registry.npmjs.org/",

"dependencies": {
"@sendbird/uikit-message-template": "^0.0.2"
"@sendbird/uikit-message-template": "^0.0.3"
},
"gitHead": "dcd044768de8cca0a69e7bbb6a33c95ce6223972"
"gitHead": "14d7cfa0fe6e0311fdc46b00a44468a0856cd435"
}

@@ -98,2 +98,5 @@ import type { CSSProperties } from 'react';

} else if (width.type === 'fixed' && width.value >= 0) {
if (parentLayout === Layout.Row) {
style['flexShrink'] = 0;
}
style['width'] = width.value;

@@ -108,2 +111,5 @@ }

} else if (height.type === 'fixed' && height.value >= 0) {
if (parentLayout === Layout.Column) {
style['flexShrink'] = 0;
}
style['height'] = height.value;

@@ -110,0 +116,0 @@ }

@@ -38,1 +38,23 @@ import { ComponentType, FlexSizeSpecValue, SizeSpec, View } from '@sendbird/uikit-message-template';

};
export const clx = (...names: (undefined | string)[]) => {
return names.filter((it) => !!it).join(' ');
};
export const hasValidURLProtocol = (url = '') => {
return ['http://', 'https://', 'ftp://'].some((protocol) => url.startsWith(protocol));
};
/**
* @param url - url to be checked
* @returns url with http:// protocol if it doesn't have any protocol
* @example
* returnUrl('www.sendbird.com') // returns 'http://www.sendbird.com'
* returnUrl('https://www.sendbird.com') // returns 'https://www.sendbird.com'
* returnUrl('ftp://www.sendbird.com') // returns 'ftp://www.sendbird.com'
* returnUrl('sendbird.com') // returns 'https://sendbird.com'
**/
export const getValidURL = (url = '') => {
if (hasValidURLProtocol(url)) return url;
return `https://${url}`;
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc