@planningcenter/tapestry 4.9.0-rc.3 → 4.9.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ import "./index.css";
2
+ import React from "react";
3
+ export interface HelperShelfProps {
4
+ /** Content rendered inside the shelf. */
5
+ children: React.ReactNode;
6
+ /**
7
+ * Id for the shelf; the trigger uses `${id}-trigger`. Defaults to a
8
+ * generated id.
9
+ */
10
+ id?: string;
11
+ /**
12
+ * Id of the element (e.g. a pane title) combined with "More info" to name
13
+ * the trigger, so several triggers on one page stay distinguishable.
14
+ */
15
+ labelledById?: string;
16
+ }
17
+ /**
18
+ * An info icon trigger and the collapsible shelf it controls, rendered as
19
+ * siblings so the parent can lay them out independently. Internal — consumed
20
+ * by `PaneHeader`'s `helpContent` prop.
21
+ */
22
+ export declare function HelperShelf({ children, id, labelledById }: HelperShelfProps): React.JSX.Element;
23
+ export declare namespace HelperShelf {
24
+ var displayName: string;
25
+ }
26
+ //# sourceMappingURL=HelperShelf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HelperShelf.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/helper-shelf/HelperShelf.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAMpB,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,gBAAgB,qBAwC3E;yBAxCe,WAAW"}
@@ -0,0 +1,37 @@
1
+ import '../../button/ActionsDropdownIconButton.js';
2
+ import '../../button/Button.js';
3
+ import '../../button/DropdownButton.js';
4
+ import '../../button/DropdownIconButton.js';
5
+ import { IconButton } from '../../button/IconButton.js';
6
+ import '../../button/LoadingButton.js';
7
+ import '../../button/PageHeaderActionsDropdownButton.js';
8
+ import Icon from '../../../utilities/Icon.js';
9
+ import { useId } from '../../../utilities/useId.js';
10
+ import classNames from 'classnames';
11
+ import React__default, { useState } from 'react';
12
+
13
+ /**
14
+ * An info icon trigger and the collapsible shelf it controls, rendered as
15
+ * siblings so the parent can lay them out independently. Internal — consumed
16
+ * by `PaneHeader`'s `helpContent` prop.
17
+ */
18
+ function HelperShelf({ children, id, labelledById }) {
19
+ const stableId = useId();
20
+ const shelfId = id || `tds-helper-shelf-${stableId}`;
21
+ const triggerId = `${shelfId}-trigger`;
22
+ const [expanded, setExpanded] = useState(false);
23
+ // Keeps collapsed shelf content out of tab order/a11y tree. Needs a string,
24
+ // not a boolean — `inert` isn't in `@types/react@18` or recognized by
25
+ // react-dom as a boolean attribute before React 19.
26
+ const inertProps = { inert: expanded ? undefined : "" };
27
+ return (React__default.createElement(React__default.Fragment, null,
28
+ React__default.createElement(IconButton, { "aria-controls": shelfId, "aria-expanded": expanded, "aria-label": "More info", "aria-labelledby": labelledById ? `${triggerId} ${labelledById}` : undefined, className: "tds-helper-shelf-trigger", icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#outlined-info-circle" }), id: triggerId, kind: "ghost", onClick: () => setExpanded((isExpanded) => !isExpanded), size: "sm" }),
29
+ React__default.createElement("div", { className: classNames("tds-helper-shelf", {
30
+ "tds-helper-shelf--expanded": expanded,
31
+ }), id: shelfId, ...inertProps },
32
+ React__default.createElement("div", { className: "tds-helper-shelf-content" }, children))));
33
+ }
34
+ HelperShelf.displayName = "HelperShelf";
35
+
36
+ export { HelperShelf };
37
+ //# sourceMappingURL=HelperShelf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HelperShelf.js","sources":["../../../../src/components/internal/helper-shelf/HelperShelf.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { IconButton } from \"@components/button\"\nimport Icon from \"@utilities/Icon\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { useState } from \"react\"\n\nexport interface HelperShelfProps {\n /** Content rendered inside the shelf. */\n children: React.ReactNode\n /**\n * Id for the shelf; the trigger uses `${id}-trigger`. Defaults to a\n * generated id.\n */\n id?: string\n /**\n * Id of the element (e.g. a pane title) combined with \"More info\" to name\n * the trigger, so several triggers on one page stay distinguishable.\n */\n labelledById?: string\n}\n\n/**\n * An info icon trigger and the collapsible shelf it controls, rendered as\n * siblings so the parent can lay them out independently. Internal — consumed\n * by `PaneHeader`'s `helpContent` prop.\n */\nexport function HelperShelf({ children, id, labelledById }: HelperShelfProps) {\n const stableId = useId()\n const shelfId = id || `tds-helper-shelf-${stableId}`\n const triggerId = `${shelfId}-trigger`\n const [expanded, setExpanded] = useState(false)\n\n // Keeps collapsed shelf content out of tab order/a11y tree. Needs a string,\n // not a boolean — `inert` isn't in `@types/react@18` or recognized by\n // react-dom as a boolean attribute before React 19.\n const inertProps = { inert: expanded ? undefined : \"\" } as {\n inert?: string\n }\n\n return (\n <>\n <IconButton\n aria-controls={shelfId}\n aria-expanded={expanded}\n aria-label=\"More info\"\n aria-labelledby={\n labelledById ? `${triggerId} ${labelledById}` : undefined\n }\n className=\"tds-helper-shelf-trigger\"\n icon={<Icon aria-hidden symbol=\"general#outlined-info-circle\" />}\n id={triggerId}\n kind=\"ghost\"\n onClick={() => setExpanded((isExpanded) => !isExpanded)}\n size=\"sm\"\n />\n <div\n className={classNames(\"tds-helper-shelf\", {\n \"tds-helper-shelf--expanded\": expanded,\n })}\n id={shelfId}\n {...inertProps}\n >\n <div className=\"tds-helper-shelf-content\">{children}</div>\n </div>\n </>\n )\n}\n\nHelperShelf.displayName = \"HelperShelf\"\n"],"names":["React"],"mappings":";;;;;;;;;;;;AAuBA;;;;AAIG;AACG,SAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAoB,EAAA;AAC1E,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;AACxB,IAAA,MAAM,OAAO,GAAG,EAAE,IAAI,CAAA,iBAAA,EAAoB,QAAQ,EAAE;AACpD,IAAA,MAAM,SAAS,GAAG,CAAA,EAAG,OAAO,UAAU;IACtC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;;;;AAK/C,IAAA,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,EAAE,EAEpD;AAED,IAAA,QACEA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAAA,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAA,eAAA,EACM,OAAO,EAAA,eAAA,EACP,QAAQ,EAAA,YAAA,EACZ,WAAW,EAAA,iBAAA,EAEpB,YAAY,GAAG,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,YAAY,CAAA,CAAE,GAAG,SAAS,EAE3D,SAAS,EAAC,0BAA0B,EACpC,IAAI,EAAEA,6BAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAAa,MAAM,EAAC,8BAA8B,EAAA,CAAG,EAChE,EAAE,EAAE,SAAS,EACb,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,MAAM,WAAW,CAAC,CAAC,UAAU,KAAK,CAAC,UAAU,CAAC,EACvD,IAAI,EAAC,IAAI,EAAA,CACT;AACF,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,UAAU,CAAC,kBAAkB,EAAE;AACxC,gBAAA,4BAA4B,EAAE,QAAQ;AACvC,aAAA,CAAC,EACF,EAAE,EAAE,OAAO,KACP,UAAU,EAAA;YAEdA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,0BAA0B,EAAA,EAAE,QAAQ,CAAO,CACtD,CACL;AAEP;AAEA,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
@@ -0,0 +1,4 @@
1
+ import "./index.css";
2
+ export type { HelperShelfProps } from "./HelperShelf";
3
+ export { HelperShelf } from "./HelperShelf";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/helper-shelf/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
@@ -2,7 +2,7 @@ import { useId } from '../../utilities/useId.js';
2
2
  import classNames from 'classnames';
3
3
  import React__default from 'react';
4
4
  import { PaneContext } from './PaneContext.js';
5
- import { PaneHeader, hasRenderableTitle } from './PaneHeader.js';
5
+ import { PaneHeader, hasRenderableContent } from './PaneHeader.js';
6
6
 
7
7
  /**
8
8
  * Flattens Fragments so a `PaneHeader` can be found regardless of whether
@@ -39,9 +39,9 @@ function Pane({ children, className, id, ...restProps }) {
39
39
  const titleId = `${paneId}-title`;
40
40
  const combinedClassName = classNames("tds-pane", className);
41
41
  const paneHeader = flattenChildren(children).find((child) => React__default.isValidElement(child) && child.type === PaneHeader);
42
- const hasTitle = hasRenderableTitle(paneHeader?.props.title);
42
+ const hasTitle = hasRenderableContent(paneHeader?.props.title);
43
43
  return (React__default.createElement("div", { ...restProps, "aria-labelledby": hasTitle ? titleId : undefined, className: combinedClassName, id: paneId, role: hasTitle ? "region" : undefined },
44
- React__default.createElement(PaneContext.Provider, { value: { titleId } }, children)));
44
+ React__default.createElement(PaneContext.Provider, { value: { paneId, titleId } }, children)));
45
45
  }
46
46
  Pane.displayName = "Pane";
47
47
 
@@ -1 +1 @@
1
- {"version":3,"file":"Pane.js","sources":["../../../src/components/pane/Pane.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes } from \"react\"\n\nimport { PaneContext } from \"./PaneContext\"\nimport { hasRenderableTitle, PaneHeader } from \"./PaneHeader\"\n\nexport interface PaneProps {\n /** `PaneHeader` / `PaneBody` / `PaneFooter`. */\n children: React.ReactNode\n}\n\nexport type PaneElementProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n keyof PaneProps\n> &\n PaneProps\n\n/**\n * Flattens Fragments so a `PaneHeader` can be found regardless of whether\n * children arrive as direct JSX children or as a single Fragment value (as\n * happens when `children` is passed via props, e.g. Storybook args or\n * `tapestry-render`).\n */\nfunction flattenChildren(children: React.ReactNode): React.ReactNode[] {\n const result: React.ReactNode[] = []\n\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n const fragmentProps = child.props as { children?: React.ReactNode }\n result.push(...flattenChildren(fragmentProps.children))\n } else {\n result.push(child)\n }\n })\n\n return result\n}\n\n/**\n * A decorative, static surface — a card-toned container with rounded corners\n * used to visually group related content. Renders a fixed anatomy: an\n * optional `PaneHeader`, a `PaneBody`, and an optional `PaneFooter`. Pane does\n * not manage layout — arrange Panes on a page, and content within one, with\n * `Flex` or another layout primitive.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function Pane({\n children,\n className,\n id,\n ...restProps\n}: PaneElementProps) {\n const stableId = useId()\n const paneId = id || `tds-pane-${stableId}`\n const titleId = `${paneId}-title`\n const combinedClassName = classNames(\"tds-pane\", className)\n\n const paneHeader = flattenChildren(children).find(\n (child): child is React.ReactElement<{ title?: React.ReactNode }> =>\n React.isValidElement(child) && child.type === PaneHeader\n )\n const hasTitle = hasRenderableTitle(paneHeader?.props.title)\n\n return (\n <div\n {...restProps}\n aria-labelledby={hasTitle ? titleId : undefined}\n className={combinedClassName}\n id={paneId}\n role={hasTitle ? \"region\" : undefined}\n >\n <PaneContext.Provider value={{ titleId }}>\n {children}\n </PaneContext.Provider>\n </div>\n )\n}\n\nPane.displayName = \"Pane\"\n"],"names":["React"],"mappings":";;;;;;AAoBA;;;;;AAKG;AACH,SAAS,eAAe,CAAC,QAAyB,EAAA;IAChD,MAAM,MAAM,GAAsB,EAAE;IAEpCA,cAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAI;AACzC,QAAA,IAAIA,cAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAKA,cAAK,CAAC,QAAQ,EAAE;AAChE,YAAA,MAAM,aAAa,GAAG,KAAK,CAAC,KAAuC;YACnE,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACzD;aAAO;AACL,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QACpB;AACF,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,MAAM;AACf;AAEA;;;;;;;;;AASG;AACG,SAAU,IAAI,CAAC,EACnB,QAAQ,EACR,SAAS,EACT,EAAE,EACF,GAAG,SAAS,EACK,EAAA;AACjB,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;AACxB,IAAA,MAAM,MAAM,GAAG,EAAE,IAAI,CAAA,SAAA,EAAY,QAAQ,EAAE;AAC3C,IAAA,MAAM,OAAO,GAAG,CAAA,EAAG,MAAM,QAAQ;IACjC,MAAM,iBAAiB,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3D,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC/C,CAAC,KAAK,KACJA,cAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,CAC3D;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;AAE5D,IAAA,QACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,SAAS,EAAA,iBAAA,EACI,QAAQ,GAAG,OAAO,GAAG,SAAS,EAC/C,SAAS,EAAE,iBAAiB,EAC5B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAA;AAErC,QAAAA,cAAA,CAAA,aAAA,CAAC,WAAW,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAA,EACrC,QAAQ,CACY,CACnB;AAEV;AAEA,IAAI,CAAC,WAAW,GAAG,MAAM;;;;"}
1
+ {"version":3,"file":"Pane.js","sources":["../../../src/components/pane/Pane.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes } from \"react\"\n\nimport { PaneContext } from \"./PaneContext\"\nimport { hasRenderableContent, PaneHeader } from \"./PaneHeader\"\n\nexport interface PaneProps {\n /** `PaneHeader` / `PaneBody` / `PaneFooter`. */\n children: React.ReactNode\n}\n\nexport type PaneElementProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n keyof PaneProps\n> &\n PaneProps\n\n/**\n * Flattens Fragments so a `PaneHeader` can be found regardless of whether\n * children arrive as direct JSX children or as a single Fragment value (as\n * happens when `children` is passed via props, e.g. Storybook args or\n * `tapestry-render`).\n */\nfunction flattenChildren(children: React.ReactNode): React.ReactNode[] {\n const result: React.ReactNode[] = []\n\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n const fragmentProps = child.props as { children?: React.ReactNode }\n result.push(...flattenChildren(fragmentProps.children))\n } else {\n result.push(child)\n }\n })\n\n return result\n}\n\n/**\n * A decorative, static surface — a card-toned container with rounded corners\n * used to visually group related content. Renders a fixed anatomy: an\n * optional `PaneHeader`, a `PaneBody`, and an optional `PaneFooter`. Pane does\n * not manage layout — arrange Panes on a page, and content within one, with\n * `Flex` or another layout primitive.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function Pane({\n children,\n className,\n id,\n ...restProps\n}: PaneElementProps) {\n const stableId = useId()\n const paneId = id || `tds-pane-${stableId}`\n const titleId = `${paneId}-title`\n const combinedClassName = classNames(\"tds-pane\", className)\n\n const paneHeader = flattenChildren(children).find(\n (child): child is React.ReactElement<{ title?: React.ReactNode }> =>\n React.isValidElement(child) && child.type === PaneHeader\n )\n const hasTitle = hasRenderableContent(paneHeader?.props.title)\n\n return (\n <div\n {...restProps}\n aria-labelledby={hasTitle ? titleId : undefined}\n className={combinedClassName}\n id={paneId}\n role={hasTitle ? \"region\" : undefined}\n >\n <PaneContext.Provider value={{ paneId, titleId }}>\n {children}\n </PaneContext.Provider>\n </div>\n )\n}\n\nPane.displayName = \"Pane\"\n"],"names":["React"],"mappings":";;;;;;AAoBA;;;;;AAKG;AACH,SAAS,eAAe,CAAC,QAAyB,EAAA;IAChD,MAAM,MAAM,GAAsB,EAAE;IAEpCA,cAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAI;AACzC,QAAA,IAAIA,cAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAKA,cAAK,CAAC,QAAQ,EAAE;AAChE,YAAA,MAAM,aAAa,GAAG,KAAK,CAAC,KAAuC;YACnE,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACzD;aAAO;AACL,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QACpB;AACF,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,MAAM;AACf;AAEA;;;;;;;;;AASG;AACG,SAAU,IAAI,CAAC,EACnB,QAAQ,EACR,SAAS,EACT,EAAE,EACF,GAAG,SAAS,EACK,EAAA;AACjB,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;AACxB,IAAA,MAAM,MAAM,GAAG,EAAE,IAAI,CAAA,SAAA,EAAY,QAAQ,EAAE;AAC3C,IAAA,MAAM,OAAO,GAAG,CAAA,EAAG,MAAM,QAAQ;IACjC,MAAM,iBAAiB,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC;IAE3D,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC/C,CAAC,KAAK,KACJA,cAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,CAC3D;IACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;AAE9D,IAAA,QACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,SAAS,EAAA,iBAAA,EACI,QAAQ,GAAG,OAAO,GAAG,SAAS,EAC/C,SAAS,EAAE,iBAAiB,EAC5B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAA;AAErC,QAAAA,cAAA,CAAA,aAAA,CAAC,WAAW,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAA,EAC7C,QAAQ,CACY,CACnB;AAEV;AAEA,IAAI,CAAC,WAAW,GAAG,MAAM;;;;"}
@@ -1,5 +1,7 @@
1
1
  import React from "react";
2
2
  export interface PaneContextValue {
3
+ /** The Pane's root id, used to derive ids for elements inside it. */
4
+ paneId: string;
3
5
  titleId: string;
4
6
  }
5
7
  export declare const PaneContext: React.Context<PaneContextValue | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"PaneContext.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,WAAW,wCAAqD,CAAA"}
1
+ {"version":3,"file":"PaneContext.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,WAAW,wCAAqD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"PaneContext.js","sources":["../../../src/components/pane/PaneContext.tsx"],"sourcesContent":["import React from \"react\"\n\nexport interface PaneContextValue {\n titleId: string\n}\n\nexport const PaneContext = React.createContext<PaneContextValue | null>(null)\n"],"names":["React"],"mappings":";;AAMO,MAAM,WAAW,GAAGA,cAAK,CAAC,aAAa,CAA0B,IAAI;;;;"}
1
+ {"version":3,"file":"PaneContext.js","sources":["../../../src/components/pane/PaneContext.tsx"],"sourcesContent":["import React from \"react\"\n\nexport interface PaneContextValue {\n /** The Pane's root id, used to derive ids for elements inside it. */\n paneId: string\n titleId: string\n}\n\nexport const PaneContext = React.createContext<PaneContextValue | null>(null)\n"],"names":["React"],"mappings":";;AAQO,MAAM,WAAW,GAAGA,cAAK,CAAC,aAAa,CAA0B,IAAI;;;;"}
@@ -7,6 +7,12 @@ export interface PaneHeaderProps {
7
7
  * `PaneHeaderActions` wrapping the buttons that affect the whole pane.
8
8
  */
9
9
  children?: React.ReactNode;
10
+ /**
11
+ * Content for the collapsible helper shelf. When set, the header renders a
12
+ * "More info" trigger after the title and the shelf beneath it. The shelf
13
+ * starts closed.
14
+ */
15
+ helpContent?: React.ReactNode;
10
16
  /**
11
17
  * Controls which heading element renders (`h2` or `h3`) so the title fits
12
18
  * the document outline wherever the Pane is nested. Visual style stays
@@ -22,20 +28,22 @@ export interface PaneHeaderProps {
22
28
  }
23
29
  export type PaneHeaderElementProps = Omit<HTMLAttributes<HTMLDivElement>, keyof PaneHeaderProps> & PaneHeaderProps;
24
30
  /**
25
- * Whether `title` produces visible heading content. Shared with `Pane` so the
26
- * root's `role="region"` / `aria-labelledby` stays in sync with whether the
27
- * heading actually renders.
31
+ * Whether `content` produces visible output — skips `undefined`, `null`, `""`,
32
+ * and booleans (e.g. `isEditing && "Edit settings"`). Used for both `title`
33
+ * and `helpContent`, and shared with `Pane` so the root's `role="region"` /
34
+ * `aria-labelledby` stays in sync with whether the heading actually renders.
28
35
  */
29
- export declare function hasRenderableTitle(title: React.ReactNode): boolean;
36
+ export declare function hasRenderableContent(content: React.ReactNode): boolean;
30
37
  /**
31
- * The header region of a `Pane` — renders the title followed by any children,
32
- * which should be a `PaneHeaderActions` when the pane has actions. Must be
33
- * rendered inside a `Pane`.
38
+ * The header region of a `Pane` — renders the title, an optional help trigger
39
+ * and shelf (`helpContent`), then any children, which should be a
40
+ * `PaneHeaderActions` when the pane has actions. Must be rendered inside a
41
+ * `Pane`.
34
42
  *
35
43
  * @component
36
44
  * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}
37
45
  */
38
- export declare function PaneHeader({ children, className, level, title, ...restProps }: PaneHeaderElementProps): React.JSX.Element;
46
+ export declare function PaneHeader({ children, className, helpContent, level, title, ...restProps }: PaneHeaderElementProps): React.JSX.Element;
39
47
  export declare namespace PaneHeader {
40
48
  var displayName: string;
41
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PaneHeader.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAIpB,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAc,MAAM,OAAO,CAAA;AAI9D,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAA;AAEnC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,cAAc,CAAC,cAAc,CAAC,EAC9B,MAAM,eAAe,CACtB,GACC,eAAe,CAAA;AAEjB;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,GAAG,OAAO,CAOlE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,KAAS,EACT,KAAK,EACL,GAAG,SAAS,EACb,EAAE,sBAAsB,qBA0BxB;yBAhCe,UAAU"}
1
+ {"version":3,"file":"PaneHeader.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAKpB,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAc,MAAM,OAAO,CAAA;AAI9D,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAA;AAEnC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B;;;;OAIG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,cAAc,CAAC,cAAc,CAAC,EAC9B,MAAM,eAAe,CACtB,GACC,eAAe,CAAA;AAEjB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,GAAG,OAAO,CAOtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAS,EACT,KAAK,EACL,GAAG,SAAS,EACb,EAAE,sBAAsB,qBAmCxB;yBA1Ce,UAAU"}
@@ -1,37 +1,42 @@
1
1
  import { Flex } from '../flex/Flex.js';
2
+ import { HelperShelf } from '../internal/helper-shelf/HelperShelf.js';
2
3
  import classNames from 'classnames';
3
4
  import React__default, { useContext } from 'react';
4
5
  import { PaneContext } from './PaneContext.js';
5
6
 
6
7
  /**
7
- * Whether `title` produces visible heading content. Shared with `Pane` so the
8
- * root's `role="region"` / `aria-labelledby` stays in sync with whether the
9
- * heading actually renders.
8
+ * Whether `content` produces visible output — skips `undefined`, `null`, `""`,
9
+ * and booleans (e.g. `isEditing && "Edit settings"`). Used for both `title`
10
+ * and `helpContent`, and shared with `Pane` so the root's `role="region"` /
11
+ * `aria-labelledby` stays in sync with whether the heading actually renders.
10
12
  */
11
- function hasRenderableTitle(title) {
12
- return (title !== undefined &&
13
- title !== null &&
14
- title !== "" &&
15
- typeof title !== "boolean");
13
+ function hasRenderableContent(content) {
14
+ return (content !== undefined &&
15
+ content !== null &&
16
+ content !== "" &&
17
+ typeof content !== "boolean");
16
18
  }
17
19
  /**
18
- * The header region of a `Pane` — renders the title followed by any children,
19
- * which should be a `PaneHeaderActions` when the pane has actions. Must be
20
- * rendered inside a `Pane`.
20
+ * The header region of a `Pane` — renders the title, an optional help trigger
21
+ * and shelf (`helpContent`), then any children, which should be a
22
+ * `PaneHeaderActions` when the pane has actions. Must be rendered inside a
23
+ * `Pane`.
21
24
  *
22
25
  * @component
23
26
  * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}
24
27
  */
25
- function PaneHeader({ children, className, level = 2, title, ...restProps }) {
26
- const { titleId } = useContext(PaneContext) ?? {};
28
+ function PaneHeader({ children, className, helpContent, level = 2, title, ...restProps }) {
29
+ const { paneId, titleId } = useContext(PaneContext) ?? {};
27
30
  const combinedClassName = classNames("tds-pane-header", className);
28
31
  const Heading = `h${level}`;
29
- const hasTitle = hasRenderableTitle(title);
32
+ const hasTitle = hasRenderableContent(title);
33
+ const hasHelpContent = hasRenderableContent(helpContent);
30
34
  return (React__default.createElement(Flex, { as: "header", align: "center", gap: 2, justify: "space-between", direction: "row", wrap: "wrap", ...restProps, className: combinedClassName, role: "group" },
31
35
  hasTitle && (React__default.createElement(Heading, { className: "tds-pane-title", id: titleId }, title)),
36
+ hasHelpContent && (React__default.createElement(HelperShelf, { id: paneId && `${paneId}-help`, labelledById: hasTitle ? titleId : undefined }, helpContent)),
32
37
  children));
33
38
  }
34
39
  PaneHeader.displayName = "PaneHeader";
35
40
 
36
- export { PaneHeader, hasRenderableTitle };
41
+ export { PaneHeader, hasRenderableContent };
37
42
  //# sourceMappingURL=PaneHeader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PaneHeader.js","sources":["../../../src/components/pane/PaneHeader.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { Flex } from \"@components/flex\"\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes, useContext } from \"react\"\n\nimport { PaneContext } from \"./PaneContext\"\n\nexport type PaneHeaderLevel = 2 | 3\n\nexport interface PaneHeaderProps {\n /**\n * Trailing header content, rendered after the title — typically a\n * `PaneHeaderActions` wrapping the buttons that affect the whole pane.\n */\n children?: React.ReactNode\n /**\n * Controls which heading element renders (`h2` or `h3`) so the title fits\n * the document outline wherever the Pane is nested. Visual style stays\n * constant at every level. Defaults to `2`; override to `3` when nesting a\n * Pane one level deeper in the heading outline.\n */\n level?: PaneHeaderLevel\n /**\n * The pane's title. Optional only in the documented exception — e.g. a\n * wizard step whose title already lives in a Stepper component.\n */\n title?: React.ReactNode\n}\n\nexport type PaneHeaderElementProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n keyof PaneHeaderProps\n> &\n PaneHeaderProps\n\n/**\n * Whether `title` produces visible heading content. Shared with `Pane` so the\n * root's `role=\"region\"` / `aria-labelledby` stays in sync with whether the\n * heading actually renders.\n */\nexport function hasRenderableTitle(title: React.ReactNode): boolean {\n return (\n title !== undefined &&\n title !== null &&\n title !== \"\" &&\n typeof title !== \"boolean\"\n )\n}\n\n/**\n * The header region of a `Pane` — renders the title followed by any children,\n * which should be a `PaneHeaderActions` when the pane has actions. Must be\n * rendered inside a `Pane`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function PaneHeader({\n children,\n className,\n level = 2,\n title,\n ...restProps\n}: PaneHeaderElementProps) {\n const { titleId } = useContext(PaneContext) ?? {}\n const combinedClassName = classNames(\"tds-pane-header\", className)\n const Heading = `h${level}` as \"h2\" | \"h3\"\n const hasTitle = hasRenderableTitle(title)\n\n return (\n <Flex\n as=\"header\"\n align=\"center\"\n gap={2}\n justify=\"space-between\"\n direction=\"row\"\n wrap=\"wrap\"\n {...restProps}\n className={combinedClassName}\n role=\"group\"\n >\n {hasTitle && (\n <Heading className=\"tds-pane-title\" id={titleId}>\n {title}\n </Heading>\n )}\n {children}\n </Flex>\n )\n}\n\nPaneHeader.displayName = \"PaneHeader\"\n"],"names":["React"],"mappings":";;;;;AAoCA;;;;AAIG;AACG,SAAU,kBAAkB,CAAC,KAAsB,EAAA;IACvD,QACE,KAAK,KAAK,SAAS;AACnB,QAAA,KAAK,KAAK,IAAI;AACd,QAAA,KAAK,KAAK,EAAE;AACZ,QAAA,OAAO,KAAK,KAAK,SAAS;AAE9B;AAEA;;;;;;;AAOG;SACa,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,KAAK,GAAG,CAAC,EACT,KAAK,EACL,GAAG,SAAS,EACW,EAAA;IACvB,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE;IACjD,MAAM,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,EAAE,SAAS,CAAC;AAClE,IAAA,MAAM,OAAO,GAAG,CAAA,CAAA,EAAI,KAAK,EAAiB;AAC1C,IAAA,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC;AAE1C,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,QAAQ,EACd,GAAG,EAAE,CAAC,EACN,OAAO,EAAC,eAAe,EACvB,SAAS,EAAC,KAAK,EACf,IAAI,EAAC,MAAM,EAAA,GACP,SAAS,EACb,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAC,OAAO,EAAA;AAEX,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,OAAO,IAAC,SAAS,EAAC,gBAAgB,EAAC,EAAE,EAAE,OAAO,EAAA,EAC5C,KAAK,CACE,CACX;QACA,QAAQ,CACJ;AAEX;AAEA,UAAU,CAAC,WAAW,GAAG,YAAY;;;;"}
1
+ {"version":3,"file":"PaneHeader.js","sources":["../../../src/components/pane/PaneHeader.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { Flex } from \"@components/flex\"\nimport { HelperShelf } from \"@components/internal/helper-shelf\"\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes, useContext } from \"react\"\n\nimport { PaneContext } from \"./PaneContext\"\n\nexport type PaneHeaderLevel = 2 | 3\n\nexport interface PaneHeaderProps {\n /**\n * Trailing header content, rendered after the title — typically a\n * `PaneHeaderActions` wrapping the buttons that affect the whole pane.\n */\n children?: React.ReactNode\n /**\n * Content for the collapsible helper shelf. When set, the header renders a\n * \"More info\" trigger after the title and the shelf beneath it. The shelf\n * starts closed.\n */\n helpContent?: React.ReactNode\n /**\n * Controls which heading element renders (`h2` or `h3`) so the title fits\n * the document outline wherever the Pane is nested. Visual style stays\n * constant at every level. Defaults to `2`; override to `3` when nesting a\n * Pane one level deeper in the heading outline.\n */\n level?: PaneHeaderLevel\n /**\n * The pane's title. Optional only in the documented exception — e.g. a\n * wizard step whose title already lives in a Stepper component.\n */\n title?: React.ReactNode\n}\n\nexport type PaneHeaderElementProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n keyof PaneHeaderProps\n> &\n PaneHeaderProps\n\n/**\n * Whether `content` produces visible output — skips `undefined`, `null`, `\"\"`,\n * and booleans (e.g. `isEditing && \"Edit settings\"`). Used for both `title`\n * and `helpContent`, and shared with `Pane` so the root's `role=\"region\"` /\n * `aria-labelledby` stays in sync with whether the heading actually renders.\n */\nexport function hasRenderableContent(content: React.ReactNode): boolean {\n return (\n content !== undefined &&\n content !== null &&\n content !== \"\" &&\n typeof content !== \"boolean\"\n )\n}\n\n/**\n * The header region of a `Pane` — renders the title, an optional help trigger\n * and shelf (`helpContent`), then any children, which should be a\n * `PaneHeaderActions` when the pane has actions. Must be rendered inside a\n * `Pane`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function PaneHeader({\n children,\n className,\n helpContent,\n level = 2,\n title,\n ...restProps\n}: PaneHeaderElementProps) {\n const { paneId, titleId } = useContext(PaneContext) ?? {}\n const combinedClassName = classNames(\"tds-pane-header\", className)\n const Heading = `h${level}` as \"h2\" | \"h3\"\n const hasTitle = hasRenderableContent(title)\n const hasHelpContent = hasRenderableContent(helpContent)\n\n return (\n <Flex\n as=\"header\"\n align=\"center\"\n gap={2}\n justify=\"space-between\"\n direction=\"row\"\n wrap=\"wrap\"\n {...restProps}\n className={combinedClassName}\n role=\"group\"\n >\n {hasTitle && (\n <Heading className=\"tds-pane-title\" id={titleId}>\n {title}\n </Heading>\n )}\n {hasHelpContent && (\n <HelperShelf\n id={paneId && `${paneId}-help`}\n labelledById={hasTitle ? titleId : undefined}\n >\n {helpContent}\n </HelperShelf>\n )}\n {children}\n </Flex>\n )\n}\n\nPaneHeader.displayName = \"PaneHeader\"\n"],"names":["React"],"mappings":";;;;;;AA2CA;;;;;AAKG;AACG,SAAU,oBAAoB,CAAC,OAAwB,EAAA;IAC3D,QACE,OAAO,KAAK,SAAS;AACrB,QAAA,OAAO,KAAK,IAAI;AAChB,QAAA,OAAO,KAAK,EAAE;AACd,QAAA,OAAO,OAAO,KAAK,SAAS;AAEhC;AAEA;;;;;;;;AAQG;SACa,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,GAAG,CAAC,EACT,KAAK,EACL,GAAG,SAAS,EACW,EAAA;AACvB,IAAA,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE;IACzD,MAAM,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,EAAE,SAAS,CAAC;AAClE,IAAA,MAAM,OAAO,GAAG,CAAA,CAAA,EAAI,KAAK,EAAiB;AAC1C,IAAA,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC;AAC5C,IAAA,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC;AAExD,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,QAAQ,EACd,GAAG,EAAE,CAAC,EACN,OAAO,EAAC,eAAe,EACvB,SAAS,EAAC,KAAK,EACf,IAAI,EAAC,MAAM,EAAA,GACP,SAAS,EACb,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAC,OAAO,EAAA;AAEX,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,OAAO,IAAC,SAAS,EAAC,gBAAgB,EAAC,EAAE,EAAE,OAAO,EAAA,EAC5C,KAAK,CACE,CACX;QACA,cAAc,KACbA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EACV,EAAE,EAAE,MAAM,IAAI,CAAA,EAAG,MAAM,CAAA,KAAA,CAAO,EAC9B,YAAY,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,EAAA,EAE3C,WAAW,CACA,CACf;QACA,QAAQ,CACJ;AAEX;AAEA,UAAU,CAAC,WAAW,GAAG,YAAY;;;;"}