@planningcenter/tapestry 4.12.0 → 4.13.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/componentRegistrars.d.ts +1 -0
- package/dist/componentRegistrars.d.ts.map +1 -1
- package/dist/componentRegistrars.js +6 -2
- package/dist/componentRegistrars.js.map +1 -1
- package/dist/components/DataTable/ActiveFilters.d.ts +23 -1
- package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
- package/dist/components/DataTable/ActiveFilters.js +49 -4
- package/dist/components/DataTable/ActiveFilters.js.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.d.ts.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.js +20 -18
- package/dist/components/DataTable/CollectionEditorsLazy.js.map +1 -1
- package/dist/components/DataTable/DataTable.d.ts +66 -50
- package/dist/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/components/DataTable/DataTable.js +78 -17
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts +18 -7
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.js +120 -104
- package/dist/components/DataTable/ManageSavedViewsModal.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.module.css.js +1 -1
- package/dist/components/DataTable/NewSavedViewButton.d.ts.map +1 -1
- package/dist/components/DataTable/NewSavedViewButton.js +1 -1
- package/dist/components/DataTable/NewSavedViewButton.js.map +1 -1
- package/dist/components/DataTable/SavedViewActions.d.ts +19 -0
- package/dist/components/DataTable/SavedViewActions.d.ts.map +1 -0
- package/dist/components/DataTable/SavedViewActions.js +34 -0
- package/dist/components/DataTable/SavedViewActions.js.map +1 -0
- package/dist/components/DataTable/SavedViewMenu.d.ts +18 -0
- package/dist/components/DataTable/SavedViewMenu.d.ts.map +1 -0
- package/dist/components/DataTable/SavedViewMenu.js +25 -0
- package/dist/components/DataTable/SavedViewMenu.js.map +1 -0
- package/dist/components/DataTable/SavedViewsBar.d.ts +25 -13
- package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
- package/dist/components/DataTable/SavedViewsBar.js +43 -83
- package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
- package/dist/components/DataTable/TableActions.d.ts +4 -2
- package/dist/components/DataTable/TableActions.d.ts.map +1 -1
- package/dist/components/DataTable/TableActions.js +11 -14
- package/dist/components/DataTable/TableActions.js.map +1 -1
- package/dist/components/DataTable/index.d.ts +2 -0
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/saveErrorMessage.d.ts +3 -0
- package/dist/components/DataTable/saveErrorMessage.d.ts.map +1 -0
- package/dist/components/DataTable/saveErrorMessage.js +9 -0
- package/dist/components/DataTable/saveErrorMessage.js.map +1 -0
- package/dist/components/DataTable/savedViews.d.ts +15 -30
- package/dist/components/DataTable/savedViews.d.ts.map +1 -1
- package/dist/components/DataTable/savedViews.js +51 -98
- package/dist/components/DataTable/savedViews.js.map +1 -1
- package/dist/components/DataTable/useActiveSavedView.d.ts +1 -1
- package/dist/components/DataTable/useActiveSavedView.d.ts.map +1 -1
- package/dist/components/DataTable/useActiveSavedView.js +5 -4
- package/dist/components/DataTable/useActiveSavedView.js.map +1 -1
- package/dist/components/DataTable/useColumnVisibility.d.ts +7 -7
- package/dist/components/DataTable/useColumnVisibility.d.ts.map +1 -1
- package/dist/components/DataTable/useColumnVisibility.js +14 -14
- package/dist/components/DataTable/useColumnVisibility.js.map +1 -1
- package/dist/components/DataTable/useResultsAnnouncement.d.ts +26 -0
- package/dist/components/DataTable/useResultsAnnouncement.d.ts.map +1 -0
- package/dist/components/DataTable/{useFilterAnnouncement.js → useResultsAnnouncement.js} +16 -12
- package/dist/components/DataTable/useResultsAnnouncement.js.map +1 -0
- package/dist/components/DataTable/useSaveStatus.d.ts +32 -0
- package/dist/components/DataTable/useSaveStatus.d.ts.map +1 -0
- package/dist/components/DataTable/useSaveStatus.js +80 -0
- package/dist/components/DataTable/useSaveStatus.js.map +1 -0
- package/dist/components/DataTable/useSavedViewNameModal.d.ts +14 -0
- package/dist/components/DataTable/useSavedViewNameModal.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewNameModal.js +43 -0
- package/dist/components/DataTable/useSavedViewNameModal.js.map +1 -0
- package/dist/components/DataTable/useSavedViewsClient.d.ts +58 -0
- package/dist/components/DataTable/useSavedViewsClient.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewsClient.js +87 -0
- package/dist/components/DataTable/useSavedViewsClient.js.map +1 -0
- package/dist/components/DataTable/useSavedViewsState.d.ts +35 -0
- package/dist/components/DataTable/useSavedViewsState.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewsState.js +192 -0
- package/dist/components/DataTable/useSavedViewsState.js.map +1 -0
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts +2 -3
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts.map +1 -1
- package/dist/components/DataTable/useUpdateSavedViewName.js +1 -2
- package/dist/components/DataTable/useUpdateSavedViewName.js.map +1 -1
- package/dist/components/button/BaseButton.d.ts +2 -0
- package/dist/components/button/BaseButton.d.ts.map +1 -1
- package/dist/components/button/BaseButton.js +8 -17
- package/dist/components/button/BaseButton.js.map +1 -1
- package/dist/components/internal/LoadingAnnouncement.d.ts +6 -0
- package/dist/components/internal/LoadingAnnouncement.d.ts.map +1 -1
- package/dist/components/internal/LoadingAnnouncement.js +12 -3
- package/dist/components/internal/LoadingAnnouncement.js.map +1 -1
- package/dist/components/internal/index.d.ts +1 -1
- package/dist/components/internal/index.d.ts.map +1 -1
- package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts +13 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts.map +1 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.js +24 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.js.map +1 -0
- package/dist/components/link/BaseLink.d.ts.map +1 -1
- package/dist/components/link/BaseLink.js +3 -13
- package/dist/components/link/BaseLink.js.map +1 -1
- package/dist/components/segmented-control/IconSegment.d.ts +30 -8
- package/dist/components/segmented-control/IconSegment.d.ts.map +1 -1
- package/dist/components/segmented-control/IconSegment.js +10 -3
- package/dist/components/segmented-control/IconSegment.js.map +1 -1
- package/dist/components/segmented-control/SegmentBase.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentBase.js +4 -2
- package/dist/components/segmented-control/SegmentBase.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.js +10 -3
- package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
- package/dist/index.css +20 -5
- package/dist/index.css.map +1 -1
- package/dist/reactRender.css +1409 -1319
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRender.js +1 -1
- package/dist/reactRenderLegacy.css +1409 -1319
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/reactRenderLegacy.js +1 -1
- package/dist/tapestryMount.css +1409 -1319
- package/dist/tapestryMount.css.map +1 -1
- package/dist/tapestryMount.js +1 -1
- package/dist/tapestryMountLegacy.css +1409 -1319
- package/dist/tapestryMountLegacy.css.map +1 -1
- package/dist/tapestryMountLegacy.js +1 -1
- package/dist/tokens-dark.css +2 -2
- package/dist/tokens-dark.css.map +1 -1
- package/dist/tokens.css +3 -3
- package/dist/tokens.css.map +1 -1
- package/dist/unstable.css +385 -295
- package/dist/unstable.css.map +1 -1
- package/dist/unstable.js +1 -0
- package/dist/unstable.js.map +1 -1
- package/package.json +6 -7
- package/dist/components/DataTable/useFilterAnnouncement.d.ts +0 -24
- package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +0 -1
- package/dist/components/DataTable/useFilterAnnouncement.js.map +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SavedView } from "./savedViews";
|
|
2
2
|
/**
|
|
3
|
-
* Saves a view's new name, trimmed. Callers skip blank and unchanged names
|
|
4
|
-
* since `view.name` is out of date while a save is pending.
|
|
3
|
+
* Saves a view's new name, trimmed. Callers skip blank and unchanged names.
|
|
5
4
|
*/
|
|
6
|
-
export declare function useUpdateSavedViewName(onUpdate?: (savedView: SavedView) => Promise<SavedView> | SavedView): (view: SavedView, name: string) => Promise<void>;
|
|
5
|
+
export declare function useUpdateSavedViewName(onUpdate?: (savedView: SavedView) => Promise<SavedView | undefined> | SavedView): (view: SavedView, name: string) => Promise<void>;
|
|
7
6
|
//# sourceMappingURL=useUpdateSavedViewName.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdateSavedViewName.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/useUpdateSavedViewName.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C
|
|
1
|
+
{"version":3,"file":"useUpdateSavedViewName.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/useUpdateSavedViewName.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,SAAS,KACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,IAEjC,MAAM,SAAS,EAAE,MAAM,MAAM,mBAG5C"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Saves a view's new name, trimmed. Callers skip blank and unchanged names
|
|
3
|
-
* since `view.name` is out of date while a save is pending.
|
|
2
|
+
* Saves a view's new name, trimmed. Callers skip blank and unchanged names.
|
|
4
3
|
*/
|
|
5
4
|
function useUpdateSavedViewName(onUpdate) {
|
|
6
5
|
return async (view, name) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdateSavedViewName.js","sources":["../../../src/components/DataTable/useUpdateSavedViewName.ts"],"sourcesContent":["import type { SavedView } from \"./savedViews\"\n\n/**\n * Saves a view's new name, trimmed. Callers skip blank and unchanged names
|
|
1
|
+
{"version":3,"file":"useUpdateSavedViewName.js","sources":["../../../src/components/DataTable/useUpdateSavedViewName.ts"],"sourcesContent":["import type { SavedView } from \"./savedViews\"\n\n/**\n * Saves a view's new name, trimmed. Callers skip blank and unchanged names.\n */\nexport function useUpdateSavedViewName(\n onUpdate?: (\n savedView: SavedView\n ) => Promise<SavedView | undefined> | SavedView\n) {\n return async (view: SavedView, name: string) => {\n await onUpdate?.({ ...view, name: name.trim() })\n }\n}\n"],"names":[],"mappings":"AAEA;;AAEG;AACG,SAAU,sBAAsB,CACpC,QAE+C,EAAA;AAE/C,IAAA,OAAO,OAAO,IAAe,EAAE,IAAY,KAAI;AAC7C,QAAA,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AAClD,IAAA,CAAC;AACH;;;;"}
|
|
@@ -2,6 +2,8 @@ import "./btn.css";
|
|
|
2
2
|
import { BaseComponentProps, ComponentKind } from "../../utilities/buttonLinkShared";
|
|
3
3
|
import React, { ButtonHTMLAttributes } from "react";
|
|
4
4
|
export interface BaseButtonProps extends Omit<BaseComponentProps, "kind"> {
|
|
5
|
+
/** Keeps a disabled button focusable, using `aria-disabled` without the native `disabled` attribute. Use when focus would otherwise be lost, such as a button that disables itself while focused. */
|
|
6
|
+
focusableWhenDisabled?: boolean;
|
|
5
7
|
/** The visual style of the button. */
|
|
6
8
|
kind?: ComponentKind;
|
|
7
9
|
/** The text content of the button. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/BaseButton.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAIlB,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAEd,MAAM,6BAA6B,CAAA;AAEpC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"BaseButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/BaseButton.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAIlB,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAEd,MAAM,6BAA6B,CAAA;AAEpC,OAAO,KAAK,EAAE,EAAE,oBAAoB,EAAc,MAAM,OAAO,CAAA;AAE/D,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACvE,qMAAqM;IACrM,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,sCAAsC;IACtC,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,sCAAsC;IACtC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,+GAA+G;IAC/G,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,eAAe,GAAG,UAAU,CACnC,GACC,eAAe,CAAA;AAEjB,eAAO,MAAM,UAAU,qLA4DtB,CAAA"}
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import LoadingSpinner from '../internal/LoadingSpinner.js';
|
|
2
|
-
import
|
|
3
|
-
import 'react-aria/private/live-announcer/LiveAnnouncer';
|
|
2
|
+
import '../internal/LoadingAnnouncement.js';
|
|
4
3
|
import '../internal/tooltip/Tooltip.js';
|
|
5
|
-
import {
|
|
4
|
+
import { useTooltipTriggerProps } from '../internal/tooltip/useTooltipTriggerProps.js';
|
|
6
5
|
import { COMPONENT_SIZE_CLASS_MAP, COMPONENT_KIND_CLASS_MAP, wrapStringWithSpan } from '../../utilities/buttonLinkShared.js';
|
|
7
6
|
import classNames from 'classnames';
|
|
8
|
-
import {
|
|
9
|
-
import { mergeRefs } from 'react-aria/mergeRefs';
|
|
7
|
+
import React, { forwardRef } from 'react';
|
|
10
8
|
|
|
11
|
-
const BaseButton = forwardRef(({ "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, className, disabled = false, fullWidth, kind = "secondary", label, loading = false, loadingAriaLabel = "Loading...", prefix, size, suffix, ...restProps }, ref) => {
|
|
12
|
-
const
|
|
13
|
-
const { "aria-describedby": tooltipId, ...tooltipTriggerProps } = tooltip?.triggerProps ?? {};
|
|
14
|
-
const mergedProps = tooltip
|
|
15
|
-
? mergeProps(restProps, tooltipTriggerProps)
|
|
16
|
-
: restProps;
|
|
17
|
-
const mergedRef = tooltip
|
|
18
|
-
? mergeRefs(ref, tooltip.ref)
|
|
19
|
-
: ref;
|
|
20
|
-
const describedBy = [ariaDescribedBy, tooltipId].filter(Boolean).join(" ") || undefined;
|
|
21
|
-
const combinedClassName = classNames(kind && "tds-btn", size && size !== "md" && COMPONENT_SIZE_CLASS_MAP[size], kind && COMPONENT_KIND_CLASS_MAP[kind], fullWidth && "tds-btn--full-width", loading && "tds-btn--loading", className, { "tds-btn--prefix": prefix, "tds-btn--suffix": suffix });
|
|
9
|
+
const BaseButton = forwardRef(({ "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, className, disabled = false, focusableWhenDisabled = false, fullWidth, kind = "secondary", label, loading = false, loadingAriaLabel = "Loading...", prefix, size, suffix, ...restProps }, ref) => {
|
|
10
|
+
const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps(restProps, ref, ariaDescribedBy);
|
|
22
11
|
const isDisabled = disabled || loading;
|
|
23
|
-
|
|
12
|
+
const isFocusableDisabled = isDisabled && focusableWhenDisabled;
|
|
13
|
+
const combinedClassName = classNames(kind && "tds-btn", size && size !== "md" && COMPONENT_SIZE_CLASS_MAP[size], kind && COMPONENT_KIND_CLASS_MAP[kind], fullWidth && "tds-btn--full-width", loading && "tds-btn--loading", isFocusableDisabled && "disabled", className, { "tds-btn--prefix": prefix, "tds-btn--suffix": suffix });
|
|
14
|
+
return (React.createElement("button", { type: "button", className: combinedClassName, ref: mergedRef, ...mergedProps, "aria-busy": loading || undefined, "aria-describedby": describedBy, "aria-disabled": isDisabled || undefined, disabled: isDisabled && !focusableWhenDisabled, onClick: isFocusableDisabled ? undefined : mergedProps.onClick, "aria-label": loading ? loadingAriaLabel : ariaLabel },
|
|
24
15
|
loading && React.createElement(LoadingSpinner, null),
|
|
25
16
|
wrapStringWithSpan(prefix),
|
|
26
17
|
loading ? React.createElement("span", null, label) : label,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseButton.js","sources":["../../../src/components/button/BaseButton.tsx"],"sourcesContent":["import \"./btn.css\"\n\nimport { LoadingSpinner } from \"@components/internal\"\nimport {
|
|
1
|
+
{"version":3,"file":"BaseButton.js","sources":["../../../src/components/button/BaseButton.tsx"],"sourcesContent":["import \"./btn.css\"\n\nimport { LoadingSpinner } from \"@components/internal\"\nimport { useTooltipTriggerProps } from \"@components/internal/tooltip/useTooltipTriggerProps\"\nimport {\n BaseComponentProps,\n COMPONENT_KIND_CLASS_MAP,\n COMPONENT_SIZE_CLASS_MAP,\n ComponentKind,\n wrapStringWithSpan,\n} from \"@utilities/buttonLinkShared\"\nimport classNames from \"classnames\"\nimport React, { ButtonHTMLAttributes, forwardRef } from \"react\"\n\nexport interface BaseButtonProps extends Omit<BaseComponentProps, \"kind\"> {\n /** Keeps a disabled button focusable, using `aria-disabled` without the native `disabled` attribute. Use when focus would otherwise be lost, such as a button that disables itself while focused. */\n focusableWhenDisabled?: boolean\n /** The visual style of the button. */\n kind?: ComponentKind\n /** The text content of the button. */\n label: React.ReactNode\n /** Whether the button is in a loading state. When true, the button is disabled and shows a loading spinner. */\n loading?: boolean\n /** Accessible label to use when the button is in loading state. */\n loadingAriaLabel?: string\n}\n\nexport type BaseButtonElementProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof BaseButtonProps | \"children\"\n> &\n BaseButtonProps\n\nexport const BaseButton = forwardRef<HTMLButtonElement, BaseButtonElementProps>(\n (\n {\n \"aria-describedby\": ariaDescribedBy,\n \"aria-label\": ariaLabel,\n className,\n disabled = false,\n focusableWhenDisabled = false,\n fullWidth,\n kind = \"secondary\",\n label,\n loading = false,\n loadingAriaLabel = \"Loading...\",\n prefix,\n size,\n suffix,\n ...restProps\n }: BaseButtonElementProps,\n ref\n ) => {\n const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps(\n restProps,\n ref,\n ariaDescribedBy\n )\n\n const isDisabled = disabled || loading\n const isFocusableDisabled = isDisabled && focusableWhenDisabled\n\n const combinedClassName = classNames(\n kind && \"tds-btn\",\n size && size !== \"md\" && COMPONENT_SIZE_CLASS_MAP[size],\n kind && COMPONENT_KIND_CLASS_MAP[kind],\n fullWidth && \"tds-btn--full-width\",\n loading && \"tds-btn--loading\",\n isFocusableDisabled && \"disabled\",\n className,\n { \"tds-btn--prefix\": prefix, \"tds-btn--suffix\": suffix }\n )\n\n return (\n <button\n type=\"button\"\n className={combinedClassName}\n ref={mergedRef}\n {...mergedProps}\n aria-busy={loading || undefined}\n aria-describedby={describedBy}\n aria-disabled={isDisabled || undefined}\n disabled={isDisabled && !focusableWhenDisabled}\n onClick={isFocusableDisabled ? undefined : mergedProps.onClick}\n aria-label={loading ? loadingAriaLabel : ariaLabel}\n >\n {loading && <LoadingSpinner />}\n {wrapStringWithSpan(prefix)}\n {loading ? <span>{label}</span> : label}\n {wrapStringWithSpan(suffix)}\n </button>\n )\n }\n)\n\nBaseButton.displayName = \"BaseButton\"\n"],"names":[],"mappings":";;;;;;;;AAiCO,MAAM,UAAU,GAAG,UAAU,CAClC,CACE,EACE,kBAAkB,EAAE,eAAe,EACnC,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,QAAQ,GAAG,KAAK,EAChB,qBAAqB,GAAG,KAAK,EAC7B,SAAS,EACT,IAAI,GAAG,WAAW,EAClB,KAAK,EACL,OAAO,GAAG,KAAK,EACf,gBAAgB,GAAG,YAAY,EAC/B,MAAM,EACN,IAAI,EACJ,MAAM,EACN,GAAG,SAAS,EACW,EACzB,GAAG,KACD;AACF,IAAA,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,sBAAsB,CACpE,SAAS,EACT,GAAG,EACH,eAAe,CAChB;AAED,IAAA,MAAM,UAAU,GAAG,QAAQ,IAAI,OAAO;AACtC,IAAA,MAAM,mBAAmB,GAAG,UAAU,IAAI,qBAAqB;IAE/D,MAAM,iBAAiB,GAAG,UAAU,CAClC,IAAI,IAAI,SAAS,EACjB,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,EACvD,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,EACtC,SAAS,IAAI,qBAAqB,EAClC,OAAO,IAAI,kBAAkB,EAC7B,mBAAmB,IAAI,UAAU,EACjC,SAAS,EACT,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,CACzD;IAED,QACE,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,iBAAiB,EAC5B,GAAG,EAAE,SAAS,EAAA,GACV,WAAW,EAAA,WAAA,EACJ,OAAO,IAAI,SAAS,EAAA,kBAAA,EACb,WAAW,EAAA,eAAA,EACd,UAAU,IAAI,SAAS,EACtC,QAAQ,EAAE,UAAU,IAAI,CAAC,qBAAqB,EAC9C,OAAO,EAAE,mBAAmB,GAAG,SAAS,GAAG,WAAW,CAAC,OAAO,EAAA,YAAA,EAClD,OAAO,GAAG,gBAAgB,GAAG,SAAS,EAAA;QAEjD,OAAO,IAAI,KAAA,CAAA,aAAA,CAAC,cAAc,EAAA,IAAA,CAAG;QAC7B,kBAAkB,CAAC,MAAM,CAAC;QAC1B,OAAO,GAAG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,IAAA,EAAO,KAAK,CAAQ,GAAG,KAAK;AACtC,QAAA,kBAAkB,CAAC,MAAM,CAAC,CACpB;AAEb,CAAC;AAGH,UAAU,CAAC,WAAW,GAAG,YAAY;;;;"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export declare const LOADING_ANNOUNCEMENT_DELAY_MS = 500;
|
|
2
|
+
/**
|
|
3
|
+
* Turns off every {@link LoadingAnnouncement} inside it while `true`. Use it
|
|
4
|
+
* when focus moves into a field during the load, because the screen reader
|
|
5
|
+
* then speaks the message only after the results appear.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SuppressLoadingAnnouncementContext: import("react").Context<boolean>;
|
|
2
8
|
/**
|
|
3
9
|
* Announces `message` to screen reader users while a loading indicator is
|
|
4
10
|
* shown. Render it next to the spinner, only while loading. It waits
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/internal/LoadingAnnouncement.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAEhD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"LoadingAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/internal/LoadingAnnouncement.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,kCAAuB,CAAA;AAEtE;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,QAcnE"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { useAnnounce } from '../../utilities/useAnnounce.js';
|
|
2
|
-
import { useEffect } from 'react';
|
|
2
|
+
import { createContext, useContext, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
const LOADING_ANNOUNCEMENT_DELAY_MS = 500;
|
|
5
|
+
/**
|
|
6
|
+
* Turns off every {@link LoadingAnnouncement} inside it while `true`. Use it
|
|
7
|
+
* when focus moves into a field during the load, because the screen reader
|
|
8
|
+
* then speaks the message only after the results appear.
|
|
9
|
+
*/
|
|
10
|
+
const SuppressLoadingAnnouncementContext = createContext(false);
|
|
5
11
|
/**
|
|
6
12
|
* Announces `message` to screen reader users while a loading indicator is
|
|
7
13
|
* shown. Render it next to the spinner, only while loading. It waits
|
|
@@ -10,12 +16,15 @@ const LOADING_ANNOUNCEMENT_DELAY_MS = 500;
|
|
|
10
16
|
*/
|
|
11
17
|
function LoadingAnnouncement({ message }) {
|
|
12
18
|
const announce = useAnnounce();
|
|
19
|
+
const isSuppressed = useContext(SuppressLoadingAnnouncementContext);
|
|
13
20
|
useEffect(() => {
|
|
21
|
+
if (isSuppressed)
|
|
22
|
+
return;
|
|
14
23
|
const timeout = setTimeout(() => announce(message), LOADING_ANNOUNCEMENT_DELAY_MS);
|
|
15
24
|
return () => clearTimeout(timeout);
|
|
16
|
-
}, [announce, message]);
|
|
25
|
+
}, [announce, isSuppressed, message]);
|
|
17
26
|
return null;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
export { LOADING_ANNOUNCEMENT_DELAY_MS, LoadingAnnouncement };
|
|
29
|
+
export { LOADING_ANNOUNCEMENT_DELAY_MS, LoadingAnnouncement, SuppressLoadingAnnouncementContext };
|
|
21
30
|
//# sourceMappingURL=LoadingAnnouncement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingAnnouncement.js","sources":["../../../src/components/internal/LoadingAnnouncement.tsx"],"sourcesContent":["import { useAnnounce } from \"@utilities/useAnnounce\"\nimport { useEffect } from \"react\"\n\nexport const LOADING_ANNOUNCEMENT_DELAY_MS = 500\n\n/**\n * Announces `message` to screen reader users while a loading indicator is\n * shown. Render it next to the spinner, only while loading. It waits\n * {@link LOADING_ANNOUNCEMENT_DELAY_MS} after mount, so a fast load says\n * nothing, and it cancels if it unmounts first.\n */\nexport function LoadingAnnouncement({ message }: { message: string }) {\n const announce = useAnnounce()\n\n useEffect(() => {\n const timeout = setTimeout(\n () => announce(message),\n LOADING_ANNOUNCEMENT_DELAY_MS\n )\n return () => clearTimeout(timeout)\n }, [announce, message])\n\n return null\n}\n"],"names":[],"mappings":";;;AAGO,MAAM,6BAA6B,GAAG;AAE7C;;;;;AAKG;AACG,SAAU,mBAAmB,CAAC,EAAE,OAAO,EAAuB,EAAA;AAClE,IAAA,MAAM,QAAQ,GAAG,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"LoadingAnnouncement.js","sources":["../../../src/components/internal/LoadingAnnouncement.tsx"],"sourcesContent":["import { useAnnounce } from \"@utilities/useAnnounce\"\nimport { createContext, useContext, useEffect } from \"react\"\n\nexport const LOADING_ANNOUNCEMENT_DELAY_MS = 500\n\n/**\n * Turns off every {@link LoadingAnnouncement} inside it while `true`. Use it\n * when focus moves into a field during the load, because the screen reader\n * then speaks the message only after the results appear.\n */\nexport const SuppressLoadingAnnouncementContext = createContext(false)\n\n/**\n * Announces `message` to screen reader users while a loading indicator is\n * shown. Render it next to the spinner, only while loading. It waits\n * {@link LOADING_ANNOUNCEMENT_DELAY_MS} after mount, so a fast load says\n * nothing, and it cancels if it unmounts first.\n */\nexport function LoadingAnnouncement({ message }: { message: string }) {\n const announce = useAnnounce()\n const isSuppressed = useContext(SuppressLoadingAnnouncementContext)\n\n useEffect(() => {\n if (isSuppressed) return\n const timeout = setTimeout(\n () => announce(message),\n LOADING_ANNOUNCEMENT_DELAY_MS\n )\n return () => clearTimeout(timeout)\n }, [announce, isSuppressed, message])\n\n return null\n}\n"],"names":[],"mappings":";;;AAGO,MAAM,6BAA6B,GAAG;AAE7C;;;;AAIG;MACU,kCAAkC,GAAG,aAAa,CAAC,KAAK;AAErE;;;;;AAKG;AACG,SAAU,mBAAmB,CAAC,EAAE,OAAO,EAAuB,EAAA;AAClE,IAAA,MAAM,QAAQ,GAAG,WAAW,EAAE;AAC9B,IAAA,MAAM,YAAY,GAAG,UAAU,CAAC,kCAAkC,CAAC;IAEnE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,YAAY;YAAE;AAClB,QAAA,MAAM,OAAO,GAAG,UAAU,CACxB,MAAM,QAAQ,CAAC,OAAO,CAAC,EACvB,6BAA6B,CAC9B;AACD,QAAA,OAAO,MAAM,YAAY,CAAC,OAAO,CAAC;IACpC,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AAErC,IAAA,OAAO,IAAI;AACb;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LoadingSpinner from "./LoadingSpinner";
|
|
2
|
-
export { LoadingAnnouncement } from "./LoadingAnnouncement";
|
|
2
|
+
export { LoadingAnnouncement, SuppressLoadingAnnouncementContext, } from "./LoadingAnnouncement";
|
|
3
3
|
export type { TooltipProps } from "./tooltip";
|
|
4
4
|
export { Tooltip } from "./tooltip";
|
|
5
5
|
export { LoadingSpinner };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/internal/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAE7C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/internal/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EACL,mBAAmB,EACnB,kCAAkC,GACnC,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ForwardedRef, type HTMLAttributes, type Ref } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Wires an element to a surrounding `<Tooltip>`. Merges the tooltip's
|
|
4
|
+
* trigger props and ref into the element's own, and joins the tooltip's
|
|
5
|
+
* `aria-describedby` with the caller's. Outside a `<Tooltip>`, returns the
|
|
6
|
+
* element's own props and ref unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useTooltipTriggerProps<E extends HTMLElement>(props: HTMLAttributes<E>, ref: ForwardedRef<E>, ariaDescribedBy?: string): {
|
|
9
|
+
describedBy: string | undefined;
|
|
10
|
+
mergedProps: HTMLAttributes<E>;
|
|
11
|
+
mergedRef: Ref<E>;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=useTooltipTriggerProps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTooltipTriggerProps.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/tooltip/useTooltipTriggerProps.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,GAAG,EAGT,MAAM,OAAO,CAAA;AAMd;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,WAAW,EAC1D,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EACxB,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,EACpB,eAAe,CAAC,EAAE,MAAM,GACvB;IACD,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;CAClB,CAaA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { mergeProps } from 'react-aria/mergeProps';
|
|
3
|
+
import { mergeRefs } from 'react-aria/mergeRefs';
|
|
4
|
+
import { TooltipTriggerContext } from './TooltipTriggerContext.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Wires an element to a surrounding `<Tooltip>`. Merges the tooltip's
|
|
8
|
+
* trigger props and ref into the element's own, and joins the tooltip's
|
|
9
|
+
* `aria-describedby` with the caller's. Outside a `<Tooltip>`, returns the
|
|
10
|
+
* element's own props and ref unchanged.
|
|
11
|
+
*/
|
|
12
|
+
function useTooltipTriggerProps(props, ref, ariaDescribedBy) {
|
|
13
|
+
const tooltip = useContext(TooltipTriggerContext);
|
|
14
|
+
const { "aria-describedby": tooltipId, ...tooltipTriggerProps } = tooltip?.triggerProps ?? {};
|
|
15
|
+
const mergedProps = tooltip ? mergeProps(props, tooltipTriggerProps) : props;
|
|
16
|
+
const mergedRef = tooltip
|
|
17
|
+
? mergeRefs(ref, tooltip.ref)
|
|
18
|
+
: ref;
|
|
19
|
+
const describedBy = [ariaDescribedBy, tooltipId].filter(Boolean).join(" ") || undefined;
|
|
20
|
+
return { describedBy, mergedProps, mergedRef };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { useTooltipTriggerProps };
|
|
24
|
+
//# sourceMappingURL=useTooltipTriggerProps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTooltipTriggerProps.js","sources":["../../../../src/components/internal/tooltip/useTooltipTriggerProps.ts"],"sourcesContent":["import {\n type ForwardedRef,\n type HTMLAttributes,\n type Ref,\n type RefObject,\n useContext,\n} from \"react\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { mergeRefs } from \"react-aria/mergeRefs\"\n\nimport { TooltipTriggerContext } from \"./TooltipTriggerContext\"\n\n/**\n * Wires an element to a surrounding `<Tooltip>`. Merges the tooltip's\n * trigger props and ref into the element's own, and joins the tooltip's\n * `aria-describedby` with the caller's. Outside a `<Tooltip>`, returns the\n * element's own props and ref unchanged.\n */\nexport function useTooltipTriggerProps<E extends HTMLElement>(\n props: HTMLAttributes<E>,\n ref: ForwardedRef<E>,\n ariaDescribedBy?: string\n): {\n describedBy: string | undefined\n mergedProps: HTMLAttributes<E>\n mergedRef: Ref<E>\n} {\n const tooltip = useContext(TooltipTriggerContext)\n const { \"aria-describedby\": tooltipId, ...tooltipTriggerProps } =\n tooltip?.triggerProps ?? {}\n\n const mergedProps = tooltip ? mergeProps(props, tooltipTriggerProps) : props\n const mergedRef = tooltip\n ? mergeRefs<E>(ref, tooltip.ref as RefObject<E>)\n : ref\n const describedBy =\n [ariaDescribedBy, tooltipId].filter(Boolean).join(\" \") || undefined\n\n return { describedBy, mergedProps, mergedRef }\n}\n"],"names":[],"mappings":";;;;;AAYA;;;;;AAKG;SACa,sBAAsB,CACpC,KAAwB,EACxB,GAAoB,EACpB,eAAwB,EAAA;AAMxB,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC;AACjD,IAAA,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,GAAG,mBAAmB,EAAE,GAC7D,OAAO,EAAE,YAAY,IAAI,EAAE;AAE7B,IAAA,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,GAAG,KAAK;IAC5E,MAAM,SAAS,GAAG;UACd,SAAS,CAAI,GAAG,EAAE,OAAO,CAAC,GAAmB;UAC7C,GAAG;AACP,IAAA,MAAM,WAAW,GACf,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;AAErE,IAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE;AAChD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseLink.d.ts","sourceRoot":"","sources":["../../../src/components/link/BaseLink.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAA;AAI1B,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAEd,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"BaseLink.d.ts","sourceRoot":"","sources":["../../../src/components/link/BaseLink.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAA;AAI1B,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAEd,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,KAAK,EAAE,EAAE,oBAAoB,EAAc,MAAM,OAAO,CAAA;AAE/D,KAAK,iBAAiB,GAAG,kBAAkB,GACzC,IAAI,CACF,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,kBAAkB,GAAG,UAAU,GAAG,MAAM,CAC/C,GAAG;IACF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB,CAAA;AAEH,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CACN,iBAAiB,GAAG;IAClB;;;;;OAKG;IACH,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,CAAC,EAAE,KAAK,CAAA;CACb,CACF,GACD,QAAQ,CAAC,iBAAiB,GAAG;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEnE,eAAO,MAAM,QAAQ,gGAuDpB,CAAA"}
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useTooltipTriggerProps } from '../internal/tooltip/useTooltipTriggerProps.js';
|
|
2
2
|
import { Slot, Slottable } from '@radix-ui/react-slot';
|
|
3
3
|
import { COMPONENT_SIZE_CLASS_MAP, COMPONENT_KIND_CLASS_MAP, wrapStringWithSpan } from '../../utilities/buttonLinkShared.js';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import React__default, { forwardRef
|
|
6
|
-
import { mergeProps } from 'react-aria/mergeProps';
|
|
7
|
-
import { mergeRefs } from 'react-aria/mergeRefs';
|
|
5
|
+
import React__default, { forwardRef } from 'react';
|
|
8
6
|
|
|
9
7
|
const BaseLink = forwardRef(({ asChild = false, "aria-describedby": ariaDescribedBy, children, className, external = false, fullWidth, href, kind, label, prefix, size, suffix, ...restProps }, ref) => {
|
|
10
|
-
const
|
|
11
|
-
const { "aria-describedby": tooltipId, ...tooltipTriggerProps } = tooltip?.triggerProps ?? {};
|
|
12
|
-
const mergedProps = tooltip
|
|
13
|
-
? mergeProps(restProps, tooltipTriggerProps)
|
|
14
|
-
: restProps;
|
|
15
|
-
const mergedRef = tooltip
|
|
16
|
-
? mergeRefs(ref, tooltip.ref)
|
|
17
|
-
: ref;
|
|
18
|
-
const describedBy = [ariaDescribedBy, tooltipId].filter(Boolean).join(" ") || undefined;
|
|
8
|
+
const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps(restProps, ref, ariaDescribedBy);
|
|
19
9
|
const combinedClassName = classNames(kind && "tds-btn", size && size !== "md" && kind && COMPONENT_SIZE_CLASS_MAP[size], kind && COMPONENT_KIND_CLASS_MAP[kind], fullWidth && "tds-btn--full-width", className, { "tds-btn--prefix": prefix, "tds-btn--suffix": suffix });
|
|
20
10
|
const externalProps = external
|
|
21
11
|
? { rel: "noopener noreferrer", target: "_blank" }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseLink.js","sources":["../../../src/components/link/BaseLink.tsx"],"sourcesContent":["import \"../button/btn.css\"\n\nimport {
|
|
1
|
+
{"version":3,"file":"BaseLink.js","sources":["../../../src/components/link/BaseLink.tsx"],"sourcesContent":["import \"../button/btn.css\"\n\nimport { useTooltipTriggerProps } from \"@components/internal/tooltip/useTooltipTriggerProps\"\nimport { Slot, Slottable } from \"@radix-ui/react-slot\"\nimport {\n BaseComponentProps,\n COMPONENT_KIND_CLASS_MAP,\n COMPONENT_SIZE_CLASS_MAP,\n ComponentKind,\n wrapStringWithSpan,\n} from \"@utilities/buttonLinkShared\"\nimport { Simplify } from \"@utilities/typeUtils\"\nimport classNames from \"classnames\"\nimport React, { AnchorHTMLAttributes, forwardRef } from \"react\"\n\ntype BaseLinkBaseProps = BaseComponentProps &\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof BaseComponentProps | \"children\" | \"href\"\n > & {\n children?: React.ReactNode\n external?: boolean\n kind?: ComponentKind\n label?: React.ReactNode\n }\n\nexport type BaseLinkElementProps =\n | Simplify<\n BaseLinkBaseProps & {\n /**\n * When true, merges the link's styling onto the child element instead\n * of rendering an `<a>`. Use to wrap a router link (e.g. react-router,\n * Next.js) or any link-like component. The `external` prop still\n * applies — it spreads `rel`/`target` onto the child element.\n */\n asChild: true\n href?: never\n }\n >\n | Simplify<BaseLinkBaseProps & { asChild?: false; href: string }>\n\nexport const BaseLink = forwardRef<HTMLAnchorElement, BaseLinkElementProps>(\n (\n {\n asChild = false,\n \"aria-describedby\": ariaDescribedBy,\n children,\n className,\n external = false,\n fullWidth,\n href,\n kind,\n label,\n prefix,\n size,\n suffix,\n ...restProps\n }: BaseLinkElementProps,\n ref\n ) => {\n const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps(\n restProps,\n ref,\n ariaDescribedBy\n )\n\n const combinedClassName = classNames(\n kind && \"tds-btn\",\n size && size !== \"md\" && kind && COMPONENT_SIZE_CLASS_MAP[size],\n kind && COMPONENT_KIND_CLASS_MAP[kind],\n fullWidth && \"tds-btn--full-width\",\n className,\n { \"tds-btn--prefix\": prefix, \"tds-btn--suffix\": suffix }\n )\n\n const externalProps = external\n ? { rel: \"noopener noreferrer\", target: \"_blank\" }\n : {}\n\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n {...(!asChild && { href })}\n className={combinedClassName}\n ref={mergedRef}\n {...mergedProps}\n aria-describedby={describedBy}\n {...externalProps}\n >\n {wrapStringWithSpan(prefix)}\n <Slottable>{label || children}</Slottable>\n {wrapStringWithSpan(suffix)}\n </Comp>\n )\n }\n)\n\nBaseLink.displayName = \"BaseLink\"\n"],"names":["React"],"mappings":";;;;;;MAyCa,QAAQ,GAAG,UAAU,CAChC,CACE,EACE,OAAO,GAAG,KAAK,EACf,kBAAkB,EAAE,eAAe,EACnC,QAAQ,EACR,SAAS,EACT,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,GAAG,SAAS,EACS,EACvB,GAAG,KACD;AACF,IAAA,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,sBAAsB,CACpE,SAAS,EACT,GAAG,EACH,eAAe,CAChB;IAED,MAAM,iBAAiB,GAAG,UAAU,CAClC,IAAI,IAAI,SAAS,EACjB,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,EAC/D,IAAI,IAAI,wBAAwB,CAAC,IAAI,CAAC,EACtC,SAAS,IAAI,qBAAqB,EAClC,SAAS,EACT,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,CACzD;IAED,MAAM,aAAa,GAAG;UAClB,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ;UAC9C,EAAE;IAEN,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,GAAG,GAAG;IAEjC,QACEA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,IACE,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,GAAG,EAAE,SAAS,EAAA,GACV,WAAW,EAAA,kBAAA,EACG,WAAW,EAAA,GACzB,aAAa,EAAA;QAEhB,kBAAkB,CAAC,MAAM,CAAC;AAC3B,QAAAA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,IAAA,EAAE,KAAK,IAAI,QAAQ,CAAa;AACzC,QAAA,kBAAkB,CAAC,MAAM,CAAC,CACtB;AAEX,CAAC;AAGH,QAAQ,CAAC,WAAW,GAAG,UAAU;;;;"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import "./index.css";
|
|
2
|
+
import { type TooltipPlacement } from "../internal/tooltip";
|
|
2
3
|
import React, { type ButtonHTMLAttributes } from "react";
|
|
3
4
|
import { type SegmentKind } from "./SegmentBase";
|
|
4
|
-
|
|
5
|
-
/** Accessible label — required since there's no visible text. */
|
|
6
|
-
"aria-label": string;
|
|
5
|
+
type IconSegmentSharedProps = {
|
|
7
6
|
/** Disables this item only. */
|
|
8
7
|
disabled?: boolean;
|
|
9
8
|
/** The icon to display. */
|
|
@@ -12,17 +11,40 @@ export interface IconSegmentProps {
|
|
|
12
11
|
* This segment's color when selected. Default `'interaction-subtle'`.
|
|
13
12
|
*/
|
|
14
13
|
kind?: SegmentKind;
|
|
14
|
+
/** Where the tooltip renders relative to the segment. Default `"bottom"`. Has no effect without `tooltip`. */
|
|
15
|
+
tooltipPlacement?: TooltipPlacement;
|
|
15
16
|
/** Unique identifier for this item. */
|
|
16
17
|
value: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
18
|
+
};
|
|
19
|
+
type IconSegmentTooltipProps = {
|
|
20
|
+
/** Accessible label. Required for icon-only segments to provide context about the segment's purpose. Not required when `tooltip` is set. When both are set, this is the name and the tooltip is visual only. */
|
|
21
|
+
"aria-label"?: string;
|
|
22
|
+
/** Text shown on hover and focus. Without `aria-label`, it is also used as the `aria-label`. With `aria-label`, start the `aria-label` with the same text (e.g. tooltip `"Grid"`, aria-label `"Grid view"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */
|
|
23
|
+
tooltip: string;
|
|
24
|
+
};
|
|
25
|
+
type IconSegmentAriaLabelProps = {
|
|
26
|
+
/** Accessible label. Required for icon-only segments to provide context about the segment's purpose. Not required when `tooltip` is set. When both are set, this is the name and the tooltip is visual only. */
|
|
27
|
+
"aria-label": string;
|
|
28
|
+
/** Text shown on hover and focus. Without `aria-label`, it is also used as the `aria-label`. With `aria-label`, start the `aria-label` with the same text (e.g. tooltip `"Grid"`, aria-label `"Grid view"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */
|
|
29
|
+
tooltip?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* An icon-only segment needs a name: `aria-label`, `tooltip`, or both.
|
|
33
|
+
* `IconSegmentAriaLabelProps` is declared last so that a missing name
|
|
34
|
+
* reports "aria-label is missing", not "tooltip is missing".
|
|
35
|
+
*/
|
|
36
|
+
type IconSegmentNameProps = IconSegmentAriaLabelProps | IconSegmentTooltipProps;
|
|
37
|
+
export type IconSegmentProps = IconSegmentSharedProps & IconSegmentNameProps;
|
|
38
|
+
export type IconSegmentElementProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof IconSegmentSharedProps | "aria-checked" | "aria-label" | "children" | "onClick" | "onKeyDown" | "role" | "tabIndex" | "tooltip" | "type"> & IconSegmentProps;
|
|
19
39
|
/**
|
|
20
40
|
* An icon-only item within a `SegmentedControl`, mirroring `IconButton`'s
|
|
21
|
-
* shape.
|
|
22
|
-
*
|
|
41
|
+
* shape. Requires an `aria-label` or `tooltip` for accessibility. Must be
|
|
42
|
+
* rendered as a direct child of `SegmentedControl` — it reads selection
|
|
43
|
+
* state, group `disabled`, and roving tabindex from that context.
|
|
23
44
|
*
|
|
24
45
|
* @component
|
|
25
46
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-segmentedcontrol--docs | Storybook Documentation}
|
|
26
47
|
*/
|
|
27
|
-
export declare const IconSegment: React.ForwardRefExoticComponent<
|
|
48
|
+
export declare const IconSegment: React.ForwardRefExoticComponent<IconSegmentElementProps & React.RefAttributes<HTMLButtonElement>>;
|
|
49
|
+
export {};
|
|
28
50
|
//# sourceMappingURL=IconSegment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconSegment.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/IconSegment.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,EAAE,KAAK,oBAAoB,EAAc,MAAM,OAAO,CAAA;AAEpE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAE7D,
|
|
1
|
+
{"version":3,"file":"IconSegment.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/IconSegment.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC7E,OAAO,KAAK,EAAE,EAAE,KAAK,oBAAoB,EAAc,MAAM,OAAO,CAAA;AAEpE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAE7D,KAAK,sBAAsB,GAAG;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,2BAA2B;IAC3B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;IACrB;;OAEG;IACH,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,8GAA8G;IAC9G,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,uBAAuB,GAAG;IAC7B,gNAAgN;IAChN,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,6RAA6R;IAC7R,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,gNAAgN;IAChN,YAAY,EAAE,MAAM,CAAA;IACpB,6RAA6R;IAC7R,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;GAIG;AACH,KAAK,oBAAoB,GAAG,yBAAyB,GAAG,uBAAuB,CAAA;AAE/E,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GAAG,oBAAoB,CAAA;AAE5E,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,oBAAoB,CAAC,iBAAiB,CAAC,EACrC,MAAM,sBAAsB,GAC5B,cAAc,GACd,YAAY,GACZ,UAAU,GACV,SAAS,GACT,WAAW,GACX,MAAM,GACN,UAAU,GACV,SAAS,GACT,MAAM,CACT,GACC,gBAAgB,CAAA;AAElB;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,mGAiCtB,CAAA"}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import { Tooltip } from '../internal/tooltip/Tooltip.js';
|
|
1
2
|
import React__default, { forwardRef } from 'react';
|
|
2
3
|
import { SegmentBase } from './SegmentBase.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* An icon-only item within a `SegmentedControl`, mirroring `IconButton`'s
|
|
6
|
-
* shape.
|
|
7
|
-
*
|
|
7
|
+
* shape. Requires an `aria-label` or `tooltip` for accessibility. Must be
|
|
8
|
+
* rendered as a direct child of `SegmentedControl` — it reads selection
|
|
9
|
+
* state, group `disabled`, and roving tabindex from that context.
|
|
8
10
|
*
|
|
9
11
|
* @component
|
|
10
12
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-segmentedcontrol--docs | Storybook Documentation}
|
|
11
13
|
*/
|
|
12
|
-
const IconSegment = forwardRef(function IconSegment({ icon, ...restProps }, ref) {
|
|
14
|
+
const IconSegment = forwardRef(function IconSegment({ icon, tooltip, tooltipPlacement = "bottom", ...restProps }, ref) {
|
|
15
|
+
if (tooltip) {
|
|
16
|
+
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...segmentProps } = restProps;
|
|
17
|
+
return (React__default.createElement(Tooltip, { content: tooltip, placement: tooltipPlacement, visualOnly: true },
|
|
18
|
+
React__default.createElement(SegmentBase, { ...segmentProps, "aria-label": ariaLabel || tooltip, content: icon, iconOnly: true, ref: ref })));
|
|
19
|
+
}
|
|
13
20
|
return React__default.createElement(SegmentBase, { ...restProps, content: icon, iconOnly: true, ref: ref });
|
|
14
21
|
});
|
|
15
22
|
IconSegment.displayName = "IconSegment";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconSegment.js","sources":["../../../src/components/segmented-control/IconSegment.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport React, { type ButtonHTMLAttributes, forwardRef } from \"react\"\n\nimport { SegmentBase, type SegmentKind } from \"./SegmentBase\"\n\
|
|
1
|
+
{"version":3,"file":"IconSegment.js","sources":["../../../src/components/segmented-control/IconSegment.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { Tooltip, type TooltipPlacement } from \"@components/internal/tooltip\"\nimport React, { type ButtonHTMLAttributes, forwardRef } from \"react\"\n\nimport { SegmentBase, type SegmentKind } from \"./SegmentBase\"\n\ntype IconSegmentSharedProps = {\n /** Disables this item only. */\n disabled?: boolean\n /** The icon to display. */\n icon: React.ReactNode\n /**\n * This segment's color when selected. Default `'interaction-subtle'`.\n */\n kind?: SegmentKind\n /** Where the tooltip renders relative to the segment. Default `\"bottom\"`. Has no effect without `tooltip`. */\n tooltipPlacement?: TooltipPlacement\n /** Unique identifier for this item. */\n value: string\n}\n\ntype IconSegmentTooltipProps = {\n /** Accessible label. Required for icon-only segments to provide context about the segment's purpose. Not required when `tooltip` is set. When both are set, this is the name and the tooltip is visual only. */\n \"aria-label\"?: string\n /** Text shown on hover and focus. Without `aria-label`, it is also used as the `aria-label`. With `aria-label`, start the `aria-label` with the same text (e.g. tooltip `\"Grid\"`, aria-label `\"Grid view\"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */\n tooltip: string\n}\n\ntype IconSegmentAriaLabelProps = {\n /** Accessible label. Required for icon-only segments to provide context about the segment's purpose. Not required when `tooltip` is set. When both are set, this is the name and the tooltip is visual only. */\n \"aria-label\": string\n /** Text shown on hover and focus. Without `aria-label`, it is also used as the `aria-label`. With `aria-label`, start the `aria-label` with the same text (e.g. tooltip `\"Grid\"`, aria-label `\"Grid view\"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */\n tooltip?: string\n}\n\n/**\n * An icon-only segment needs a name: `aria-label`, `tooltip`, or both.\n * `IconSegmentAriaLabelProps` is declared last so that a missing name\n * reports \"aria-label is missing\", not \"tooltip is missing\".\n */\ntype IconSegmentNameProps = IconSegmentAriaLabelProps | IconSegmentTooltipProps\n\nexport type IconSegmentProps = IconSegmentSharedProps & IconSegmentNameProps\n\nexport type IconSegmentElementProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | keyof IconSegmentSharedProps\n | \"aria-checked\"\n | \"aria-label\"\n | \"children\"\n | \"onClick\"\n | \"onKeyDown\"\n | \"role\"\n | \"tabIndex\"\n | \"tooltip\"\n | \"type\"\n> &\n IconSegmentProps\n\n/**\n * An icon-only item within a `SegmentedControl`, mirroring `IconButton`'s\n * shape. Requires an `aria-label` or `tooltip` for accessibility. Must be\n * rendered as a direct child of `SegmentedControl` — it reads selection\n * state, group `disabled`, and roving tabindex from that context.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-segmentedcontrol--docs | Storybook Documentation}\n */\nexport const IconSegment = forwardRef<\n HTMLButtonElement,\n IconSegmentElementProps\n>(function IconSegment(\n {\n icon,\n tooltip,\n tooltipPlacement = \"bottom\",\n ...restProps\n }: IconSegmentElementProps,\n ref\n) {\n if (tooltip) {\n const {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...segmentProps\n } = restProps\n\n return (\n <Tooltip content={tooltip} placement={tooltipPlacement} visualOnly>\n <SegmentBase\n {...segmentProps}\n aria-label={ariaLabel || tooltip}\n content={icon}\n iconOnly\n ref={ref}\n />\n </Tooltip>\n )\n }\n\n return <SegmentBase {...restProps} content={icon} iconOnly ref={ref} />\n})\n\nIconSegment.displayName = \"IconSegment\"\n"],"names":["React"],"mappings":";;;;AA4DA;;;;;;;;AAQG;MACU,WAAW,GAAG,UAAU,CAGnC,SAAS,WAAW,CACpB,EACE,IAAI,EACJ,OAAO,EACP,gBAAgB,GAAG,QAAQ,EAC3B,GAAG,SAAS,EACY,EAC1B,GAAG,EAAA;IAEH,IAAI,OAAO,EAAE;AACX,QAAA,MAAM,EACJ,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,YAAY,EAChB,GAAG,SAAS;AAEb,QAAA,QACEA,cAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAA,IAAA,EAAA;YAChEA,cAAA,CAAA,aAAA,CAAC,WAAW,OACN,YAAY,EAAA,YAAA,EACJ,SAAS,IAAI,OAAO,EAChC,OAAO,EAAE,IAAI,EACb,QAAQ,QACR,GAAG,EAAE,GAAG,EAAA,CACR,CACM;IAEd;AAEA,IAAA,OAAOA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,GAAK,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAA,IAAA,EAAC,GAAG,EAAE,GAAG,GAAI;AACzE,CAAC;AAED,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentBase.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentBase.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SegmentBase.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentBase.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,oBAAoB,EAA0B,MAAM,OAAO,CAAA;AAIhF,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,kBAAkB,GAClB,oBAAoB,GACpB,gBAAgB,GAChB,SAAS,GACT,SAAS,CAAA;AAWb,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,oBAAoB,CAAC,iBAAiB,CAAC,EACrC,MAAM,gBAAgB,GACtB,cAAc,GACd,UAAU,GACV,SAAS,GACT,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,CACT,GACC,gBAAgB,CAAA;AAElB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,iQA6FtB,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useTooltipTriggerProps } from '../internal/tooltip/useTooltipTriggerProps.js';
|
|
1
2
|
import classNames from 'classnames';
|
|
2
3
|
import React__default, { forwardRef, useContext } from 'react';
|
|
3
4
|
import { SegmentedControlContext } from './SegmentedControlContext.js';
|
|
@@ -16,7 +17,7 @@ const ARROW_KEYS = [
|
|
|
16
17
|
* and disabled propagation all live here so the two public components only
|
|
17
18
|
* differ in what they render inside the button.
|
|
18
19
|
*/
|
|
19
|
-
const SegmentBase = forwardRef(function SegmentBase({ className, content, disabled = false, iconOnly = false, kind = "interaction-subtle", value, ...restProps }, ref) {
|
|
20
|
+
const SegmentBase = forwardRef(function SegmentBase({ "aria-describedby": ariaDescribedBy, className, content, disabled = false, iconOnly = false, kind = "interaction-subtle", value, ...restProps }, ref) {
|
|
20
21
|
const context = useContext(SegmentedControlContext);
|
|
21
22
|
const isDisabled = disabled || (context?.disabled ?? false);
|
|
22
23
|
const isChecked = context?.value === value;
|
|
@@ -62,7 +63,8 @@ const SegmentBase = forwardRef(function SegmentBase({ className, content, disabl
|
|
|
62
63
|
if (nextValue)
|
|
63
64
|
context?.onSelect(nextValue);
|
|
64
65
|
};
|
|
65
|
-
|
|
66
|
+
const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps({ ...restProps, onClick: handleClick, onKeyDown: handleKeyDown }, ref, ariaDescribedBy);
|
|
67
|
+
return (React__default.createElement("button", { ...mergedProps, "aria-checked": isChecked ? "true" : "false", "aria-describedby": describedBy, className: combinedClassName, "data-segment-value": value, disabled: isDisabled, ref: mergedRef, role: "radio", tabIndex: value === context?.tabbableValue ? 0 : -1, type: "button" }, content));
|
|
66
68
|
});
|
|
67
69
|
SegmentBase.displayName = "SegmentBase";
|
|
68
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentBase.js","sources":["../../../src/components/segmented-control/SegmentBase.tsx"],"sourcesContent":["import classNames from \"classnames\"\nimport React, { type ButtonHTMLAttributes, forwardRef, useContext } from \"react\"\n\nimport { SegmentedControlContext } from \"./SegmentedControlContext\"\n\nexport type SegmentKind =\n | \"error\"\n | \"interaction-bold\"\n | \"interaction-subtle\"\n | \"neutral-subtle\"\n | \"success\"\n | \"warning\"\n\nconst ARROW_KEYS = [\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"Home\",\n \"End\",\n]\n\nexport interface SegmentBaseProps {\n content: React.ReactNode\n disabled?: boolean\n iconOnly?: boolean\n kind?: SegmentKind\n value: string\n}\n\nexport type SegmentBaseElementProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | keyof SegmentBaseProps\n | \"aria-checked\"\n | \"children\"\n | \"onClick\"\n | \"onKeyDown\"\n | \"role\"\n | \"tabIndex\"\n | \"type\"\n> &\n SegmentBaseProps\n\n/**\n * Shared `role=\"radio\"` button implementation for `Segment` and\n * `IconSegment` — selection state, roving tabindex, arrow-key navigation,\n * and disabled propagation all live here so the two public components only\n * differ in what they render inside the button.\n */\nexport const SegmentBase = forwardRef<\n HTMLButtonElement,\n SegmentBaseElementProps\n>(function SegmentBase(\n {\n className,\n content,\n disabled = false,\n iconOnly = false,\n kind = \"interaction-subtle\",\n value,\n ...restProps\n }: SegmentBaseElementProps,\n ref\n) {\n const context = useContext(SegmentedControlContext)\n const isDisabled = disabled || (context?.disabled ?? false)\n const isChecked = context?.value === value\n\n const combinedClassName = classNames(\n \"tds-segmented-control-segment\",\n iconOnly && \"tds-segmented-control-segment--icon-only\",\n `tds-segmented-control-segment--${kind}`,\n className\n )\n\n const handleClick = () => {\n if (isDisabled) return\n context?.onSelect(value)\n }\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (!ARROW_KEYS.includes(event.key)) return\n\n const track = event.currentTarget.closest('[role=\"radiogroup\"]')\n if (!track) return\n\n const segments = Array.from(\n track.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]:not(:disabled)')\n )\n const currentIndex = segments.indexOf(event.currentTarget)\n if (currentIndex === -1) return\n\n let nextIndex = currentIndex\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = currentIndex === 0 ? segments.length - 1 : currentIndex - 1\n break\n case \"ArrowRight\":\n case \"ArrowDown\":\n nextIndex = currentIndex === segments.length - 1 ? 0 : currentIndex + 1\n break\n case \"Home\":\n nextIndex = 0\n break\n case \"End\":\n nextIndex = segments.length - 1\n break\n }\n\n const nextSegment = segments[nextIndex]\n if (!nextSegment || nextSegment === event.currentTarget) return\n\n event.preventDefault()\n nextSegment.focus()\n const nextValue = nextSegment.dataset.segmentValue\n if (nextValue) context?.onSelect(nextValue)\n }\n\n return (\n <button\n {...
|
|
1
|
+
{"version":3,"file":"SegmentBase.js","sources":["../../../src/components/segmented-control/SegmentBase.tsx"],"sourcesContent":["import { useTooltipTriggerProps } from \"@components/internal/tooltip/useTooltipTriggerProps\"\nimport classNames from \"classnames\"\nimport React, { type ButtonHTMLAttributes, forwardRef, useContext } from \"react\"\n\nimport { SegmentedControlContext } from \"./SegmentedControlContext\"\n\nexport type SegmentKind =\n | \"error\"\n | \"interaction-bold\"\n | \"interaction-subtle\"\n | \"neutral-subtle\"\n | \"success\"\n | \"warning\"\n\nconst ARROW_KEYS = [\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"Home\",\n \"End\",\n]\n\nexport interface SegmentBaseProps {\n content: React.ReactNode\n disabled?: boolean\n iconOnly?: boolean\n kind?: SegmentKind\n value: string\n}\n\nexport type SegmentBaseElementProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | keyof SegmentBaseProps\n | \"aria-checked\"\n | \"children\"\n | \"onClick\"\n | \"onKeyDown\"\n | \"role\"\n | \"tabIndex\"\n | \"type\"\n> &\n SegmentBaseProps\n\n/**\n * Shared `role=\"radio\"` button implementation for `Segment` and\n * `IconSegment` — selection state, roving tabindex, arrow-key navigation,\n * and disabled propagation all live here so the two public components only\n * differ in what they render inside the button.\n */\nexport const SegmentBase = forwardRef<\n HTMLButtonElement,\n SegmentBaseElementProps\n>(function SegmentBase(\n {\n \"aria-describedby\": ariaDescribedBy,\n className,\n content,\n disabled = false,\n iconOnly = false,\n kind = \"interaction-subtle\",\n value,\n ...restProps\n }: SegmentBaseElementProps,\n ref\n) {\n const context = useContext(SegmentedControlContext)\n const isDisabled = disabled || (context?.disabled ?? false)\n const isChecked = context?.value === value\n\n const combinedClassName = classNames(\n \"tds-segmented-control-segment\",\n iconOnly && \"tds-segmented-control-segment--icon-only\",\n `tds-segmented-control-segment--${kind}`,\n className\n )\n\n const handleClick = () => {\n if (isDisabled) return\n context?.onSelect(value)\n }\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (!ARROW_KEYS.includes(event.key)) return\n\n const track = event.currentTarget.closest('[role=\"radiogroup\"]')\n if (!track) return\n\n const segments = Array.from(\n track.querySelectorAll<HTMLButtonElement>('[role=\"radio\"]:not(:disabled)')\n )\n const currentIndex = segments.indexOf(event.currentTarget)\n if (currentIndex === -1) return\n\n let nextIndex = currentIndex\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = currentIndex === 0 ? segments.length - 1 : currentIndex - 1\n break\n case \"ArrowRight\":\n case \"ArrowDown\":\n nextIndex = currentIndex === segments.length - 1 ? 0 : currentIndex + 1\n break\n case \"Home\":\n nextIndex = 0\n break\n case \"End\":\n nextIndex = segments.length - 1\n break\n }\n\n const nextSegment = segments[nextIndex]\n if (!nextSegment || nextSegment === event.currentTarget) return\n\n event.preventDefault()\n nextSegment.focus()\n const nextValue = nextSegment.dataset.segmentValue\n if (nextValue) context?.onSelect(nextValue)\n }\n\n const { describedBy, mergedProps, mergedRef } = useTooltipTriggerProps(\n { ...restProps, onClick: handleClick, onKeyDown: handleKeyDown },\n ref,\n ariaDescribedBy\n )\n\n return (\n <button\n {...mergedProps}\n aria-checked={isChecked ? \"true\" : \"false\"}\n aria-describedby={describedBy}\n className={combinedClassName}\n data-segment-value={value}\n disabled={isDisabled}\n ref={mergedRef}\n role=\"radio\"\n tabIndex={value === context?.tabbableValue ? 0 : -1}\n type=\"button\"\n >\n {content}\n </button>\n )\n})\n\nSegmentBase.displayName = \"SegmentBase\"\n"],"names":["React"],"mappings":";;;;;AAcA,MAAM,UAAU,GAAG;IACjB,WAAW;IACX,YAAY;IACZ,SAAS;IACT,WAAW;IACX,MAAM;IACN,KAAK;CACN;AAuBD;;;;;AAKG;AACI,MAAM,WAAW,GAAG,UAAU,CAGnC,SAAS,WAAW,CACpB,EACE,kBAAkB,EAAE,eAAe,EACnC,SAAS,EACT,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,KAAK,EAChB,IAAI,GAAG,oBAAoB,EAC3B,KAAK,EACL,GAAG,SAAS,EACY,EAC1B,GAAG,EAAA;AAEH,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,uBAAuB,CAAC;IACnD,MAAM,UAAU,GAAG,QAAQ,KAAK,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC;AAC3D,IAAA,MAAM,SAAS,GAAG,OAAO,EAAE,KAAK,KAAK,KAAK;AAE1C,IAAA,MAAM,iBAAiB,GAAG,UAAU,CAClC,+BAA+B,EAC/B,QAAQ,IAAI,0CAA0C,EACtD,kCAAkC,IAAI,CAAA,CAAE,EACxC,SAAS,CACV;IAED,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,IAAI,UAAU;YAAE;AAChB,QAAA,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;AAC1B,IAAA,CAAC;AAED,IAAA,MAAM,aAAa,GAAG,CAAC,KAA6C,KAAI;QACtE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE;QAErC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,qBAAqB,CAAC;AAChE,QAAA,IAAI,CAAC,KAAK;YAAE;AAEZ,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CACzB,KAAK,CAAC,gBAAgB,CAAoB,+BAA+B,CAAC,CAC3E;QACD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;QAC1D,IAAI,YAAY,KAAK,EAAE;YAAE;QAEzB,IAAI,SAAS,GAAG,YAAY;AAC5B,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,SAAS;AACZ,gBAAA,SAAS,GAAG,YAAY,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC;gBACvE;AACF,YAAA,KAAK,YAAY;AACjB,YAAA,KAAK,WAAW;AACd,gBAAA,SAAS,GAAG,YAAY,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC;gBACvE;AACF,YAAA,KAAK,MAAM;gBACT,SAAS,GAAG,CAAC;gBACb;AACF,YAAA,KAAK,KAAK;AACR,gBAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAC/B;;AAGJ,QAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC;AACvC,QAAA,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,KAAK,CAAC,aAAa;YAAE;QAEzD,KAAK,CAAC,cAAc,EAAE;QACtB,WAAW,CAAC,KAAK,EAAE;AACnB,QAAA,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY;AAClD,QAAA,IAAI,SAAS;AAAE,YAAA,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC;AAC7C,IAAA,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,sBAAsB,CACpE,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,EAChE,GAAG,EACH,eAAe,CAChB;IAED,QACEA,cAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAA,GACM,WAAW,EAAA,cAAA,EACD,SAAS,GAAG,MAAM,GAAG,OAAO,EAAA,kBAAA,EACxB,WAAW,EAC7B,SAAS,EAAE,iBAAiB,EAAA,oBAAA,EACR,KAAK,EACzB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,SAAS,EACd,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,KAAK,KAAK,OAAO,EAAE,aAAa,GAAG,CAAC,GAAG,EAAE,EACnD,IAAI,EAAC,QAAQ,EAAA,EAEZ,OAAO,CACD;AAEb,CAAC;AAED,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAIpB,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAIpB,OAAO,KAAK,EAAE,EACZ,KAAK,cAAc,EAIpB,MAAM,OAAO,CAAA;AAId,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAA;AAE9C,UAAU,2BAA2B;IACnC,wCAAwC;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sBAAsB;IACtB,IAAI,CAAC,EAAE,oBAAoB,CAAA;CAC5B;AAED,UAAU,+BAAgC,SAAQ,2BAA2B;IAC3E,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAA;CACd;AAED,UAAU,iCACR,SAAQ,2BAA2B;IACnC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,MAAM,qBAAqB,GAC7B,+BAA+B,GAC/B,iCAAiC,CAAA;AAErC,MAAM,MAAM,4BAA4B,GAAG,IAAI,CAC7C,cAAc,CAAC,cAAc,CAAC,EAC9B,MAAM,qBAAqB,GAAG,UAAU,GAAG,MAAM,CAClD,GACC,qBAAqB,CAAA;AAEvB;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;4HAa1B,4BAA4B;;CAyE9B,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useId } from '../../utilities/useId.js';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import React__default, { useState } from 'react';
|
|
3
|
+
import React__default, { useState, useRef, useLayoutEffect } from 'react';
|
|
4
4
|
import { SegmentedControlContext } from './SegmentedControlContext.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -22,10 +22,17 @@ const SegmentedControl = ({ children, className, defaultValue, disabled = false,
|
|
|
22
22
|
setUncontrolledValue(nextValue);
|
|
23
23
|
onChange?.(nextValue);
|
|
24
24
|
};
|
|
25
|
+
const trackRef = useRef(null);
|
|
26
|
+
const [fallbackTabbableValue, setFallbackTabbableValue] = useState();
|
|
27
|
+
useLayoutEffect(() => {
|
|
28
|
+
const enabledSegments = Array.from(trackRef.current?.querySelectorAll('[role="radio"]:not(:disabled)') ?? []);
|
|
29
|
+
const selectedIsEnabled = enabledSegments.some((segment) => segment.dataset.segmentValue === selectedValue);
|
|
30
|
+
setFallbackTabbableValue(selectedIsEnabled ? undefined : enabledSegments[0]?.dataset.segmentValue);
|
|
31
|
+
}, [children, disabled, selectedValue]);
|
|
25
32
|
const contextValue = {
|
|
26
33
|
disabled,
|
|
27
34
|
onSelect,
|
|
28
|
-
tabbableValue: selectedValue,
|
|
35
|
+
tabbableValue: fallbackTabbableValue ?? selectedValue,
|
|
29
36
|
value: selectedValue,
|
|
30
37
|
};
|
|
31
38
|
const stableId = useId();
|
|
@@ -37,7 +44,7 @@ const SegmentedControl = ({ children, className, defaultValue, disabled = false,
|
|
|
37
44
|
}, className);
|
|
38
45
|
return (React__default.createElement("div", { ...restProps, className: combinedClassName, id: componentId },
|
|
39
46
|
React__default.createElement("div", { className: classNames("tds-segmented-control-label", hideLabel && "tds-segmented-control-label--hidden"), id: labelId }, label),
|
|
40
|
-
React__default.createElement("div", { "aria-labelledby": labelId, className: "tds-segmented-control-track", role: "radiogroup" },
|
|
47
|
+
React__default.createElement("div", { "aria-labelledby": labelId, className: "tds-segmented-control-track", ref: trackRef, role: "radiogroup" },
|
|
41
48
|
React__default.createElement(SegmentedControlContext.Provider, { value: contextValue }, children))));
|
|
42
49
|
};
|
|
43
50
|
SegmentedControl.displayName = "SegmentedControl";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.js","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, {
|
|
1
|
+
{"version":3,"file":"SegmentedControl.js","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, {\n type HTMLAttributes,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\"\n\nimport { SegmentedControlContext } from \"./SegmentedControlContext\"\n\nexport type SegmentedControlSize = \"md\" | \"sm\"\n\ninterface SegmentedControlSharedProps {\n /** `Segment`/`IconSegment` elements. */\n children: React.ReactNode\n /** Disables the whole group. */\n disabled?: boolean\n /**\n * If `true`, the group spans 100% of its container and items split the\n * width evenly. Intended for a primary mode switch at the top of a\n * section/modal/pane — not for a control nested deep in a form.\n */\n fullWidth?: boolean\n /**\n * If `true`, renders `label` visually hidden instead of a visible\n * element.\n */\n hideLabel?: boolean\n /**\n * Accessible label for the group. Rendered as a visible element by\n * default.\n */\n label: string\n /** Called with the newly selected item's `value`. */\n onChange?: (value: string) => void\n /** Default `'md'`. */\n size?: SegmentedControlSize\n}\n\ninterface SegmentedControlControlledProps extends SegmentedControlSharedProps {\n defaultValue?: never\n /** Controlled selected item's `value`. */\n value: string\n}\n\ninterface SegmentedControlUncontrolledProps\n extends SegmentedControlSharedProps {\n /**\n * Uncontrolled initial selected item's `value` — a segmented control\n * always reflects a current mode, so one item must start selected.\n */\n defaultValue: string\n value?: never\n}\n\nexport type SegmentedControlProps =\n | SegmentedControlControlledProps\n | SegmentedControlUncontrolledProps\n\nexport type SegmentedControlElementProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n keyof SegmentedControlProps | \"children\" | \"role\"\n> &\n SegmentedControlProps\n\n/**\n * A single-select group of items — Table/Card, Yes/No, Tag/Tag group —\n * where exactly one `Segment`/`IconSegment` is selected at a time. Arrow keys\n * move the selection, and the group is one tab stop.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-segmentedcontrol--docs | Storybook Documentation}\n */\nexport const SegmentedControl = ({\n children,\n className,\n defaultValue,\n disabled = false,\n fullWidth = false,\n hideLabel = false,\n id,\n label,\n onChange,\n size = \"md\",\n value,\n ...restProps\n}: SegmentedControlElementProps) => {\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue)\n const isControlled = value !== undefined\n const selectedValue = isControlled ? value : uncontrolledValue\n\n const onSelect = (nextValue: string) => {\n if (nextValue === selectedValue) return\n if (!isControlled) setUncontrolledValue(nextValue)\n onChange?.(nextValue)\n }\n\n const trackRef = useRef<HTMLDivElement>(null)\n const [fallbackTabbableValue, setFallbackTabbableValue] = useState<\n string | undefined\n >()\n\n useLayoutEffect(() => {\n const enabledSegments = Array.from(\n trackRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]:not(:disabled)'\n ) ?? []\n )\n const selectedIsEnabled = enabledSegments.some(\n (segment) => segment.dataset.segmentValue === selectedValue\n )\n setFallbackTabbableValue(\n selectedIsEnabled ? undefined : enabledSegments[0]?.dataset.segmentValue\n )\n }, [children, disabled, selectedValue])\n\n const contextValue = {\n disabled,\n onSelect,\n tabbableValue: fallbackTabbableValue ?? selectedValue,\n value: selectedValue,\n }\n\n const stableId = useId()\n const componentId = id || `tds-segmented-control-${stableId}`\n const labelId = `${componentId}-label`\n\n const combinedClassName = classNames(\n \"tds-segmented-control\",\n {\n \"tds-segmented-control--full-width\": fullWidth,\n \"tds-segmented-control--sm\": size === \"sm\",\n },\n className\n )\n\n return (\n <div {...restProps} className={combinedClassName} id={componentId}>\n <div\n className={classNames(\n \"tds-segmented-control-label\",\n hideLabel && \"tds-segmented-control-label--hidden\"\n )}\n id={labelId}\n >\n {label}\n </div>\n <div\n aria-labelledby={labelId}\n className=\"tds-segmented-control-track\"\n ref={trackRef}\n role=\"radiogroup\"\n >\n <SegmentedControlContext.Provider value={contextValue}>\n {children}\n </SegmentedControlContext.Provider>\n </div>\n </div>\n )\n}\n\nSegmentedControl.displayName = \"SegmentedControl\"\n"],"names":["React"],"mappings":";;;;;AAoEA;;;;;;;AAOG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,KAAK,EACjB,EAAE,EACF,KAAK,EACL,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,KAAK,EACL,GAAG,SAAS,EACiB,KAAI;IACjC,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC;AACxE,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;IACxC,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,iBAAiB;AAE9D,IAAA,MAAM,QAAQ,GAAG,CAAC,SAAiB,KAAI;QACrC,IAAI,SAAS,KAAK,aAAa;YAAE;AACjC,QAAA,IAAI,CAAC,YAAY;YAAE,oBAAoB,CAAC,SAAS,CAAC;AAClD,QAAA,QAAQ,GAAG,SAAS,CAAC;AACvB,IAAA,CAAC;AAED,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC;IAC7C,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,QAAQ,EAE/D;IAEH,eAAe,CAAC,MAAK;AACnB,QAAA,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAChC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAChC,+BAA+B,CAChC,IAAI,EAAE,CACR;AACD,QAAA,MAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,CAC5C,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,YAAY,KAAK,aAAa,CAC5D;AACD,QAAA,wBAAwB,CACtB,iBAAiB,GAAG,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CACzE;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEvC,IAAA,MAAM,YAAY,GAAG;QACnB,QAAQ;QACR,QAAQ;QACR,aAAa,EAAE,qBAAqB,IAAI,aAAa;AACrD,QAAA,KAAK,EAAE,aAAa;KACrB;AAED,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;AACxB,IAAA,MAAM,WAAW,GAAG,EAAE,IAAI,CAAA,sBAAA,EAAyB,QAAQ,EAAE;AAC7D,IAAA,MAAM,OAAO,GAAG,CAAA,EAAG,WAAW,QAAQ;AAEtC,IAAA,MAAM,iBAAiB,GAAG,UAAU,CAClC,uBAAuB,EACvB;AACE,QAAA,mCAAmC,EAAE,SAAS;QAC9C,2BAA2B,EAAE,IAAI,KAAK,IAAI;KAC3C,EACD,SAAS,CACV;IAED,QACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAS,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,EAAA;AAC/D,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,UAAU,CACnB,6BAA6B,EAC7B,SAAS,IAAI,qCAAqC,CACnD,EACD,EAAE,EAAE,OAAO,EAAA,EAEV,KAAK,CACF;AACN,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,iBAAA,EACmB,OAAO,EACxB,SAAS,EAAC,6BAA6B,EACvC,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,YAAY,EAAA;AAEjB,YAAAA,cAAA,CAAA,aAAA,CAAC,uBAAuB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,EAClD,QAAQ,CACwB,CAC/B,CACF;AAEV;AAEA,gBAAgB,CAAC,WAAW,GAAG,kBAAkB;;;;"}
|