@webority/mobile-ui 0.110.3 → 0.111.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.
- package/dist/canvas-kit/kit.js +7562 -7549
- package/dist/canvas-kit/manifest.json +2 -3
- package/dist/canvas-kit/release.json +6 -6
- package/lib/commonjs/components/Markdown/parse.js +1 -1
- package/lib/commonjs/components/MessageBubble/MessageBubble.js +1 -1
- package/lib/module/components/Markdown/parse.js +1 -1
- package/lib/module/components/MessageBubble/MessageBubble.js +1 -1
- package/lib/typescript/commonjs/components/Markdown/parse.d.ts +5 -0
- package/lib/typescript/commonjs/components/MessageBubble/MessageBubble.d.ts +4 -1
- package/lib/typescript/module/components/Markdown/parse.d.ts +5 -0
- package/lib/typescript/module/components/MessageBubble/MessageBubble.d.ts +4 -1
- package/package.json +7 -7
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"kind": "WeborityPhone",
|
|
3
3
|
"library": {
|
|
4
4
|
"name": "@webority/mobile-ui",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.111.0"
|
|
6
6
|
},
|
|
7
7
|
"rendererProtocolVersion": 13,
|
|
8
8
|
"platform": "Phone",
|
|
@@ -9687,8 +9687,7 @@
|
|
|
9687
9687
|
"name": "markdown",
|
|
9688
9688
|
"type": "boolean",
|
|
9689
9689
|
"required": false,
|
|
9690
|
-
"description": "Draws the text as Markdown. Ignored when the bubble has children."
|
|
9691
|
-
"default": false
|
|
9690
|
+
"description": "Draws the text as Markdown. Defaults to on for theirs and off for mine; an error draws plain text. Ignored when the bubble has children."
|
|
9692
9691
|
},
|
|
9693
9692
|
{
|
|
9694
9693
|
"name": "replyTo",
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webority-phone",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.111.0",
|
|
4
4
|
"platform": "Phone",
|
|
5
5
|
"kitModuleVersion": 2,
|
|
6
6
|
"rendererProtocolVersion": 13,
|
|
7
7
|
"library": {
|
|
8
8
|
"name": "@webority/mobile-ui",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.111.0"
|
|
10
10
|
},
|
|
11
11
|
"files": {
|
|
12
12
|
"manifest.json": {
|
|
13
|
-
"sha256": "
|
|
14
|
-
"bytes":
|
|
13
|
+
"sha256": "bfec2b5f3f05af4e426d626e171f3c1ab0cc48b1de9788283db0d9111e700687",
|
|
14
|
+
"bytes": 636850
|
|
15
15
|
},
|
|
16
16
|
"kit.js": {
|
|
17
|
-
"sha256": "
|
|
18
|
-
"bytes":
|
|
17
|
+
"sha256": "dd99b24a61ccb329d9187301f28da0e9bc783179fc091484ff30b9c22c6b766c",
|
|
18
|
+
"bytes": 5952040
|
|
19
19
|
},
|
|
20
20
|
"kit.css": {
|
|
21
21
|
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseMarkdown=exports.parseInline=void 0;const INLINE_PATTERNS=[{re:/^`([^`]+)`/,build:e=>({type:"code",value:e[1]})},{re:/^\[([^\]]*)\]\(([^)\s]+)\)/,build:(e,n)=>({type:"link",href:e[2],children:n(e[1])})},{re:/^\*\*([\s\S]+?)\*\*/,build:(e,n)=>({type:"strong",children:n(e[1])})},{re:/^__([\s\S]+?)__/,build:(e,n)=>({type:"strong",children:n(e[1])})},{re:/^~~([\s\S]+?)~~/,build:(e,n)=>({type:"strike",children:n(e[1])})},{re:/^\*([^*\n]+)\*/,build:(e,n)=>({type:"em",children:n(e[1])})},{re:/^_([^_\n]+)_/,build:(e,n)=>({type:"em",children:n(e[1])})}],parseInline=e=>{const n=[];let t="",
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseMarkdown=exports.parseInline=exports.markdownToPlainText=void 0;const INLINE_PATTERNS=[{re:/^`([^`]+)`/,build:e=>({type:"code",value:e[1]})},{re:/^\[([^\]]*)\]\(([^)\s]+)\)/,build:(e,n)=>({type:"link",href:e[2],children:n(e[1])})},{re:/^\*\*([\s\S]+?)\*\*/,build:(e,n)=>({type:"strong",children:n(e[1])})},{re:/^__([\s\S]+?)__/,build:(e,n)=>({type:"strong",children:n(e[1])})},{re:/^~~([\s\S]+?)~~/,build:(e,n)=>({type:"strike",children:n(e[1])})},{re:/^\*([^*\n]+)\*/,build:(e,n)=>({type:"em",children:n(e[1])})},{re:/^_([^_\n]+)_/,build:(e,n)=>({type:"em",children:n(e[1])})}],parseInline=e=>{const n=[];let t="",r=e;const flush=()=>{t&&(n.push({type:"text",value:t}),t="")};for(;r.length>0;){if(r.startsWith("\\")&&r.length>1){t+=r[1],r=r.slice(2);continue}let e=!1;for(const{re:t,build:s}of INLINE_PATTERNS){const i=t.exec(r);if(i){flush(),n.push(s(i,parseInline)),r=r.slice(i[0].length),e=!0;break}}e||(t+=r[0],r=r.slice(1))}return flush(),n};exports.parseInline=parseInline;const MAX_LIST_DEPTH=4,depthOf=e=>{const n=e.replace(/\t/g," ").length;return Math.min(Math.floor(n/2),4)},HEADING=/^(#{1,6})\s+(.*)$/,UNORDERED=/^(\s*)[-*+]\s+(.*)$/,ORDERED=/^(\s*)(\d+)[.)]\s+(.*)$/,QUOTE=/^\s*>\s?(.*)$/,RULE=/^\s*([-*_])\s*(?:\1\s*){2,}$/,FENCE=/^\s*```\s*(\S+)?\s*$/,parseMarkdown=e=>{const n=[],t=(e??"").replace(/\r\n?/g,"\n").split("\n");let r=[];const flushParagraph=()=>{r.length>0&&(n.push({type:"paragraph",children:parseInline(r.join(" ").trim())}),r=[])};for(let e=0;e<t.length;e++){const s=t[e],i=FENCE.exec(s);if(i){flushParagraph();const r=[];for(e++;e<t.length&&!FENCE.test(t[e]);)r.push(t[e]),e++;n.push({type:"codeBlock",value:r.join("\n"),language:i[1]});continue}if(""===s.trim()){flushParagraph();continue}if(RULE.test(s)){flushParagraph(),n.push({type:"rule"});continue}const l=HEADING.exec(s);if(l){flushParagraph(),n.push({type:"heading",level:l[1].length,children:parseInline(l[2])});continue}const o=ORDERED.exec(s);if(o){flushParagraph(),n.push({type:"listItem",ordered:!0,index:Number(o[2]),depth:depthOf(o[1]),children:parseInline(o[3])});continue}const p=UNORDERED.exec(s);if(p){flushParagraph(),n.push({type:"listItem",ordered:!1,index:0,depth:depthOf(p[1]),children:parseInline(p[2])});continue}const a=QUOTE.exec(s);a?(flushParagraph(),n.push({type:"quote",children:parseInline(a[1])})):r.push(s.trim())}return flushParagraph(),n};exports.parseMarkdown=parseMarkdown;const inlinePlainText=e=>e.map(e=>"text"===e.type||"code"===e.type?e.value:inlinePlainText(e.children)).join(""),markdownToPlainText=e=>parseMarkdown(e).map(e=>{switch(e.type){case"heading":case"paragraph":case"listItem":case"quote":return inlinePlainText(e.children);case"codeBlock":return e.value;default:return""}}).filter(Boolean).join(" ");exports.markdownToPlainText=markdownToPlainText;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.MessageBubble=exports.DEFAULT_MESSAGE_BUBBLE_LABELS=void 0;var _mobileCore=require("@webority/mobile-core"),_react=require("react"),_reactNative=require("react-native"),_index=require("../../theme/index.js"),_announce=require("../../utils/announce.js"),_corners=require("../../utils/corners.js"),_warnInvalidValue=require("../../utils/warnInvalidValue.js"),_index2=require("../AppIcon/index.js"),_index3=require("../Button/index.js"),_index4=require("../Markdown/index.js"),_useContextMenu=require("../Menu/useContextMenu.js"),_index5=require("../Text/index.js"),_jsxRuntime=require("react/jsx-runtime");const DEFAULT_MESSAGE_BUBBLE_LABELS=exports.DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",copy:"Copy",replyTo:e=>e?`Reply to ${e}`:"Reply"}),MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.MessageBubble=exports.DEFAULT_MESSAGE_BUBBLE_LABELS=void 0;var _mobileCore=require("@webority/mobile-core"),_react=require("react"),_reactNative=require("react-native"),_index=require("../../theme/index.js"),_announce=require("../../utils/announce.js"),_corners=require("../../utils/corners.js"),_warnInvalidValue=require("../../utils/warnInvalidValue.js"),_index2=require("../AppIcon/index.js"),_index3=require("../Button/index.js"),_index4=require("../Markdown/index.js"),_parse=require("../Markdown/parse.js"),_useContextMenu=require("../Menu/useContextMenu.js"),_index5=require("../Text/index.js"),_jsxRuntime=require("react/jsx-runtime");const DEFAULT_MESSAGE_BUBBLE_LABELS=exports.DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",copy:"Copy",replyTo:e=>e?`Reply to ${e}`:"Reply"}),MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,s)=>{switch(s){case"read":return e.colors["info-text"];case"failed":return e.colors["danger-text"];default:return e.colors["text-subtle"]}},MessageBubble=({side:e,text:s,children:t,markdown:r,groupPosition:n="single",author:i,time:a,status:o,replyTo:l,streaming:u=!1,error:c,onRetry:d,actions:x,onCopy:b,onLongPress:_,footer:m,labels:p,haptic:y,style:h,testID:g})=>{(0,_warnInvalidValue.warnInvalidValue)("MessageBubble","side",e,["mine","theirs"]),(0,_warnInvalidValue.warnInvalidValue)("MessageBubble","groupPosition",n,["single","first","middle","last"]),(0,_warnInvalidValue.warnInvalidValue)("MessageBubble","status",o,["sending","sent","delivered","read","failed"]);const f=(0,_index.useTheme)(),j=(0,_react.useMemo)(()=>buildStyles(f),[f]),v=p?{...DEFAULT_MESSAGE_BUBBLE_LABELS,...p}:DEFAULT_MESSAGE_BUBBLE_LABELS,B="mine"===e,L=!c&&(r??"theirs"===e),T="single"===n||"first"===n,M="single"===n||"last"===n,R=null==a?"":(0,_mobileCore.formatTime)(a),E=("failed"===o||Boolean(c))&&Boolean(d),S=B?v.you:i??"",A=(0,_react.useMemo)(()=>{const e=[];return b&&!x?.some(e=>"copy"===e.name)&&e.push({name:"copy",label:v.copy,onPress:()=>b(s)}),x&&e.push(...x),l?.onPress&&e.push({name:"openReply",label:v.replyTo(l.author),onPress:l.onPress}),E&&d&&e.push({name:"retry",label:v.retry,onPress:d}),e},[x,b,s,l,E,d,v]),I=(x?.length??0)>0||Boolean(b),P=(0,_react.useMemo)(()=>I?{items:A.map(({name:e,label:s,onPress:t})=>({key:e,label:s,onPress:t}))}:void 0,[I,A]),w=(0,_useContextMenu.useContextMenu)(P,{haptic:y,testID:g}),C=w.hostProps.onLongPress,k=!t||(x?.length??0)>0,q=o&&B?v[o]:"",D=(0,_react.useMemo)(()=>L&&null==t?(0,_parse.markdownToPlainText)(s):s,[L,t,s]),V=[S,R,D,l?`${v.replyTo(l.author)}: ${l.text}`:"",q].filter(Boolean).join(", "),$=(0,_react.useRef)(u);(0,_react.useEffect)(()=>{$.current&&!u&&!c&&s&&(0,_announce.announce)(S?`${S}, ${D}`:D),$.current=u},[u,c,s,D,S]);const U=(0,_react.useRef)(c);(0,_react.useEffect)(()=>{c&&c!==U.current&&(0,_announce.announce)(c,{polite:!1}),U.current=c},[c]);const N=(0,_react.useCallback)(e=>{C?.(e),_?.()},[C,_]),F=(0,_react.useCallback)(e=>{A.find(s=>s.name===e.nativeEvent.actionName)?.onPress()},[A]),z=f.radius.xl,H=f.radius.sm,O=B?{borderTopRightRadius:T?z:H,borderBottomRightRadius:M?z:H}:{borderTopLeftRadius:T?z:H,borderBottomLeftRadius:M?z:H},G=t??(L?(0,_jsxRuntime.jsx)(_index4.Markdown,{children:s}):(0,_jsxRuntime.jsx)(_index5.Text,{variant:"body",children:s})),W=l?(0,_jsxRuntime.jsxs)(_reactNative.Pressable,{onPress:l.onPress,disabled:!l.onPress,accessibilityRole:l.onPress?"button":void 0,accessibilityLabel:`${v.replyTo(l.author)}: ${l.text}`,style:j.quote,children:[l.author?(0,_jsxRuntime.jsx)(_index5.Text,{variant:"caption",weight:"semibold",color:"link",numberOfLines:1,children:l.author}):null,(0,_jsxRuntime.jsx)(_index5.Text,{variant:"bodySmall",color:"secondary",numberOfLines:2,children:l.text})]}):null,X=[j.bubble,B?j.mine:j.theirs,O],Y=k?{accessible:!0,accessibilityLabel:V,accessibilityState:{busy:u},"aria-busy":u,accessibilityActions:A.map(({name:e,label:s})=>({name:e,label:s})),onAccessibilityAction:F}:{accessible:!1},J=I?(0,_jsxRuntime.jsxs)(_reactNative.Pressable,{ref:w.hostRef,...w.hostProps,onLongPress:N,delayLongPress:350,style:X,testID:g?`${g}-bubble`:void 0,...Y,children:[W,G]}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:X,testID:g?`${g}-bubble`:void 0,...Y,children:[W,G]}),K=M&&(""!==R||B&&o);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[j.root,B?j.rootMine:j.rootTheirs,{marginTop:T?f.space.sm:f.space.xxs},h],testID:g,children:[!B&&T&&i?(0,_jsxRuntime.jsx)(_index5.Text,{variant:"caption",color:"secondary",style:j.author,numberOfLines:1,importantForAccessibility:k?"no-hide-descendants":"auto",accessibilityElementsHidden:k,children:i}):null,J,w.renderSurface(),K?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[j.meta,B?j.metaMine:null],importantForAccessibility:k?"no-hide-descendants":"auto",accessibilityElementsHidden:k,children:[R?(0,_jsxRuntime.jsx)(_index5.Text,{variant:"caption",color:"tertiary",children:R}):null,B&&o?(0,_jsxRuntime.jsx)(_index2.AppIcon,{name:statusIcon(o),size:14,color:statusColour(f,o),accessibilityLabel:v[o],testID:g?`${g}-status-${o}`:void 0}):null]}):null,c?(0,_jsxRuntime.jsx)(_index5.Text,{variant:"bodySmall",color:"danger",style:B?j.endText:null,children:c}):null,E?(0,_jsxRuntime.jsx)(_index3.Button,{label:v.retry,variant:"link",size:"sm",leftIcon:"refresh-cw",onPress:d,testID:g?`${g}-retry`:void 0}):null,m]})};exports.MessageBubble=MessageBubble;const buildStyles=e=>_reactNative.StyleSheet.create({root:{maxWidth:"85%",gap:e.space.xs},rootMine:{alignSelf:"flex-end",alignItems:"flex-end"},rootTheirs:{alignSelf:"flex-start",alignItems:"flex-start"},author:{paddingHorizontal:e.space.md},bubble:{borderRadius:e.radius.xl,..._corners.smoothCorners,paddingHorizontal:e.space.md,paddingVertical:e.space.sm,gap:e.space.xs},mine:{backgroundColor:e.colors["primary-soft"]},theirs:{backgroundColor:e.colors["bg-subtle"]},quote:{borderLeftWidth:3,borderLeftColor:e.colors.primary,paddingLeft:e.space.sm,paddingVertical:e.space.xs},meta:{flexDirection:"row",alignItems:"center",gap:e.space.xs,paddingHorizontal:e.space.xs},metaMine:{justifyContent:"flex-end"},endText:{textAlign:"right"}});var _default=exports.default=MessageBubble;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const INLINE_PATTERNS=[{re:/^`([^`]+)`/,build:e=>({type:"code",value:e[1]})},{re:/^\[([^\]]*)\]\(([^)\s]+)\)/,build:(e,t)=>({type:"link",href:e[2],children:t(e[1])})},{re:/^\*\*([\s\S]+?)\*\*/,build:(e,t)=>({type:"strong",children:t(e[1])})},{re:/^__([\s\S]+?)__/,build:(e,t)=>({type:"strong",children:t(e[1])})},{re:/^~~([\s\S]+?)~~/,build:(e,t)=>({type:"strike",children:t(e[1])})},{re:/^\*([^*\n]+)\*/,build:(e,t)=>({type:"em",children:t(e[1])})},{re:/^_([^_\n]+)_/,build:(e,t)=>({type:"em",children:t(e[1])})}];export const parseInline=e=>{const t=[];let n="",
|
|
1
|
+
"use strict";const INLINE_PATTERNS=[{re:/^`([^`]+)`/,build:e=>({type:"code",value:e[1]})},{re:/^\[([^\]]*)\]\(([^)\s]+)\)/,build:(e,t)=>({type:"link",href:e[2],children:t(e[1])})},{re:/^\*\*([\s\S]+?)\*\*/,build:(e,t)=>({type:"strong",children:t(e[1])})},{re:/^__([\s\S]+?)__/,build:(e,t)=>({type:"strong",children:t(e[1])})},{re:/^~~([\s\S]+?)~~/,build:(e,t)=>({type:"strike",children:t(e[1])})},{re:/^\*([^*\n]+)\*/,build:(e,t)=>({type:"em",children:t(e[1])})},{re:/^_([^_\n]+)_/,build:(e,t)=>({type:"em",children:t(e[1])})}];export const parseInline=e=>{const t=[];let n="",i=e;const flush=()=>{n&&(t.push({type:"text",value:n}),n="")};for(;i.length>0;){if(i.startsWith("\\")&&i.length>1){n+=i[1],i=i.slice(2);continue}let e=!1;for(const{re:n,build:s}of INLINE_PATTERNS){const r=n.exec(i);if(r){flush(),t.push(s(r,parseInline)),i=i.slice(r[0].length),e=!0;break}}e||(n+=i[0],i=i.slice(1))}return flush(),t};const MAX_LIST_DEPTH=4,depthOf=e=>{const t=e.replace(/\t/g," ").length;return Math.min(Math.floor(t/2),4)},HEADING=/^(#{1,6})\s+(.*)$/,UNORDERED=/^(\s*)[-*+]\s+(.*)$/,ORDERED=/^(\s*)(\d+)[.)]\s+(.*)$/,QUOTE=/^\s*>\s?(.*)$/,RULE=/^\s*([-*_])\s*(?:\1\s*){2,}$/,FENCE=/^\s*```\s*(\S+)?\s*$/;export const parseMarkdown=e=>{const t=[],n=(e??"").replace(/\r\n?/g,"\n").split("\n");let i=[];const flushParagraph=()=>{i.length>0&&(t.push({type:"paragraph",children:parseInline(i.join(" ").trim())}),i=[])};for(let e=0;e<n.length;e++){const s=n[e],r=FENCE.exec(s);if(r){flushParagraph();const i=[];for(e++;e<n.length&&!FENCE.test(n[e]);)i.push(n[e]),e++;t.push({type:"codeBlock",value:i.join("\n"),language:r[1]});continue}if(""===s.trim()){flushParagraph();continue}if(RULE.test(s)){flushParagraph(),t.push({type:"rule"});continue}const l=HEADING.exec(s);if(l){flushParagraph(),t.push({type:"heading",level:l[1].length,children:parseInline(l[2])});continue}const c=ORDERED.exec(s);if(c){flushParagraph(),t.push({type:"listItem",ordered:!0,index:Number(c[2]),depth:depthOf(c[1]),children:parseInline(c[3])});continue}const o=UNORDERED.exec(s);if(o){flushParagraph(),t.push({type:"listItem",ordered:!1,index:0,depth:depthOf(o[1]),children:parseInline(o[2])});continue}const p=QUOTE.exec(s);p?(flushParagraph(),t.push({type:"quote",children:parseInline(p[1])})):i.push(s.trim())}return flushParagraph(),t};const inlinePlainText=e=>e.map(e=>"text"===e.type||"code"===e.type?e.value:inlinePlainText(e.children)).join("");export const markdownToPlainText=e=>parseMarkdown(e).map(e=>{switch(e.type){case"heading":case"paragraph":case"listItem":case"quote":return inlinePlainText(e.children);case"codeBlock":return e.value;default:return""}}).filter(Boolean).join(" ");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{formatTime}from"@webority/mobile-core";import{useCallback,useEffect,useMemo,useRef}from"react";import{Pressable,StyleSheet,View}from"react-native";import{useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{warnInvalidValue}from"../../utils/warnInvalidValue.js";import{AppIcon}from"../AppIcon/index.js";import{Button}from"../Button/index.js";import{Markdown}from"../Markdown/index.js";import{useContextMenu}from"../Menu/useContextMenu.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",copy:"Copy",replyTo:e=>e?`Reply to ${e}`:"Reply"});const MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,s)=>{switch(s){case"read":return e.colors["info-text"];case"failed":return e.colors["danger-text"];default:return e.colors["text-subtle"]}};export const MessageBubble=({side:e,text:s,children:t,markdown:o
|
|
1
|
+
"use strict";import{formatTime}from"@webority/mobile-core";import{useCallback,useEffect,useMemo,useRef}from"react";import{Pressable,StyleSheet,View}from"react-native";import{useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{warnInvalidValue}from"../../utils/warnInvalidValue.js";import{AppIcon}from"../AppIcon/index.js";import{Button}from"../Button/index.js";import{Markdown}from"../Markdown/index.js";import{markdownToPlainText}from"../Markdown/parse.js";import{useContextMenu}from"../Menu/useContextMenu.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",copy:"Copy",replyTo:e=>e?`Reply to ${e}`:"Reply"});const MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,s)=>{switch(s){case"read":return e.colors["info-text"];case"failed":return e.colors["danger-text"];default:return e.colors["text-subtle"]}};export const MessageBubble=({side:e,text:s,children:t,markdown:o,groupPosition:r="single",author:n,time:a,status:i,replyTo:l,streaming:c=!1,error:u,onRetry:d,actions:m,onCopy:p,onLongPress:b,footer:x,labels:f,haptic:y,style:h,testID:g})=>{warnInvalidValue("MessageBubble","side",e,["mine","theirs"]),warnInvalidValue("MessageBubble","groupPosition",r,["single","first","middle","last"]),warnInvalidValue("MessageBubble","status",i,["sending","sent","delivered","read","failed"]);const T=useTheme(),j=useMemo(()=>buildStyles(T),[T]),L=f?{...DEFAULT_MESSAGE_BUBBLE_LABELS,...f}:DEFAULT_MESSAGE_BUBBLE_LABELS,_="mine"===e,B=!u&&(o??"theirs"===e),M="single"===r||"first"===r,P="single"===r||"last"===r,S=null==a?"":formatTime(a),v=("failed"===i||Boolean(u))&&Boolean(d),I=_?L.you:n??"",w=useMemo(()=>{const e=[];return p&&!m?.some(e=>"copy"===e.name)&&e.push({name:"copy",label:L.copy,onPress:()=>p(s)}),m&&e.push(...m),l?.onPress&&e.push({name:"openReply",label:L.replyTo(l.author),onPress:l.onPress}),v&&d&&e.push({name:"retry",label:L.retry,onPress:d}),e},[m,p,s,l,v,d,L]),E=(m?.length??0)>0||Boolean(p),A=useMemo(()=>E?{items:w.map(({name:e,label:s,onPress:t})=>({key:e,label:s,onPress:t}))}:void 0,[E,w]),k=useContextMenu(A,{haptic:y,testID:g}),C=k.hostProps.onLongPress,R=!t||(m?.length??0)>0,D=i&&_?L[i]:"",$=useMemo(()=>B&&null==t?markdownToPlainText(s):s,[B,t,s]),V=[I,S,$,l?`${L.replyTo(l.author)}: ${l.text}`:"",D].filter(Boolean).join(", "),U=useRef(c);useEffect(()=>{U.current&&!c&&!u&&s&&announce(I?`${I}, ${$}`:$),U.current=c},[c,u,s,$,I]);const z=useRef(u);useEffect(()=>{u&&u!==z.current&&announce(u,{polite:!1}),z.current=u},[u]);const H=useCallback(e=>{C?.(e),b?.()},[C,b]),F=useCallback(e=>{w.find(s=>s.name===e.nativeEvent.actionName)?.onPress()},[w]),O=T.radius.xl,G=T.radius.sm,N=_?{borderTopRightRadius:M?O:G,borderBottomRightRadius:P?O:G}:{borderTopLeftRadius:M?O:G,borderBottomLeftRadius:P?O:G},W=t??(B?_jsx(Markdown,{children:s}):_jsx(Text,{variant:"body",children:s})),q=l?_jsxs(Pressable,{onPress:l.onPress,disabled:!l.onPress,accessibilityRole:l.onPress?"button":void 0,accessibilityLabel:`${L.replyTo(l.author)}: ${l.text}`,style:j.quote,children:[l.author?_jsx(Text,{variant:"caption",weight:"semibold",color:"link",numberOfLines:1,children:l.author}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",numberOfLines:2,children:l.text})]}):null,X=[j.bubble,_?j.mine:j.theirs,N],Y=R?{accessible:!0,accessibilityLabel:V,accessibilityState:{busy:c},"aria-busy":c,accessibilityActions:w.map(({name:e,label:s})=>({name:e,label:s})),onAccessibilityAction:F}:{accessible:!1},J=E?_jsxs(Pressable,{ref:k.hostRef,...k.hostProps,onLongPress:H,delayLongPress:350,style:X,testID:g?`${g}-bubble`:void 0,...Y,children:[q,W]}):_jsxs(View,{style:X,testID:g?`${g}-bubble`:void 0,...Y,children:[q,W]}),K=P&&(""!==S||_&&i);return _jsxs(View,{style:[j.root,_?j.rootMine:j.rootTheirs,{marginTop:M?T.space.sm:T.space.xxs},h],testID:g,children:[!_&&M&&n?_jsx(Text,{variant:"caption",color:"secondary",style:j.author,numberOfLines:1,importantForAccessibility:R?"no-hide-descendants":"auto",accessibilityElementsHidden:R,children:n}):null,J,k.renderSurface(),K?_jsxs(View,{style:[j.meta,_?j.metaMine:null],importantForAccessibility:R?"no-hide-descendants":"auto",accessibilityElementsHidden:R,children:[S?_jsx(Text,{variant:"caption",color:"tertiary",children:S}):null,_&&i?_jsx(AppIcon,{name:statusIcon(i),size:14,color:statusColour(T,i),accessibilityLabel:L[i],testID:g?`${g}-status-${i}`:void 0}):null]}):null,u?_jsx(Text,{variant:"bodySmall",color:"danger",style:_?j.endText:null,children:u}):null,v?_jsx(Button,{label:L.retry,variant:"link",size:"sm",leftIcon:"refresh-cw",onPress:d,testID:g?`${g}-retry`:void 0}):null,x]})};const buildStyles=e=>StyleSheet.create({root:{maxWidth:"85%",gap:e.space.xs},rootMine:{alignSelf:"flex-end",alignItems:"flex-end"},rootTheirs:{alignSelf:"flex-start",alignItems:"flex-start"},author:{paddingHorizontal:e.space.md},bubble:{borderRadius:e.radius.xl,...smoothCorners,paddingHorizontal:e.space.md,paddingVertical:e.space.sm,gap:e.space.xs},mine:{backgroundColor:e.colors["primary-soft"]},theirs:{backgroundColor:e.colors["bg-subtle"]},quote:{borderLeftWidth:3,borderLeftColor:e.colors.primary,paddingLeft:e.space.sm,paddingVertical:e.space.xs},meta:{flexDirection:"row",alignItems:"center",gap:e.space.xs,paddingHorizontal:e.space.xs},metaMine:{justifyContent:"flex-end"},endText:{textAlign:"right"}});export default MessageBubble;
|
|
@@ -55,4 +55,9 @@ export type BlockNode = {
|
|
|
55
55
|
};
|
|
56
56
|
export declare const parseInline: (input: string) => InlineNode[];
|
|
57
57
|
export declare const parseMarkdown: (source: string) => BlockNode[];
|
|
58
|
+
/**
|
|
59
|
+
* The text a screen reader should speak for a markdown source: the words without
|
|
60
|
+
* the emphasis, code, link and heading marks, one block after another.
|
|
61
|
+
*/
|
|
62
|
+
export declare const markdownToPlainText: (source: string) => string;
|
|
58
63
|
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -44,7 +44,10 @@ export interface MessageBubbleProps {
|
|
|
44
44
|
text: string;
|
|
45
45
|
/** Rich content in place of `text` (a chart, an image, a renderer of your own). */
|
|
46
46
|
children?: React.ReactNode;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Draws `text` with the library `Markdown`. Default on for `theirs` and off for
|
|
49
|
+
* `mine`. An `error` bubble always draws plain text. Ignored with `children`.
|
|
50
|
+
*/
|
|
48
51
|
markdown?: boolean;
|
|
49
52
|
/** Default `'single'`. */
|
|
50
53
|
groupPosition?: MessageGroupPosition;
|
|
@@ -55,4 +55,9 @@ export type BlockNode = {
|
|
|
55
55
|
};
|
|
56
56
|
export declare const parseInline: (input: string) => InlineNode[];
|
|
57
57
|
export declare const parseMarkdown: (source: string) => BlockNode[];
|
|
58
|
+
/**
|
|
59
|
+
* The text a screen reader should speak for a markdown source: the words without
|
|
60
|
+
* the emphasis, code, link and heading marks, one block after another.
|
|
61
|
+
*/
|
|
62
|
+
export declare const markdownToPlainText: (source: string) => string;
|
|
58
63
|
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -44,7 +44,10 @@ export interface MessageBubbleProps {
|
|
|
44
44
|
text: string;
|
|
45
45
|
/** Rich content in place of `text` (a chart, an image, a renderer of your own). */
|
|
46
46
|
children?: React.ReactNode;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Draws `text` with the library `Markdown`. Default on for `theirs` and off for
|
|
49
|
+
* `mine`. An `error` bubble always draws plain text. Ignored with `children`.
|
|
50
|
+
*/
|
|
48
51
|
markdown?: boolean;
|
|
49
52
|
/** Default `'single'`. */
|
|
50
53
|
groupPosition?: MessageGroupPosition;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/mobile-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.111.0",
|
|
4
4
|
"description": "Beautiful, animated, accessible React Native components, theme and form engine for Webority projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"react-native-safe-area-context": ">=5.4.0",
|
|
101
101
|
"react-native-svg": ">=15.0.0",
|
|
102
102
|
"react-native-worklets": ">=0.10.0",
|
|
103
|
-
"@webority/canvas-kit": "0.
|
|
104
|
-
"@webority/mobile-core": "0.
|
|
103
|
+
"@webority/canvas-kit": "0.111.0",
|
|
104
|
+
"@webority/mobile-core": "0.111.0"
|
|
105
105
|
},
|
|
106
106
|
"peerDependenciesMeta": {
|
|
107
107
|
"@react-navigation/bottom-tabs": {
|
|
@@ -170,10 +170,10 @@
|
|
|
170
170
|
"react-test-renderer": "19.2.8",
|
|
171
171
|
"rimraf": "6.1.3",
|
|
172
172
|
"typescript": "5.9.3",
|
|
173
|
-
"@webority/
|
|
174
|
-
"@webority/
|
|
175
|
-
"@webority/
|
|
176
|
-
"@webority/
|
|
173
|
+
"@webority/canvas-kit": "0.111.0",
|
|
174
|
+
"@webority/mobile-core": "0.111.0",
|
|
175
|
+
"@webority/mobile-dev": "0.0.0",
|
|
176
|
+
"@webority/tokens": "0.111.0"
|
|
177
177
|
},
|
|
178
178
|
"scripts": {
|
|
179
179
|
"build": "bob build && node ../mobile-dev/scripts/minify-lib.mjs && node -e \"require('node:fs').rmSync('dist/canvas-kit',{recursive:true,force:true})\" && node ../canvas-kit/dist/cli.js build --config canvas-kit.json --out dist/canvas-kit",
|