From db4a307583b0ff505eb3b00102f3116a353b145e Mon Sep 17 00:00:00 2001 From: Rachael Thomas Date: Thu, 9 Apr 2026 18:28:44 -0600 Subject: [PATCH] Update Accordion component to add optional anchorID and add to MS Teams channel data accordion --- components/ui/Accordion.tsx | 30 +++++++++++++++++-- .../chat/microsoft-teams/overview.mdx | 2 +- .../setting-channel-data.mdx | 2 +- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/components/ui/Accordion.tsx b/components/ui/Accordion.tsx index 375ebb9bc..b80480583 100644 --- a/components/ui/Accordion.tsx +++ b/components/ui/Accordion.tsx @@ -2,7 +2,7 @@ import { Box, Stack } from "@telegraph/layout"; import { MenuItem } from "@telegraph/menu"; import { Icon } from "@telegraph/icon"; import { AnimatePresence, motion } from "framer-motion"; -import { useState, useMemo } from "react"; +import { useState, useMemo, useLayoutEffect } from "react"; import { Text, Code } from "@telegraph/typography"; import { ChevronRight } from "lucide-react"; @@ -15,11 +15,24 @@ const AccordionGroup = ({ children }) => ( ); +function getHashFragment(): string { + if (typeof window === "undefined") return ""; + const { hash } = window.location; + if (!hash || hash === "#") return ""; + try { + return decodeURIComponent(hash.slice(1)); + } catch { + return hash.slice(1); + } +} + type AccordionProps = { children: React.ReactNode; title: string; description?: string; defaultOpen?: boolean; + /** When set, this value is used as the element `id` and the accordion opens if the URL hash matches (for deep links). */ + anchorId?: string; }; // Helper function to parse title and split into text and code parts @@ -68,12 +81,25 @@ const Accordion = ({ title, description, defaultOpen = false, + anchorId, }: AccordionProps) => { const [open, setOpen] = useState(defaultOpen); const titleParts = useMemo(() => parseTitleWithCode(title), [title]); + useLayoutEffect(() => { + if (!anchorId) return; + const syncFromHash = () => { + if (getHashFragment() === anchorId) { + setOpen(true); + } + }; + syncFromHash(); + window.addEventListener("hashchange", syncFromHash); + return () => window.removeEventListener("hashchange", syncFromHash); + }, [anchorId]); + return ( - + setOpen(!open)} diff --git a/content/integrations/chat/microsoft-teams/overview.mdx b/content/integrations/chat/microsoft-teams/overview.mdx index 1ad824271..5023ee6a8 100644 --- a/content/integrations/chat/microsoft-teams/overview.mdx +++ b/content/integrations/chat/microsoft-teams/overview.mdx @@ -163,7 +163,7 @@ To use TeamsKit, you'll need to configure the API permissions and OAuth redirect ## How to set channel data for a Microsoft Teams integration in Knock -In Knock, the [`ChannelData`](/managing-recipients/setting-channel-data) concept provides you a way of storing recipient-specific connection data for a given integration. If you reference the [channel data requirements for Microsoft Teams](/managing-recipients/setting-channel-data#chat-app-channels), you'll see that there are two different schemas for an `MsTeamsConnection` stored on a [`User`](/concepts/users) or an [`Object`](/concepts/objects) in Knock. +In Knock, the [`ChannelData`](/managing-recipients/setting-channel-data) concept provides you a way of storing recipient-specific connection data for a given integration. If you reference the [channel data requirements for Microsoft Teams](/managing-recipients/setting-channel-data#microsoft-teams-channel-data), you'll see that there are two different schemas for an `MsTeamsConnection` stored on a [`User`](/concepts/users) or an [`Object`](/concepts/objects) in Knock. Here's an example of setting channel data on an `Object` in Knock. diff --git a/content/managing-recipients/setting-channel-data.mdx b/content/managing-recipients/setting-channel-data.mdx index a2d596561..0eab7917e 100644 --- a/content/managing-recipients/setting-channel-data.mdx +++ b/content/managing-recipients/setting-channel-data.mdx @@ -241,7 +241,7 @@ The `PushDevice` object is used to optionally set device-level metadata for a pu | incoming_webhook.url | `string` | The Discord incoming webhook URL (to be used instead of the properties above) | - + | Property | Type | Description | | ----------- | --------------------- | ---------------------------------- | | connections | `MsTeamsConnection[]` | One or more connections to MsTeams |