From fe7988b43353074569c56c74e6dd6f10c4f77cc4 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Thu, 10 Apr 2025 13:03:12 -0500 Subject: [PATCH 01/26] feat(docs): data viz base structure --- .../sidebar/SidebarNavigation.tsx | 15 ++- packages/paste-website/src/constants.ts | 1 + .../engineering/base-chart.mdx | 112 ++++++++++++++++++ .../data-visualization/engineering/index.mdx | 112 ++++++++++++++++++ .../foundations/data-visualization/index.mdx | 10 ++ 5 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 packages/paste-website/src/pages/foundations/data-visualization/engineering/base-chart.mdx create mode 100644 packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 3c5dc6565d..21264257cd 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -135,9 +135,18 @@ const SiteSidebarNavigation = (): JSX.Element => { Word list - - Data visualization - + + Overview + + Overview + + Base Chart + + + diff --git a/packages/paste-website/src/constants.ts b/packages/paste-website/src/constants.ts index faf02fb74f..96caa18a22 100644 --- a/packages/paste-website/src/constants.ts +++ b/packages/paste-website/src/constants.ts @@ -48,6 +48,7 @@ export const SidebarCategoryRoutes = { FOUNDATIONS: "/foundations", CONTENT: "/foundations/content", FOUNDATIONS_LOCALIZATION: "/foundations/localization", + DATA_VISUALIZATION: "/foundations/data-visualization", PATTERNS: "/patterns", EXPERIENCES: "/experiences", COMPONENTS: "/components", diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/base-chart.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/base-chart.mdx new file mode 100644 index 0000000000..d22c506bc2 --- /dev/null +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/base-chart.mdx @@ -0,0 +1,112 @@ +export const meta = { + title: "Data Visualization - Base Chart", + description: "The base component required to funciton with Paste components.", + slug: "/foundations/data-visualization/engineering/base-chart", +}; + +import Image from "next/image"; +import Highcharts from "highcharts"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import HighchartsReact from "highcharts-react-official"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; + +import { Box } from "@twilio-paste/box"; +import { Heading } from "@twilio-paste/heading"; +import { Text } from "@twilio-paste/text"; +import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; +import { PageHeaderSeparator } from "@twilio-paste/page-header"; +import { Separator } from "@twilio-paste/separator"; + +import { SidebarCategoryRoutes } from "../../../../constants"; +import DefaultLayout from "../../../../layouts/DefaultLayout"; +import { getNavigationData } from "../../../../utils/api"; + +export default DefaultLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + return { + props: { + navigationData, + }, + }; +}; + + + + + + + + + + + + + +## Introduction + +This foundation page was created to help establish a familiar and accessible user experience when interacting with data visualization across all Twilio products. These recommendations should enable you to tell accurate and convincing stories around data in a visually consistent and accessible manner. + +### Adding Highcharts Accessibility module + +Highcharts by default does not include its [Accessibility](https://www.highcharts.com/docs/accessibility/accessibility-module) module. Every Highcharts license includes the Accessibility module which adheres to the WCAG 2.1 standard and adds enhanced keyboard navigation and screen reader functionality. + +A helper function `applyPasteHighchartsModules` is available from the [data visualization library package](/core/libraries/data-visualization#applypastehighchartsmodules), which applies additional modules to Highcharts. This function should be called at the component level where the Highcharts namespace is passed to HighchartsReact. + +```jsx +import * as Highcharts from "highcharts"; +import HighchartsReact from "highcharts-react-official"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import * as React from "react"; +import { + usePasteHighchartsTheme, + applyPasteHighchartsModules, +} from "@twilio-paste/core/data-visualization-library"; +import { ChartContext } from "@twilio-paste/core/chart-provider"; +import { Box } from "@twilio-paste/core/box"; + + +const Chart: React.FC = () => { + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); + const chartRef = React.useRef(null); + const { options, setChart, setChartRef } = React.useContext(); + const [chartOptions, setChartOptions] = React.useState( + usePasteHighchartsTheme(options) + ); + + React.useLayoutEffect(() => { + setChartOptions(Highcharts.merge(chartOptions, options)); + }, [options]); + + React.useEffect(() => { + if (chartRef.current) { + setChartRef(chartRef.current); + } + }, [chartRef.current]); + + const callback = (chart: Highcharts.Chart) => { + if (chart?.series?.length > 0) { + setChart(chart); + } + }; + + return ( + + + + ); +}; + +export const BaseChart = React.memo(Chart); +``` + + + + diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx new file mode 100644 index 0000000000..08216afd42 --- /dev/null +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -0,0 +1,112 @@ +export const meta = { + title: "Data Visualization", + description: "An introduciton to building charts for engineers.", + slug: "/foundations/data-visualization/engineering/", +}; + +import Image from "next/image"; +import Highcharts from "highcharts"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import HighchartsReact from "highcharts-react-official"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; + +import { Box } from "@twilio-paste/box"; +import { Heading } from "@twilio-paste/heading"; +import { Text } from "@twilio-paste/text"; +import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; +import { PageHeaderSeparator } from "@twilio-paste/page-header"; +import { Separator } from "@twilio-paste/separator"; + +import { SidebarCategoryRoutes } from "../../../../constants"; +import DefaultLayout from "../../../../layouts/DefaultLayout"; +import { getNavigationData } from "../../../../utils/api"; + +export default DefaultLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + return { + props: { + navigationData, + }, + }; +}; + + + + + + + + + + + + + +## Introduction + +This foundation page was created to help establish a familiar and accessible user experience when interacting with data visualization across all Twilio products. These recommendations should enable you to tell accurate and convincing stories around data in a visually consistent and accessible manner. + +### Adding Highcharts Accessibility module + +Highcharts by default does not include its [Accessibility](https://www.highcharts.com/docs/accessibility/accessibility-module) module. Every Highcharts license includes the Accessibility module which adheres to the WCAG 2.1 standard and adds enhanced keyboard navigation and screen reader functionality. + +A helper function `applyPasteHighchartsModules` is available from the [data visualization library package](/core/libraries/data-visualization#applypastehighchartsmodules), which applies additional modules to Highcharts. This function should be called at the component level where the Highcharts namespace is passed to HighchartsReact. + +```jsx +import * as Highcharts from "highcharts"; +import HighchartsReact from "highcharts-react-official"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import * as React from "react"; +import { + usePasteHighchartsTheme, + applyPasteHighchartsModules, +} from "@twilio-paste/core/data-visualization-library"; +import { ChartContext } from "@twilio-paste/core/chart-provider"; +import { Box } from "@twilio-paste/core/box"; + + +const Chart: React.FC = () => { + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); + const chartRef = React.useRef(null); + const { options, setChart, setChartRef } = React.useContext(); + const [chartOptions, setChartOptions] = React.useState( + usePasteHighchartsTheme(options) + ); + + React.useLayoutEffect(() => { + setChartOptions(Highcharts.merge(chartOptions, options)); + }, [options]); + + React.useEffect(() => { + if (chartRef.current) { + setChartRef(chartRef.current); + } + }, [chartRef.current]); + + const callback = (chart: Highcharts.Chart) => { + if (chart?.series?.length > 0) { + setChart(chart); + } + }; + + return ( + + + + ); +}; + +export const BaseChart = React.memo(Chart); +``` + + + + diff --git a/packages/paste-website/src/pages/foundations/data-visualization/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/index.mdx index bb542d3552..1cfa7b47ca 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/index.mdx @@ -16,6 +16,7 @@ import { Text } from "@twilio-paste/text"; import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; import { PageHeaderSeparator } from "@twilio-paste/page-header"; import { Separator } from "@twilio-paste/separator"; +import {Anchor} from "@twilio-paste/anchor"; import { ResponsiveImage } from "../../../components/ResponsiveImage"; import { SidebarCategoryRoutes } from "../../../constants"; @@ -62,6 +63,15 @@ This foundation page was created to help establish a familiar and accessible use ### For engineers + + + Paste Chart support + + We're actively working on full charting support through a suite of Paste components designed to make it easy to build pre-styled, interactive charts. As we expand these capabilities, we’ll continue adding more examples and documentation in the Engineering section. We plan to roll out support for additional chart types over time and recommend using our components if they fit your current needs. + + + + The easiest way to use the data visualization tokens in your charts is to use `usePasteHighchartsTheme` from the [data visualization library package](/core/libraries/data-visualization) with [Highcharts](https://www.highcharts.com/). The `usePasteHighchartsTheme` hook takes an object of Highchart configurations and returns a new object with Paste colors and fonts. Be sure to include the [Highcharts Accessibility module](/foundations/data-visualization#adding-highcharts-accessibility-module) to ensure that your charts are accessible to all users. From 4654b80f84cb9547f190f50fb052cd303426bc81 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 11 Apr 2025 09:53:45 -0500 Subject: [PATCH 02/26] feat(data-viz): wokring base chart --- .../components/list/stories/index.stories.tsx | 42 +++++++++++++++- .../stories/base-chart.stories.tsx | 30 ++++++++++++ .../stories/components/BaseChart.tsx | 48 +++++++++++++++++++ .../data-visualization/engineering/index.mdx | 24 +++------- 4 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx create mode 100644 packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx diff --git a/packages/paste-core/components/list/stories/index.stories.tsx b/packages/paste-core/components/list/stories/index.stories.tsx index d48d50dc83..225674ba0a 100644 --- a/packages/paste-core/components/list/stories/index.stories.tsx +++ b/packages/paste-core/components/list/stories/index.stories.tsx @@ -5,7 +5,7 @@ import { Stack } from "@twilio-paste/stack"; import { useTheme } from "@twilio-paste/theme"; import * as React from "react"; -import { ListItem, OrderedList, UnorderedList } from "../src"; +import { List, ListItem, OrderedList, UnorderedList } from "../src"; // eslint-disable-next-line import/no-default-export export default { @@ -110,6 +110,46 @@ export const NestedUnorderedList = (): React.ReactNode => { ); }; +export const DefaultList = (): React.ReactNode => { + return ( + <> + + + Deliver critical time-sensitive messages to employees and customers at scale with the Programmable Messaging + API. + + + + Deliver critical time-sensitive messages to employees and customers at scale with the Programmable Messaging + API. + + + + Deliver critical time-sensitive messages to employees and customers at scale with the Programmable + Messaging API. + + + Proactively inform customers about account activity, purchase confirmations, and shipping notifications + with the + Programmable Messaging API. + + + + Proactively inform customers about account activity, purchase confirmations, and shipping notifications with + the + Programmable Messaging API. + + + + Proactively inform customers about account activity, purchase confirmations, and shipping notifications with + the + Programmable Messaging API. + + + + ); +}; + export const CustomOrderedList: StoryFn = (_args, { parameters: { isTestEnvironment } }) => { const currentTheme = useTheme(); return ( diff --git a/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx b/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx new file mode 100644 index 0000000000..a1ddbdda1f --- /dev/null +++ b/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx @@ -0,0 +1,30 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import { Stack } from "@twilio-paste/stack"; +import * as React from "react"; +/* eslint-enable */ + +import { ChartProvider } from "@twilio-paste/chart-provider"; +import { BaseChart } from "./components/BaseChart"; +import { lineChartOptions } from "./options/lineChartOptions"; + +// eslint-disable-next-line import/no-default-export +export default { + title: "Libraries/data-visualization/base-chart", + parameters: { + chromatic: { disableSnapshot: true }, + a11y: { + // no need to a11y check composition of a11y checked components + disable: true, + }, + }, +} as Meta; + +export const HighchartsOptions: StoryFn = () => { + return ( + + + + + + ); +}; diff --git a/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx new file mode 100644 index 0000000000..517b5bb5bc --- /dev/null +++ b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx @@ -0,0 +1,48 @@ +import { Box } from "@twilio-paste/box"; +import { ChartContext } from "@twilio-paste/chart-provider"; +import * as Highcharts from "highcharts"; +import HighchartsReact from "highcharts-react-official"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import * as React from "react"; + +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "../../src"; + +const Chart: React.FC = () => { + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); + const chartRef = React.useRef(null); + const { options, setChart, setChartRef } = React.useContext(ChartContext); + const [chartOptions, setChartOptions] = React.useState( + // disabling animation for stories only. Not included in our docs exmaples + usePasteHighchartsTheme({ ...options, plotOptions: { series: { animation: false } } }), + ); + + React.useLayoutEffect(() => { + setChartOptions(Highcharts.merge(chartOptions, options)); + }, [options]); + + React.useEffect(() => { + if (chartRef.current) { + setChartRef(chartRef.current); + } + }, [chartRef.current]); + + const callback = (chart: Highcharts.Chart) => { + if (chart?.series?.length > 0) { + setChart(chart); + } + }; + + return ( + + + + ); +}; + +export const BaseChart = React.memo(Chart); diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index 08216afd42..a2bfb348b0 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -46,34 +46,24 @@ export const getStaticProps = async () => { ## Introduction -This foundation page was created to help establish a familiar and accessible user experience when interacting with data visualization across all Twilio products. These recommendations should enable you to tell accurate and convincing stories around data in a visually consistent and accessible manner. +When building -### Adding Highcharts Accessibility module - -Highcharts by default does not include its [Accessibility](https://www.highcharts.com/docs/accessibility/accessibility-module) module. Every Highcharts license includes the Accessibility module which adheres to the WCAG 2.1 standard and adds enhanced keyboard navigation and screen reader functionality. - -A helper function `applyPasteHighchartsModules` is available from the [data visualization library package](/core/libraries/data-visualization#applypastehighchartsmodules), which applies additional modules to Highcharts. This function should be called at the component level where the Highcharts namespace is passed to HighchartsReact. +## Base chart ```jsx +import { ChartContext } from "@twilio-paste/core/chart-provider"; +import { Box } from "@twilio-paste/core/box"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/core/data-visualization-library"; import * as Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; import * as React from "react"; -import { - usePasteHighchartsTheme, - applyPasteHighchartsModules, -} from "@twilio-paste/core/data-visualization-library"; -import { ChartContext } from "@twilio-paste/core/chart-provider"; -import { Box } from "@twilio-paste/core/box"; - const Chart: React.FC = () => { applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); const chartRef = React.useRef(null); - const { options, setChart, setChartRef } = React.useContext(); - const [chartOptions, setChartOptions] = React.useState( - usePasteHighchartsTheme(options) - ); + const { options, setChart, setChartRef } = React.useContext(ChartContext); + const [chartOptions, setChartOptions] = React.useState(usePasteHighchartsTheme(options)); React.useLayoutEffect(() => { setChartOptions(Highcharts.merge(chartOptions, options)); From 0cbd203d6075b5929e2048c0b75084eb7ec3b2b9 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 11 Apr 2025 10:37:37 -0500 Subject: [PATCH 03/26] feat(data-viz): wip --- .../src/usePasteHighchartsTheme.tsx | 8 +- .../stories/components/BaseChart.tsx | 2 +- .../sidebar/SidebarNavigation.tsx | 3 - .../engineering/base-chart.mdx | 112 ------------------ .../data-visualization/engineering/index.mdx | 36 +++++- 5 files changed, 42 insertions(+), 119 deletions(-) delete mode 100644 packages/paste-website/src/pages/foundations/data-visualization/engineering/base-chart.mdx diff --git a/packages/paste-libraries/data-visualization/src/usePasteHighchartsTheme.tsx b/packages/paste-libraries/data-visualization/src/usePasteHighchartsTheme.tsx index 23e81c5079..c671813e3a 100644 --- a/packages/paste-libraries/data-visualization/src/usePasteHighchartsTheme.tsx +++ b/packages/paste-libraries/data-visualization/src/usePasteHighchartsTheme.tsx @@ -105,9 +105,15 @@ export const usePasteHighchartsTheme = (options: Highcharts.Options): Highcharts }, }, tooltip: { - backgroundColor: context.backgroundColors.colorBackground, + backgroundColor: context.backgroundColors.colorBackgroundBodyInverse, + borderColor: context.borderColors.colorBorderInverse, + borderWidth: context.borderWidths.borderWidth10, + borderRadius: context.radii.borderRadius30.replace("px", ""), + padding: 12, style: { + fontFamily: context.fonts.fontFamilyText, color: context.textColors.colorText, + fontSize: context.fontSizes.fontSize30, }, }, credits: { diff --git a/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx index 517b5bb5bc..c0e533d9c3 100644 --- a/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx +++ b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx @@ -12,7 +12,7 @@ const Chart: React.FC = () => { const chartRef = React.useRef(null); const { options, setChart, setChartRef } = React.useContext(ChartContext); const [chartOptions, setChartOptions] = React.useState( - // disabling animation for stories only. Not included in our docs exmaples + // disabling animation for stories only. Not included in our docs examples usePasteHighchartsTheme({ ...options, plotOptions: { series: { animation: false } } }), ); diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 21264257cd..844353576a 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -142,9 +142,6 @@ const SiteSidebarNavigation = (): JSX.Element => { categoryRoute={`${SidebarCategoryRoutes.DATA_VISUALIZATION}/engineering`} > Overview - - Base Chart - { - const navigationData = await getNavigationData(); - return { - props: { - navigationData, - }, - }; -}; - - - - - - - - - - - - - -## Introduction - -This foundation page was created to help establish a familiar and accessible user experience when interacting with data visualization across all Twilio products. These recommendations should enable you to tell accurate and convincing stories around data in a visually consistent and accessible manner. - -### Adding Highcharts Accessibility module - -Highcharts by default does not include its [Accessibility](https://www.highcharts.com/docs/accessibility/accessibility-module) module. Every Highcharts license includes the Accessibility module which adheres to the WCAG 2.1 standard and adds enhanced keyboard navigation and screen reader functionality. - -A helper function `applyPasteHighchartsModules` is available from the [data visualization library package](/core/libraries/data-visualization#applypastehighchartsmodules), which applies additional modules to Highcharts. This function should be called at the component level where the Highcharts namespace is passed to HighchartsReact. - -```jsx -import * as Highcharts from "highcharts"; -import HighchartsReact from "highcharts-react-official"; -import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; -import * as React from "react"; -import { - usePasteHighchartsTheme, - applyPasteHighchartsModules, -} from "@twilio-paste/core/data-visualization-library"; -import { ChartContext } from "@twilio-paste/core/chart-provider"; -import { Box } from "@twilio-paste/core/box"; - - -const Chart: React.FC = () => { - applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); - const chartRef = React.useRef(null); - const { options, setChart, setChartRef } = React.useContext(); - const [chartOptions, setChartOptions] = React.useState( - usePasteHighchartsTheme(options) - ); - - React.useLayoutEffect(() => { - setChartOptions(Highcharts.merge(chartOptions, options)); - }, [options]); - - React.useEffect(() => { - if (chartRef.current) { - setChartRef(chartRef.current); - } - }, [chartRef.current]); - - const callback = (chart: Highcharts.Chart) => { - if (chart?.series?.length > 0) { - setChart(chart); - } - }; - - return ( - - - - ); -}; - -export const BaseChart = React.memo(Chart); -``` - - - - diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index a2bfb348b0..4a498c1f99 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -16,6 +16,7 @@ import { Text } from "@twilio-paste/text"; import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; import { PageHeaderSeparator } from "@twilio-paste/page-header"; import { Separator } from "@twilio-paste/separator"; +import { InlineCode } from "@twilio-paste/inline-code"; import { SidebarCategoryRoutes } from "../../../../constants"; import DefaultLayout from "../../../../layouts/DefaultLayout"; @@ -46,9 +47,38 @@ export const getStaticProps = async () => { ## Introduction -When building + + + In progress + As our current data visualization offerings are in progress these documents are subject to change. We will revise and expand these pages when new features are supported. + + -## Base chart +Our charting components are designed to work seamlessly with Highcharts. However, due to licensing restrictions, we cannot include Highcharts directly in our library. This limitation creates challenges when developing components for a library we cannot directly integrate with. + +To address this, we have created components and wrappers that simplify the Highcharts API. These tools expose various props, allowing you to configure charts through a streamlined and user-friendly interface. The props are transformed into objects that Highcharts can interpret, and our components automatically apply styles to the charts for a consistent appearance. + +## Setup + +To ensure our components function correctly, some initial configuration is required in your project. This seciton will cover: +- Storing and retrieving rendered chart objects. +- Setting up the chart context. +- Adding any additional modules required for additional functionality such as gauges, exporting etc. + +### Base chart + +You will need to include a component that retrieves the chart configuration from our components' context and passes it to Highcharts. This component must also capture the rendered chart and store it in our `ChartContext`. + +Storing the rendered chart is essential for several reasons. It allows us to determine the positioning of elements relative to the screen, enabling the placement of components like tooltips. Additionally, it facilitates triggering update functions on the chart for interactions such as zooming or toggling the visibility of series through a legend component. + + + + Modules subject to change + As we expand our supported charts you will need to maintain this file to include any required modules for the new charts or functionality of our components to work correctly. The change will look like the following: + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule, HighchartsSankeyModule, ...); + + ```jsx import { ChartContext } from "@twilio-paste/core/chart-provider"; @@ -60,6 +90,7 @@ import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; import * as React from "react"; const Chart: React.FC = () => { + // Load the accessibility module and any other modules you need. applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); const chartRef = React.useRef(null); const { options, setChart, setChartRef } = React.useContext(ChartContext); @@ -76,6 +107,7 @@ const Chart: React.FC = () => { }, [chartRef.current]); const callback = (chart: Highcharts.Chart) => { + // Ensure the chart has been rendered before setting it. This will cause issues in our components if the series is empty. if (chart?.series?.length > 0) { setChart(chart); } From 97f8ac222d8a1dc98e82f604a8c9e73c8a3bd6e6 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 11 Apr 2025 16:18:19 -0500 Subject: [PATCH 04/26] feat(data-viz): wip --- .../sidebar/SidebarNavigation.tsx | 26 ++++++++ .../data-visualization/chart-provider/api.mdx | 61 +++++++++++++++++++ .../chart-provider/changelog.mdx | 36 +++++++++++ .../chart-provider/index.mdx | 58 ++++++++++++++++++ .../engineering/chart-types.mdx | 57 +++++++++++++++++ .../data-visualization/engineering/index.mdx | 22 +++++-- 6 files changed, 255 insertions(+), 5 deletions(-) create mode 100644 packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx create mode 100644 packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx create mode 100644 packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx create mode 100644 packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 844353576a..84d6d8e2c7 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -142,6 +142,9 @@ const SiteSidebarNavigation = (): JSX.Element => { categoryRoute={`${SidebarCategoryRoutes.DATA_VISUALIZATION}/engineering`} > Overview + + Chart types + { if (name === "Sidebar Navigation") { return null; } + if (name === "Data Visualization") { + return ( + + event({ + category: "Left Navigation", + action: `click-${name}`, + label: name, + }) + } + > + + Chart Provider + + + ); + } return ( {name} diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx b/packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx new file mode 100644 index 0000000000..87f5279e8f --- /dev/null +++ b/packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx @@ -0,0 +1,61 @@ +import Changelog from '@twilio-paste/chart-provider/CHANGELOG.md'; // I don't know why this is needed but if you remove it the page fails to render +import packageJson from '@twilio-paste/chart-provider/package.json'; + +import {SidebarCategoryRoutes} from '../../../../constants'; +import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData, getComponentApi} from '../../../../utils/api'; + +export const meta = { + title: 'ChartProvider', + package: '@twilio-paste/chart-provider', + description: packageJson.description, + slug: '/components/chart-provider/api', +}; + +export default ComponentPageLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + const feature = await getFeature('Chart Provider'); + const {componentApi, componentApiTocData} = getComponentApi('@twilio-paste/chart-provider'); + return { + props: { + data: { + ...packageJson, + ...feature, + }, + componentApi, + mdxHeadings: [...mdxHeadings, ...componentApiTocData], + navigationData, + pageHeaderData: { + categoryRoute: SidebarCategoryRoutes.COMPONENTS, + githubUrl: 'https://github.com/twilio-labs/paste/tree/main/packages/paste-core/components/chart-provider', + storybookUrl: '/?path=/story/components-chartprovider', + }, + }, + }; +}; + +## Installation + +```bash +yarn add @twilio-paste/chart-provider - or - yarn add @twilio-paste/core +``` + +## Usage + +```jsx +import { ChartProvider } from '@twilio-paste/core/chart-provider'; + +const ChartProviderExample = () => { + return ( + + + + ); +}; +``` + +## Props + + diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx b/packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx new file mode 100644 index 0000000000..829b22e20c --- /dev/null +++ b/packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx @@ -0,0 +1,36 @@ +import {SidebarCategoryRoutes} from '../../../../constants'; +import Changelog from '@twilio-paste/chart-provider/CHANGELOG.md'; +import packageJson from '@twilio-paste/chart-provider/package.json'; +import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData} from '../../../../utils/api'; + +export const meta = { + title: 'Chart Provider', + package: '@twilio-paste/chart-provider', + description: packageJson.description, + slug: '/components/chart-provider/changelog', +}; + +export default ComponentPageLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + const feature = await getFeature('Chart Provider'); + return { + props: { + data: { + ...packageJson, + ...feature, + }, + navigationData, + mdxHeadings, + pageHeaderData: { + categoryRoute: SidebarCategoryRoutes.COMPONENTS, + githubUrl: 'https://github.com/twilio-labs/paste/tree/main/packages/paste-core/components/chart-provider', + storybookUrl: '/?path=/story/components-chartprovider', + }, + }, + }; +}; + + diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx b/packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx new file mode 100644 index 0000000000..2d2741f82b --- /dev/null +++ b/packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx @@ -0,0 +1,58 @@ +import { ChartProvider } from '@twilio-paste/chart-provider'; +import packageJson from '@twilio-paste/chart-provider/package.json'; + +import {SidebarCategoryRoutes} from '../../../../constants'; +import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData} from '../../../../utils/api'; + +export const meta = { + title: 'Chart Provider', + package: '@twilio-paste/chart-provider', + description: packageJson.description, + slug: '/components/data-viz/chart-provider/', +}; + +export default ComponentPageLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + const feature = await getFeature('Chart Provider'); + return { + props: { + data: { + ...packageJson, + ...feature, + }, + navigationData, + mdxHeadings, + pageHeaderData: { + categoryRoute: SidebarCategoryRoutes.COMPONENTS, + githubUrl: 'https://github.com/twilio-labs/paste/tree/main/packages/paste-core/components/chart-provider', + storybookUrl: '/?path=/story/components-chartprovider', //TODO: Update this to the correct storybook URL + }, + }, + }; +}; + + + {``} + + +## Guidelines + +## About Chart Provider + +## Examples + + + {``} + + +## Composition Notes + diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx new file mode 100644 index 0000000000..cfc6ff4a95 --- /dev/null +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx @@ -0,0 +1,57 @@ +export const meta = { + title: "Data Visualization", + description: "Display the supported chart types for the Paste Data Visualization library with coded examples.", + slug: "/foundations/data-visualization/engineering/chart-types", +}; + +import Image from "next/image"; +import Highcharts from "highcharts"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import HighchartsReact from "highcharts-react-official"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; + +import { Box } from "@twilio-paste/box"; +import { Heading } from "@twilio-paste/heading"; +import { Text } from "@twilio-paste/text"; +import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; +import { PageHeaderSeparator } from "@twilio-paste/page-header"; +import { Separator } from "@twilio-paste/separator"; +import { InlineCode } from "@twilio-paste/inline-code"; + +import { SidebarCategoryRoutes } from "../../../../constants"; +import DefaultLayout from "../../../../layouts/DefaultLayout"; +import { getNavigationData } from "../../../../utils/api"; + +export default DefaultLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + return { + props: { + navigationData, + }, + }; +}; + + + + + + + + + + + + + + + + In progress + As our current data visualization offerings are in progress these documents are subject to change. We will revise and expand these pages when new chart types are supported. + + + + + + diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index 4a498c1f99..c240567351 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -1,6 +1,6 @@ export const meta = { title: "Data Visualization", - description: "An introduciton to building charts for engineers.", + description: "An overview of integrating Highcharts with Paste's data visualization components, including setup, licensing, and chart context.", slug: "/foundations/data-visualization/engineering/", }; @@ -56,21 +56,26 @@ export const getStaticProps = async () => { Our charting components are designed to work seamlessly with Highcharts. However, due to licensing restrictions, we cannot include Highcharts directly in our library. This limitation creates challenges when developing components for a library we cannot directly integrate with. -To address this, we have created components and wrappers that simplify the Highcharts API. These tools expose various props, allowing you to configure charts through a streamlined and user-friendly interface. The props are transformed into objects that Highcharts can interpret, and our components automatically apply styles to the charts for a consistent appearance. +To address this, we have created components and wrappers that simplify the Highcharts API. These tools expose various props, allowing you to configure charts through a streamlined and user-friendly interface. The props are transformed into objects that Highcharts can interpret, and our components automatically apply styles to the charts for a consistent appearance on a chart type bases. Global styles will be set in the `BaseChart` using our existing hook. + +## Licensing + +Paste does not provide a license for Twilio usage. Licenses are acquired on an applicaiton level. ODds are, if you are developing in one of our existing products you already have one. If you are creating a new application you may need to acquire a new license. ## Setup To ensure our components function correctly, some initial configuration is required in your project. This seciton will cover: - Storing and retrieving rendered chart objects. -- Setting up the chart context. - Adding any additional modules required for additional functionality such as gauges, exporting etc. -### Base chart - You will need to include a component that retrieves the chart configuration from our components' context and passes it to Highcharts. This component must also capture the rendered chart and store it in our `ChartContext`. Storing the rendered chart is essential for several reasons. It allows us to determine the positioning of elements relative to the screen, enabling the placement of components like tooltips. Additionally, it facilitates triggering update functions on the chart for interactions such as zooming or toggling the visibility of series through a legend component. +### BaseChart + +We recommend copying the below code and creating an instance of it in your application to use with our components. This component is designed to be reused across all charts. You do not need a new instance of this component for each chart. + Modules subject to change @@ -128,6 +133,13 @@ const Chart: React.FC = () => { export const BaseChart = React.memo(Chart); ``` +## Chart context + +We use React Context to store the rendered chart object to use in our components. When talking about the chart context we do not only mean the rendered object but also the initial configuration. You will need to pass data to the context for the BaseChart to read and use. + +Each individual chart instance will be wrapped in a [ChartProvider](/components/data-visualization/chart-provider) which sets the initial configuration and apply chart specific styles. + +An individual chart instance does not mean a chart only. It may also mean chart titles, legends, tooltips and any other component that does not sit in or on the chart canvas. In simpler terms, it is a container that wraps not only the Highcharts elements but any of our Paste components that interact with that chart instance. From 1f696ac54568863a369b5fd72638fad30dcb5f0a Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 14 Apr 2025 09:02:03 -0500 Subject: [PATCH 05/26] feat(data-viz): wip --- .../components/site-wrapper/sidebar/SidebarNavigation.tsx | 5 +++-- .../{data-visualization => }/chart-provider/api.mdx | 6 +++--- .../{data-visualization => }/chart-provider/changelog.mdx | 6 +++--- .../{data-visualization => }/chart-provider/index.mdx | 6 +++--- .../foundations/data-visualization/engineering/index.mdx | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) rename packages/paste-website/src/pages/components/{data-visualization => }/chart-provider/api.mdx (91%) rename packages/paste-website/src/pages/components/{data-visualization => }/chart-provider/changelog.mdx (82%) rename packages/paste-website/src/pages/components/{data-visualization => }/chart-provider/index.mdx (85%) diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 84d6d8e2c7..bc132c004d 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -372,6 +372,7 @@ const SiteSidebarNavigation = (): JSX.Element => { if (name === "Sidebar Navigation") { return null; } + if(['Chart Provider'].includes(name)) {return null} if (name === "Data Visualization") { return ( { } > Chart Provider diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx b/packages/paste-website/src/pages/components/chart-provider/api.mdx similarity index 91% rename from packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx rename to packages/paste-website/src/pages/components/chart-provider/api.mdx index 87f5279e8f..bbbc7324e9 100644 --- a/packages/paste-website/src/pages/components/data-visualization/chart-provider/api.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/api.mdx @@ -1,9 +1,9 @@ import Changelog from '@twilio-paste/chart-provider/CHANGELOG.md'; // I don't know why this is needed but if you remove it the page fails to render import packageJson from '@twilio-paste/chart-provider/package.json'; -import {SidebarCategoryRoutes} from '../../../../constants'; -import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; -import {getFeature, getNavigationData, getComponentApi} from '../../../../utils/api'; +import {SidebarCategoryRoutes} from '../../../constants'; +import ComponentPageLayout from '../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData, getComponentApi} from '../../../utils/api'; export const meta = { title: 'ChartProvider', diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx b/packages/paste-website/src/pages/components/chart-provider/changelog.mdx similarity index 82% rename from packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx rename to packages/paste-website/src/pages/components/chart-provider/changelog.mdx index 829b22e20c..db2af07583 100644 --- a/packages/paste-website/src/pages/components/data-visualization/chart-provider/changelog.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/changelog.mdx @@ -1,8 +1,8 @@ -import {SidebarCategoryRoutes} from '../../../../constants'; +import {SidebarCategoryRoutes} from '../../../constants'; import Changelog from '@twilio-paste/chart-provider/CHANGELOG.md'; import packageJson from '@twilio-paste/chart-provider/package.json'; -import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; -import {getFeature, getNavigationData} from '../../../../utils/api'; +import ComponentPageLayout from '../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData} from '../../../utils/api'; export const meta = { title: 'Chart Provider', diff --git a/packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx similarity index 85% rename from packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx rename to packages/paste-website/src/pages/components/chart-provider/index.mdx index 2d2741f82b..452abe8a97 100644 --- a/packages/paste-website/src/pages/components/data-visualization/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -1,9 +1,9 @@ import { ChartProvider } from '@twilio-paste/chart-provider'; import packageJson from '@twilio-paste/chart-provider/package.json'; -import {SidebarCategoryRoutes} from '../../../../constants'; -import ComponentPageLayout from '../../../../layouts/ComponentPageLayout'; -import {getFeature, getNavigationData} from '../../../../utils/api'; +import {SidebarCategoryRoutes} from '../../../constants'; +import ComponentPageLayout from '../../../layouts/ComponentPageLayout'; +import {getFeature, getNavigationData} from '../../../utils/api'; export const meta = { title: 'Chart Provider', diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index c240567351..df46982e07 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -137,7 +137,7 @@ export const BaseChart = React.memo(Chart); We use React Context to store the rendered chart object to use in our components. When talking about the chart context we do not only mean the rendered object but also the initial configuration. You will need to pass data to the context for the BaseChart to read and use. -Each individual chart instance will be wrapped in a [ChartProvider](/components/data-visualization/chart-provider) which sets the initial configuration and apply chart specific styles. +Each individual chart instance will be wrapped in a [ChartProvider](/components/chart-provider) which sets the initial configuration and apply chart specific styles. An individual chart instance does not mean a chart only. It may also mean chart titles, legends, tooltips and any other component that does not sit in or on the chart canvas. In simpler terms, it is a container that wraps not only the Highcharts elements but any of our Paste components that interact with that chart instance. From 427a1bde9d278fe837a742b058cf8e6060ee9b1b Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 14 Apr 2025 10:53:26 -0500 Subject: [PATCH 06/26] feat(data-viz): wip --- .../data-visualization/BaseChart.tsx | 47 +++++++++++++++ .../ChartProviderExamples.ts | 57 +++++++++++++++++++ .../pages/components/chart-provider/index.mdx | 16 ++++-- 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx create mode 100644 packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts diff --git a/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx new file mode 100644 index 0000000000..e47c171be0 --- /dev/null +++ b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx @@ -0,0 +1,47 @@ +import { Box } from "@twilio-paste/box"; +import { ChartContext } from "@twilio-paste/chart-provider"; +import * as Highcharts from "highcharts"; +import HighchartsReact from "highcharts-react-official"; +import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; +import * as React from "react"; + + +const Chart: React.FC = () => { + applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); + const chartRef = React.useRef(null); + const { options, setChart, setChartRef } = React.useContext(ChartContext); + const [chartOptions, setChartOptions] = React.useState( + usePasteHighchartsTheme(options), + ); + + React.useLayoutEffect(() => { + setChartOptions(Highcharts.merge(chartOptions, options)); + }, [options]); + + React.useEffect(() => { + if (chartRef.current) { + setChartRef(chartRef.current); + } + }, [chartRef.current]); + + const callback = (chart: Highcharts.Chart) => { + if (chart?.series?.length > 0) { + setChart(chart); + } + }; + + return ( + + + + ); +}; + +export const ExamplesDataVizBaseChart = React.memo(Chart); \ No newline at end of file diff --git a/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts b/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts new file mode 100644 index 0000000000..189b053a16 --- /dev/null +++ b/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts @@ -0,0 +1,57 @@ +export const SimpleChartProviderExample = ` +const ChartProviderExample = () => { + const lineSeriesData = [ + { + name: "Installation", + data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175], + }, + { + name: "Manufacturing", + data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434], + }, + ] + + return ( + + + + ); +}; + +render(); +`.trim(); + +export const CustomChartProviderExample = ` +const ChartProviderExample = () => { + const lineSeriesData = [ + { + name: "Installation", + data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175], + type: "line", + }, + { + name: "Manufacturing", + data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434], + type: "line", + }, + { + name: "Sales & Distribution", + data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387], + type: "column", + }, + { + name: "Project Development", + data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227], + type: "column", + }, + ] + + return ( + + + + ); +}; + +render(); +`.trim(); diff --git a/packages/paste-website/src/pages/components/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx index 452abe8a97..7c7af0a51f 100644 --- a/packages/paste-website/src/pages/components/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -4,6 +4,8 @@ import packageJson from '@twilio-paste/chart-provider/package.json'; import {SidebarCategoryRoutes} from '../../../constants'; import ComponentPageLayout from '../../../layouts/ComponentPageLayout'; import {getFeature, getNavigationData} from '../../../utils/api'; +import {ExamplesDataVizBaseChart as BaseChart} from '../../../component-examples/data-visualization/BaseChart'; +import {CustomChartProviderExample, SimpleChartProviderExample} from '../../../component-examples/data-visualization/ChartProviderExamples'; export const meta = { title: 'Chart Provider', @@ -35,10 +37,11 @@ export const getStaticProps = async () => { }; - {``} +{SimpleChartProviderExample} ## Guidelines @@ -47,11 +50,16 @@ export const getStaticProps = async () => { ## Examples +### Custom Chart + + + - {``} +{CustomChartProviderExample} ## Composition Notes From 3ba67893328db16f95a0f3e4774375df94a8f747 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 14 Apr 2025 11:09:52 -0500 Subject: [PATCH 07/26] feat(data-viz): sitemap --- cypress/integration/sitemap-vrt/constants.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cypress/integration/sitemap-vrt/constants.ts b/cypress/integration/sitemap-vrt/constants.ts index fcf0b3ee93..ec3c4ca723 100644 --- a/cypress/integration/sitemap-vrt/constants.ts +++ b/cypress/integration/sitemap-vrt/constants.ts @@ -61,6 +61,7 @@ export const SITEMAP = [ "/components/card/", "/components/card/api", "/components/card/changelog", + "/components/chart-provider/", "/components/chat-composer/", "/components/chat-composer/api", "/components/chat-composer/changelog", @@ -284,6 +285,8 @@ export const SITEMAP = [ "/foundations/content/word-list/", "/foundations/illustrations/", "/foundations/data-visualization/", + "/foundations/data-visualization/engineering/", + "/foundations/data-visualization/engineering/chart-types/", "/foundations/spacing-and-layout/", "/foundations/typography/", "/inclusive-design/", From db4051033f8200b4f036a6aca38bd4baa29426dc Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 14 Apr 2025 11:14:56 -0500 Subject: [PATCH 08/26] feat(data-viz): docs exmapleds --- .../data-visualization/ChartProviderExamples.ts | 2 +- .../pages/components/chart-provider/index.mdx | 17 ++++++++++++++--- .../engineering/chart-types.mdx | 13 +++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts b/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts index 189b053a16..461f90b637 100644 --- a/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts +++ b/packages/paste-website/src/component-examples/data-visualization/ChartProviderExamples.ts @@ -47,7 +47,7 @@ const ChartProviderExample = () => { ] return ( - + ); diff --git a/packages/paste-website/src/pages/components/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx index 7c7af0a51f..9b43d86651 100644 --- a/packages/paste-website/src/pages/components/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -1,4 +1,6 @@ import { ChartProvider } from '@twilio-paste/chart-provider'; +import { Box } from '@twilio-paste/box'; +import { Callout, CalloutHeading, CalloutText } from '@twilio-paste/callout'; import packageJson from '@twilio-paste/chart-provider/package.json'; import {SidebarCategoryRoutes} from '../../../constants'; @@ -48,11 +50,22 @@ export const getStaticProps = async () => { ## About Chart Provider +ChartProvider is a wrapper around Highcharts that provides a consistent API for configuring an individual chart instance. This component has no visible elements and is an engineering asset only. It acts as a store for chart options and provides a context for managing chart state. The ChartProvider component is responsible for rendering the chart and managing its lifecycle. + +We highly recommend using our [BaseChart](/foundations/data-visualization/engineering#basechart) code inside the ChartProvider to ensure that the chart is rendered correctly and state is correctly stored. + ## Examples -### Custom Chart +### Custom charts +You can use the `highchartsOptions` to create unsupported charts by passing options directly to the base chart without modification, but we recommend using our wrappers for easier migration, access to the rendered chart object, and enhanced custom interactions. + + + Compatibility + If you build charts using the Highcharts API it will be unlikely that our Paste components will function as they depend on helper funcitons and event tracking that we enrich the default options with. + + { {CustomChartProviderExample} -## Composition Notes - diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx index cfc6ff4a95..36ee511c35 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/chart-types.mdx @@ -14,6 +14,7 @@ import { Box } from "@twilio-paste/box"; import { Heading } from "@twilio-paste/heading"; import { Text } from "@twilio-paste/text"; import { Callout, CalloutHeading, CalloutText } from "@twilio-paste/callout"; +import { ChartProvider } from "@twilio-paste/chart-provider"; import { PageHeaderSeparator } from "@twilio-paste/page-header"; import { Separator } from "@twilio-paste/separator"; import { InlineCode } from "@twilio-paste/inline-code"; @@ -21,6 +22,8 @@ import { InlineCode } from "@twilio-paste/inline-code"; import { SidebarCategoryRoutes } from "../../../../constants"; import DefaultLayout from "../../../../layouts/DefaultLayout"; import { getNavigationData } from "../../../../utils/api"; +import { CustomChartProviderExample } from "../../../../component-examples/data-visualization/ChartProviderExamples"; +import { ExamplesDataVizBaseChart as BaseChart } from "../../../../component-examples/data-visualization/BaseChart"; export default DefaultLayout; @@ -52,6 +55,16 @@ export const getStaticProps = async () => { +### Custom + + +{CustomChartProviderExample} + + From 1b602022813fa70e6dc5a0527e927e7ae1188618 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 14 Apr 2025 12:14:04 -0500 Subject: [PATCH 09/26] feat(data-viz): ci checks --- .../data-visualization/stories/base-chart.stories.tsx | 3 +-- .../data-visualization/stories/components/BaseChart.tsx | 2 +- .../component-examples/data-visualization/BaseChart.tsx | 7 ++----- .../components/site-wrapper/sidebar/SidebarNavigation.tsx | 4 +++- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx b/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx index a1ddbdda1f..da83445912 100644 --- a/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx +++ b/packages/paste-libraries/data-visualization/stories/base-chart.stories.tsx @@ -1,9 +1,8 @@ import type { Meta, StoryFn } from "@storybook/react"; +import { ChartProvider } from "@twilio-paste/chart-provider"; import { Stack } from "@twilio-paste/stack"; import * as React from "react"; -/* eslint-enable */ -import { ChartProvider } from "@twilio-paste/chart-provider"; import { BaseChart } from "./components/BaseChart"; import { lineChartOptions } from "./options/lineChartOptions"; diff --git a/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx index c0e533d9c3..137003f155 100644 --- a/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx +++ b/packages/paste-libraries/data-visualization/stories/components/BaseChart.tsx @@ -26,7 +26,7 @@ const Chart: React.FC = () => { } }, [chartRef.current]); - const callback = (chart: Highcharts.Chart) => { + const callback = (chart: Highcharts.Chart): void => { if (chart?.series?.length > 0) { setChart(chart); } diff --git a/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx index e47c171be0..92da437fda 100644 --- a/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx +++ b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx @@ -6,14 +6,11 @@ import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; import * as React from "react"; - const Chart: React.FC = () => { applyPasteHighchartsModules(Highcharts, HighchartsAccessibilityModule); const chartRef = React.useRef(null); const { options, setChart, setChartRef } = React.useContext(ChartContext); - const [chartOptions, setChartOptions] = React.useState( - usePasteHighchartsTheme(options), - ); + const [chartOptions, setChartOptions] = React.useState(usePasteHighchartsTheme(options)); React.useLayoutEffect(() => { setChartOptions(Highcharts.merge(chartOptions, options)); @@ -44,4 +41,4 @@ const Chart: React.FC = () => { ); }; -export const ExamplesDataVizBaseChart = React.memo(Chart); \ No newline at end of file +export const ExamplesDataVizBaseChart = React.memo(Chart); diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index bc132c004d..e7f0782452 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -372,7 +372,9 @@ const SiteSidebarNavigation = (): JSX.Element => { if (name === "Sidebar Navigation") { return null; } - if(['Chart Provider'].includes(name)) {return null} + if (["Chart Provider"].includes(name)) { + return null; + } if (name === "Data Visualization") { return ( Date: Wed, 16 Apr 2025 10:19:24 -0500 Subject: [PATCH 10/26] feat(data-viz): docs refinement --- .../src/pages/components/chart-provider/index.mdx | 6 +++--- .../data-visualization/engineering/index.mdx | 10 +++++----- .../src/pages/foundations/data-visualization/index.mdx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/paste-website/src/pages/components/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx index 9b43d86651..c84b1a24d2 100644 --- a/packages/paste-website/src/pages/components/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -50,7 +50,7 @@ export const getStaticProps = async () => { ## About Chart Provider -ChartProvider is a wrapper around Highcharts that provides a consistent API for configuring an individual chart instance. This component has no visible elements and is an engineering asset only. It acts as a store for chart options and provides a context for managing chart state. The ChartProvider component is responsible for rendering the chart and managing its lifecycle. +Chart Provider is a wrapper around Highcharts that provides a consistent API for configuring an individual chart instance. This component has no visible elements and is an engineering asset only. It acts as a store for chart options and provides a context for managing chart state. We highly recommend using our [BaseChart](/foundations/data-visualization/engineering#basechart) code inside the ChartProvider to ensure that the chart is rendered correctly and state is correctly stored. @@ -58,12 +58,12 @@ We highly recommend using our [BaseChart](/foundations/data-visualization/engine ### Custom charts -You can use the `highchartsOptions` to create unsupported charts by passing options directly to the base chart without modification, but we recommend using our wrappers for easier migration, access to the rendered chart object, and enhanced custom interactions. +You can use the `highchartsOptions` to create unsupported charts by passing the Higcharts config directly to the base chart without modification. We recommend using our wrappers for easier migration and a simpler way of accessing the rendered chart object for building custom interactions. Compatibility - If you build charts using the Highcharts API it will be unlikely that our Paste components will function as they depend on helper funcitons and event tracking that we enrich the default options with. + If you build charts using the Highcharts API it will be unlikely that our Paste data visualization components will function correctly as they depend on helper funcitons and event tracking that we enrich the default options with. diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index df46982e07..525ee8f2ec 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -54,13 +54,13 @@ export const getStaticProps = async () => { -Our charting components are designed to work seamlessly with Highcharts. However, due to licensing restrictions, we cannot include Highcharts directly in our library. This limitation creates challenges when developing components for a library we cannot directly integrate with. +Our charting components are designed to work seamlessly with Highcharts. However, due to licensing restrictions, we cannot include Highcharts directly in our library. This limitation creates challenges when developing components for a library we cannot directly interact with. To address this, we have created components and wrappers that simplify the Highcharts API. These tools expose various props, allowing you to configure charts through a streamlined and user-friendly interface. The props are transformed into objects that Highcharts can interpret, and our components automatically apply styles to the charts for a consistent appearance on a chart type bases. Global styles will be set in the `BaseChart` using our existing hook. ## Licensing -Paste does not provide a license for Twilio usage. Licenses are acquired on an applicaiton level. ODds are, if you are developing in one of our existing products you already have one. If you are creating a new application you may need to acquire a new license. +Paste does not provide a license for Twilio usage. Licenses are acquired on an applicaiton level. If you are developing in one of our existing products it is highly likely licenses are already purchased. If you are creating a new application you may need to acquire a new license. If you need further information you can reach out to us via [GitHub discussions](https://github.com/twilio-labs/paste/discussions/new?category=q-a) or the Procurement team. ## Setup @@ -68,7 +68,7 @@ To ensure our components function correctly, some initial configuration is requi - Storing and retrieving rendered chart objects. - Adding any additional modules required for additional functionality such as gauges, exporting etc. -You will need to include a component that retrieves the chart configuration from our components' context and passes it to Highcharts. This component must also capture the rendered chart and store it in our `ChartContext`. +You will need to include a component that retrieves the chart configuration from our [ChartProvider](/components/chart-provider)'s context and passes it to Highcharts. This component must also capture the rendered chart and store it in the Chart Provider context. Storing the rendered chart is essential for several reasons. It allows us to determine the positioning of elements relative to the screen, enabling the placement of components like tooltips. Additionally, it facilitates triggering update functions on the chart for interactions such as zooming or toggling the visibility of series through a legend component. @@ -135,11 +135,11 @@ export const BaseChart = React.memo(Chart); ``` ## Chart context -We use React Context to store the rendered chart object to use in our components. When talking about the chart context we do not only mean the rendered object but also the initial configuration. You will need to pass data to the context for the BaseChart to read and use. +We use React Context to store the rendered chart object to use in our components. When talking about the chart context we do not only mean the rendered object but also the initial configuration. You will need to pass data to the context for the `BaseChart` to read and use. Each individual chart instance will be wrapped in a [ChartProvider](/components/chart-provider) which sets the initial configuration and apply chart specific styles. -An individual chart instance does not mean a chart only. It may also mean chart titles, legends, tooltips and any other component that does not sit in or on the chart canvas. In simpler terms, it is a container that wraps not only the Highcharts elements but any of our Paste components that interact with that chart instance. +An individual chart instance does not mean a chart only. It may also mean chart titles, legends, tooltips and any other component that does not sit in or on the chart canvas. In simpler terms, it is a container that wraps not only the Highcharts elements but any of our Paste components that interact with that chart and canvas. diff --git a/packages/paste-website/src/pages/foundations/data-visualization/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/index.mdx index 1cfa7b47ca..c9443ee2ee 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/index.mdx @@ -67,7 +67,7 @@ This foundation page was created to help establish a familiar and accessible use Paste Chart support - We're actively working on full charting support through a suite of Paste components designed to make it easy to build pre-styled, interactive charts. As we expand these capabilities, we’ll continue adding more examples and documentation in the Engineering section. We plan to roll out support for additional chart types over time and recommend using our components if they fit your current needs. + We're actively working on full charting support through a suite of Paste components designed to make it easy to build pre-styled, interactive charts. As we expand these capabilities, we will continue adding more examples and documentation in the Engineering section. We plan to roll out support for additional chart types over time and recommend using our components if they fit your current needs. From 1b5bc22b3de1f63c507e30d9a5b95f17ac6ac312 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:24:55 -0500 Subject: [PATCH 11/26] chore(cleanup): remove redundant story --- .../components/list/stories/index.stories.tsx | 42 +------------------ 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/packages/paste-core/components/list/stories/index.stories.tsx b/packages/paste-core/components/list/stories/index.stories.tsx index 225674ba0a..d48d50dc83 100644 --- a/packages/paste-core/components/list/stories/index.stories.tsx +++ b/packages/paste-core/components/list/stories/index.stories.tsx @@ -5,7 +5,7 @@ import { Stack } from "@twilio-paste/stack"; import { useTheme } from "@twilio-paste/theme"; import * as React from "react"; -import { List, ListItem, OrderedList, UnorderedList } from "../src"; +import { ListItem, OrderedList, UnorderedList } from "../src"; // eslint-disable-next-line import/no-default-export export default { @@ -110,46 +110,6 @@ export const NestedUnorderedList = (): React.ReactNode => { ); }; -export const DefaultList = (): React.ReactNode => { - return ( - <> - - - Deliver critical time-sensitive messages to employees and customers at scale with the Programmable Messaging - API. - - - - Deliver critical time-sensitive messages to employees and customers at scale with the Programmable Messaging - API. - - - - Deliver critical time-sensitive messages to employees and customers at scale with the Programmable - Messaging API. - - - Proactively inform customers about account activity, purchase confirmations, and shipping notifications - with the - Programmable Messaging API. - - - - Proactively inform customers about account activity, purchase confirmations, and shipping notifications with - the - Programmable Messaging API. - - - - Proactively inform customers about account activity, purchase confirmations, and shipping notifications with - the - Programmable Messaging API. - - - - ); -}; - export const CustomOrderedList: StoryFn = (_args, { parameters: { isTestEnvironment } }) => { const currentTheme = useTheme(); return ( From bb8c48be31b2d09759fcdd0ac314af6f2f1d2c8a Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:29:45 -0500 Subject: [PATCH 12/26] chore(cleanup): changeset --- .changeset/cuddly-berries-explain.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/cuddly-berries-explain.md diff --git a/.changeset/cuddly-berries-explain.md b/.changeset/cuddly-berries-explain.md new file mode 100644 index 0000000000..ecfe88f3d1 --- /dev/null +++ b/.changeset/cuddly-berries-explain.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/core": minor +"@twilio-paste/data-visualization-library": minor +--- + +[Data Visualization Library] update Highcharts native tooltip styles to align more closely with Paste styles including correctly setting the font family From 7d0d76bfa7e48663d0811d7bb703d04aff0c1aa1 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:33:52 -0500 Subject: [PATCH 13/26] fix(data-viz): fix urls --- .../components/site-wrapper/sidebar/SidebarNavigation.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index e7f0782452..5a2b416715 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -372,20 +372,20 @@ const SiteSidebarNavigation = (): JSX.Element => { if (name === "Sidebar Navigation") { return null; } - if (["Chart Provider"].includes(name)) { + if (["Data Visualization"].includes(name)) { return null; } - if (name === "Data Visualization") { + if (name === "Chart Provider") { return ( event({ category: "Left Navigation", action: `click-${name}`, - label: name, + label: "Data Visualization", }) } > From d828fb3e6acffcea74742e40478c535e7e547142 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:35:46 -0500 Subject: [PATCH 14/26] fix(data-viz): fix slugs --- .../paste-website/src/pages/components/chart-provider/api.mdx | 2 +- .../src/pages/components/chart-provider/changelog.mdx | 2 +- .../paste-website/src/pages/components/chart-provider/index.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/paste-website/src/pages/components/chart-provider/api.mdx b/packages/paste-website/src/pages/components/chart-provider/api.mdx index bbbc7324e9..68a507997a 100644 --- a/packages/paste-website/src/pages/components/chart-provider/api.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/api.mdx @@ -9,7 +9,7 @@ export const meta = { title: 'ChartProvider', package: '@twilio-paste/chart-provider', description: packageJson.description, - slug: '/components/chart-provider/api', + slug: '/components/chart-provider/api/', }; export default ComponentPageLayout; diff --git a/packages/paste-website/src/pages/components/chart-provider/changelog.mdx b/packages/paste-website/src/pages/components/chart-provider/changelog.mdx index db2af07583..019de7af08 100644 --- a/packages/paste-website/src/pages/components/chart-provider/changelog.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/changelog.mdx @@ -8,7 +8,7 @@ export const meta = { title: 'Chart Provider', package: '@twilio-paste/chart-provider', description: packageJson.description, - slug: '/components/chart-provider/changelog', + slug: '/components/chart-provider/changelog/', }; export default ComponentPageLayout; diff --git a/packages/paste-website/src/pages/components/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx index c84b1a24d2..7ff1a313cc 100644 --- a/packages/paste-website/src/pages/components/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -13,7 +13,7 @@ export const meta = { title: 'Chart Provider', package: '@twilio-paste/chart-provider', description: packageJson.description, - slug: '/components/data-viz/chart-provider/', + slug: '/components/chart-provider/', }; export default ComponentPageLayout; From 8b7fcf498cb7bd19474a54a93611d0af3a642e9e Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:48:02 -0500 Subject: [PATCH 15/26] feat(data-vix): chart-provider in project.json --- packages/paste-website/package.json | 1 + .../src/component-examples/data-visualization/BaseChart.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/paste-website/package.json b/packages/paste-website/package.json index 122ebf5c10..4dbe7a8ae6 100644 --- a/packages/paste-website/package.json +++ b/packages/paste-website/package.json @@ -52,6 +52,7 @@ "@twilio-paste/card": "^10.1.0", "@twilio-paste/chat-composer": "^6.0.1", "@twilio-paste/chat-log": "^6.0.1", + "@twilio-paste/chart-provider": "^2.0.1", "@twilio-paste/checkbox": "^14.0.1", "@twilio-paste/clipboard-copy-library": "^4.0.1", "@twilio-paste/code-block": "^6.0.1", diff --git a/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx index 92da437fda..b9ad272c36 100644 --- a/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx +++ b/packages/paste-website/src/component-examples/data-visualization/BaseChart.tsx @@ -1,9 +1,9 @@ import { Box } from "@twilio-paste/box"; import { ChartContext } from "@twilio-paste/chart-provider"; +import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; import * as Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import HighchartsAccessibilityModule from "highcharts/modules/accessibility"; -import { applyPasteHighchartsModules, usePasteHighchartsTheme } from "@twilio-paste/data-visualization-library"; import * as React from "react"; const Chart: React.FC = () => { @@ -22,7 +22,7 @@ const Chart: React.FC = () => { } }, [chartRef.current]); - const callback = (chart: Highcharts.Chart) => { + const callback = (chart: Highcharts.Chart): void => { if (chart?.series?.length > 0) { setChart(chart); } From 2297ca32ef69ba3dadff1644fb0fc35a78e4ff13 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:51:37 -0500 Subject: [PATCH 16/26] chore(data-vix): test chanpshots --- .../__test__/__snapshots__/index.spec.tsx.snap | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/paste-libraries/data-visualization/__test__/__snapshots__/index.spec.tsx.snap b/packages/paste-libraries/data-visualization/__test__/__snapshots__/index.spec.tsx.snap index 1e7b20ed73..f8bb776329 100644 --- a/packages/paste-libraries/data-visualization/__test__/__snapshots__/index.spec.tsx.snap +++ b/packages/paste-libraries/data-visualization/__test__/__snapshots__/index.spec.tsx.snap @@ -131,9 +131,15 @@ Object { "text": "Solar Employment Growth by Sector, 2010-2016", }, "tooltip": Object { - "backgroundColor": "rgb(244, 244, 246)", + "backgroundColor": "rgb(18, 28, 45)", + "borderColor": "rgb(136, 145, 170)", + "borderRadius": "8", + "borderWidth": "1px", + "padding": 12, "style": Object { "color": "rgb(18, 28, 45)", + "fontFamily": "'Inter var experimental', 'Inter var', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif", + "fontSize": "0.875rem", }, }, "xAxis": Object { @@ -228,9 +234,15 @@ Object { }, }, "tooltip": Object { - "backgroundColor": "rgb(244, 244, 246)", + "backgroundColor": "rgb(18, 28, 45)", + "borderColor": "rgb(136, 145, 170)", + "borderRadius": "8", + "borderWidth": "1px", + "padding": 12, "style": Object { "color": "rgb(18, 28, 45)", + "fontFamily": "'Inter var experimental', 'Inter var', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif", + "fontSize": "0.875rem", }, }, "xAxis": Object { From 882cefca4d6f45e4df86b127e4f010773f130e81 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 10:57:49 -0500 Subject: [PATCH 17/26] chore(ci): fix supabase --- apps/backend/package.json | 2 +- apps/backend/supabase/schema.gen.ts | 273 ++++++++++------------------ packages/paste-website/package.json | 2 +- yarn.lock | 11 +- 4 files changed, 108 insertions(+), 180 deletions(-) diff --git a/apps/backend/package.json b/apps/backend/package.json index ef7b193cbc..b6d95281e9 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -9,6 +9,6 @@ "db:reset": "yarn supabase db reset" }, "devDependencies": { - "supabase": "^2.6.8" + "supabase": "^2.8.1" } } diff --git a/apps/backend/supabase/schema.gen.ts b/apps/backend/supabase/schema.gen.ts index d7c0e7c109..85cc661288 100644 --- a/apps/backend/supabase/schema.gen.ts +++ b/apps/backend/supabase/schema.gen.ts @@ -225,23 +225,12 @@ export type Database = { [_ in never]: never } Functions: { - binary_quantize: - | { - Args: { - "": string - } - Returns: unknown - } - | { - Args: { - "": unknown - } - Returns: unknown - } + binary_quantize: { + Args: { "": string } | { "": unknown } + Returns: unknown + } get_page_parents: { - Args: { - page_id: number - } + Args: { page_id: number } Returns: { id: number parent_page_id: number @@ -250,103 +239,57 @@ export type Database = { }[] } halfvec_avg: { - Args: { - "": number[] - } + Args: { "": number[] } Returns: unknown } halfvec_out: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } halfvec_send: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: string } halfvec_typmod_in: { - Args: { - "": unknown[] - } + Args: { "": unknown[] } Returns: number } hnsw_bit_support: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } hnsw_halfvec_support: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } hnsw_sparsevec_support: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } hnswhandler: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } ivfflat_bit_support: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } ivfflat_halfvec_support: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } ivfflathandler: { - Args: { - "": unknown - } + Args: { "": unknown } + Returns: unknown + } + l2_norm: { + Args: { "": unknown } | { "": unknown } + Returns: number + } + l2_normalize: { + Args: { "": string } | { "": unknown } | { "": unknown } Returns: unknown } - l2_norm: - | { - Args: { - "": unknown - } - Returns: number - } - | { - Args: { - "": unknown - } - Returns: number - } - l2_normalize: - | { - Args: { - "": string - } - Returns: string - } - | { - Args: { - "": unknown - } - Returns: unknown - } - | { - Args: { - "": unknown - } - Returns: unknown - } match_discussions: { Args: { embedding: string @@ -420,21 +363,15 @@ export type Database = { }[] } sparsevec_out: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: unknown } sparsevec_send: { - Args: { - "": unknown - } + Args: { "": unknown } Returns: string } sparsevec_typmod_in: { - Args: { - "": unknown[] - } + Args: { "": unknown[] } Returns: number } upsert_story_and_create_story_render: { @@ -450,46 +387,27 @@ export type Database = { Returns: undefined } vector_avg: { - Args: { - "": number[] - } + Args: { "": number[] } Returns: string } - vector_dims: - | { - Args: { - "": string - } - Returns: number - } - | { - Args: { - "": unknown - } - Returns: number - } + vector_dims: { + Args: { "": string } | { "": unknown } + Returns: number + } vector_norm: { - Args: { - "": string - } + Args: { "": string } Returns: number } vector_out: { - Args: { - "": string - } + Args: { "": string } Returns: unknown } vector_send: { - Args: { - "": string - } + Args: { "": string } Returns: string } vector_typmod_in: { - Args: { - "": unknown[] - } + Args: { "": unknown[] } Returns: number } } @@ -719,30 +637,19 @@ export type Database = { } Functions: { can_insert_object: { - Args: { - bucketid: string - name: string - owner: string - metadata: Json - } + Args: { bucketid: string; name: string; owner: string; metadata: Json } Returns: undefined } extension: { - Args: { - name: string - } + Args: { name: string } Returns: string } filename: { - Args: { - name: string - } + Args: { name: string } Returns: string } foldername: { - Args: { - name: string - } + Args: { name: string } Returns: string[] } get_size_by_bucket: { @@ -817,27 +724,29 @@ export type Database = { } } -type PublicSchema = Database[Extract] +type DefaultSchema = Database[Extract] export type Tables< - PublicTableNameOrOptions extends - | keyof (PublicSchema["Tables"] & PublicSchema["Views"]) + DefaultSchemaTableNameOrOptions extends + | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"]) + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof Database + } + ? keyof (Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + Database[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) : never = never, -> = PublicTableNameOrOptions extends { schema: keyof Database } - ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { +> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } + ? (Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + Database[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { Row: infer R } ? R : never - : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & - PublicSchema["Views"]) - ? (PublicSchema["Tables"] & - PublicSchema["Views"])[PublicTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & + DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & + DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { Row: infer R } ? R @@ -845,20 +754,22 @@ export type Tables< : never export type TablesInsert< - PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + DefaultSchemaTableNameOrOptions extends + | keyof DefaultSchema["Tables"] | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof Database + } + ? keyof Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, -> = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { +> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } + ? Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { Insert: infer I } ? I : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { Insert: infer I } ? I @@ -866,20 +777,22 @@ export type TablesInsert< : never export type TablesUpdate< - PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + DefaultSchemaTableNameOrOptions extends + | keyof DefaultSchema["Tables"] | { schema: keyof Database }, - TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + TableName extends DefaultSchemaTableNameOrOptions extends { + schema: keyof Database + } + ? keyof Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, -> = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { +> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } + ? Database[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { Update: infer U } ? U : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { Update: infer U } ? U @@ -887,21 +800,23 @@ export type TablesUpdate< : never export type Enums< - PublicEnumNameOrOptions extends - | keyof PublicSchema["Enums"] + DefaultSchemaEnumNameOrOptions extends + | keyof DefaultSchema["Enums"] | { schema: keyof Database }, - EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] + EnumName extends DefaultSchemaEnumNameOrOptions extends { + schema: keyof Database + } + ? keyof Database[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] : never = never, -> = PublicEnumNameOrOptions extends { schema: keyof Database } - ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] - : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] - ? PublicSchema["Enums"][PublicEnumNameOrOptions] +> = DefaultSchemaEnumNameOrOptions extends { schema: keyof Database } + ? Database[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] + : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] + ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] : never export type CompositeTypes< PublicCompositeTypeNameOrOptions extends - | keyof PublicSchema["CompositeTypes"] + | keyof DefaultSchema["CompositeTypes"] | { schema: keyof Database }, CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { schema: keyof Database @@ -910,7 +825,19 @@ export type CompositeTypes< : never = never, > = PublicCompositeTypeNameOrOptions extends { schema: keyof Database } ? Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] - : PublicCompositeTypeNameOrOptions extends keyof PublicSchema["CompositeTypes"] - ? PublicSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] + : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] + ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] : never +export const Constants = { + graphql_public: { + Enums: {}, + }, + public: { + Enums: {}, + }, + storage: { + Enums: {}, + }, +} as const + diff --git a/packages/paste-website/package.json b/packages/paste-website/package.json index 4dbe7a8ae6..9eefcbc269 100644 --- a/packages/paste-website/package.json +++ b/packages/paste-website/package.json @@ -50,9 +50,9 @@ "@twilio-paste/button-group": "^5.0.1", "@twilio-paste/callout": "^5.0.1", "@twilio-paste/card": "^10.1.0", + "@twilio-paste/chart-provider": "^2.0.1", "@twilio-paste/chat-composer": "^6.0.1", "@twilio-paste/chat-log": "^6.0.1", - "@twilio-paste/chart-provider": "^2.0.1", "@twilio-paste/checkbox": "^14.0.1", "@twilio-paste/clipboard-copy-library": "^4.0.1", "@twilio-paste/code-block": "^6.0.1", diff --git a/yarn.lock b/yarn.lock index c6b43a1128..62fc01cb97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11099,7 +11099,7 @@ __metadata: version: 0.0.0-use.local resolution: "@twilio-paste/backend@workspace:apps/backend" dependencies: - supabase: ^2.6.8 + supabase: ^2.8.1 languageName: unknown linkType: soft @@ -15770,6 +15770,7 @@ __metadata: "@twilio-paste/button-group": ^5.0.1 "@twilio-paste/callout": ^5.0.1 "@twilio-paste/card": ^10.1.0 + "@twilio-paste/chart-provider": ^2.0.1 "@twilio-paste/chat-composer": ^6.0.1 "@twilio-paste/chat-log": ^6.0.1 "@twilio-paste/checkbox": ^14.0.1 @@ -43343,9 +43344,9 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard -"supabase@npm:^2.6.8": - version: 2.8.1 - resolution: "supabase@npm:2.8.1" +"supabase@npm:^2.8.1": + version: 2.22.1 + resolution: "supabase@npm:2.22.1" dependencies: bin-links: ^5.0.0 https-proxy-agent: ^7.0.2 @@ -43353,7 +43354,7 @@ resolve@^2.0.0-next.3: tar: 7.4.3 bin: supabase: bin/supabase - checksum: 10b240963da4263ad8d03e84b97939504f5690eb894a9ee8ae225d69c0b8f31a890e9e24e9d4b2757c714eb38addb6878f6e531f9f7279c22de50a991b8e7cd4 + checksum: 2b12441bc6754b6b845e91765b2b7585aae7af944fb77d20f52e4894e70761650dfb148453c83a6eaee426bba5e2f28da2200e8f4f86a31fbc34dc70f35f4c84 languageName: node linkType: hard From 65f2844b212c4903283e87a1b32717746d556aa9 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 11:03:03 -0500 Subject: [PATCH 18/26] chore(ci): fix supabase --- apps/backend/supabase/schema.gen.ts | 112 ++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/apps/backend/supabase/schema.gen.ts b/apps/backend/supabase/schema.gen.ts index 85cc661288..b471f2dd96 100644 --- a/apps/backend/supabase/schema.gen.ts +++ b/apps/backend/supabase/schema.gen.ts @@ -486,6 +486,7 @@ export type Database = { created_at: string | null id: string last_accessed_at: string | null + level: number | null metadata: Json | null name: string | null owner: string | null @@ -500,6 +501,7 @@ export type Database = { created_at?: string | null id?: string last_accessed_at?: string | null + level?: number | null metadata?: Json | null name?: string | null owner?: string | null @@ -514,6 +516,7 @@ export type Database = { created_at?: string | null id?: string last_accessed_at?: string | null + level?: number | null metadata?: Json | null name?: string | null owner?: string | null @@ -533,6 +536,38 @@ export type Database = { }, ] } + prefixes: { + Row: { + bucket_id: string + created_at: string | null + level: number + name: string + updated_at: string | null + } + Insert: { + bucket_id: string + created_at?: string | null + level?: number + name: string + updated_at?: string | null + } + Update: { + bucket_id?: string + created_at?: string | null + level?: number + name?: string + updated_at?: string | null + } + Relationships: [ + { + foreignKeyName: "prefixes_bucketId_fkey" + columns: ["bucket_id"] + isOneToOne: false + referencedRelation: "buckets" + referencedColumns: ["id"] + }, + ] + } s3_multipart_uploads: { Row: { bucket_id: string @@ -636,10 +671,18 @@ export type Database = { [_ in never]: never } Functions: { + add_prefixes: { + Args: { _bucket_id: string; _name: string } + Returns: undefined + } can_insert_object: { Args: { bucketid: string; name: string; owner: string; metadata: Json } Returns: undefined } + delete_prefix: { + Args: { _bucket_id: string; _name: string } + Returns: boolean + } extension: { Args: { name: string } Returns: string @@ -652,6 +695,18 @@ export type Database = { Args: { name: string } Returns: string[] } + get_level: { + Args: { name: string } + Returns: number + } + get_prefix: { + Args: { name: string } + Returns: string + } + get_prefixes: { + Args: { name: string } + Returns: string[] + } get_size_by_bucket: { Args: Record Returns: { @@ -714,6 +769,63 @@ export type Database = { metadata: Json }[] } + search_legacy_v1: { + Args: { + prefix: string + bucketname: string + limits?: number + levels?: number + offsets?: number + search?: string + sortcolumn?: string + sortorder?: string + } + Returns: { + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + search_v1_optimised: { + Args: { + prefix: string + bucketname: string + limits?: number + levels?: number + offsets?: number + search?: string + sortcolumn?: string + sortorder?: string + } + Returns: { + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + search_v2: { + Args: { + prefix: string + bucket_name: string + limits?: number + levels?: number + start_after?: string + } + Returns: { + key: string + name: string + id: string + updated_at: string + created_at: string + metadata: Json + }[] + } } Enums: { [_ in never]: never From 3f21680540b24922200f4c6a087286f0f624e934 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 11:21:24 -0500 Subject: [PATCH 19/26] chore(ci): ignore generated files for linting --- .eslintignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eslintignore b/.eslintignore index 009797d238..6aee0e1c31 100644 --- a/.eslintignore +++ b/.eslintignore @@ -19,3 +19,5 @@ packages/**/dist/* tsconfig.build.tsbuildinfo **/*.d.ts + +apps/backend/supabase/schema.gen.ts From e4b069af750e7ed17b72bbe431eff85c8aa2df3c Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 11:38:48 -0500 Subject: [PATCH 20/26] chore(data-vix): typos --- .../paste-website/src/pages/components/chart-provider/index.mdx | 2 +- .../pages/foundations/data-visualization/engineering/index.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/paste-website/src/pages/components/chart-provider/index.mdx b/packages/paste-website/src/pages/components/chart-provider/index.mdx index 7ff1a313cc..54d1a57572 100644 --- a/packages/paste-website/src/pages/components/chart-provider/index.mdx +++ b/packages/paste-website/src/pages/components/chart-provider/index.mdx @@ -63,7 +63,7 @@ You can use the `highchartsOptions` to create unsupported charts by passing the Compatibility - If you build charts using the Highcharts API it will be unlikely that our Paste data visualization components will function correctly as they depend on helper funcitons and event tracking that we enrich the default options with. + If you build charts using the Highcharts API it will be unlikely that our Paste data visualization components will function correctly as they depend on helper functions and event tracking that we enrich the default options with. diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index 525ee8f2ec..d6be3e1c6d 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -60,7 +60,7 @@ To address this, we have created components and wrappers that simplify the Highc ## Licensing -Paste does not provide a license for Twilio usage. Licenses are acquired on an applicaiton level. If you are developing in one of our existing products it is highly likely licenses are already purchased. If you are creating a new application you may need to acquire a new license. If you need further information you can reach out to us via [GitHub discussions](https://github.com/twilio-labs/paste/discussions/new?category=q-a) or the Procurement team. +Paste does not provide a license for Twilio usage. Licenses are acquired on an application level. If you are developing in one of our existing products it is highly likely licenses are already purchased. If you are creating a new application you may need to acquire a new license. If you need further information you can reach out to us via [GitHub discussions](https://github.com/twilio-labs/paste/discussions/new?category=q-a) or the Procurement team. ## Setup From 856fa9623459937edb9d3c565be366b0028e5bea Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 12:11:52 -0500 Subject: [PATCH 21/26] chore(data-vix): trigger rebuild --- .../pages/foundations/data-visualization/engineering/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index d6be3e1c6d..e5e954c906 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -133,6 +133,7 @@ const Chart: React.FC = () => { export const BaseChart = React.memo(Chart); ``` + ## Chart context We use React Context to store the rendered chart object to use in our components. When talking about the chart context we do not only mean the rendered object but also the initial configuration. You will need to pass data to the context for the `BaseChart` to read and use. From fa6c7b48a45baaf99df93e3fad77429af731b152 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 14:58:50 -0500 Subject: [PATCH 22/26] chore(data-vix): trigger rebuild --- .../pages/foundations/data-visualization/engineering/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index e5e954c906..a23c1ff25d 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -144,4 +144,4 @@ An individual chart instance does not mean a chart only. It may also mean chart - + \ No newline at end of file From 34bcf1e3cb5d0dba3611cd546d3050abc487fd6d Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 16 Apr 2025 14:58:56 -0500 Subject: [PATCH 23/26] chore(data-vix): trigger rebuild --- .../pages/foundations/data-visualization/engineering/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx index a23c1ff25d..e5e954c906 100644 --- a/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx +++ b/packages/paste-website/src/pages/foundations/data-visualization/engineering/index.mdx @@ -144,4 +144,4 @@ An individual chart instance does not mean a chart only. It may also mean chart - \ No newline at end of file + From ff5cf146124c4a127bf62bce7ee4a899d8ae6d8c Mon Sep 17 00:00:00 2001 From: krisantrobus <55083528+krisantrobus@users.noreply.github.com> Date: Tue, 29 Apr 2025 12:30:37 -0500 Subject: [PATCH 24/26] Update packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx Co-authored-by: Sarah --- .../src/components/site-wrapper/sidebar/SidebarNavigation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 5a2b416715..a4fe061850 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -138,7 +138,7 @@ const SiteSidebarNavigation = (): JSX.Element => { Overview Overview From 80bbe936da7d4d1dde743d54fdecec2f3538122b Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Tue, 29 Apr 2025 13:26:10 -0500 Subject: [PATCH 25/26] feat(data-visualization): vrt --- cypress/integration/sitemap-vrt/constants.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cypress/integration/sitemap-vrt/constants.ts b/cypress/integration/sitemap-vrt/constants.ts index 2f1be9121f..0d4bed9e0a 100644 --- a/cypress/integration/sitemap-vrt/constants.ts +++ b/cypress/integration/sitemap-vrt/constants.ts @@ -63,6 +63,8 @@ export const SITEMAP = [ "/components/card/api", "/components/card/changelog", "/components/chart-provider/", + "/components/chart-provider/api", + "/components/chart-provider/changelog", "/components/chat-composer/", "/components/chat-composer/api", "/components/chat-composer/changelog", From 069f892cfe97c7f7d3a489230746bb9bf1049186 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Tue, 29 Apr 2025 14:46:34 -0500 Subject: [PATCH 26/26] chore(tests): add support for same title sidebar disclousres --- cypress/integration/sidebar-navigation/index.spec.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cypress/integration/sidebar-navigation/index.spec.ts b/cypress/integration/sidebar-navigation/index.spec.ts index 55f3d365d9..610a1e4c50 100644 --- a/cypress/integration/sidebar-navigation/index.spec.ts +++ b/cypress/integration/sidebar-navigation/index.spec.ts @@ -1,9 +1,10 @@ const sidebarNavigationDisclosures = [ "introduction", + "foundations", + "data-visualization", "for-designers", "for-engineers", "contributing", - "foundations", "content", "patterns", "components", @@ -34,9 +35,10 @@ describe("Sidebar navigation", () => { cy.get(`[data-cy="${contentSelector}"]`).as("currentContent"); cy.get("@currentContent").should("have.css", "display", "none"); cy.get("@currentContent").should("have.attr", "hidden", "hidden"); - - cy.get(`[data-cy="${buttonSelector}"]`).click().should("have.attr", "aria-expanded", "true"); - cy.get("@currentContent").scrollIntoView().should("have.css", "display", "block"); + cy.get(`[data-cy="${buttonSelector}"]`).click({ multiple: true }).should("have.attr", "aria-expanded", "true"); + cy.get("@currentContent").each(($el) => { + cy.wrap($el).scrollIntoView().should("have.css", "display", "block"); + }); }); }); @@ -44,7 +46,7 @@ describe("Sidebar navigation", () => { const buttonSelector = `${BASE}-button-${disclosureName}`; it(`should close the the "${disclosureName}" sidebar disclosure`, () => { - cy.get(`[data-cy="${buttonSelector}"]`).click().should("have.attr", "aria-expanded", "false"); + cy.get(`[data-cy="${buttonSelector}"]`).click({ multiple: true }).should("have.attr", "aria-expanded", "false"); }); }); });