@planningcenter/tapestry 4.11.0 → 4.12.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.
Files changed (104) hide show
  1. package/dist/components/DataTable/DataTable.d.ts +47 -13
  2. package/dist/components/DataTable/DataTable.d.ts.map +1 -1
  3. package/dist/components/DataTable/DataTable.js +29 -23
  4. package/dist/components/DataTable/DataTable.js.map +1 -1
  5. package/dist/components/DataTable/DeleteSavedViewAlertDialog.d.ts +14 -0
  6. package/dist/components/DataTable/DeleteSavedViewAlertDialog.d.ts.map +1 -0
  7. package/dist/components/DataTable/DeleteSavedViewAlertDialog.js +10 -0
  8. package/dist/components/DataTable/DeleteSavedViewAlertDialog.js.map +1 -0
  9. package/dist/components/DataTable/ManageSavedViewsButton.d.ts +4 -1
  10. package/dist/components/DataTable/ManageSavedViewsButton.d.ts.map +1 -1
  11. package/dist/components/DataTable/ManageSavedViewsButton.js +3 -7
  12. package/dist/components/DataTable/ManageSavedViewsButton.js.map +1 -1
  13. package/dist/components/DataTable/ManageSavedViewsModal.d.ts +8 -1
  14. package/dist/components/DataTable/ManageSavedViewsModal.d.ts.map +1 -1
  15. package/dist/components/DataTable/ManageSavedViewsModal.js +116 -5
  16. package/dist/components/DataTable/ManageSavedViewsModal.js.map +1 -1
  17. package/dist/components/DataTable/ManageSavedViewsModal.module.css.js +4 -0
  18. package/dist/components/DataTable/ManageSavedViewsModal.module.css.js.map +1 -0
  19. package/dist/components/DataTable/NewSavedViewModal.d.ts +4 -1
  20. package/dist/components/DataTable/NewSavedViewModal.d.ts.map +1 -1
  21. package/dist/components/DataTable/NewSavedViewModal.js.map +1 -1
  22. package/dist/components/DataTable/ResultsCount.d.ts +9 -0
  23. package/dist/components/DataTable/ResultsCount.d.ts.map +1 -1
  24. package/dist/components/DataTable/ResultsCount.js +1 -1
  25. package/dist/components/DataTable/ResultsCount.js.map +1 -1
  26. package/dist/components/DataTable/SavedViewsBar.d.ts +14 -6
  27. package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
  28. package/dist/components/DataTable/SavedViewsBar.js +162 -45
  29. package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
  30. package/dist/components/DataTable/TableActions.d.ts.map +1 -1
  31. package/dist/components/DataTable/TableActions.js +4 -6
  32. package/dist/components/DataTable/TableActions.js.map +1 -1
  33. package/dist/components/DataTable/ViewSettingsToggle.d.ts.map +1 -1
  34. package/dist/components/DataTable/ViewSettingsToggle.js +2 -4
  35. package/dist/components/DataTable/ViewSettingsToggle.js.map +1 -1
  36. package/dist/components/DataTable/index.d.ts +1 -1
  37. package/dist/components/DataTable/index.d.ts.map +1 -1
  38. package/dist/components/DataTable/savedViews.d.ts +16 -15
  39. package/dist/components/DataTable/savedViews.d.ts.map +1 -1
  40. package/dist/components/DataTable/savedViews.js +28 -6
  41. package/dist/components/DataTable/savedViews.js.map +1 -1
  42. package/dist/components/DataTable/useActiveSavedView.d.ts +1 -1
  43. package/dist/components/DataTable/useActiveSavedView.d.ts.map +1 -1
  44. package/dist/components/DataTable/useActiveSavedView.js +9 -3
  45. package/dist/components/DataTable/useActiveSavedView.js.map +1 -1
  46. package/dist/components/DataTable/useFilterAnnouncement.d.ts +24 -0
  47. package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +1 -0
  48. package/dist/components/DataTable/useFilterAnnouncement.js +49 -0
  49. package/dist/components/DataTable/useFilterAnnouncement.js.map +1 -0
  50. package/dist/components/DataTable/useUpdateSavedViewName.d.ts +7 -0
  51. package/dist/components/DataTable/useUpdateSavedViewName.d.ts.map +1 -0
  52. package/dist/components/DataTable/useUpdateSavedViewName.js +12 -0
  53. package/dist/components/DataTable/useUpdateSavedViewName.js.map +1 -0
  54. package/dist/components/button/ActionsDropdownIconButton.d.ts +17 -9
  55. package/dist/components/button/ActionsDropdownIconButton.d.ts.map +1 -1
  56. package/dist/components/button/ActionsDropdownIconButton.js +5 -2
  57. package/dist/components/button/ActionsDropdownIconButton.js.map +1 -1
  58. package/dist/components/button/DropdownIconButton.d.ts +4 -5
  59. package/dist/components/button/DropdownIconButton.d.ts.map +1 -1
  60. package/dist/components/button/DropdownIconButton.js +2 -1
  61. package/dist/components/button/DropdownIconButton.js.map +1 -1
  62. package/dist/components/button/IconButton.d.ts +33 -10
  63. package/dist/components/button/IconButton.d.ts.map +1 -1
  64. package/dist/components/button/IconButton.js +8 -2
  65. package/dist/components/button/IconButton.js.map +1 -1
  66. package/dist/components/button/ToggleIconButton.d.ts +2 -2
  67. package/dist/components/button/ToggleIconButton.d.ts.map +1 -1
  68. package/dist/components/button/ToggleIconButton.js.map +1 -1
  69. package/dist/components/button/index.d.ts +1 -0
  70. package/dist/components/button/index.d.ts.map +1 -1
  71. package/dist/components/combo-box/ComboBox.d.ts +6 -0
  72. package/dist/components/combo-box/ComboBox.d.ts.map +1 -1
  73. package/dist/components/combo-box/ComboBox.js.map +1 -1
  74. package/dist/components/internal/alert-dialog/AlertDialog.d.ts +56 -0
  75. package/dist/components/internal/alert-dialog/AlertDialog.d.ts.map +1 -0
  76. package/dist/components/internal/alert-dialog/AlertDialog.js +68 -0
  77. package/dist/components/internal/alert-dialog/AlertDialog.js.map +1 -0
  78. package/dist/components/internal/alert-dialog/index.d.ts +5 -0
  79. package/dist/components/internal/alert-dialog/index.d.ts.map +1 -0
  80. package/dist/components/internal/tooltip/Tooltip.d.ts +9 -3
  81. package/dist/components/internal/tooltip/Tooltip.d.ts.map +1 -1
  82. package/dist/components/internal/tooltip/Tooltip.js +63 -8
  83. package/dist/components/internal/tooltip/Tooltip.js.map +1 -1
  84. package/dist/components/pane/PaneDivider.d.ts +5 -2
  85. package/dist/components/pane/PaneDivider.d.ts.map +1 -1
  86. package/dist/components/pane/PaneDivider.js +2 -2
  87. package/dist/components/pane/PaneDivider.js.map +1 -1
  88. package/dist/index.css +27 -27
  89. package/dist/index.css.map +1 -1
  90. package/dist/reactRender.css +1301 -1189
  91. package/dist/reactRender.css.map +1 -1
  92. package/dist/reactRenderLegacy.css +1301 -1189
  93. package/dist/reactRenderLegacy.css.map +1 -1
  94. package/dist/tapestryMount.css +1301 -1189
  95. package/dist/tapestryMount.css.map +1 -1
  96. package/dist/tapestryMountLegacy.css +1301 -1189
  97. package/dist/tapestryMountLegacy.css.map +1 -1
  98. package/dist/unstable.css +112 -0
  99. package/dist/unstable.css.map +1 -1
  100. package/dist/utilities/useAnnounce.d.ts +15 -0
  101. package/dist/utilities/useAnnounce.d.ts.map +1 -0
  102. package/dist/utilities/useAnnounce.js +27 -0
  103. package/dist/utilities/useAnnounce.js.map +1 -0
  104. package/package.json +3 -4
@@ -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 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 /**\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 * - 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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"}
@@ -0,0 +1,56 @@
1
+ import "../../modal/index.css";
2
+ import "./index.css";
3
+ import React, { type HTMLAttributes } from "react";
4
+ export type AlertDialogType = "danger" | "error" | "info" | "success" | "warning";
5
+ export interface AlertDialogProps {
6
+ /** Default `'Cancel'`. The cancel button's label. */
7
+ cancelButtonLabel?: string;
8
+ /**
9
+ * The content explaining the alert. Becomes the alert's accessible
10
+ * description. A string is wrapped in a `<p>`.
11
+ */
12
+ children: React.ReactNode;
13
+ /** Default `'Okay'`. The confirm button's label. */
14
+ confirmButtonLabel?: string;
15
+ /** Default `false`. `true` hides the cancel button, for simple notifications. */
16
+ hideCancel?: boolean;
17
+ /** Fires when the cancel button is clicked, or Esc is pressed. */
18
+ onCancel?: () => void;
19
+ /**
20
+ * Fires when the confirm button is clicked, or Esc is pressed when
21
+ * `hideCancel` is set.
22
+ */
23
+ onConfirm?: () => void;
24
+ /** Controls the alert. */
25
+ open: boolean;
26
+ /** The alert's accessible name, displayed as the heading. */
27
+ title: string;
28
+ /**
29
+ * Default `'warning'`. Sets the status icon and its color. `'danger'` also
30
+ * renders the confirm button as a `delete` button.
31
+ */
32
+ type?: AlertDialogType;
33
+ }
34
+ export type AlertDialogElementProps = Omit<HTMLAttributes<HTMLElement>, keyof AlertDialogProps | "role"> & AlertDialogProps;
35
+ /**
36
+ * A modal dialog that interrupts the user with an important message and asks
37
+ * them to confirm or cancel. Renders with `role="alertdialog"` and shares
38
+ * `Modal`'s overlay, frame, and animation styles.
39
+ *
40
+ * Neither button closes the alert on its own — close it by setting `open` to
41
+ * `false` from `onConfirm` and `onCancel`.
42
+ *
43
+ * Esc fires `onCancel`, or `onConfirm` when `hideCancel` is set, so the alert
44
+ * is always dismissible from the keyboard. The exception is a `danger` alert
45
+ * with `hideCancel`, where Esc does nothing so it can't confirm a destructive
46
+ * action. Backdrop clicks never dismiss the alert.
47
+ *
48
+ * Rest props, including `data-*`, land on the dialog. The buttons carry
49
+ * `data-alert-dialog-action="cancel" | "confirm"`, so non-React environments
50
+ * (e.g. Rails + Stimulus) can handle their clicks from the dialog.
51
+ *
52
+ * @component
53
+ * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/internal-alertdialog--docs | Storybook Documentation}
54
+ */
55
+ export declare const AlertDialog: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLElement>, "role" | keyof AlertDialogProps> & AlertDialogProps & React.RefAttributes<HTMLElement>>;
56
+ //# sourceMappingURL=AlertDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/alert-dialog/AlertDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAA;AAC9B,OAAO,aAAa,CAAA;AAMpB,OAAO,KAAK,EAAE,EAAc,KAAK,cAAc,EAAE,MAAM,OAAO,CAAA;AAI9D,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,SAAS,GACT,SAAS,CAAA;AAEb,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,0BAA0B;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,cAAc,CAAC,WAAW,CAAC,EAC3B,MAAM,gBAAgB,GAAG,MAAM,CAChC,GACC,gBAAgB,CAAA;AAUlB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,iKA+EvB,CAAA"}
@@ -0,0 +1,68 @@
1
+ import '../../button/ActionsDropdownIconButton.js';
2
+ import { Button } from '../../button/Button.js';
3
+ import '../../button/DropdownButton.js';
4
+ import '../../button/DropdownIconButton.js';
5
+ import '../../button/IconButton.js';
6
+ import '../../button/LoadingButton.js';
7
+ import '../../button/PageHeaderActionsDropdownButton.js';
8
+ import Icon from '../../../utilities/Icon.js';
9
+ import { useId } from '../../../utilities/useId.js';
10
+ import classNames from 'classnames';
11
+ import React__default, { forwardRef } from 'react';
12
+ import { Dialog } from 'react-aria-components/Dialog';
13
+ import { ModalOverlay, Modal } from 'react-aria-components/Modal';
14
+
15
+ const ICON_SYMBOLS = {
16
+ danger: "general#exclamation-triangle",
17
+ error: "general#x-circle",
18
+ info: "general#info-circle",
19
+ success: "general#check-circle",
20
+ warning: "general#exclamation-triangle",
21
+ };
22
+ /**
23
+ * A modal dialog that interrupts the user with an important message and asks
24
+ * them to confirm or cancel. Renders with `role="alertdialog"` and shares
25
+ * `Modal`'s overlay, frame, and animation styles.
26
+ *
27
+ * Neither button closes the alert on its own — close it by setting `open` to
28
+ * `false` from `onConfirm` and `onCancel`.
29
+ *
30
+ * Esc fires `onCancel`, or `onConfirm` when `hideCancel` is set, so the alert
31
+ * is always dismissible from the keyboard. The exception is a `danger` alert
32
+ * with `hideCancel`, where Esc does nothing so it can't confirm a destructive
33
+ * action. Backdrop clicks never dismiss the alert.
34
+ *
35
+ * Rest props, including `data-*`, land on the dialog. The buttons carry
36
+ * `data-alert-dialog-action="cancel" | "confirm"`, so non-React environments
37
+ * (e.g. Rails + Stimulus) can handle their clicks from the dialog.
38
+ *
39
+ * @component
40
+ * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/internal-alertdialog--docs | Storybook Documentation}
41
+ */
42
+ const AlertDialog = forwardRef(function AlertDialog({ cancelButtonLabel = "Cancel", children, className, confirmButtonLabel = "Okay", hideCancel = false, id, onCancel, onConfirm, open, title, type = "warning", ...restProps }, ref) {
43
+ const stableId = useId();
44
+ const alertDialogId = id || `tds-alert-dialog-${stableId}`;
45
+ const titleId = `${alertDialogId}-title`;
46
+ const bodyId = `${alertDialogId}-body`;
47
+ return (React__default.createElement(ModalOverlay, { className: "tds-modal-overlay", isDismissable: false, isKeyboardDismissDisabled: hideCancel && type === "danger", isOpen: open, onOpenChange: (isOpen) => {
48
+ if (isOpen)
49
+ return;
50
+ if (hideCancel)
51
+ onConfirm?.();
52
+ else
53
+ onCancel?.();
54
+ } },
55
+ React__default.createElement(Modal, { className: "tds-modal-frame" },
56
+ React__default.createElement(Dialog, { ...restProps, ref: ref, "aria-describedby": bodyId, "aria-labelledby": titleId, className: classNames("tds-modal", "tds-alert-dialog", className), id: alertDialogId, role: "alertdialog" },
57
+ React__default.createElement("header", { className: "tds-alert-dialog-header" },
58
+ React__default.createElement(Icon, { "aria-hidden": true, className: `tds-alert-dialog-icon tds-alert-dialog-icon--${type}`, symbol: ICON_SYMBOLS[type] }),
59
+ React__default.createElement("h2", { className: "tds-alert-dialog-title", id: titleId }, title)),
60
+ React__default.createElement("div", { className: "tds-alert-dialog-body", id: bodyId }, typeof children === "string" ? React__default.createElement("p", null, children) : children),
61
+ React__default.createElement("footer", { className: "tds-modal-footer tds-alert-dialog-footer" },
62
+ !hideCancel && (React__default.createElement(Button, { "data-alert-dialog-action": "cancel", kind: "ghost", label: cancelButtonLabel, onClick: onCancel })),
63
+ React__default.createElement(Button, { "data-alert-dialog-action": "confirm", kind: type === "danger" ? "delete" : "primary", label: confirmButtonLabel, onClick: onConfirm }))))));
64
+ });
65
+ AlertDialog.displayName = "AlertDialog";
66
+
67
+ export { AlertDialog };
68
+ //# sourceMappingURL=AlertDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlertDialog.js","sources":["../../../../src/components/internal/alert-dialog/AlertDialog.tsx"],"sourcesContent":["import \"../../modal/index.css\"\nimport \"./index.css\"\n\nimport { Button } from \"@components/button\"\nimport Icon from \"@utilities/Icon\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { forwardRef, type HTMLAttributes } from \"react\"\nimport { Dialog } from \"react-aria-components/Dialog\"\nimport { Modal as AriaModal, ModalOverlay } from \"react-aria-components/Modal\"\n\nexport type AlertDialogType =\n | \"danger\"\n | \"error\"\n | \"info\"\n | \"success\"\n | \"warning\"\n\nexport interface AlertDialogProps {\n /** Default `'Cancel'`. The cancel button's label. */\n cancelButtonLabel?: string\n /**\n * The content explaining the alert. Becomes the alert's accessible\n * description. A string is wrapped in a `<p>`.\n */\n children: React.ReactNode\n /** Default `'Okay'`. The confirm button's label. */\n confirmButtonLabel?: string\n /** Default `false`. `true` hides the cancel button, for simple notifications. */\n hideCancel?: boolean\n /** Fires when the cancel button is clicked, or Esc is pressed. */\n onCancel?: () => void\n /**\n * Fires when the confirm button is clicked, or Esc is pressed when\n * `hideCancel` is set.\n */\n onConfirm?: () => void\n /** Controls the alert. */\n open: boolean\n /** The alert's accessible name, displayed as the heading. */\n title: string\n /**\n * Default `'warning'`. Sets the status icon and its color. `'danger'` also\n * renders the confirm button as a `delete` button.\n */\n type?: AlertDialogType\n}\n\nexport type AlertDialogElementProps = Omit<\n HTMLAttributes<HTMLElement>,\n keyof AlertDialogProps | \"role\"\n> &\n AlertDialogProps\n\nconst ICON_SYMBOLS: Record<AlertDialogType, string> = {\n danger: \"general#exclamation-triangle\",\n error: \"general#x-circle\",\n info: \"general#info-circle\",\n success: \"general#check-circle\",\n warning: \"general#exclamation-triangle\",\n}\n\n/**\n * A modal dialog that interrupts the user with an important message and asks\n * them to confirm or cancel. Renders with `role=\"alertdialog\"` and shares\n * `Modal`'s overlay, frame, and animation styles.\n *\n * Neither button closes the alert on its own — close it by setting `open` to\n * `false` from `onConfirm` and `onCancel`.\n *\n * Esc fires `onCancel`, or `onConfirm` when `hideCancel` is set, so the alert\n * is always dismissible from the keyboard. The exception is a `danger` alert\n * with `hideCancel`, where Esc does nothing so it can't confirm a destructive\n * action. Backdrop clicks never dismiss the alert.\n *\n * Rest props, including `data-*`, land on the dialog. The buttons carry\n * `data-alert-dialog-action=\"cancel\" | \"confirm\"`, so non-React environments\n * (e.g. Rails + Stimulus) can handle their clicks from the dialog.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/internal-alertdialog--docs | Storybook Documentation}\n */\nexport const AlertDialog = forwardRef<HTMLElement, AlertDialogElementProps>(\n function AlertDialog(\n {\n cancelButtonLabel = \"Cancel\",\n children,\n className,\n confirmButtonLabel = \"Okay\",\n hideCancel = false,\n id,\n onCancel,\n onConfirm,\n open,\n title,\n type = \"warning\",\n ...restProps\n }: AlertDialogElementProps,\n ref\n ) {\n const stableId = useId()\n const alertDialogId = id || `tds-alert-dialog-${stableId}`\n const titleId = `${alertDialogId}-title`\n const bodyId = `${alertDialogId}-body`\n\n return (\n <ModalOverlay\n className=\"tds-modal-overlay\"\n isDismissable={false}\n isKeyboardDismissDisabled={hideCancel && type === \"danger\"}\n isOpen={open}\n onOpenChange={(isOpen) => {\n if (isOpen) return\n if (hideCancel) onConfirm?.()\n else onCancel?.()\n }}\n >\n <AriaModal className=\"tds-modal-frame\">\n <Dialog\n {...restProps}\n ref={ref}\n aria-describedby={bodyId}\n aria-labelledby={titleId}\n className={classNames(\"tds-modal\", \"tds-alert-dialog\", className)}\n id={alertDialogId}\n role=\"alertdialog\"\n >\n <header className=\"tds-alert-dialog-header\">\n <Icon\n aria-hidden\n className={`tds-alert-dialog-icon tds-alert-dialog-icon--${type}`}\n symbol={ICON_SYMBOLS[type]}\n />\n <h2 className=\"tds-alert-dialog-title\" id={titleId}>\n {title}\n </h2>\n </header>\n <div className=\"tds-alert-dialog-body\" id={bodyId}>\n {typeof children === \"string\" ? <p>{children}</p> : children}\n </div>\n <footer className=\"tds-modal-footer tds-alert-dialog-footer\">\n {!hideCancel && (\n <Button\n data-alert-dialog-action=\"cancel\"\n kind=\"ghost\"\n label={cancelButtonLabel}\n onClick={onCancel}\n />\n )}\n <Button\n data-alert-dialog-action=\"confirm\"\n kind={type === \"danger\" ? \"delete\" : \"primary\"}\n label={confirmButtonLabel}\n onClick={onConfirm}\n />\n </footer>\n </Dialog>\n </AriaModal>\n </ModalOverlay>\n )\n }\n)\n\nAlertDialog.displayName = \"AlertDialog\"\n"],"names":["React","AriaModal"],"mappings":";;;;;;;;;;;;;;AAsDA,MAAM,YAAY,GAAoC;AACpD,IAAA,MAAM,EAAE,8BAA8B;AACtC,IAAA,KAAK,EAAE,kBAAkB;AACzB,IAAA,IAAI,EAAE,qBAAqB;AAC3B,IAAA,OAAO,EAAE,sBAAsB;AAC/B,IAAA,OAAO,EAAE,8BAA8B;CACxC;AAED;;;;;;;;;;;;;;;;;;;AAmBG;MACU,WAAW,GAAG,UAAU,CACnC,SAAS,WAAW,CAClB,EACE,iBAAiB,GAAG,QAAQ,EAC5B,QAAQ,EACR,SAAS,EACT,kBAAkB,GAAG,MAAM,EAC3B,UAAU,GAAG,KAAK,EAClB,EAAE,EACF,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,KAAK,EACL,IAAI,GAAG,SAAS,EAChB,GAAG,SAAS,EACY,EAC1B,GAAG,EAAA;AAEH,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;AACxB,IAAA,MAAM,aAAa,GAAG,EAAE,IAAI,CAAA,iBAAA,EAAoB,QAAQ,EAAE;AAC1D,IAAA,MAAM,OAAO,GAAG,CAAA,EAAG,aAAa,QAAQ;AACxC,IAAA,MAAM,MAAM,GAAG,CAAA,EAAG,aAAa,OAAO;AAEtC,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EACX,SAAS,EAAC,mBAAmB,EAC7B,aAAa,EAAE,KAAK,EACpB,yBAAyB,EAAE,UAAU,IAAI,IAAI,KAAK,QAAQ,EAC1D,MAAM,EAAE,IAAI,EACZ,YAAY,EAAE,CAAC,MAAM,KAAI;AACvB,YAAA,IAAI,MAAM;gBAAE;AACZ,YAAA,IAAI,UAAU;gBAAE,SAAS,IAAI;;gBACxB,QAAQ,IAAI;QACnB,CAAC,EAAA;AAED,QAAAA,cAAA,CAAA,aAAA,CAACC,KAAS,EAAA,EAAC,SAAS,EAAC,iBAAiB,EAAA;AACpC,YAAAD,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAA,GACD,SAAS,EACb,GAAG,EAAE,GAAG,EAAA,kBAAA,EACU,MAAM,EAAA,iBAAA,EACP,OAAO,EACxB,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACjE,EAAE,EAAE,aAAa,EACjB,IAAI,EAAC,aAAa,EAAA;gBAElBA,cAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,yBAAyB,EAAA;AACzC,oBAAAA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAEH,SAAS,EAAE,gDAAgD,IAAI,CAAA,CAAE,EACjE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAA,CAC1B;oBACFA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,wBAAwB,EAAC,EAAE,EAAE,OAAO,EAAA,EAC/C,KAAK,CACH,CACE;gBACTA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uBAAuB,EAAC,EAAE,EAAE,MAAM,EAAA,EAC9C,OAAO,QAAQ,KAAK,QAAQ,GAAGA,cAAA,CAAA,aAAA,CAAA,GAAA,EAAA,IAAA,EAAI,QAAQ,CAAK,GAAG,QAAQ,CACxD;gBACNA,cAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,0CAA0C,EAAA;oBACzD,CAAC,UAAU,KACVA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAA,0BAAA,EACoB,QAAQ,EACjC,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,QAAQ,GACjB,CACH;AACD,oBAAAA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAA,0BAAA,EACoB,SAAS,EAClC,IAAI,EAAE,IAAI,KAAK,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAC9C,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,SAAS,EAAA,CAClB,CACK,CACF,CACC,CACC;AAEnB,CAAC;AAGH,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
@@ -0,0 +1,5 @@
1
+ import "../../modal/index.css";
2
+ import "./index.css";
3
+ export type { AlertDialogElementProps, AlertDialogProps, AlertDialogType, } from "./AlertDialog";
4
+ export { AlertDialog } from "./AlertDialog";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/alert-dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAA;AAC9B,OAAO,aAAa,CAAA;AAEpB,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,GAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
@@ -15,6 +15,12 @@ export interface TooltipProps {
15
15
  content: string;
16
16
  /** Where the tooltip renders relative to the trigger. Default `'bottom start'`. */
17
17
  placement?: Placement;
18
+ /**
19
+ * Shows the tooltip on screen only. The tooltip is hidden from assistive
20
+ * tech and not linked to the trigger, so the trigger must carry its own
21
+ * name (e.g. `aria-label`).
22
+ */
23
+ visualOnly?: boolean;
18
24
  }
19
25
  /**
20
26
  * Shows a short hover/focus hint next to a trigger. Built from React Aria's
@@ -22,10 +28,10 @@ export interface TooltipProps {
22
28
  * that component unmounts its content entirely while closed, so a screen
23
29
  * reader's virtual cursor never gets access to the description unless real
24
30
  * DOM focus lands on the trigger. This keeps the tooltip content always
25
- * mounted and wires `aria-describedby` unconditionally, toggling only CSS
26
- * visibility.
31
+ * mounted and wires `aria-describedby` (unless `visualOnly`), toggling only
32
+ * CSS visibility.
27
33
  */
28
- export declare function Tooltip({ children, content, placement, }: TooltipProps): React.JSX.Element;
34
+ export declare function Tooltip({ children, content, placement, visualOnly, }: TooltipProps): React.JSX.Element;
29
35
  export declare namespace Tooltip {
30
36
  var displayName: string;
31
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/tooltip/Tooltip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,KAAK,YAAY,EAAU,MAAM,OAAO,CAAA;AAExD,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,+BAA+B,CAAA;AActC,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,YAAY,CAAA;IACtB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,OAAO,EACP,SAA0B,GAC3B,EAAE,YAAY,qBAyEd;yBA7Ee,OAAO"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../src/components/internal/tooltip/Tooltip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,KAAK,YAAY,EAAU,MAAM,OAAO,CAAA;AAExD,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,+BAA+B,CAAA;AActC,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,YAAY,CAAA;IACtB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,OAAO,EACP,SAA0B,EAC1B,UAAkB,GACnB,EAAE,YAAY,qBA0Ed;yBA/Ee,OAAO"}
@@ -1,12 +1,67 @@
1
1
  import { tokens } from '@planningcenter/tapestry-tokens/tokens';
2
- import 'react';
3
- import 'classnames';
4
- import 'react-aria/Overlay';
5
- import 'react-aria/useOverlayPosition';
6
- import 'react-aria/useTooltipTrigger';
7
- import 'react-stately/useTooltipTriggerState';
8
- import './TooltipTriggerContext.js';
2
+ import { useId } from '../../../utilities/useId.js';
3
+ import classNames from 'classnames';
4
+ import React, { useRef } from 'react';
5
+ import { Overlay } from 'react-aria/Overlay';
6
+ import { useOverlayPosition } from 'react-aria/useOverlayPosition';
7
+ import { useTooltipTrigger, useTooltip } from 'react-aria/useTooltipTrigger';
8
+ import { useTooltipTriggerState } from 'react-stately/useTooltipTriggerState';
9
+ import { TooltipTriggerContext } from './TooltipTriggerContext.js';
9
10
 
10
- parseFloat(tokens["--t-focus-ring-offset"]) +
11
+ // Single source of truth for the arrow's dimensions -- index.css reads these
12
+ // via --tds-tooltip-arrow-size/--tds-tooltip-arrow-depth instead of its own literals.
13
+ const ARROW_SIZE = 10;
14
+ const ARROW_DEPTH = 5;
15
+ const FOCUS_RING_REACH = parseFloat(tokens["--t-focus-ring-offset"]) +
11
16
  parseFloat(tokens["--t-focus-ring-width"]);
17
+ /**
18
+ * Shows a short hover/focus hint next to a trigger. Built from React Aria's
19
+ * tooltip hooks rather than `react-aria-components`'s `<Tooltip>`, because
20
+ * that component unmounts its content entirely while closed, so a screen
21
+ * reader's virtual cursor never gets access to the description unless real
22
+ * DOM focus lands on the trigger. This keeps the tooltip content always
23
+ * mounted and wires `aria-describedby` (unless `visualOnly`), toggling only
24
+ * CSS visibility.
25
+ */
26
+ function Tooltip({ children, content, placement = "bottom start", visualOnly = false, }) {
27
+ const triggerRef = useRef(null);
28
+ const overlayRef = useRef(null);
29
+ const tooltipId = `tds-tooltip-${useId()}`;
30
+ const state = useTooltipTriggerState();
31
+ const { triggerProps } = useTooltipTrigger({}, state, triggerRef);
32
+ const { tooltipProps: ariaTooltipProps } = useTooltip({ id: tooltipId }, state);
33
+ const { arrowProps, overlayProps, placement: resolvedPlacement, } = useOverlayPosition({
34
+ arrowSize: ARROW_SIZE,
35
+ isOpen: state.isOpen,
36
+ offset: ARROW_DEPTH + FOCUS_RING_REACH,
37
+ onClose: () => state.close(true),
38
+ overlayRef,
39
+ placement,
40
+ targetRef: triggerRef,
41
+ });
42
+ const contextValue = {
43
+ ref: triggerRef,
44
+ triggerProps: {
45
+ ...triggerProps,
46
+ "aria-describedby": visualOnly ? undefined : tooltipId,
47
+ },
48
+ };
49
+ return (React.createElement(React.Fragment, null,
50
+ React.createElement(TooltipTriggerContext.Provider, { value: contextValue }, children),
51
+ React.createElement(Overlay, { disableFocusManagement: true },
52
+ React.createElement("div", { ...ariaTooltipProps, ...overlayProps, ref: overlayRef, "aria-hidden": visualOnly || undefined, className: classNames("tds-tooltip", {
53
+ "tds-tooltip--open": state.isOpen,
54
+ }), "data-placement": resolvedPlacement, style: {
55
+ ...overlayProps.style,
56
+ "--tds-tooltip-arrow-depth-raw": `${ARROW_DEPTH}px`,
57
+ "--tds-tooltip-arrow-size-raw": `${ARROW_SIZE}px`,
58
+ } },
59
+ content,
60
+ React.createElement("div", { className: "tds-tooltip-arrow", ...arrowProps },
61
+ React.createElement("svg", { "aria-hidden": true, className: "tds-tooltip-arrow-icon", role: "img", viewBox: `0 0 ${ARROW_SIZE} ${ARROW_DEPTH}` },
62
+ React.createElement("polygon", { points: `${ARROW_SIZE / 2},0 0,${ARROW_DEPTH} ${ARROW_SIZE},${ARROW_DEPTH}` })))))));
63
+ }
64
+ Tooltip.displayName = "Tooltip";
65
+
66
+ export { Tooltip };
12
67
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/internal/tooltip/Tooltip.tsx"],"sourcesContent":["import { tokens } from \"@planningcenter/tapestry-tokens/tokens\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type ReactElement, useRef } from \"react\"\nimport { Overlay } from \"react-aria/Overlay\"\nimport {\n type Placement,\n useOverlayPosition,\n} from \"react-aria/useOverlayPosition\"\nimport { useTooltip, useTooltipTrigger } from \"react-aria/useTooltipTrigger\"\nimport { useTooltipTriggerState } from \"react-stately/useTooltipTriggerState\"\n\nimport { TooltipTriggerContext } from \"./TooltipTriggerContext\"\n\n// Single source of truth for the arrow's dimensions -- index.css reads these\n// via --tds-tooltip-arrow-size/--tds-tooltip-arrow-depth instead of its own literals.\nconst ARROW_SIZE = 10\nconst ARROW_DEPTH = 5\nconst FOCUS_RING_REACH =\n parseFloat(tokens[\"--t-focus-ring-offset\"]) +\n parseFloat(tokens[\"--t-focus-ring-width\"])\n\nexport interface TooltipProps {\n /**\n * A single `BaseButton`-derived element (e.g. `IconButton`, `Button`) to\n * act as the trigger. Must be exactly one trigger — nothing enforces this\n * at runtime, so a fragment with more than one child would silently hand\n * every child the same ref and trigger props.\n */\n children: ReactElement\n /**\n * The hint text. Best used with information beyond the trigger's accessible name\n * (e.g. its `aria-label` or visible label).\n */\n content: string\n /** Where the tooltip renders relative to the trigger. Default `'bottom start'`. */\n placement?: Placement\n}\n\n/**\n * Shows a short hover/focus hint next to a trigger. Built from React Aria's\n * tooltip hooks rather than `react-aria-components`'s `<Tooltip>`, because\n * that component unmounts its content entirely while closed, so a screen\n * reader's virtual cursor never gets access to the description unless real\n * DOM focus lands on the trigger. This keeps the tooltip content always\n * mounted and wires `aria-describedby` unconditionally, toggling only CSS\n * visibility.\n */\nexport function Tooltip({\n children,\n content,\n placement = \"bottom start\",\n}: TooltipProps) {\n const triggerRef = useRef<HTMLButtonElement>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n const tooltipId = `tds-tooltip-${useId()}`\n\n const state = useTooltipTriggerState()\n const { triggerProps } = useTooltipTrigger({}, state, triggerRef)\n const { tooltipProps: ariaTooltipProps } = useTooltip(\n { id: tooltipId },\n state\n )\n\n const {\n arrowProps,\n overlayProps,\n placement: resolvedPlacement,\n } = useOverlayPosition({\n arrowSize: ARROW_SIZE,\n isOpen: state.isOpen,\n offset: ARROW_DEPTH + FOCUS_RING_REACH,\n onClose: () => state.close(true),\n overlayRef,\n placement,\n targetRef: triggerRef,\n })\n\n const contextValue = {\n ref: triggerRef,\n triggerProps: {\n ...triggerProps,\n \"aria-describedby\": tooltipId,\n },\n }\n\n return (\n <>\n <TooltipTriggerContext.Provider value={contextValue}>\n {children}\n </TooltipTriggerContext.Provider>\n <Overlay disableFocusManagement>\n <div\n {...ariaTooltipProps}\n {...overlayProps}\n ref={overlayRef}\n className={classNames(\"tds-tooltip\", {\n \"tds-tooltip--open\": state.isOpen,\n })}\n data-placement={resolvedPlacement}\n style={\n {\n ...overlayProps.style,\n \"--tds-tooltip-arrow-depth-raw\": `${ARROW_DEPTH}px`,\n \"--tds-tooltip-arrow-size-raw\": `${ARROW_SIZE}px`,\n } as React.CSSProperties\n }\n >\n {content}\n <div className=\"tds-tooltip-arrow\" {...arrowProps}>\n <svg\n aria-hidden\n className=\"tds-tooltip-arrow-icon\"\n role=\"img\"\n viewBox={`0 0 ${ARROW_SIZE} ${ARROW_DEPTH}`}\n >\n <polygon\n points={`${ARROW_SIZE / 2},0 0,${ARROW_DEPTH} ${ARROW_SIZE},${ARROW_DEPTH}`}\n />\n </svg>\n </div>\n </div>\n </Overlay>\n </>\n )\n}\n\nTooltip.displayName = \"Tooltip\"\n"],"names":[],"mappings":";;;;;;;;;AAmBE,UAAU,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3C,IAAA,UAAU,CAAC,MAAM,CAAC,sBAAsB,CAAC"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/internal/tooltip/Tooltip.tsx"],"sourcesContent":["import { tokens } from \"@planningcenter/tapestry-tokens/tokens\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type ReactElement, useRef } from \"react\"\nimport { Overlay } from \"react-aria/Overlay\"\nimport {\n type Placement,\n useOverlayPosition,\n} from \"react-aria/useOverlayPosition\"\nimport { useTooltip, useTooltipTrigger } from \"react-aria/useTooltipTrigger\"\nimport { useTooltipTriggerState } from \"react-stately/useTooltipTriggerState\"\n\nimport { TooltipTriggerContext } from \"./TooltipTriggerContext\"\n\n// Single source of truth for the arrow's dimensions -- index.css reads these\n// via --tds-tooltip-arrow-size/--tds-tooltip-arrow-depth instead of its own literals.\nconst ARROW_SIZE = 10\nconst ARROW_DEPTH = 5\nconst FOCUS_RING_REACH =\n parseFloat(tokens[\"--t-focus-ring-offset\"]) +\n parseFloat(tokens[\"--t-focus-ring-width\"])\n\nexport interface TooltipProps {\n /**\n * A single `BaseButton`-derived element (e.g. `IconButton`, `Button`) to\n * act as the trigger. Must be exactly one trigger — nothing enforces this\n * at runtime, so a fragment with more than one child would silently hand\n * every child the same ref and trigger props.\n */\n children: ReactElement\n /**\n * The hint text. Best used with information beyond the trigger's accessible name\n * (e.g. its `aria-label` or visible label).\n */\n content: string\n /** Where the tooltip renders relative to the trigger. Default `'bottom start'`. */\n placement?: Placement\n /**\n * Shows the tooltip on screen only. The tooltip is hidden from assistive\n * tech and not linked to the trigger, so the trigger must carry its own\n * name (e.g. `aria-label`).\n */\n visualOnly?: boolean\n}\n\n/**\n * Shows a short hover/focus hint next to a trigger. Built from React Aria's\n * tooltip hooks rather than `react-aria-components`'s `<Tooltip>`, because\n * that component unmounts its content entirely while closed, so a screen\n * reader's virtual cursor never gets access to the description unless real\n * DOM focus lands on the trigger. This keeps the tooltip content always\n * mounted and wires `aria-describedby` (unless `visualOnly`), toggling only\n * CSS visibility.\n */\nexport function Tooltip({\n children,\n content,\n placement = \"bottom start\",\n visualOnly = false,\n}: TooltipProps) {\n const triggerRef = useRef<HTMLButtonElement>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n const tooltipId = `tds-tooltip-${useId()}`\n\n const state = useTooltipTriggerState()\n const { triggerProps } = useTooltipTrigger({}, state, triggerRef)\n const { tooltipProps: ariaTooltipProps } = useTooltip(\n { id: tooltipId },\n state\n )\n\n const {\n arrowProps,\n overlayProps,\n placement: resolvedPlacement,\n } = useOverlayPosition({\n arrowSize: ARROW_SIZE,\n isOpen: state.isOpen,\n offset: ARROW_DEPTH + FOCUS_RING_REACH,\n onClose: () => state.close(true),\n overlayRef,\n placement,\n targetRef: triggerRef,\n })\n\n const contextValue = {\n ref: triggerRef,\n triggerProps: {\n ...triggerProps,\n \"aria-describedby\": visualOnly ? undefined : tooltipId,\n },\n }\n\n return (\n <>\n <TooltipTriggerContext.Provider value={contextValue}>\n {children}\n </TooltipTriggerContext.Provider>\n <Overlay disableFocusManagement>\n <div\n {...ariaTooltipProps}\n {...overlayProps}\n ref={overlayRef}\n aria-hidden={visualOnly || undefined}\n className={classNames(\"tds-tooltip\", {\n \"tds-tooltip--open\": state.isOpen,\n })}\n data-placement={resolvedPlacement}\n style={\n {\n ...overlayProps.style,\n \"--tds-tooltip-arrow-depth-raw\": `${ARROW_DEPTH}px`,\n \"--tds-tooltip-arrow-size-raw\": `${ARROW_SIZE}px`,\n } as React.CSSProperties\n }\n >\n {content}\n <div className=\"tds-tooltip-arrow\" {...arrowProps}>\n <svg\n aria-hidden\n className=\"tds-tooltip-arrow-icon\"\n role=\"img\"\n viewBox={`0 0 ${ARROW_SIZE} ${ARROW_DEPTH}`}\n >\n <polygon\n points={`${ARROW_SIZE / 2},0 0,${ARROW_DEPTH} ${ARROW_SIZE},${ARROW_DEPTH}`}\n />\n </svg>\n </div>\n </div>\n </Overlay>\n </>\n )\n}\n\nTooltip.displayName = \"Tooltip\"\n"],"names":[],"mappings":";;;;;;;;;;AAcA;AACA;AACA,MAAM,UAAU,GAAG,EAAE;AACrB,MAAM,WAAW,GAAG,CAAC;AACrB,MAAM,gBAAgB,GACpB,UAAU,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3C,IAAA,UAAU,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAyB5C;;;;;;;;AAQG;AACG,SAAU,OAAO,CAAC,EACtB,QAAQ,EACR,OAAO,EACP,SAAS,GAAG,cAAc,EAC1B,UAAU,GAAG,KAAK,GACL,EAAA;AACb,IAAA,MAAM,UAAU,GAAG,MAAM,CAAoB,IAAI,CAAC;AAClD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC/C,IAAA,MAAM,SAAS,GAAG,CAAA,YAAA,EAAe,KAAK,EAAE,EAAE;AAE1C,IAAA,MAAM,KAAK,GAAG,sBAAsB,EAAE;AACtC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC;AACjE,IAAA,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,UAAU,CACnD,EAAE,EAAE,EAAE,SAAS,EAAE,EACjB,KAAK,CACN;IAED,MAAM,EACJ,UAAU,EACV,YAAY,EACZ,SAAS,EAAE,iBAAiB,GAC7B,GAAG,kBAAkB,CAAC;AACrB,QAAA,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,WAAW,GAAG,gBAAgB;QACtC,OAAO,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,UAAU;QACV,SAAS;AACT,QAAA,SAAS,EAAE,UAAU;AACtB,KAAA,CAAC;AAEF,IAAA,MAAM,YAAY,GAAG;AACnB,QAAA,GAAG,EAAE,UAAU;AACf,QAAA,YAAY,EAAE;AACZ,YAAA,GAAG,YAAY;YACf,kBAAkB,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS;AACvD,SAAA;KACF;AAED,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA;QACE,KAAA,CAAA,aAAA,CAAC,qBAAqB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,EAChD,QAAQ,CACsB;QACjC,KAAA,CAAA,aAAA,CAAC,OAAO,IAAC,sBAAsB,EAAA,IAAA,EAAA;AAC7B,YAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,gBAAgB,EAAA,GAChB,YAAY,EAChB,GAAG,EAAE,UAAU,EAAA,aAAA,EACF,UAAU,IAAI,SAAS,EACpC,SAAS,EAAE,UAAU,CAAC,aAAa,EAAE;oBACnC,mBAAmB,EAAE,KAAK,CAAC,MAAM;AAClC,iBAAA,CAAC,EAAA,gBAAA,EACc,iBAAiB,EACjC,KAAK,EACH;oBACE,GAAG,YAAY,CAAC,KAAK;oBACrB,+BAA+B,EAAE,CAAA,EAAG,WAAW,CAAA,EAAA,CAAI;oBACnD,8BAA8B,EAAE,CAAA,EAAG,UAAU,CAAA,EAAA,CAAI;AAC3B,iBAAA,EAAA;gBAGzB,OAAO;AACR,gBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mBAAmB,EAAA,GAAK,UAAU,EAAA;AAC/C,oBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAEE,SAAS,EAAC,wBAAwB,EAClC,IAAI,EAAC,KAAK,EACV,OAAO,EAAE,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,EAAA;wBAE3C,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA,EACE,MAAM,EAAE,CAAA,EAAG,UAAU,GAAG,CAAC,CAAA,KAAA,EAAQ,WAAW,CAAA,CAAA,EAAI,UAAU,IAAI,WAAW,CAAA,CAAE,GAC3E,CACE,CACF,CACF,CACE,CACT;AAEP;AAEA,OAAO,CAAC,WAAW,GAAG,SAAS;;;;"}
@@ -1,13 +1,16 @@
1
1
  import "./index.css";
2
2
  import React, { type HTMLAttributes } from "react";
3
- export type PaneDividerElementProps = HTMLAttributes<HTMLHRElement>;
3
+ export type PaneDividerElementProps = HTMLAttributes<HTMLHRElement> & {
4
+ /** Keeps the rule inside `PaneBody`'s padding instead of bleeding to the Pane's edges. */
5
+ inset?: boolean;
6
+ };
4
7
  /**
5
8
  * A 1px rule between sub-sections inside a `PaneBody`.
6
9
  *
7
10
  * @component
8
11
  * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}
9
12
  */
10
- export declare function PaneDivider({ className, ...restProps }: PaneDividerElementProps): React.JSX.Element;
13
+ export declare function PaneDivider({ className, inset, ...restProps }: PaneDividerElementProps): React.JSX.Element;
11
14
  export declare namespace PaneDivider {
12
15
  var displayName: string;
13
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PaneDivider.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneDivider.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAA;AAElD,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA;AAEnE;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,SAAS,EACb,EAAE,uBAAuB,qBAIzB;yBAPe,WAAW"}
1
+ {"version":3,"file":"PaneDivider.d.ts","sourceRoot":"","sources":["../../../src/components/pane/PaneDivider.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAA;AAElD,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,aAAa,CAAC,GAAG;IACpE,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,KAAa,EACb,GAAG,SAAS,EACb,EAAE,uBAAuB,qBAQzB;yBAZe,WAAW"}
@@ -7,8 +7,8 @@ import React__default from 'react';
7
7
  * @component
8
8
  * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}
9
9
  */
10
- function PaneDivider({ className, ...restProps }) {
11
- const combinedClassName = classNames("tds-pane-divider", className);
10
+ function PaneDivider({ className, inset = false, ...restProps }) {
11
+ const combinedClassName = classNames("tds-pane-divider", { "tds-pane-divider--inset": inset }, className);
12
12
  return React__default.createElement("hr", { ...restProps, className: combinedClassName });
13
13
  }
14
14
  PaneDivider.displayName = "PaneDivider";
@@ -1 +1 @@
1
- {"version":3,"file":"PaneDivider.js","sources":["../../../src/components/pane/PaneDivider.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes } from \"react\"\n\nexport type PaneDividerElementProps = HTMLAttributes<HTMLHRElement>\n\n/**\n * A 1px rule between sub-sections inside a `PaneBody`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function PaneDivider({\n className,\n ...restProps\n}: PaneDividerElementProps) {\n const combinedClassName = classNames(\"tds-pane-divider\", className)\n\n return <hr {...restProps} className={combinedClassName} />\n}\n\nPaneDivider.displayName = \"PaneDivider\"\n"],"names":["React"],"mappings":";;;AAOA;;;;;AAKG;AACG,SAAU,WAAW,CAAC,EAC1B,SAAS,EACT,GAAG,SAAS,EACY,EAAA;IACxB,MAAM,iBAAiB,GAAG,UAAU,CAAC,kBAAkB,EAAE,SAAS,CAAC;AAEnE,IAAA,OAAOA,wCAAQ,SAAS,EAAE,SAAS,EAAE,iBAAiB,GAAI;AAC5D;AAEA,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
1
+ {"version":3,"file":"PaneDivider.js","sources":["../../../src/components/pane/PaneDivider.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport classNames from \"classnames\"\nimport React, { type HTMLAttributes } from \"react\"\n\nexport type PaneDividerElementProps = HTMLAttributes<HTMLHRElement> & {\n /** Keeps the rule inside `PaneBody`'s padding instead of bleeding to the Pane's edges. */\n inset?: boolean\n}\n\n/**\n * A 1px rule between sub-sections inside a `PaneBody`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/unstable-pane--docs | Storybook Documentation}\n */\nexport function PaneDivider({\n className,\n inset = false,\n ...restProps\n}: PaneDividerElementProps) {\n const combinedClassName = classNames(\n \"tds-pane-divider\",\n { \"tds-pane-divider--inset\": inset },\n className\n )\n\n return <hr {...restProps} className={combinedClassName} />\n}\n\nPaneDivider.displayName = \"PaneDivider\"\n"],"names":["React"],"mappings":";;;AAUA;;;;;AAKG;AACG,SAAU,WAAW,CAAC,EAC1B,SAAS,EACT,KAAK,GAAG,KAAK,EACb,GAAG,SAAS,EACY,EAAA;AACxB,IAAA,MAAM,iBAAiB,GAAG,UAAU,CAClC,kBAAkB,EAClB,EAAE,yBAAyB,EAAE,KAAK,EAAE,EACpC,SAAS,CACV;AAED,IAAA,OAAOA,wCAAQ,SAAS,EAAE,SAAS,EAAE,iBAAiB,GAAI;AAC5D;AAEA,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
package/dist/index.css CHANGED
@@ -2770,33 +2770,6 @@ tds-sidenav-section:not(.hydrated) > [slot="ssr"]{
2770
2770
  border-color:var(--tds-btn-border-color-disabled);
2771
2771
  }
2772
2772
 
2773
- .tds-loading-spinner{
2774
- position:absolute;
2775
- right:0;
2776
- left:0;
2777
- visibility:var(--tds-loading-spinner-visibility, hidden);
2778
- width:var(--tds-loading-spinner-size, 1.25em);
2779
- height:var(--tds-loading-spinner-size, 1.25em);
2780
- margin:auto;
2781
- border:var(--tds-loading-spinner-track-width, 4px) solid var(--tds-loading-spinner-track-color, var(--t-fill-color-transparency-dark-020));
2782
- border-top-color:var(--tds-loading-spinner-color, currentcolor);
2783
- border-radius:50%;
2784
- animation:spinner-rotate 500ms infinite linear;
2785
- animation-play-state:var(--tds-loading-spinner-animation-play-state, paused);
2786
- }
2787
-
2788
- @keyframes spinner-rotate{
2789
- to{
2790
- transform:rotate(360deg);
2791
- }
2792
- }
2793
-
2794
- @media (prefers-reduced-motion: reduce){
2795
- [class*="--loading"] .tds-loading-spinner{
2796
- --tds-loading-spinner-animation-play-state:paused;
2797
- }
2798
- }
2799
-
2800
2773
  .tds-tooltip{
2801
2774
  --tds-tooltip-arrow-depth:var(--tds-tooltip-arrow-depth-raw);
2802
2775
  --tds-tooltip-arrow-size:var(--tds-tooltip-arrow-size-raw);
@@ -2871,6 +2844,33 @@ tds-sidenav-section:not(.hydrated) > [slot="ssr"]{
2871
2844
  transform:var(--tds-tooltip-arrow-rotate);
2872
2845
  }
2873
2846
 
2847
+ .tds-loading-spinner{
2848
+ position:absolute;
2849
+ right:0;
2850
+ left:0;
2851
+ visibility:var(--tds-loading-spinner-visibility, hidden);
2852
+ width:var(--tds-loading-spinner-size, 1.25em);
2853
+ height:var(--tds-loading-spinner-size, 1.25em);
2854
+ margin:auto;
2855
+ border:var(--tds-loading-spinner-track-width, 4px) solid var(--tds-loading-spinner-track-color, var(--t-fill-color-transparency-dark-020));
2856
+ border-top-color:var(--tds-loading-spinner-color, currentcolor);
2857
+ border-radius:50%;
2858
+ animation:spinner-rotate 500ms infinite linear;
2859
+ animation-play-state:var(--tds-loading-spinner-animation-play-state, paused);
2860
+ }
2861
+
2862
+ @keyframes spinner-rotate{
2863
+ to{
2864
+ transform:rotate(360deg);
2865
+ }
2866
+ }
2867
+
2868
+ @media (prefers-reduced-motion: reduce){
2869
+ [class*="--loading"] .tds-loading-spinner{
2870
+ --tds-loading-spinner-animation-play-state:paused;
2871
+ }
2872
+ }
2873
+
2874
2874
  .tds-button-group{
2875
2875
  display:inline-flex;
2876
2876
  }