@planningcenter/tapestry 4.11.0 → 4.12.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/components/DataTable/CollectionEditorsLazy.js +2 -1
- package/dist/components/DataTable/CollectionEditorsLazy.js.map +1 -1
- package/dist/components/DataTable/DataTable.d.ts +49 -14
- package/dist/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/components/DataTable/DataTable.js +32 -24
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DeleteSavedViewAlertDialog.d.ts +14 -0
- package/dist/components/DataTable/DeleteSavedViewAlertDialog.d.ts.map +1 -0
- package/dist/components/DataTable/DeleteSavedViewAlertDialog.js +10 -0
- package/dist/components/DataTable/DeleteSavedViewAlertDialog.js.map +1 -0
- package/dist/components/DataTable/ManageSavedViewsButton.d.ts +4 -1
- package/dist/components/DataTable/ManageSavedViewsButton.d.ts.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsButton.js +3 -7
- package/dist/components/DataTable/ManageSavedViewsButton.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts +11 -1
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.js +265 -5
- package/dist/components/DataTable/ManageSavedViewsModal.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.module.css.js +4 -0
- package/dist/components/DataTable/ManageSavedViewsModal.module.css.js.map +1 -0
- package/dist/components/DataTable/NewSavedViewModal.d.ts +4 -1
- package/dist/components/DataTable/NewSavedViewModal.d.ts.map +1 -1
- package/dist/components/DataTable/NewSavedViewModal.js.map +1 -1
- package/dist/components/DataTable/ResultsCount.d.ts +9 -0
- package/dist/components/DataTable/ResultsCount.d.ts.map +1 -1
- package/dist/components/DataTable/ResultsCount.js +1 -1
- package/dist/components/DataTable/ResultsCount.js.map +1 -1
- package/dist/components/DataTable/SavedViewsBar.d.ts +14 -6
- package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
- package/dist/components/DataTable/SavedViewsBar.js +176 -45
- package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
- package/dist/components/DataTable/TableActions.d.ts.map +1 -1
- package/dist/components/DataTable/TableActions.js +4 -6
- package/dist/components/DataTable/TableActions.js.map +1 -1
- package/dist/components/DataTable/ViewSettingsToggle.d.ts.map +1 -1
- package/dist/components/DataTable/ViewSettingsToggle.js +2 -4
- package/dist/components/DataTable/ViewSettingsToggle.js.map +1 -1
- package/dist/components/DataTable/index.d.ts +1 -1
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/savedViews.d.ts +40 -15
- package/dist/components/DataTable/savedViews.d.ts.map +1 -1
- package/dist/components/DataTable/savedViews.js +85 -6
- 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 +9 -3
- package/dist/components/DataTable/useActiveSavedView.js.map +1 -1
- package/dist/components/DataTable/useFilterAnnouncement.d.ts +24 -0
- package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +1 -0
- package/dist/components/DataTable/useFilterAnnouncement.js +49 -0
- package/dist/components/DataTable/useFilterAnnouncement.js.map +1 -0
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts +7 -0
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts.map +1 -0
- package/dist/components/DataTable/useUpdateSavedViewName.js +12 -0
- package/dist/components/DataTable/useUpdateSavedViewName.js.map +1 -0
- package/dist/components/button/ActionsDropdownIconButton.d.ts +18 -9
- package/dist/components/button/ActionsDropdownIconButton.d.ts.map +1 -1
- package/dist/components/button/ActionsDropdownIconButton.js +5 -2
- package/dist/components/button/ActionsDropdownIconButton.js.map +1 -1
- package/dist/components/button/BaseButton.d.ts.map +1 -1
- package/dist/components/button/BaseButton.js +2 -1
- package/dist/components/button/BaseButton.js.map +1 -1
- package/dist/components/button/DropdownIconButton.d.ts +4 -5
- package/dist/components/button/DropdownIconButton.d.ts.map +1 -1
- package/dist/components/button/DropdownIconButton.js +2 -1
- package/dist/components/button/DropdownIconButton.js.map +1 -1
- package/dist/components/button/IconButton.d.ts +31 -10
- package/dist/components/button/IconButton.d.ts.map +1 -1
- package/dist/components/button/IconButton.js +8 -2
- package/dist/components/button/IconButton.js.map +1 -1
- package/dist/components/button/ToggleIconButton.d.ts +4 -1
- package/dist/components/button/ToggleIconButton.d.ts.map +1 -1
- package/dist/components/button/ToggleIconButton.js +1 -0
- package/dist/components/button/ToggleIconButton.js.map +1 -1
- package/dist/components/button/index.d.ts +1 -0
- package/dist/components/button/index.d.ts.map +1 -1
- package/dist/components/combo-box/ComboBox.d.ts +8 -0
- package/dist/components/combo-box/ComboBox.d.ts.map +1 -1
- package/dist/components/combo-box/ComboBox.js +31 -5
- package/dist/components/combo-box/ComboBox.js.map +1 -1
- package/dist/components/date-picker/DatePicker.d.ts.map +1 -1
- package/dist/components/date-picker/DatePicker.js +18 -14
- package/dist/components/date-picker/DatePicker.js.map +1 -1
- package/dist/components/internal/LoadingAnnouncement.d.ts +11 -0
- package/dist/components/internal/LoadingAnnouncement.d.ts.map +1 -0
- package/dist/components/internal/LoadingAnnouncement.js +21 -0
- package/dist/components/internal/LoadingAnnouncement.js.map +1 -0
- package/dist/components/internal/alert-dialog/AlertDialog.d.ts +56 -0
- package/dist/components/internal/alert-dialog/AlertDialog.d.ts.map +1 -0
- package/dist/components/internal/alert-dialog/AlertDialog.js +68 -0
- package/dist/components/internal/alert-dialog/AlertDialog.js.map +1 -0
- package/dist/components/internal/alert-dialog/index.d.ts +5 -0
- package/dist/components/internal/alert-dialog/index.d.ts.map +1 -0
- package/dist/components/internal/index.d.ts +1 -0
- package/dist/components/internal/index.d.ts.map +1 -1
- package/dist/components/internal/tooltip/Tooltip.d.ts +13 -5
- package/dist/components/internal/tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/internal/tooltip/Tooltip.js +63 -8
- package/dist/components/internal/tooltip/Tooltip.js.map +1 -1
- package/dist/components/internal/tooltip/TooltipTriggerContext.d.ts +3 -3
- package/dist/components/internal/tooltip/TooltipTriggerContext.d.ts.map +1 -1
- package/dist/components/internal/tooltip/TooltipTriggerContext.js +1 -1
- package/dist/components/internal/tooltip/TooltipTriggerContext.js.map +1 -1
- package/dist/components/internal/tooltip/index.d.ts +1 -1
- package/dist/components/internal/tooltip/index.d.ts.map +1 -1
- package/dist/components/link/BaseLink.d.ts.map +1 -1
- package/dist/components/link/BaseLink.js +15 -3
- package/dist/components/link/BaseLink.js.map +1 -1
- package/dist/components/link/IconLink.d.ts +28 -290
- package/dist/components/link/IconLink.d.ts.map +1 -1
- package/dist/components/link/IconLink.js +9 -2
- package/dist/components/link/IconLink.js.map +1 -1
- package/dist/components/page-header/defineElements.js +1 -1
- package/dist/components/pane/Pane.d.ts +1 -1
- package/dist/components/pane/Pane.js +1 -1
- package/dist/components/pane/Pane.js.map +1 -1
- package/dist/components/pane/PaneBody.d.ts +1 -1
- package/dist/components/pane/PaneBody.js +1 -1
- package/dist/components/pane/PaneBody.js.map +1 -1
- package/dist/components/pane/PaneDivider.d.ts +6 -3
- package/dist/components/pane/PaneDivider.d.ts.map +1 -1
- package/dist/components/pane/PaneDivider.js +3 -3
- package/dist/components/pane/PaneDivider.js.map +1 -1
- package/dist/components/pane/PaneFooter.d.ts +1 -1
- package/dist/components/pane/PaneFooter.js +1 -1
- package/dist/components/pane/PaneFooter.js.map +1 -1
- package/dist/components/pane/PaneHeader.d.ts +1 -1
- package/dist/components/pane/PaneHeader.js +1 -1
- package/dist/components/pane/PaneHeader.js.map +1 -1
- package/dist/components/pane/PaneHeaderActions.d.ts +1 -1
- package/dist/components/pane/PaneHeaderActions.js +1 -1
- package/dist/components/pane/PaneHeaderActions.js.map +1 -1
- package/dist/components/sidenav/defineElements.js +1 -1
- package/dist/components/time-field/TimeField.d.ts.map +1 -1
- package/dist/components/time-field/TimeField.js +7 -3
- package/dist/components/time-field/TimeField.js.map +1 -1
- package/dist/index.css +169 -27
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/{p-np7vhMVg.js → p-A1JK45WV.js} +3 -3
- package/dist/packages/tapestry-wc/dist/components/p-A1JK45WV.js.map +1 -0
- package/dist/packages/tapestry-wc/dist/components/{p-BVvtAaVT.js → p-BbuNAv9q.js} +3 -3
- package/dist/packages/tapestry-wc/dist/components/p-BbuNAv9q.js.map +1 -0
- package/dist/packages/tapestry-wc/dist/components/{p-B2xqMgNQ.js → p-CBFtMIxJ.js} +2 -2
- package/dist/packages/tapestry-wc/dist/components/p-CBFtMIxJ.js.map +1 -0
- package/dist/packages/tapestry-wc/dist/components/{p-Rn6lOB18.js → p-CY_DC4d_.js} +3 -3
- package/dist/packages/tapestry-wc/dist/components/p-CY_DC4d_.js.map +1 -0
- package/dist/packages/tapestry-wc/dist/components/{p-6NO22Vi_.js → p-DNHgMtxw.js} +2 -2
- package/dist/packages/tapestry-wc/dist/components/p-DNHgMtxw.js.map +1 -0
- package/dist/packages/tapestry-wc/dist/components/tds-page-header-nav.js +2 -2
- package/dist/packages/tapestry-wc/dist/components/tds-page-header-nav.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/tds-page-header.js +3 -3
- package/dist/packages/tapestry-wc/dist/components/tds-page-header.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-item.js +3 -3
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-item.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-responsive-header.js +2 -2
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-responsive-header.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-section.js +3 -3
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav-section.js.map +1 -1
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav.js +5 -5
- package/dist/packages/tapestry-wc/dist/components/tds-sidenav.js.map +1 -1
- package/dist/reactRender.css +756 -574
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +756 -574
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/tapestryMount.css +756 -574
- package/dist/tapestryMount.css.map +1 -1
- package/dist/tapestryMountLegacy.css +756 -574
- package/dist/tapestryMountLegacy.css.map +1 -1
- package/dist/unstable.css +309 -127
- package/dist/unstable.css.map +1 -1
- package/dist/unstable.d.ts +0 -1
- package/dist/unstable.d.ts.map +1 -1
- package/dist/unstable.js +6 -6
- package/dist/utilities/dateFieldLocale.d.ts +2 -0
- package/dist/utilities/dateFieldLocale.d.ts.map +1 -0
- package/dist/utilities/dateFieldLocale.js +32 -0
- package/dist/utilities/dateFieldLocale.js.map +1 -0
- package/dist/utilities/useAnnounce.d.ts +22 -0
- package/dist/utilities/useAnnounce.d.ts.map +1 -0
- package/dist/utilities/useAnnounce.js +27 -0
- package/dist/utilities/useAnnounce.js.map +1 -0
- package/dist/utilities/useDateFieldLocale.d.ts +2 -0
- package/dist/utilities/useDateFieldLocale.d.ts.map +1 -0
- package/dist/utilities/useDateFieldLocale.js +11 -0
- package/dist/utilities/useDateFieldLocale.js.map +1 -0
- package/package.json +4 -4
- package/dist/packages/tapestry-wc/dist/components/p-6NO22Vi_.js.map +0 -1
- package/dist/packages/tapestry-wc/dist/components/p-B2xqMgNQ.js.map +0 -1
- package/dist/packages/tapestry-wc/dist/components/p-BVvtAaVT.js.map +0 -1
- package/dist/packages/tapestry-wc/dist/components/p-Rn6lOB18.js.map +0 -1
- package/dist/packages/tapestry-wc/dist/components/p-np7vhMVg.js.map +0 -1
|
@@ -1,24 +1,45 @@
|
|
|
1
1
|
import "./btn.css";
|
|
2
|
+
import { type TooltipPlacement } from "../internal/tooltip";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { BaseButtonElementProps } from "./BaseButton";
|
|
4
|
-
|
|
5
|
-
/** Accessible label. Required for icon-only buttons to provide context about the button's purpose. */
|
|
6
|
-
"aria-label": string;
|
|
5
|
+
type IconButtonSharedProps = Omit<BaseButtonElementProps, "label"> & {
|
|
7
6
|
/** The icon to display in the button. Set via story args for non-primitive values. */
|
|
8
7
|
icon: React.ReactNode;
|
|
9
8
|
};
|
|
9
|
+
export type IconButtonBaseProps = IconButtonSharedProps & {
|
|
10
|
+
/** Accessible label. Required for icon-only buttons to provide context about the button's purpose. */
|
|
11
|
+
"aria-label": string;
|
|
12
|
+
};
|
|
13
|
+
type IconButtonTooltipProps = {
|
|
14
|
+
/** Accessible label. Required for icon-only buttons to provide context about the button's purpose. Not required when `tooltip` is set. When both are set, this is the name and the tooltip is visual only. */
|
|
15
|
+
"aria-label"?: string;
|
|
16
|
+
/** 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 `"Delete"`, aria-label `"Delete, 3 selected"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */
|
|
17
|
+
tooltip: string;
|
|
18
|
+
};
|
|
19
|
+
type IconButtonAriaLabelProps = {
|
|
20
|
+
/** Accessible label. Required for icon-only buttons to provide context about the button'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 `"Delete"`, aria-label `"Delete, 3 selected"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */
|
|
23
|
+
tooltip?: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* An icon-only button needs a name: `aria-label`, `tooltip`, or both.
|
|
27
|
+
* `IconButtonAriaLabelProps` is declared last so that a missing name
|
|
28
|
+
* reports "aria-label is missing", not "tooltip is missing".
|
|
29
|
+
*/
|
|
30
|
+
type IconButtonNameProps = IconButtonAriaLabelProps | IconButtonTooltipProps;
|
|
31
|
+
export type IconButtonProps = IconButtonSharedProps & IconButtonNameProps & {
|
|
32
|
+
/** Where the tooltip renders relative to the button. Default `"bottom"`. Has no effect without `tooltip`. */
|
|
33
|
+
tooltipPlacement?: TooltipPlacement;
|
|
34
|
+
};
|
|
10
35
|
/**
|
|
11
36
|
* An icon-only button component that renders as a button element.
|
|
12
|
-
* Requires an icon and aria-label for accessibility.
|
|
37
|
+
* Requires an icon, and an aria-label or tooltip for accessibility.
|
|
13
38
|
*
|
|
14
39
|
* @component
|
|
15
40
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/buttons-icon-button--docs | Storybook Documentation}
|
|
16
41
|
* @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}
|
|
17
42
|
*/
|
|
18
|
-
export declare const IconButton: React.ForwardRefExoticComponent<
|
|
19
|
-
|
|
20
|
-
"aria-label": string;
|
|
21
|
-
/** The icon to display in the button. Set via story args for non-primitive values. */
|
|
22
|
-
icon: React.ReactNode;
|
|
23
|
-
} & React.RefAttributes<HTMLButtonElement>>;
|
|
43
|
+
export declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
44
|
+
export {};
|
|
24
45
|
//# sourceMappingURL=IconButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAElB,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAE7E,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAc,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAEjE,KAAK,qBAAqB,GAAG,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,GAAG;IACnE,sFAAsF;IACtF,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,GAAG;IACxD,sGAAsG;IACtG,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,KAAK,sBAAsB,GAAG;IAC5B,8MAA8M;IAC9M,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wSAAwS;IACxS,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC9B,8MAA8M;IAC9M,YAAY,EAAE,MAAM,CAAA;IACpB,wSAAwS;IACxS,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;GAIG;AACH,KAAK,mBAAmB,GAAG,wBAAwB,GAAG,sBAAsB,CAAA;AAE5E,MAAM,MAAM,eAAe,GAAG,qBAAqB,GACjD,mBAAmB,GAAG;IACpB,6GAA6G;IAC7G,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC,CAAA;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,2FA0CtB,CAAA"}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
import { Tooltip } from '../internal/tooltip/Tooltip.js';
|
|
1
2
|
import classNames from 'classnames';
|
|
2
3
|
import React, { forwardRef } from 'react';
|
|
3
4
|
import { BaseButton } from './BaseButton.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* An icon-only button component that renders as a button element.
|
|
7
|
-
* Requires an icon and aria-label for accessibility.
|
|
8
|
+
* Requires an icon, and an aria-label or tooltip for accessibility.
|
|
8
9
|
*
|
|
9
10
|
* @component
|
|
10
11
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/buttons-icon-button--docs | Storybook Documentation}
|
|
11
12
|
* @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}
|
|
12
13
|
*/
|
|
13
|
-
const IconButton = forwardRef(({ className, icon, ...restProps }, ref) => {
|
|
14
|
+
const IconButton = forwardRef(({ className, icon, tooltip, tooltipPlacement = "bottom", ...restProps }, ref) => {
|
|
14
15
|
const iconOnlyClassName = classNames("tds-btn--icononly", className);
|
|
16
|
+
if (tooltip) {
|
|
17
|
+
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...buttonProps } = restProps;
|
|
18
|
+
return (React.createElement(Tooltip, { content: tooltip, placement: tooltipPlacement, visualOnly: true },
|
|
19
|
+
React.createElement(BaseButton, { ...buttonProps, "aria-label": ariaLabel || tooltip, label: icon, className: iconOnlyClassName, ref: ref })));
|
|
20
|
+
}
|
|
15
21
|
return (React.createElement(BaseButton, { ...restProps, label: icon, className: iconOnlyClassName, ref: ref }));
|
|
16
22
|
});
|
|
17
23
|
IconButton.displayName = "IconButton";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.js","sources":["../../../src/components/button/IconButton.tsx"],"sourcesContent":["import \"./btn.css\"\n\nimport classNames from \"classnames\"\nimport React, { forwardRef } from \"react\"\n\nimport { BaseButton, BaseButtonElementProps } from \"./BaseButton\"\n\
|
|
1
|
+
{"version":3,"file":"IconButton.js","sources":["../../../src/components/button/IconButton.tsx"],"sourcesContent":["import \"./btn.css\"\n\nimport { Tooltip, type TooltipPlacement } from \"@components/internal/tooltip\"\nimport classNames from \"classnames\"\nimport React, { forwardRef } from \"react\"\n\nimport { BaseButton, BaseButtonElementProps } from \"./BaseButton\"\n\ntype IconButtonSharedProps = Omit<BaseButtonElementProps, \"label\"> & {\n /** The icon to display in the button. Set via story args for non-primitive values. */\n icon: React.ReactNode\n}\n\nexport type IconButtonBaseProps = IconButtonSharedProps & {\n /** Accessible label. Required for icon-only buttons to provide context about the button's purpose. */\n \"aria-label\": string\n}\n\ntype IconButtonTooltipProps = {\n /** Accessible label. Required for icon-only buttons to provide context about the button'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 `\"Delete\"`, aria-label `\"Delete, 3 selected\"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */\n tooltip: string\n}\n\ntype IconButtonAriaLabelProps = {\n /** Accessible label. Required for icon-only buttons to provide context about the button'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 `\"Delete\"`, aria-label `\"Delete, 3 selected\"`). The tooltip itself is hidden from screen readers. Ignores `aria-labelledby`. */\n tooltip?: string\n}\n\n/**\n * An icon-only button needs a name: `aria-label`, `tooltip`, or both.\n * `IconButtonAriaLabelProps` is declared last so that a missing name\n * reports \"aria-label is missing\", not \"tooltip is missing\".\n */\ntype IconButtonNameProps = IconButtonAriaLabelProps | IconButtonTooltipProps\n\nexport type IconButtonProps = IconButtonSharedProps &\n IconButtonNameProps & {\n /** Where the tooltip renders relative to the button. Default `\"bottom\"`. Has no effect without `tooltip`. */\n tooltipPlacement?: TooltipPlacement\n }\n\n/**\n * An icon-only button component that renders as a button element.\n * Requires an icon, and an aria-label or tooltip for accessibility.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/buttons-icon-button--docs | Storybook Documentation}\n * @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}\n */\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n (\n {\n className,\n icon,\n tooltip,\n tooltipPlacement = \"bottom\",\n ...restProps\n }: IconButtonProps,\n ref\n ) => {\n const iconOnlyClassName = classNames(\"tds-btn--icononly\", className)\n\n if (tooltip) {\n const {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...buttonProps\n } = restProps\n\n return (\n <Tooltip content={tooltip} placement={tooltipPlacement} visualOnly>\n <BaseButton\n {...buttonProps}\n aria-label={ariaLabel || tooltip}\n label={icon}\n className={iconOnlyClassName}\n ref={ref}\n />\n </Tooltip>\n )\n }\n\n return (\n <BaseButton\n {...restProps}\n label={icon}\n className={iconOnlyClassName}\n ref={ref}\n />\n )\n }\n)\n\nIconButton.displayName = \"IconButton\"\n"],"names":[],"mappings":";;;;;AA6CA;;;;;;;AAOG;AACI,MAAM,UAAU,GAAG,UAAU,CAClC,CACE,EACE,SAAS,EACT,IAAI,EACJ,OAAO,EACP,gBAAgB,GAAG,QAAQ,EAC3B,GAAG,SAAS,EACI,EAClB,GAAG,KACD;IACF,MAAM,iBAAiB,GAAG,UAAU,CAAC,mBAAmB,EAAE,SAAS,CAAC;IAEpE,IAAI,OAAO,EAAE;AACX,QAAA,MAAM,EACJ,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,WAAW,EACf,GAAG,SAAS;AAEb,QAAA,QACE,KAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAA,IAAA,EAAA;YAChE,KAAA,CAAA,aAAA,CAAC,UAAU,OACL,WAAW,EAAA,YAAA,EACH,SAAS,IAAI,OAAO,EAChC,KAAK,EAAE,IAAI,EACX,SAAS,EAAE,iBAAiB,EAC5B,GAAG,EAAE,GAAG,EAAA,CACR,CACM;IAEd;AAEA,IAAA,QACE,KAAA,CAAA,aAAA,CAAC,UAAU,OACL,SAAS,EACb,KAAK,EAAE,IAAI,EACX,SAAS,EAAE,iBAAiB,EAC5B,GAAG,EAAE,GAAG,EAAA,CACR;AAEN,CAAC;AAGH,UAAU,CAAC,WAAW,GAAG,YAAY;;;;"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { DistributiveOmit } from "../../utilities/typeUtils";
|
|
1
2
|
import React from "react";
|
|
2
3
|
import { IconButtonProps } from "./IconButton";
|
|
3
4
|
import { ToggleButtonProps } from "./ToggleButton";
|
|
5
|
+
export type ToggleIconButtonProps = DistributiveOmit<IconButtonProps, "onChange"> & ToggleButtonProps;
|
|
4
6
|
/**
|
|
5
7
|
* An icon-only button that stays either "on" or "off" after each click.
|
|
8
|
+
* Requires an `aria-label` or `tooltip` for accessibility.
|
|
6
9
|
* Maps `pressed` to the native `aria-pressed` attribute, always present
|
|
7
10
|
* since a toggle button must announce that state. Manages its own pressed
|
|
8
11
|
* state, starting from `false`, when `pressed` is omitted — pass
|
|
@@ -13,5 +16,5 @@ import { ToggleButtonProps } from "./ToggleButton";
|
|
|
13
16
|
* @component
|
|
14
17
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-toggle-icon-button--docs | Storybook Documentation}
|
|
15
18
|
*/
|
|
16
|
-
export declare const ToggleIconButton: React.ForwardRefExoticComponent<
|
|
19
|
+
export declare const ToggleIconButton: React.ForwardRefExoticComponent<ToggleIconButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
17
20
|
//# sourceMappingURL=ToggleIconButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleIconButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/ToggleIconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAc,eAAe,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EACL,iBAAiB,EAGlB,MAAM,gBAAgB,CAAA;AAEvB
|
|
1
|
+
{"version":3,"file":"ToggleIconButton.d.ts","sourceRoot":"","sources":["../../../src/components/button/ToggleIconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAc,eAAe,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EACL,iBAAiB,EAGlB,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAClD,eAAe,EACf,UAAU,CACX,GACC,iBAAiB,CAAA;AAEnB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,iGAkC5B,CAAA"}
|
|
@@ -4,6 +4,7 @@ import { usePressedState, toggleButtonProps } from './ToggleButton.js';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* An icon-only button that stays either "on" or "off" after each click.
|
|
7
|
+
* Requires an `aria-label` or `tooltip` for accessibility.
|
|
7
8
|
* Maps `pressed` to the native `aria-pressed` attribute, always present
|
|
8
9
|
* since a toggle button must announce that state. Manages its own pressed
|
|
9
10
|
* state, starting from `false`, when `pressed` is omitted — pass
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleIconButton.js","sources":["../../../src/components/button/ToggleIconButton.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\"\n\nimport { IconButton, IconButtonProps } from \"./IconButton\"\nimport {\n ToggleButtonProps,\n toggleButtonProps,\n usePressedState,\n} from \"./ToggleButton\"\n\n/**\n * An icon-only button that stays either \"on\" or \"off\" after each click.\n * Maps `pressed` to the native `aria-pressed` attribute, always present\n * since a toggle button must announce that state. Manages its own pressed\n * state, starting from `false`, when `pressed` is omitted — pass\n * `defaultPressed` and/or `onChange` to seed or observe that\n * uncontrolled state. Carries no default `kind` or CSS; `kind`/`className`\n * stay exactly as caller-controlled as they are on plain `IconButton`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-toggle-icon-button--docs | Storybook Documentation}\n */\nexport const ToggleIconButton = forwardRef<\n HTMLButtonElement,\n
|
|
1
|
+
{"version":3,"file":"ToggleIconButton.js","sources":["../../../src/components/button/ToggleIconButton.tsx"],"sourcesContent":["import type { DistributiveOmit } from \"@utilities/typeUtils\"\nimport React, { forwardRef } from \"react\"\n\nimport { IconButton, IconButtonProps } from \"./IconButton\"\nimport {\n ToggleButtonProps,\n toggleButtonProps,\n usePressedState,\n} from \"./ToggleButton\"\n\nexport type ToggleIconButtonProps = DistributiveOmit<\n IconButtonProps,\n \"onChange\"\n> &\n ToggleButtonProps\n\n/**\n * An icon-only button that stays either \"on\" or \"off\" after each click.\n * Requires an `aria-label` or `tooltip` for accessibility.\n * Maps `pressed` to the native `aria-pressed` attribute, always present\n * since a toggle button must announce that state. Manages its own pressed\n * state, starting from `false`, when `pressed` is omitted — pass\n * `defaultPressed` and/or `onChange` to seed or observe that\n * uncontrolled state. Carries no default `kind` or CSS; `kind`/`className`\n * stay exactly as caller-controlled as they are on plain `IconButton`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-toggle-icon-button--docs | Storybook Documentation}\n */\nexport const ToggleIconButton = forwardRef<\n HTMLButtonElement,\n ToggleIconButtonProps\n>(\n (\n {\n defaultPressed,\n onClick,\n onChange,\n pressed,\n ...restProps\n }: ToggleIconButtonProps,\n ref\n ) => {\n const [currentPressed, togglePressed] = usePressedState({\n defaultPressed,\n onChange,\n pressed,\n })\n\n const handleClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {\n togglePressed()\n onClick?.(event)\n }\n\n return (\n <IconButton\n ref={ref}\n {...restProps}\n onClick={handleClick}\n {...toggleButtonProps({ pressed: currentPressed })}\n />\n )\n }\n)\n\nToggleIconButton.displayName = \"ToggleIconButton\"\n"],"names":["React"],"mappings":";;;;AAgBA;;;;;;;;;;;;AAYG;MACU,gBAAgB,GAAG,UAAU,CAIxC,CACE,EACE,cAAc,EACd,OAAO,EACP,QAAQ,EACR,OAAO,EACP,GAAG,SAAS,EACU,EACxB,GAAG,KACD;AACF,IAAA,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,eAAe,CAAC;QACtD,cAAc;QACd,QAAQ;QACR,OAAO;AACR,KAAA,CAAC;AAEF,IAAA,MAAM,WAAW,GAA+C,CAAC,KAAK,KAAI;AACxE,QAAA,aAAa,EAAE;AACf,QAAA,OAAO,GAAG,KAAK,CAAC;AAClB,IAAA,CAAC;IAED,QACEA,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EACT,GAAG,EAAE,GAAG,EAAA,GACJ,SAAS,EACb,OAAO,EAAE,WAAW,EAAA,GAChB,iBAAiB,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAA,CAClD;AAEN,CAAC;AAGH,gBAAgB,CAAC,WAAW,GAAG,kBAAkB;;;;"}
|
|
@@ -12,4 +12,5 @@ export type { LoadingButtonProps } from "./LoadingButton";
|
|
|
12
12
|
export { LoadingButton } from "./LoadingButton";
|
|
13
13
|
export type { PageHeaderActionsDropdownButtonProps } from "./PageHeaderActionsDropdownButton";
|
|
14
14
|
export { PageHeaderActionsDropdownButton } from "./PageHeaderActionsDropdownButton";
|
|
15
|
+
export type { TooltipPlacement } from "../internal/tooltip";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAElB,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,oCAAoC,EAAE,MAAM,mCAAmC,CAAA;AAC7F,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/button/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAElB,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,oCAAoC,EAAE,MAAM,mCAAmC,CAAA;AAC7F,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAA;AACnF,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA"}
|
|
@@ -8,6 +8,12 @@ export type ComboBoxSize = "md" | "lg";
|
|
|
8
8
|
export type ComboBoxLoadingState = "error" | "filtering" | "idle" | "loading" | "loadingMore" | "sorting";
|
|
9
9
|
type ComboBoxChildren<T extends object> = NonNullable<AriaListBoxProps<T>["children"]>;
|
|
10
10
|
export interface ComboBoxProps<T extends object = object> {
|
|
11
|
+
/**
|
|
12
|
+
* If `true`, keeps typed text that does not match an option. Turn it on when
|
|
13
|
+
* ComboBox is a standalone search and the suggestions are shortcuts. Leave it
|
|
14
|
+
* off in forms, where the value needs to match one of the options.
|
|
15
|
+
*/
|
|
16
|
+
allowsCustomValue?: boolean;
|
|
11
17
|
/** The contents of the listbox. */
|
|
12
18
|
children: ComboBoxChildren<T>;
|
|
13
19
|
/** Helper text displayed below the component. Styled as error text when `invalid` is `true`. */
|
|
@@ -26,6 +32,8 @@ export interface ComboBoxProps<T extends object = object> {
|
|
|
26
32
|
* Async loading state for the listbox.
|
|
27
33
|
* - `"loading"`: while the collection is empty, replaces the empty state with a spinner.
|
|
28
34
|
* - `"loadingMore"`: shows an inline spinner at the bottom of the listbox (use with `onLoadMore`).
|
|
35
|
+
* - `"filtering"`: renders as `"idle"`, but tells screen reader users "Loading" when results are slow to arrive after typing stops.
|
|
36
|
+
* - `"error"`: renders as `"idle"`, but reads the empty state (`renderEmptyState`) to screen reader users while the collection is empty.
|
|
29
37
|
* - Other values render as `"idle"`.
|
|
30
38
|
*/
|
|
31
39
|
loadingState?: ComboBoxLoadingState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/combo-box/ComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAA;AAC1B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"ComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/combo-box/ComboBox.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,13 @@ import '../button/DropdownIconButton.js';
|
|
|
5
5
|
import { IconButton } from '../button/IconButton.js';
|
|
6
6
|
import '../button/LoadingButton.js';
|
|
7
7
|
import '../button/PageHeaderActionsDropdownButton.js';
|
|
8
|
+
import { LoadingAnnouncement, LOADING_ANNOUNCEMENT_DELAY_MS } from '../internal/LoadingAnnouncement.js';
|
|
8
9
|
import LoadingSpinner from '../internal/LoadingSpinner.js';
|
|
9
10
|
import Icon from '../../utilities/Icon.js';
|
|
11
|
+
import { useAnnounce } from '../../utilities/useAnnounce.js';
|
|
12
|
+
import { useId } from '../../utilities/useId.js';
|
|
10
13
|
import classNames from 'classnames';
|
|
11
|
-
import React, { useContext } from 'react';
|
|
14
|
+
import React, { useContext, useEffect } from 'react';
|
|
12
15
|
import { ListBoxLoadMoreItem, ComboBox as ComboBox$1, Label, Input, Button, Popover, ListBox, Text, ListBoxItem, ListBoxSection, ComboBoxStateContext, Collection } from 'react-aria-components/ComboBox';
|
|
13
16
|
import { Group } from 'react-aria-components/Group';
|
|
14
17
|
import { Header } from 'react-aria-components/Header';
|
|
@@ -20,6 +23,21 @@ function ClearButton() {
|
|
|
20
23
|
const state = useContext(ComboBoxStateContext);
|
|
21
24
|
return (React.createElement(IconButton, { "aria-label": "Clear", className: "tds-combo-box-clear-button", "data-input-empty": !state?.inputValue ? true : undefined, icon: React.createElement(Icon, { "aria-hidden": true, className: "tds-combo-box-clear-icon", symbol: "general#x" }), kind: "neutral-inline", onClick: () => state?.setInputValue(""), onMouseDown: (event) => event.preventDefault(), tabIndex: -1 }));
|
|
22
25
|
}
|
|
26
|
+
function ErrorAnnouncement({ labelledBy }) {
|
|
27
|
+
const announce = useAnnounce();
|
|
28
|
+
const inputValue = useContext(ComboBoxStateContext)?.inputValue;
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const timeout = setTimeout(() => announce({ "aria-labelledby": labelledBy }), LOADING_ANNOUNCEMENT_DELAY_MS);
|
|
31
|
+
return () => clearTimeout(timeout);
|
|
32
|
+
}, [announce, inputValue, labelledBy]);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function FilteringAnnouncement() {
|
|
36
|
+
const state = useContext(ComboBoxStateContext);
|
|
37
|
+
if (!state?.isOpen)
|
|
38
|
+
return null;
|
|
39
|
+
return React.createElement(LoadingAnnouncement, { key: state.inputValue, message: "Loading" });
|
|
40
|
+
}
|
|
23
41
|
/**
|
|
24
42
|
* A combo box combines a text input with a filterable popover
|
|
25
43
|
* listbox, allowing users to type to search and select from a list of options.
|
|
@@ -34,13 +52,15 @@ function ClearButton() {
|
|
|
34
52
|
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}
|
|
35
53
|
*/
|
|
36
54
|
function ComboBox({ allowsEmptyCollection = true, children, className, description, disabled, filter, hideLabel, invalid, label, loadingState, menuTrigger = "focus", onChange, onLoadMore, placeholder, readOnly, renderEmptyState = "No results", required, showClearButton, showSearchIcon, size = "md", ...restProps }) {
|
|
55
|
+
const emptyStateId = `tds-combo-box-empty-state-${useId()}`;
|
|
37
56
|
const combinedClassName = classNames("tds-field tds-combo-box", {
|
|
38
57
|
"tds-combo-box--lg": size === "lg",
|
|
39
58
|
"tds-field--lg": size === "lg",
|
|
40
59
|
}, className);
|
|
41
60
|
const loadMoreItem = onLoadMore && (React.createElement(ListBoxLoadMoreItem, { className: "tds-combo-box-load-more", isLoading: loadingState === "loadingMore", onLoadMore: onLoadMore },
|
|
42
|
-
React.createElement("
|
|
43
|
-
|
|
61
|
+
React.createElement("span", { className: "tds-combo-box-loading-label--hidden" }, "Loading more"),
|
|
62
|
+
React.createElement(LoadingSpinner, null),
|
|
63
|
+
React.createElement(LoadingAnnouncement, { message: "Loading more" })));
|
|
44
64
|
const renderChildren = () => {
|
|
45
65
|
if (typeof children === "function") {
|
|
46
66
|
return (React.createElement(Collection, { items: restProps.items ?? restProps.defaultItems }, children));
|
|
@@ -67,10 +87,16 @@ function ComboBox({ allowsEmptyCollection = true, children, className, descripti
|
|
|
67
87
|
!disabled && React.createElement(ClearButton, null)),
|
|
68
88
|
React.createElement(Popover, { className: "tds-combo-box-popover" },
|
|
69
89
|
React.createElement(ListBox, { className: "tds-combo-box-list", renderEmptyState: allowsEmptyCollection
|
|
70
|
-
? () => (React.createElement("div", {
|
|
90
|
+
? () => (React.createElement("div", { className: "tds-combo-box-empty-state", id: emptyStateId },
|
|
91
|
+
loadingState === "error" && (React.createElement(ErrorAnnouncement, { labelledBy: emptyStateId })),
|
|
92
|
+
loadingState === "loading" ? (React.createElement(React.Fragment, null,
|
|
93
|
+
React.createElement("span", { className: "tds-combo-box-loading-label--hidden" }, "Loading"),
|
|
94
|
+
React.createElement(LoadingSpinner, null),
|
|
95
|
+
React.createElement(LoadingAnnouncement, { message: "Loading" }))) : (resolveEmptyState(renderEmptyState))))
|
|
71
96
|
: undefined },
|
|
72
97
|
renderChildren(),
|
|
73
|
-
loadMoreItem)
|
|
98
|
+
loadMoreItem),
|
|
99
|
+
loadingState === "filtering" && React.createElement(FilteringAnnouncement, null)),
|
|
74
100
|
description && (React.createElement(Text, { className: "tds-field-description", slot: "description" },
|
|
75
101
|
React.createElement(Icon, { "aria-hidden": true, className: "tds-field-description-invalid-icon", symbol: "general#exclamation-triangle" }),
|
|
76
102
|
description))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboBox.js","sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import \"../button/btn.css\"\nimport \"../field/index.css\"\nimport \"./index.css\"\n\nimport { IconButton } from \"@components/button\"\nimport LoadingSpinner from \"@components/internal/LoadingSpinner\"\nimport Icon from \"@utilities/Icon\"\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport classNames from \"classnames\"\nimport React, { type ReactNode, useContext } from \"react\"\nimport {\n Button,\n Collection,\n ComboBox as AriaComboBox,\n type ComboBoxProps as AriaComboBoxProps,\n ComboBoxStateContext,\n Input,\n type Key,\n Label,\n ListBox,\n ListBoxItem,\n type ListBoxItemProps,\n ListBoxLoadMoreItem,\n type ListBoxProps as AriaListBoxProps,\n ListBoxSection,\n type ListBoxSectionProps,\n Popover,\n Text,\n} from \"react-aria-components/ComboBox\"\nimport { Group } from \"react-aria-components/Group\"\nimport { Header } from \"react-aria-components/Header\"\n\nexport type ComboBoxSize = \"md\" | \"lg\"\n\nexport type ComboBoxLoadingState =\n | \"error\"\n | \"filtering\"\n | \"idle\"\n | \"loading\"\n | \"loadingMore\"\n | \"sorting\"\n\ntype ComboBoxChildren<T extends object> = NonNullable<\n AriaListBoxProps<T>[\"children\"]\n>\n\nexport interface ComboBoxProps<T extends object = object> {\n /** The contents of the listbox. */\n children: ComboBoxChildren<T>\n /** Helper text displayed below the component. Styled as error text when `invalid` is `true`. */\n description?: ReactNode\n /** Disables the field and trigger button. */\n disabled?: boolean\n /** Custom filter function for determining if an item should appear in the list. */\n filter?: (textValue: string, inputValue: string) => boolean\n /** If `true`, the `label` text is rendered as an `aria-label` instead of a visible label element. */\n hideLabel?: boolean\n /** Whether the input is in an invalid state. */\n invalid?: boolean\n /** Accessible label for the field. */\n label: string\n /**\n * Async loading state for the listbox.\n * - `\"loading\"`: while the collection is empty, replaces the empty state with a spinner.\n * - `\"loadingMore\"`: shows an inline spinner at the bottom of the listbox (use with `onLoadMore`).\n * - Other values render as `\"idle\"`.\n */\n loadingState?: ComboBoxLoadingState\n /**\n * The interaction that opens the popover.\n * - `\"input\"`: opens when the user enters text in the input.\n * - `\"focus\"`: opens when the user focuses (via click or keyboard) into the input.\n * - `\"manual\"`: opens only via the trigger button or arrow keys.\n * @default \"focus\"\n */\n menuTrigger?: \"focus\" | \"input\" | \"manual\"\n /**\n * Called when the selected value(s) change.\n * Receives `Key[]` when `selectionMode` is `\"multiple\"`, otherwise `Key | null`.\n */\n onChange?: ((value: Key | null) => void) | ((value: Key[]) => void)\n /** Called when the user scrolls near the bottom of the listbox. Pair with `loadingState` for infinite scroll. */\n onLoadMore?: () => void\n /** Placeholder text for the input. */\n placeholder?: string\n /** If `true`, allows the value to be read but not changed. */\n readOnly?: boolean\n /** Content to display when there are no items in the list. Defaults to \"No results\". */\n renderEmptyState?: ReactNode | (() => ReactNode)\n /** If `true`, appends an asterisk at the end of the label text. */\n required?: boolean\n /**\n * If `true`, renders a button after the input that clears its text. Only\n * applies when `menuTrigger` is `\"focus\"`, where no trigger button is rendered.\n */\n showClearButton?: boolean\n /** If `true`, renders a search icon before the input. */\n showSearchIcon?: boolean\n /** The size of the combo box. */\n size?: ComboBoxSize\n}\n\ntype AriaComboBoxPropsToOmit = \"slot\"\n\ntype AriaComboBoxPropsToInclude =\n | \"allowsEmptyCollection\"\n | \"defaultItems\"\n | \"defaultValue\"\n | \"disabledKeys\"\n | \"inputValue\"\n | \"items\"\n | \"name\"\n | \"onInputChange\"\n | \"selectionMode\"\n | \"value\"\n\nexport type ComboBoxElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n AriaComboBoxProps<T, \"single\" | \"multiple\">,\n ComboBoxProps<T>,\n AriaComboBoxPropsToOmit,\n AriaComboBoxPropsToInclude\n >\n\nfunction resolveEmptyState(value: ReactNode | (() => ReactNode)): ReactNode {\n return typeof value === \"function\" ? value() : value\n}\n\nfunction ClearButton() {\n const state = useContext(ComboBoxStateContext)\n\n return (\n <IconButton\n aria-label=\"Clear\"\n className=\"tds-combo-box-clear-button\"\n data-input-empty={!state?.inputValue ? true : undefined}\n icon={\n <Icon\n aria-hidden\n className=\"tds-combo-box-clear-icon\"\n symbol=\"general#x\"\n />\n }\n kind=\"neutral-inline\"\n onClick={() => state?.setInputValue(\"\")}\n onMouseDown={(event) => event.preventDefault()}\n tabIndex={-1}\n />\n )\n}\n\n/**\n * A combo box combines a text input with a filterable popover\n * listbox, allowing users to type to search and select from a list of options.\n *\n * It supports both single and multiple selection (`selectionMode`), custom filtering,\n * and asynchronous data loading with infinite scroll capabilities (`loadingState` and `onLoadMore`).\n * Collections can be either static or dynamic, managed via the `children`, `items`,\n * or `defaultItems` props. To construct the dropdown list, compose this component\n * with `ComboBoxItem` for individual options and `ComboBoxSection` for grouping.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBox<T extends object>({\n allowsEmptyCollection = true,\n children,\n className,\n description,\n disabled,\n filter,\n hideLabel,\n invalid,\n label,\n loadingState,\n menuTrigger = \"focus\",\n onChange,\n onLoadMore,\n placeholder,\n readOnly,\n renderEmptyState = \"No results\",\n required,\n showClearButton,\n showSearchIcon,\n size = \"md\",\n ...restProps\n}: ComboBoxElementProps<T>) {\n const combinedClassName = classNames(\n \"tds-field tds-combo-box\",\n {\n \"tds-combo-box--lg\": size === \"lg\",\n \"tds-field--lg\": size === \"lg\",\n },\n className\n )\n\n const loadMoreItem = onLoadMore && (\n <ListBoxLoadMoreItem\n className=\"tds-combo-box-load-more\"\n isLoading={loadingState === \"loadingMore\"}\n onLoadMore={onLoadMore}\n >\n <div aria-label=\"Loading more\" role=\"status\">\n <LoadingSpinner />\n </div>\n </ListBoxLoadMoreItem>\n )\n\n const renderChildren = () => {\n if (typeof children === \"function\") {\n return (\n <Collection items={restProps.items ?? restProps.defaultItems}>\n {children}\n </Collection>\n )\n }\n return children\n }\n\n return (\n // React Aria's ComboBox is generic over selection mode (M). We instantiate\n // it with the union \"single\" | \"multiple\" so value/defaultValue/selectionMode\n // accept both shapes. onChange still needs a cast because our type is a union\n // of function types (to allow narrower handlers like\n // `setValue: (Key|null) => void`), which isn't assignable to RAC's\n // single-function signature.\n <AriaComboBox<T, \"single\" | \"multiple\">\n {...restProps}\n allowsEmptyCollection={allowsEmptyCollection}\n aria-label={hideLabel ? label : undefined}\n className={combinedClassName}\n defaultFilter={filter}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n menuTrigger={menuTrigger}\n onChange={onChange as (value: Key | Key[] | null) => void}\n >\n {!hideLabel && <Label className=\"tds-field-label\">{label}</Label>}\n <Group className=\"tds-field-control tds-combo-box-field\">\n {showSearchIcon && (\n <Icon\n aria-hidden\n className=\"tds-combo-box-search-icon\"\n symbol=\"general#search\"\n />\n )}\n <Input\n aria-invalid={invalid || undefined}\n className=\"tds-combo-box-input\"\n placeholder={placeholder}\n />\n {menuTrigger !== \"focus\" && !readOnly && (\n <Button className=\"tds-combo-box-button tds-btn tds-btn--infield\">\n <Icon aria-hidden symbol=\"general#down-caret\" />\n </Button>\n )}\n {showClearButton &&\n menuTrigger === \"focus\" &&\n !readOnly &&\n !disabled && <ClearButton />}\n </Group>\n <Popover className=\"tds-combo-box-popover\">\n <ListBox\n className=\"tds-combo-box-list\"\n renderEmptyState={\n allowsEmptyCollection\n ? () => (\n <div\n aria-label={\n loadingState === \"loading\" ? \"Loading\" : undefined\n }\n className=\"tds-combo-box-empty-state\"\n role={loadingState === \"loading\" ? \"status\" : undefined}\n >\n {loadingState === \"loading\" ? (\n <LoadingSpinner />\n ) : (\n resolveEmptyState(renderEmptyState)\n )}\n </div>\n )\n : undefined\n }\n >\n {renderChildren()}\n {loadMoreItem}\n </ListBox>\n </Popover>\n {description && (\n <Text className=\"tds-field-description\" slot=\"description\">\n <Icon\n aria-hidden\n className=\"tds-field-description-invalid-icon\"\n symbol=\"general#exclamation-triangle\"\n />\n {description}\n </Text>\n )}\n </AriaComboBox>\n )\n}\n\nexport interface ComboBoxItemProps {\n /** Disables the item. */\n disabled?: boolean\n}\n\ntype AriaListBoxItemPropsToOmit = \"isDisabled\"\n\ntype AriaListBoxItemPropsToInclude = \"onAction\" | \"textValue\" | \"value\"\n\nexport type ComboBoxItemElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n ListBoxItemProps<T>,\n ComboBoxItemProps,\n AriaListBoxItemPropsToOmit,\n AriaListBoxItemPropsToInclude\n >\n\n/**\n * A selectable option within a {@link ComboBox}. Renders as a listbox item.\n *\n * Provide an `id` (or `key` when rendering from a collection) to identify the\n * option, and `textValue` when the visible children are not plain text so\n * type-ahead and screen readers have a stable label to use.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBoxItem<T extends object>({\n className,\n disabled,\n ...restProps\n}: ComboBoxItemElementProps<T>) {\n return (\n <ListBoxItem\n {...restProps}\n className={classNames(\"tds-combo-box-list-item\", className)}\n isDisabled={disabled}\n />\n )\n}\n\nexport interface ComboBoxSectionProps {\n /** The items rendered within the section. */\n children: ReactNode\n /** Optional heading text rendered above the section's items. */\n title?: string\n}\n\ntype AriaListBoxSectionPropsToInclude = \"dependencies\"\n\nexport type ComboBoxSectionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n ListBoxSectionProps<T>,\n ComboBoxSectionProps,\n never,\n AriaListBoxSectionPropsToInclude\n >\n\n/**\n * A group of related {@link ComboBoxItem}s within a {@link ComboBox}. Renders\n * an optional `title` heading above its items.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBoxSection<T extends object>({\n children,\n className,\n title,\n ...restProps\n}: ComboBoxSectionElementProps<T>) {\n return (\n <ListBoxSection\n {...restProps}\n className={classNames(\"tds-combo-box-list-section\", className)}\n >\n {title && (\n <Header className=\"tds-combo-box-section-header\">{title}</Header>\n )}\n {children}\n </ListBoxSection>\n )\n}\n"],"names":["AriaComboBox"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboBox.js","sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import \"../button/btn.css\"\nimport \"../field/index.css\"\nimport \"./index.css\"\n\nimport { IconButton } from \"@components/button\"\nimport {\n LOADING_ANNOUNCEMENT_DELAY_MS,\n LoadingAnnouncement,\n} from \"@components/internal/LoadingAnnouncement\"\nimport LoadingSpinner from \"@components/internal/LoadingSpinner\"\nimport Icon from \"@utilities/Icon\"\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport { useAnnounce } from \"@utilities/useAnnounce\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type ReactNode, useContext, useEffect } from \"react\"\nimport {\n Button,\n Collection,\n ComboBox as AriaComboBox,\n type ComboBoxProps as AriaComboBoxProps,\n ComboBoxStateContext,\n Input,\n type Key,\n Label,\n ListBox,\n ListBoxItem,\n type ListBoxItemProps,\n ListBoxLoadMoreItem,\n type ListBoxProps as AriaListBoxProps,\n ListBoxSection,\n type ListBoxSectionProps,\n Popover,\n Text,\n} from \"react-aria-components/ComboBox\"\nimport { Group } from \"react-aria-components/Group\"\nimport { Header } from \"react-aria-components/Header\"\n\nexport type ComboBoxSize = \"md\" | \"lg\"\n\nexport type ComboBoxLoadingState =\n | \"error\"\n | \"filtering\"\n | \"idle\"\n | \"loading\"\n | \"loadingMore\"\n | \"sorting\"\n\ntype ComboBoxChildren<T extends object> = NonNullable<\n AriaListBoxProps<T>[\"children\"]\n>\n\nexport interface ComboBoxProps<T extends object = object> {\n /**\n * If `true`, keeps typed text that does not match an option. Turn it on when\n * ComboBox is a standalone search and the suggestions are shortcuts. Leave it\n * off in forms, where the value needs to match one of the options.\n */\n allowsCustomValue?: boolean\n /** The contents of the listbox. */\n children: ComboBoxChildren<T>\n /** Helper text displayed below the component. Styled as error text when `invalid` is `true`. */\n description?: ReactNode\n /** Disables the field and trigger button. */\n disabled?: boolean\n /** Custom filter function for determining if an item should appear in the list. */\n filter?: (textValue: string, inputValue: string) => boolean\n /** If `true`, the `label` text is rendered as an `aria-label` instead of a visible label element. */\n hideLabel?: boolean\n /** Whether the input is in an invalid state. */\n invalid?: boolean\n /** Accessible label for the field. */\n label: string\n /**\n * Async loading state for the listbox.\n * - `\"loading\"`: while the collection is empty, replaces the empty state with a spinner.\n * - `\"loadingMore\"`: shows an inline spinner at the bottom of the listbox (use with `onLoadMore`).\n * - `\"filtering\"`: renders as `\"idle\"`, but tells screen reader users \"Loading\" when results are slow to arrive after typing stops.\n * - `\"error\"`: renders as `\"idle\"`, but reads the empty state (`renderEmptyState`) to screen reader users while the collection is empty.\n * - Other values render as `\"idle\"`.\n */\n loadingState?: ComboBoxLoadingState\n /**\n * The interaction that opens the popover.\n * - `\"input\"`: opens when the user enters text in the input.\n * - `\"focus\"`: opens when the user focuses (via click or keyboard) into the input.\n * - `\"manual\"`: opens only via the trigger button or arrow keys.\n * @default \"focus\"\n */\n menuTrigger?: \"focus\" | \"input\" | \"manual\"\n /**\n * Called when the selected value(s) change.\n * Receives `Key[]` when `selectionMode` is `\"multiple\"`, otherwise `Key | null`.\n */\n onChange?: ((value: Key | null) => void) | ((value: Key[]) => void)\n /** Called when the user scrolls near the bottom of the listbox. Pair with `loadingState` for infinite scroll. */\n onLoadMore?: () => void\n /** Placeholder text for the input. */\n placeholder?: string\n /** If `true`, allows the value to be read but not changed. */\n readOnly?: boolean\n /** Content to display when there are no items in the list. Defaults to \"No results\". */\n renderEmptyState?: ReactNode | (() => ReactNode)\n /** If `true`, appends an asterisk at the end of the label text. */\n required?: boolean\n /**\n * If `true`, renders a button after the input that clears its text. Only\n * applies when `menuTrigger` is `\"focus\"`, where no trigger button is rendered.\n */\n showClearButton?: boolean\n /** If `true`, renders a search icon before the input. */\n showSearchIcon?: boolean\n /** The size of the combo box. */\n size?: ComboBoxSize\n}\n\ntype AriaComboBoxPropsToOmit = \"slot\"\n\ntype AriaComboBoxPropsToInclude =\n | \"allowsEmptyCollection\"\n | \"defaultItems\"\n | \"defaultValue\"\n | \"disabledKeys\"\n | \"inputValue\"\n | \"items\"\n | \"name\"\n | \"onInputChange\"\n | \"selectionMode\"\n | \"value\"\n\nexport type ComboBoxElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n AriaComboBoxProps<T, \"single\" | \"multiple\">,\n ComboBoxProps<T>,\n AriaComboBoxPropsToOmit,\n AriaComboBoxPropsToInclude\n >\n\nfunction resolveEmptyState(value: ReactNode | (() => ReactNode)): ReactNode {\n return typeof value === \"function\" ? value() : value\n}\n\nfunction ClearButton() {\n const state = useContext(ComboBoxStateContext)\n\n return (\n <IconButton\n aria-label=\"Clear\"\n className=\"tds-combo-box-clear-button\"\n data-input-empty={!state?.inputValue ? true : undefined}\n icon={\n <Icon\n aria-hidden\n className=\"tds-combo-box-clear-icon\"\n symbol=\"general#x\"\n />\n }\n kind=\"neutral-inline\"\n onClick={() => state?.setInputValue(\"\")}\n onMouseDown={(event) => event.preventDefault()}\n tabIndex={-1}\n />\n )\n}\n\nfunction ErrorAnnouncement({ labelledBy }: { labelledBy: string }) {\n const announce = useAnnounce()\n const inputValue = useContext(ComboBoxStateContext)?.inputValue\n\n useEffect(() => {\n const timeout = setTimeout(\n () => announce({ \"aria-labelledby\": labelledBy }),\n LOADING_ANNOUNCEMENT_DELAY_MS\n )\n return () => clearTimeout(timeout)\n }, [announce, inputValue, labelledBy])\n\n return null\n}\n\nfunction FilteringAnnouncement() {\n const state = useContext(ComboBoxStateContext)\n if (!state?.isOpen) return null\n\n return <LoadingAnnouncement key={state.inputValue} message=\"Loading\" />\n}\n\n/**\n * A combo box combines a text input with a filterable popover\n * listbox, allowing users to type to search and select from a list of options.\n *\n * It supports both single and multiple selection (`selectionMode`), custom filtering,\n * and asynchronous data loading with infinite scroll capabilities (`loadingState` and `onLoadMore`).\n * Collections can be either static or dynamic, managed via the `children`, `items`,\n * or `defaultItems` props. To construct the dropdown list, compose this component\n * with `ComboBoxItem` for individual options and `ComboBoxSection` for grouping.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBox<T extends object>({\n allowsEmptyCollection = true,\n children,\n className,\n description,\n disabled,\n filter,\n hideLabel,\n invalid,\n label,\n loadingState,\n menuTrigger = \"focus\",\n onChange,\n onLoadMore,\n placeholder,\n readOnly,\n renderEmptyState = \"No results\",\n required,\n showClearButton,\n showSearchIcon,\n size = \"md\",\n ...restProps\n}: ComboBoxElementProps<T>) {\n const emptyStateId = `tds-combo-box-empty-state-${useId()}`\n const combinedClassName = classNames(\n \"tds-field tds-combo-box\",\n {\n \"tds-combo-box--lg\": size === \"lg\",\n \"tds-field--lg\": size === \"lg\",\n },\n className\n )\n\n const loadMoreItem = onLoadMore && (\n <ListBoxLoadMoreItem\n className=\"tds-combo-box-load-more\"\n isLoading={loadingState === \"loadingMore\"}\n onLoadMore={onLoadMore}\n >\n <span className=\"tds-combo-box-loading-label--hidden\">Loading more</span>\n <LoadingSpinner />\n <LoadingAnnouncement message=\"Loading more\" />\n </ListBoxLoadMoreItem>\n )\n\n const renderChildren = () => {\n if (typeof children === \"function\") {\n return (\n <Collection items={restProps.items ?? restProps.defaultItems}>\n {children}\n </Collection>\n )\n }\n return children\n }\n\n return (\n // React Aria's ComboBox is generic over selection mode (M). We instantiate\n // it with the union \"single\" | \"multiple\" so value/defaultValue/selectionMode\n // accept both shapes. onChange still needs a cast because our type is a union\n // of function types (to allow narrower handlers like\n // `setValue: (Key|null) => void`), which isn't assignable to RAC's\n // single-function signature.\n <AriaComboBox<T, \"single\" | \"multiple\">\n {...restProps}\n allowsEmptyCollection={allowsEmptyCollection}\n aria-label={hideLabel ? label : undefined}\n className={combinedClassName}\n defaultFilter={filter}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n menuTrigger={menuTrigger}\n onChange={onChange as (value: Key | Key[] | null) => void}\n >\n {!hideLabel && <Label className=\"tds-field-label\">{label}</Label>}\n <Group className=\"tds-field-control tds-combo-box-field\">\n {showSearchIcon && (\n <Icon\n aria-hidden\n className=\"tds-combo-box-search-icon\"\n symbol=\"general#search\"\n />\n )}\n <Input\n aria-invalid={invalid || undefined}\n className=\"tds-combo-box-input\"\n placeholder={placeholder}\n />\n {menuTrigger !== \"focus\" && !readOnly && (\n <Button className=\"tds-combo-box-button tds-btn tds-btn--infield\">\n <Icon aria-hidden symbol=\"general#down-caret\" />\n </Button>\n )}\n {showClearButton &&\n menuTrigger === \"focus\" &&\n !readOnly &&\n !disabled && <ClearButton />}\n </Group>\n <Popover className=\"tds-combo-box-popover\">\n <ListBox\n className=\"tds-combo-box-list\"\n renderEmptyState={\n allowsEmptyCollection\n ? () => (\n <div className=\"tds-combo-box-empty-state\" id={emptyStateId}>\n {loadingState === \"error\" && (\n <ErrorAnnouncement labelledBy={emptyStateId} />\n )}\n {loadingState === \"loading\" ? (\n <>\n <span className=\"tds-combo-box-loading-label--hidden\">\n Loading\n </span>\n <LoadingSpinner />\n <LoadingAnnouncement message=\"Loading\" />\n </>\n ) : (\n resolveEmptyState(renderEmptyState)\n )}\n </div>\n )\n : undefined\n }\n >\n {renderChildren()}\n {loadMoreItem}\n </ListBox>\n {loadingState === \"filtering\" && <FilteringAnnouncement />}\n </Popover>\n {description && (\n <Text className=\"tds-field-description\" slot=\"description\">\n <Icon\n aria-hidden\n className=\"tds-field-description-invalid-icon\"\n symbol=\"general#exclamation-triangle\"\n />\n {description}\n </Text>\n )}\n </AriaComboBox>\n )\n}\n\nexport interface ComboBoxItemProps {\n /** Disables the item. */\n disabled?: boolean\n}\n\ntype AriaListBoxItemPropsToOmit = \"isDisabled\"\n\ntype AriaListBoxItemPropsToInclude = \"onAction\" | \"textValue\" | \"value\"\n\nexport type ComboBoxItemElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n ListBoxItemProps<T>,\n ComboBoxItemProps,\n AriaListBoxItemPropsToOmit,\n AriaListBoxItemPropsToInclude\n >\n\n/**\n * A selectable option within a {@link ComboBox}. Renders as a listbox item.\n *\n * Provide an `id` (or `key` when rendering from a collection) to identify the\n * option, and `textValue` when the visible children are not plain text so\n * type-ahead and screen readers have a stable label to use.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBoxItem<T extends object>({\n className,\n disabled,\n ...restProps\n}: ComboBoxItemElementProps<T>) {\n return (\n <ListBoxItem\n {...restProps}\n className={classNames(\"tds-combo-box-list-item\", className)}\n isDisabled={disabled}\n />\n )\n}\n\nexport interface ComboBoxSectionProps {\n /** The items rendered within the section. */\n children: ReactNode\n /** Optional heading text rendered above the section's items. */\n title?: string\n}\n\ntype AriaListBoxSectionPropsToInclude = \"dependencies\"\n\nexport type ComboBoxSectionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n ListBoxSectionProps<T>,\n ComboBoxSectionProps,\n never,\n AriaListBoxSectionPropsToInclude\n >\n\n/**\n * A group of related {@link ComboBoxItem}s within a {@link ComboBox}. Renders\n * an optional `title` heading above its items.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-combobox--docs | Storybook Documentation}\n */\nexport function ComboBoxSection<T extends object>({\n children,\n className,\n title,\n ...restProps\n}: ComboBoxSectionElementProps<T>) {\n return (\n <ListBoxSection\n {...restProps}\n className={classNames(\"tds-combo-box-list-section\", className)}\n >\n {title && (\n <Header className=\"tds-combo-box-section-header\">{title}</Header>\n )}\n {children}\n </ListBoxSection>\n )\n}\n"],"names":["AriaComboBox"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/date-picker/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAA;AAC1B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,aAAa,CAAA;AAEpB,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/date-picker/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAA;AAC1B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,aAAa,CAAA;AAEpB,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAGhF,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAwB,MAAM,OAAO,CAAA;AAGnE,OAAO,EAUL,KAAK,eAAe,IAAI,mBAAmB,EAM5C,MAAM,kCAAkC,CAAA;AAYzC,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAAA;AAExC,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,CAAA;AAepD,MAAM,WAAW,eAAe;IAC9B,4GAA4G;IAC5G,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,wFAAwF;IACxF,YAAY,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACzC,gGAAgG;IAChG,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;IACtE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAA;IACjD,qGAAqG;IACrG,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAA;IAChD,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,GAAG,CAAC,EAAE,mBAAmB,CAAA;IACzB,uEAAuE;IACvE,GAAG,CAAC,EAAE,mBAAmB,CAAA;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAA;IAC5C,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,oEAAoE;IACpE,KAAK,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;CACnC;AAED,KAAK,yBAAyB,GAC1B,UAAU,GACV,aAAa,GACb,aAAa,GACb,cAAc,GACd,WAAW,GACX,cAAc,GACd,kBAAkB,GAClB,qBAAqB,GACrB,yBAAyB,GACzB,MAAM,CAAA;AAEV,KAAK,4BAA4B,GAAG,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAA;AAEtE,MAAM,MAAM,sBAAsB,GAAG,+BAA+B,CAClE,mBAAmB,CAAC,SAAS,CAAC,EAC9B,eAAe,EACf,yBAAyB,EACzB,4BAA4B,CAC7B,CAAA;AA0QD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAA8C,EAC9C,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,KAAK,EACL,GAAG,EACH,GAAG,EACH,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,IAAW,EACX,KAAK,EACL,uBAA+B,EAC/B,GAAG,SAAS,EACb,EAAE,sBAAsB,qBA4HxB;yBAjJe,UAAU"}
|
|
@@ -2,8 +2,10 @@ import { CalendarDate as $2aaf608024c21ca1$export$99faa760c7908e4f } from './../
|
|
|
2
2
|
import { today as $ad063034c8620db8$export$d0bdf45af03a6ea3, getLocalTimeZone as $ad063034c8620db8$export$aa8b41735afcabd2, isSameDay as $ad063034c8620db8$export$ea39ec197993aef0 } from './../../ext/@internationalized/date/dist/private/queries.js';
|
|
3
3
|
import { parseDate as $58246871e4652552$export$6b862160d295c8e } from './../../ext/@internationalized/date/dist/private/string.js';
|
|
4
4
|
import Icon from '../../utilities/Icon.js';
|
|
5
|
+
import { useDateFieldLocale } from '../../utilities/useDateFieldLocale.js';
|
|
5
6
|
import classNames from 'classnames';
|
|
6
7
|
import React, { useState, useContext } from 'react';
|
|
8
|
+
import { I18nProvider } from 'react-aria/I18nProvider';
|
|
7
9
|
import { CalendarStateContext } from 'react-aria-components/Calendar';
|
|
8
10
|
import { DatePicker as DatePicker$1, Label, Group, DateInput, DateSegment, Button, Popover, Calendar, Text, CalendarGrid, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell } from 'react-aria-components/DatePicker';
|
|
9
11
|
import { Dialog } from 'react-aria-components/Dialog';
|
|
@@ -153,6 +155,7 @@ function DatePicker({ className, defaultValue, description, disabled, firstDayOf
|
|
|
153
155
|
onChange,
|
|
154
156
|
value,
|
|
155
157
|
});
|
|
158
|
+
const dateFieldLocale = useDateFieldLocale();
|
|
156
159
|
return (React.createElement(DatePicker$1, { ...restProps, "aria-label": hideLabel ? label : undefined, className: combinedClassName, isDateUnavailable: isDateUnavailable, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, maxValue: convertedMax, minValue: convertedMin, onBlur: (event) => {
|
|
157
160
|
onBlur?.(event);
|
|
158
161
|
if (!formatDateOnBlur || !computedValue)
|
|
@@ -169,20 +172,21 @@ function DatePicker({ className, defaultValue, description, disabled, firstDayOf
|
|
|
169
172
|
}, value: computedValue },
|
|
170
173
|
!hideLabel && React.createElement(Label, { className: "tds-field-label" }, label),
|
|
171
174
|
React.createElement(Group, { "aria-invalid": invalid || undefined, className: "tds-field-control tds-date-picker-field" },
|
|
172
|
-
React.createElement(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
175
|
+
React.createElement(I18nProvider, { locale: dateFieldLocale },
|
|
176
|
+
React.createElement(DateInput, { className: "tds-date-picker-input" }, (segment) => (React.createElement(DateSegment, { "aria-invalid": invalid || undefined, className: segment.type === "literal"
|
|
177
|
+
? "tds-field-date-segment-separator"
|
|
178
|
+
: "tds-field-date-segment", segment: segment.type === "year" &&
|
|
179
|
+
!segment.isPlaceholder &&
|
|
180
|
+
segment.value != null &&
|
|
181
|
+
alwaysShowFourDigitYear
|
|
182
|
+
? {
|
|
183
|
+
...segment,
|
|
184
|
+
text: new Intl.NumberFormat(undefined, {
|
|
185
|
+
minimumIntegerDigits: 4,
|
|
186
|
+
useGrouping: false,
|
|
187
|
+
}).format(segment.value),
|
|
188
|
+
}
|
|
189
|
+
: segment })))),
|
|
186
190
|
React.createElement(Button, { className: "tds-btn tds-btn--infield tds-date-picker-button" },
|
|
187
191
|
React.createElement(Icon, { "aria-hidden": true, symbol: "general#calendar" }))),
|
|
188
192
|
React.createElement(Popover, { className: classNames("tds-date-picker-popover", {
|