@ably/ui 15.2.0 → 15.2.1-dev.bfb46ac

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/core/Flash.js CHANGED
@@ -1 +1 @@
1
- import React,{useEffect,useState,useRef}from"react";import DOMPurify from"dompurify";import{getRemoteDataStore}from"./remote-data-store.js";import ConnectStateWrapper from"./ConnectStateWrapper";import Icon from"./Icon";const REDUCER_KEY="flashes";const FLASH_DATA_ID="ui-flashes";const initialState={items:[]};const reducerFlashes={[REDUCER_KEY]:(state=initialState,action)=>{switch(action.type){case"flash/push":{const flashes=Array.isArray(action.payload)?action.payload:[action.payload];return{items:[...state.items,...flashes]}}default:return state}}};const selectFlashes=store=>store.getState()[REDUCER_KEY];const FLASH_BG_COLOR={error:"bg-gui-error",success:"bg-zingy-green",notice:"bg-electric-cyan",info:"bg-electric-cyan",alert:"bg-active-orange"};const FLASH_TEXT_COLOR={error:"text-white",success:"text-cool-black",notice:"text-cool-black",info:"text-cool-black",alert:"text-white"};const AUTO_HIDE=["success","info","notice"];const AUTO_HIDE_TIME=8e3;const useAutoHide=(type,closeFlash)=>{const timeoutId=useRef(null);useEffect(()=>{if(AUTO_HIDE.includes(type)){timeoutId.current=setTimeout(()=>{closeFlash()},AUTO_HIDE_TIME)}return()=>{if(timeoutId.current){clearTimeout(timeoutId.current)}}},[])};const Flash=({id,type,content,removeFlash})=>{const ref=useRef(null);const[closed,setClosed]=useState(false);const[flashHeight,setFlashHeight]=useState(0);const[triggerEntryAnimation,setTriggerEntryAnimation]=useState(false);const closeFlash=()=>{if(ref.current){setFlashHeight(ref.current.getBoundingClientRect().height)}setClosed(true);setTimeout(()=>{if(id){removeFlash(id)}},100)};useEffect(()=>setTriggerEntryAnimation(true),[]);useAutoHide(type,closeFlash);const animateEntry=triggerEntryAnimation&&!closed;let style;if(flashHeight&&!closed){style={height:`${flashHeight}px`}}else if(closed){style={height:0,marginTop:0,zIndex:-1}}else{style={}}const safeContent=DOMPurify.sanitize(content,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method","rel"]});const withIcons={notice:"icon-gui-ably-badge",success:"icon-gui-tick",error:"icon-gui-warning",alert:"icon-gui-warning",info:""};const iconColor={notice:"text-cool-black",success:"text-cool-black",error:"text-white",alert:"text-white",info:""};return React.createElement("div",{className:`ui-flash-message ui-grid-px ${animateEntry?"ui-flash-message-enter":""}`,style:style,ref:ref,"data-id":"ui-flash"},React.createElement("div",{className:`${FLASH_BG_COLOR[type]} p-32 flex align-center rounded shadow-container-subtle`},withIcons[type]&&iconColor[type]&&React.createElement(Icon,{name:withIcons[type],color:iconColor[type],size:"1.5rem",additionalCSS:"mr-16 self-baseline"}),React.createElement("p",{className:`ui-text-p1 mr-16 ${FLASH_TEXT_COLOR[type]}`,dangerouslySetInnerHTML:{__html:safeContent}}),React.createElement("button",{type:"button",className:"p-0 ml-auto self-start focus:outline-none",onClick:closeFlash},iconColor[type]&&React.createElement(Icon,{name:"icon-gui-close",color:iconColor[type],size:"1.5rem",additionalCSS:"transition-colors"}))))};const Flashes=({flashes})=>{const[flashesWithIds,setFlashesWithIds]=useState([]);const removeFlash=flashId=>setFlashesWithIds(items=>items.filter(item=>item.id!==flashId));useEffect(()=>{setFlashesWithIds(state=>{return[...state,...(flashes?.items??[]).map(flash=>({...flash,id:Math.random().toString(36).slice(2),removed:false}))]})},[flashes]);return React.createElement("div",{className:"ui-flash","data-id":FLASH_DATA_ID},flashesWithIds.filter(item=>!item.removed).map(flash=>React.createElement(Flash,{key:flash.id,...flash,removeFlash:removeFlash})))};const BackendFlashes=({flashes})=>{useEffect(()=>{const transformedFlashes=flashes.map(flash=>{const[type,content]=flash;return{type,content}})||[];if(transformedFlashes.length>0){const store=getRemoteDataStore();store.dispatch({type:"flash/push",payload:transformedFlashes})}},[]);const WrappedFlashes=ConnectStateWrapper(Flashes,{flashes:selectFlashes});return React.createElement(WrappedFlashes,null)};export{reducerFlashes,FLASH_DATA_ID,Flashes};export default BackendFlashes;
1
+ import React,{useEffect,useState,useRef}from"react";import DOMPurify from"dompurify";import{getRemoteDataStore}from"./remote-data-store.js";import ConnectStateWrapper from"./ConnectStateWrapper";import Icon from"./Icon";const REDUCER_KEY="flashes";const FLASH_DATA_ID="ui-flashes";const initialState={items:[]};const reducerFlashes={[REDUCER_KEY]:(state=initialState,action)=>{switch(action.type){case"flash/push":{const flashes=Array.isArray(action.payload)?action.payload:[action.payload];return{items:[...state.items,...flashes]}}default:return state}}};const selectFlashes=store=>store.getState()[REDUCER_KEY];const FLASH_BG_COLOR={error:"bg-gui-error",success:"bg-zingy-green",notice:"bg-electric-cyan",info:"bg-electric-cyan",alert:"bg-active-orange"};const FLASH_TEXT_COLOR={error:"text-white",success:"text-cool-black",notice:"text-cool-black",info:"text-cool-black",alert:"text-white"};const AUTO_HIDE=["success","info","notice"];const AUTO_HIDE_TIME=8e3;const useAutoHide=(type,closeFlash)=>{const timeoutId=useRef(null);useEffect(()=>{if(AUTO_HIDE.includes(type)){timeoutId.current=setTimeout(()=>{closeFlash()},AUTO_HIDE_TIME)}return()=>{if(timeoutId.current){clearTimeout(timeoutId.current)}}},[])};const Flash=({id,type,content,removeFlash})=>{const ref=useRef(null);const[closed,setClosed]=useState(false);const[flashHeight,setFlashHeight]=useState(0);const[triggerEntryAnimation,setTriggerEntryAnimation]=useState(false);const closeFlash=()=>{if(ref.current){setFlashHeight(ref.current.getBoundingClientRect().height)}setClosed(true);setTimeout(()=>{if(id){removeFlash(id)}},100)};useEffect(()=>setTriggerEntryAnimation(true),[]);useAutoHide(type,closeFlash);const animateEntry=triggerEntryAnimation&&!closed;let style;if(flashHeight&&!closed){style={height:`${flashHeight}px`}}else if(closed){style={height:0,marginTop:0,zIndex:-1}}else{style={}}const safeContent=DOMPurify.sanitize(content,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method","rel"]});const withIcons={notice:"icon-gui-ably-badge",success:"icon-gui-tick",error:"icon-gui-warning",alert:"icon-gui-warning",info:""};const iconColor={notice:"text-cool-black",success:"text-cool-black",error:"text-white",alert:"text-white",info:""};return React.createElement("div",{className:`ui-flash-message ui-grid-px ${animateEntry?"ui-flash-message-enter":""}`,style:style,ref:ref,"data-id":"ui-flash"},React.createElement("div",{className:`${FLASH_BG_COLOR[type]} p-32 flex align-center rounded shadow-container-subtle`},withIcons[type]&&iconColor[type]&&React.createElement(Icon,{name:withIcons[type],color:iconColor[type],size:"1.5rem",additionalCSS:"mr-16 self-baseline"}),React.createElement("p",{className:`ui-text-p1 mr-16 ${FLASH_TEXT_COLOR[type]}`,dangerouslySetInnerHTML:{__html:safeContent}}),React.createElement("button",{type:"button",className:"p-0 ml-auto self-start focus:outline-none",onClick:closeFlash},iconColor[type]&&React.createElement(Icon,{name:"icon-gui-close",color:iconColor[type],size:"1.5rem",additionalCSS:"transition-colors"}))))};const Flashes=({flashes})=>{const[flashesWithIds,setFlashesWithIds]=useState([]);const removeFlash=flashId=>setFlashesWithIds(items=>items.filter(item=>item.id!==flashId));useEffect(()=>{setFlashesWithIds(state=>{return[...state,...(flashes?.items??[]).map(flash=>({...flash,id:Math.random().toString(36).slice(2),removed:false,removeFlash}))]})},[flashes,removeFlash]);return React.createElement("div",{className:"ui-flash","data-id":FLASH_DATA_ID},flashesWithIds.filter(item=>!item.removed).map(flash=>React.createElement(Flash,{key:flash.id,...flash,removeFlash:removeFlash})))};const BackendFlashes=({flashes})=>{useEffect(()=>{const transformedFlashes=flashes.map(flash=>{const[type,content]=flash;return{type,content}})||[];if(transformedFlashes.length>0){const store=getRemoteDataStore();store.dispatch({type:"flash/push",payload:transformedFlashes})}},[]);const WrappedFlashes=ConnectStateWrapper(Flashes,{flashes:selectFlashes});return React.createElement(WrappedFlashes,null)};export{reducerFlashes,FLASH_DATA_ID,Flashes};export default BackendFlashes;
package/core/Notice.js CHANGED
@@ -1 +1 @@
1
- import React,{useEffect}from"react";import NoticeScripts from"./Notice/component.js";import Icon from"./Icon";const contentWrapperClasses="w-full pr-8 ui-text-p3 self-center";const ContentWrapper=({buttonLink,children})=>buttonLink?React.createElement("a",{href:buttonLink,className:contentWrapperClasses},children):React.createElement("div",{className:contentWrapperClasses},children);const Notice=({buttonLink,buttonLabel,bodyText,title,config,closeBtn,bgColor="bg-gradient-active-orange",textColor="text-white"})=>{useEffect(()=>{NoticeScripts({bannerContainer:document.querySelector('[data-id="ui-notice"]'),cookieId:config?.cookieId,noticeId:config?.noticeId,options:{collapse:config?.collapse||false}})},[]);const wrapperClasses=["ui-announcement",bgColor,textColor].join(" ");return React.createElement("div",{className:wrapperClasses,"data-id":"ui-notice",style:{maxHeight:0,overflow:"hidden"}},React.createElement("div",{className:"ui-grid-px py-16 max-w-screen-xl mx-auto flex items-start"},React.createElement(ContentWrapper,{buttonLink:buttonLink??"#"},React.createElement("strong",{className:"font-bold whitespace-nowrap pr-4"},title),React.createElement("span",{className:"pr-4"},bodyText),buttonLabel&&React.createElement("span",{className:"underline cursor-pointer whitespace-nowrap"},buttonLabel)),closeBtn&&React.createElement("button",{type:"button",className:"ml-auto h-20 w-20 border-none bg-none self-baseline"},React.createElement(Icon,{name:"icon-gui-close",size:"1.25rem",color:"text-cool-black"}))))};export default Notice;
1
+ import React,{useEffect}from"react";import DOMPurify from"dompurify";import NoticeScripts from"./Notice/component.js";import Icon from"./Icon";import useRailsUjsLinks from"./hooks/use-rails-ujs-hooks";const contentWrapperClasses="w-full pr-8 ui-text-p3 self-center";const ContentWrapper=({buttonLink,children})=>buttonLink?React.createElement("a",{href:buttonLink,className:contentWrapperClasses},children):React.createElement("div",{className:contentWrapperClasses},children);const Notice=({buttonLink,buttonLabel,bodyText="",title,config,closeBtn,bgColor="bg-gradient-active-orange",textColor="text-white"})=>{useEffect(()=>{NoticeScripts({bannerContainer:document.querySelector('[data-id="ui-notice"]'),cookieId:config?.cookieId,noticeId:config?.noticeId,options:{collapse:config?.collapse||false}})},[]);const wrapperClasses=["ui-announcement",bgColor,textColor].join(" ");const safeContent=DOMPurify.sanitize(bodyText,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method","rel"]});const contentRef=useRailsUjsLinks();return React.createElement("div",{className:wrapperClasses,"data-id":"ui-notice",style:{maxHeight:0,overflow:"hidden"}},React.createElement("div",{className:"ui-grid-px py-16 max-w-screen-xl mx-auto flex items-start"},React.createElement(ContentWrapper,{buttonLink:buttonLink??"#"},React.createElement("strong",{className:"font-bold whitespace-nowrap pr-4"},title),React.createElement("span",{ref:contentRef,className:"pr-4",dangerouslySetInnerHTML:{__html:DOMPurify.sanitize(safeContent)}}),buttonLabel&&React.createElement("span",{className:"underline cursor-pointer whitespace-nowrap"},buttonLabel)),closeBtn&&React.createElement("button",{type:"button",className:"ml-auto h-20 w-20 border-none bg-none self-baseline"},React.createElement(Icon,{name:"icon-gui-close",size:"1.25rem",color:"text-cool-black"}))))};export default Notice;
@@ -0,0 +1 @@
1
+ import{useEffect,useRef}from"react";const useRailsUjsLinks=()=>{const containerRef=useRef(null);useEffect(()=>{const container=containerRef.current;if(!container)return;const handleClick=event=>{const target=event.target;const link=target.closest("a[data-method]");if(!link)return;if(!container.contains(link))return;event.preventDefault();const method=link.dataset.method?.toLowerCase()??"get";const href=link.getAttribute("href");if(!href){console.warn("Rails UJS link has no href attribute");return}const csrfParam=document.querySelector('meta[name="csrf-param"]')?.content;const csrfToken=document.querySelector('meta[name="csrf-token"]')?.content;if(method!=="post")return;const form=document.createElement("form");form.method="POST";form.action=href;form.style.display="none";if(csrfParam&&csrfToken){const csrfInput=document.createElement("input");csrfInput.type="hidden";csrfInput.name=csrfParam;csrfInput.value=csrfToken;form.appendChild(csrfInput)}else{console.warn("No CSRF token found in document")}if(method!=="post"){const methodInput=document.createElement("input");methodInput.type="hidden";methodInput.name="_method";methodInput.value=method;form.appendChild(methodInput)}document.body.appendChild(form);form.submit()};container.addEventListener("click",handleClick);return()=>container.removeEventListener("click",handleClick)},[]);return containerRef};export default useRailsUjsLinks;
@@ -0,0 +1 @@
1
+ ["bg-blue-400","bg-blue-100","bg-neutral-1300","bg-neutral-300","bg-neutral-200","bg-neutral-100","bg-neutral-000","bg-neutral-600","bg-orange-900","bg-orange-600","border-blue-400","border-neutral-200","border-neutral-600","border-neutral-500","border-orange-600","from-neutral-400","group-hover:bg-neutral-100","text-blue-600","text-blue-200","text-neutral-1300","text-neutral-300","text-neutral-000","text-neutral-1100","text-neutral-1000","text-neutral-800","text-neutral-700","text-neutral-600","text-neutral-500","text-orange-200","text-orange-600"]
package/index.d.ts CHANGED
@@ -400,7 +400,7 @@ type FlashProps = {
400
400
  };
401
401
  type FlashesProps = {
402
402
  flashes: {
403
- items: FlashProps[];
403
+ items: Pick<FlashProps, "type" | "content">[];
404
404
  };
405
405
  };
406
406
  type BackendFlashesProps = {
@@ -551,6 +551,7 @@ export default function Meganav({ themeName, addSearchApiKey }: {
551
551
 
552
552
  declare module '@ably/ui/core/Meganav' {
553
553
  import { ReactNode } from "react";
554
+ import type { NoticeProps } from "@ably/ui/core/Notice";
554
555
  import { ColorClass } from "@ably/ui/core/styles/colors/types";
555
556
  export type MeganavTheme = {
556
557
  backgroundColor?: ColorClass;
@@ -564,11 +565,7 @@ export type MeganavTheme = {
564
565
  export type AbsUrl = (path: string) => string;
565
566
  export type MeganavPaths = {
566
567
  logo: string;
567
- iconSprites: string;
568
568
  ablyStack: string;
569
- blogThumb1: string;
570
- blogThumb2: string;
571
- blogThumb3: string;
572
569
  awsLogo?: string;
573
570
  };
574
571
  export type MeganavPanels = {
@@ -603,23 +600,18 @@ export type MeganavSessionState = {
603
600
  href: string;
604
601
  };
605
602
  };
603
+ export type NoticeApiProps = {
604
+ props: NoticeProps;
605
+ config: {
606
+ cookieId: string;
607
+ noticeId: string;
608
+ collapse: boolean;
609
+ };
610
+ };
606
611
  type MeganavProps = {
607
612
  paths?: MeganavPaths;
608
- themeName: "white" | "black" | "transparentToWhite";
609
- notice?: {
610
- props: {
611
- title: string;
612
- bodyText: string;
613
- buttonLink: string;
614
- buttonLabel: string;
615
- closeBtn: boolean;
616
- };
617
- config: {
618
- cookieId: string;
619
- noticeId: string;
620
- collapse: boolean;
621
- };
622
- };
613
+ themeName?: "white" | "black" | "transparentToWhite";
614
+ notice?: NoticeApiProps;
623
615
  loginLink?: string;
624
616
  urlBase?: string;
625
617
  addSearchApiKey: string;
@@ -883,7 +875,7 @@ function Notice({ bannerContainer, cookieId, noticeId, options }: {
883
875
  }
884
876
 
885
877
  declare module '@ably/ui/core/Notice' {
886
- type NoticeProps = {
878
+ export type NoticeProps = {
887
879
  buttonLink?: string;
888
880
  buttonLabel?: string;
889
881
  bodyText?: string;
@@ -1216,6 +1208,13 @@ export function queryIdAll(val: any, root?: Document): NodeListOf<Element>;
1216
1208
  //# sourceMappingURL=dom-query.d.ts.map
1217
1209
  }
1218
1210
 
1211
+ declare module '@ably/ui/core/hooks/use-rails-ujs-hooks' {
1212
+ import { RefObject } from 'react';
1213
+ const useRailsUjsLinks: () => RefObject<HTMLDivElement>;
1214
+ export default useRailsUjsLinks;
1215
+ //# sourceMappingURL=use-rails-ujs-hooks.d.ts.map
1216
+ }
1217
+
1219
1218
  declare module '@ably/ui/core/hubspot-chat-toggle' {
1220
1219
  export default function toggleChatWidget(params: any): (() => void) | undefined;
1221
1220
  //# sourceMappingURL=hubspot-chat-toggle.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ably/ui",
3
- "version": "15.2.0",
3
+ "version": "15.2.1-dev.bfb46ac",
4
4
  "description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,15 +19,15 @@
19
19
  "workerDirectory": "./public"
20
20
  },
21
21
  "devDependencies": {
22
- "@storybook/addon-a11y": "^8.4.0",
23
- "@storybook/addon-essentials": "^8.4.0",
24
- "@storybook/addon-interactions": "^8.4.0",
25
- "@storybook/addon-links": "^8.4.0",
26
- "@storybook/blocks": "^8.4.0",
27
- "@storybook/react-vite": "^8.4.0",
28
- "@storybook/test": "^8.4.0",
22
+ "@storybook/addon-a11y": "^8.4.7",
23
+ "@storybook/addon-essentials": "^8.4.7",
24
+ "@storybook/addon-interactions": "^8.4.7",
25
+ "@storybook/addon-links": "^8.4.7",
26
+ "@storybook/blocks": "^8.4.7",
27
+ "@storybook/react-vite": "^8.4.7",
28
+ "@storybook/test": "^8.4.7",
29
29
  "@storybook/test-runner": "^0.21.0",
30
- "@swc/cli": "^0.5.0",
30
+ "@swc/cli": "^0.6.0",
31
31
  "@swc/core": "^1.4.11",
32
32
  "@tailwindcss/container-queries": "^0.1.1",
33
33
  "@types/dompurify": "^3.0.5",
@@ -43,7 +43,7 @@
43
43
  "eslint": "^8.57.0",
44
44
  "eslint-config-prettier": "^9.1.0",
45
45
  "eslint-plugin-react": "^7.34.3",
46
- "eslint-plugin-storybook": "^0.11.0",
46
+ "eslint-plugin-storybook": "^0.11.2",
47
47
  "heroicons": "^2.2.0",
48
48
  "http-server": "14.1.1",
49
49
  "msw": "2.6.1",
@@ -51,13 +51,13 @@
51
51
  "playwright": "^1.49.1",
52
52
  "prettier": "^3.2.5",
53
53
  "react-syntax-highlighter": "^15.6.1",
54
- "storybook": "^8.4.0",
54
+ "storybook": "^8.4.7",
55
55
  "storybook-dark-mode": "^4.0.2",
56
56
  "svg-sprite": "^2.0.4",
57
57
  "tailwindcss": "^3.3.6",
58
58
  "ts-node": "^10.9.2",
59
59
  "typescript": "5.7.2",
60
- "vite": "^5.2.12"
60
+ "vite": "^6.0.0"
61
61
  },
62
62
  "scripts": {
63
63
  "build:prebuild": "rm -rf core reset && mkdir -p dist/core",