@planningcenter/tapestry 4.6.1 → 4.7.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 (88) hide show
  1. package/dist/components/DataTable/ActiveFilterInstance.d.ts +13 -0
  2. package/dist/components/DataTable/ActiveFilterInstance.d.ts.map +1 -0
  3. package/dist/components/DataTable/ActiveFilterInstance.js +23 -0
  4. package/dist/components/DataTable/ActiveFilterInstance.js.map +1 -0
  5. package/dist/components/DataTable/ActiveFilters.d.ts +3 -4
  6. package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
  7. package/dist/components/DataTable/ActiveFilters.js +25 -35
  8. package/dist/components/DataTable/ActiveFilters.js.map +1 -1
  9. package/dist/components/DataTable/DataTable.d.ts +1 -0
  10. package/dist/components/DataTable/DataTable.d.ts.map +1 -1
  11. package/dist/components/DataTable/DataTable.js +12 -2
  12. package/dist/components/DataTable/DataTable.js.map +1 -1
  13. package/dist/components/DataTable/FilterChip.d.ts +26 -0
  14. package/dist/components/DataTable/FilterChip.d.ts.map +1 -0
  15. package/dist/components/DataTable/FilterChip.js +36 -0
  16. package/dist/components/DataTable/FilterChip.js.map +1 -0
  17. package/dist/components/DataTable/FilterContext.d.ts.map +1 -1
  18. package/dist/components/DataTable/FilterContext.js +3 -1
  19. package/dist/components/DataTable/FilterContext.js.map +1 -1
  20. package/dist/components/DataTable/FilterControls.d.ts +8 -2
  21. package/dist/components/DataTable/FilterControls.d.ts.map +1 -1
  22. package/dist/components/DataTable/FilterControls.js +48 -7
  23. package/dist/components/DataTable/FilterControls.js.map +1 -1
  24. package/dist/components/DataTable/FilterTypes.d.ts +14 -1
  25. package/dist/components/DataTable/FilterTypes.d.ts.map +1 -1
  26. package/dist/components/DataTable/OperatorSelect.d.ts +1 -2
  27. package/dist/components/DataTable/OperatorSelect.d.ts.map +1 -1
  28. package/dist/components/DataTable/OperatorSelect.js.map +1 -1
  29. package/dist/components/DataTable/SearchableFilters.d.ts +14 -0
  30. package/dist/components/DataTable/SearchableFilters.d.ts.map +1 -0
  31. package/dist/components/DataTable/SearchableFilters.js +35 -0
  32. package/dist/components/DataTable/SearchableFilters.js.map +1 -0
  33. package/dist/components/DataTable/collectionFilter.d.ts +48 -0
  34. package/dist/components/DataTable/collectionFilter.d.ts.map +1 -0
  35. package/dist/components/DataTable/collectionFilter.js +86 -0
  36. package/dist/components/DataTable/collectionFilter.js.map +1 -0
  37. package/dist/components/DataTable/dateFilter.d.ts +60 -0
  38. package/dist/components/DataTable/dateFilter.d.ts.map +1 -0
  39. package/dist/components/DataTable/dateFilter.js +67 -0
  40. package/dist/components/DataTable/dateFilter.js.map +1 -0
  41. package/dist/components/DataTable/filters.d.ts +5 -0
  42. package/dist/components/DataTable/filters.d.ts.map +1 -0
  43. package/dist/components/DataTable/index.d.ts +4 -0
  44. package/dist/components/DataTable/index.d.ts.map +1 -1
  45. package/dist/components/DataTable/numberFilter.d.ts +46 -0
  46. package/dist/components/DataTable/numberFilter.d.ts.map +1 -0
  47. package/dist/components/DataTable/numberFilter.js +63 -0
  48. package/dist/components/DataTable/numberFilter.js.map +1 -0
  49. package/dist/components/DataTable/resolveOperators.d.ts +7 -0
  50. package/dist/components/DataTable/resolveOperators.d.ts.map +1 -0
  51. package/dist/components/DataTable/resolveOperators.js +11 -0
  52. package/dist/components/DataTable/resolveOperators.js.map +1 -0
  53. package/dist/components/DataTable/textFilter.d.ts +58 -0
  54. package/dist/components/DataTable/textFilter.d.ts.map +1 -0
  55. package/dist/components/DataTable/textFilter.js +49 -0
  56. package/dist/components/DataTable/textFilter.js.map +1 -0
  57. package/dist/components/DataTable/useShelfExpanded.d.ts +6 -0
  58. package/dist/components/DataTable/useShelfExpanded.d.ts.map +1 -0
  59. package/dist/components/DataTable/useShelfExpanded.js +26 -0
  60. package/dist/components/DataTable/useShelfExpanded.js.map +1 -0
  61. package/dist/components/dropdown/Dropdown.d.ts +4 -0
  62. package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
  63. package/dist/components/dropdown/Dropdown.js +4 -0
  64. package/dist/components/dropdown/Dropdown.js.map +1 -1
  65. package/dist/components/input/Input.d.ts +4 -4
  66. package/dist/components/input/Input.d.ts.map +1 -1
  67. package/dist/components/input/Input.js +3 -3
  68. package/dist/components/input/Input.js.map +1 -1
  69. package/dist/components/popover/Popover.d.ts +1 -1
  70. package/dist/components/popover/Popover.js +1 -1
  71. package/dist/components/popover/Popover.js.map +1 -1
  72. package/dist/index.css +89 -1
  73. package/dist/index.css.map +1 -1
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/reactRender.css +1292 -1041
  79. package/dist/reactRender.css.map +1 -1
  80. package/dist/reactRenderLegacy.css +1292 -1041
  81. package/dist/reactRenderLegacy.css.map +1 -1
  82. package/dist/unstable.css +3717 -3466
  83. package/dist/unstable.css.map +1 -1
  84. package/dist/unstable.d.ts +0 -1
  85. package/dist/unstable.d.ts.map +1 -1
  86. package/dist/unstable.js +5 -1
  87. package/dist/unstable.js.map +1 -1
  88. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/components/input/Input.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { InputTextBase } from \"@components/input-text-base\"\nimport classNames from \"classnames\"\nimport React, { forwardRef, type InputHTMLAttributes } from \"react\"\n\nexport type InputSize = \"lg\" | \"md\"\n\nexport type InputType =\n | \"email\"\n | \"number\"\n | \"password\"\n | \"search\"\n | \"tel\"\n | \"text\"\n | \"url\"\n\ninterface InputBaseProps {\n /** Helper text displayed below the input. Styled as an error when `invalid`. */\n description?: React.ReactNode\n /** Whether the input is in an invalid state. */\n invalid?: boolean\n /** If true, all text is selected when the input receives focus. */\n selectTextOnFocus?: boolean\n /** The size of the input. */\n size?: InputSize\n /** Supported input types — defaults to 'text' */\n type?: InputType\n}\n\ninterface InputWithAutoWidth {\n /** If true, the input width grows to fit content. Mutually exclusive with `expand`. */\n autoWidth?: boolean\n expand?: never\n}\n\ninterface InputWithExpand {\n autoWidth?: never\n /** If true, sets `data-flex-expand` so the input grows/shrinks to fill a `Flex` row. Mutually exclusive with `autoWidth`. */\n expand?: boolean\n}\n\ntype InputSizingProps = InputWithAutoWidth | InputWithExpand\n\ninterface InputWithVisibleLabel extends InputBaseProps {\n /** If true, the label is visually hidden and set as aria-label. */\n hideLabel?: false\n /** The label text for the input. */\n label: React.ReactNode\n}\n\ninterface InputWithHiddenLabel extends InputBaseProps {\n /** If true, the label is visually hidden and set as aria-label. */\n hideLabel: true\n /** The label text for the input. Must be a string when hidden. */\n label: string\n}\n\ninterface InputWithAriaLabelledBy extends InputBaseProps {\n \"aria-labelledby\": string\n hideLabel?: never\n label?: never\n}\n\nexport type InputProps =\n | InputWithAriaLabelledBy\n | InputWithHiddenLabel\n | InputWithVisibleLabel\n\n/**\n * Combines standard HTML input attributes with custom Input props.\n * Omits 'size' and 'type' from HTML attributes to avoid conflict with our strict types.\n */\nexport type InputElementProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n keyof InputProps | keyof InputSizingProps | \"size\" | \"type\"\n> &\n InputProps &\n InputSizingProps\n\n/**\n * A text input component that renders as an HTML `<input>` with a label and\n * optional description. Supports the standard text-like input types\n * (`text`, `email`, `password`, `search`, `tel`, `url`, `number`), invalid\n * state, and `lg`/`md` sizing.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/components-input--docs | Storybook Documentation}\n * @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}\n */\nexport const Input = forwardRef<HTMLInputElement, InputElementProps>(\n function Input(\n {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n autoComplete,\n autoWidth,\n className,\n description,\n expand,\n hideLabel,\n id,\n invalid,\n label,\n onFocus,\n selectTextOnFocus,\n size = \"md\",\n type = \"text\",\n ...restProps\n }: InputElementProps,\n ref\n ) {\n const autoCompleteBlockingProps =\n autoComplete === \"off\"\n ? {\n \"data-1p-ignore\": true,\n \"data-bwignore\": true,\n \"data-form-type\": \"other\",\n \"data-lpignore\": true,\n }\n : {}\n\n const handleFocus = selectTextOnFocus\n ? (event: React.FocusEvent<HTMLInputElement>) => {\n try {\n event.currentTarget.select()\n } catch {\n // Some input types (e.g. number) do not support text selection.\n }\n onFocus?.(event)\n }\n : onFocus\n\n const wrapperClassName = classNames(\n { \"tds-input--auto-width\": autoWidth },\n className\n )\n\n return (\n <InputTextBase\n className={wrapperClassName}\n description={description}\n expand={expand}\n hideLabel={hideLabel || !!ariaLabelledBy}\n id={id}\n invalid={invalid}\n label={label}\n size={size}\n >\n {({ descriptionId, inputId }) => (\n <input\n {...restProps}\n {...autoCompleteBlockingProps}\n aria-describedby={descriptionId}\n aria-invalid={invalid || undefined}\n aria-label={hideLabel ? ariaLabel || (label as string) : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n autoComplete={autoComplete}\n id={inputId}\n onFocus={handleFocus}\n ref={ref}\n type={type}\n />\n )}\n </InputTextBase>\n )\n }\n)\n\nInput.displayName = \"Input\"\n"],"names":["React"],"mappings":";;;;AAgFA;;;;;;;;;AASG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,SAAS,KAAK,CACZ,EACE,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,MAAM,EACN,SAAS,EACT,EAAE,EACF,OAAO,EACP,KAAK,EACL,OAAO,EACP,iBAAiB,EACjB,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,MAAM,EACb,GAAG,SAAS,EACM,EACpB,GAAG,EAAA;AAEH,IAAA,MAAM,yBAAyB,GAC7B,YAAY,KAAK;AACf,UAAE;AACE,YAAA,gBAAgB,EAAE,IAAI;AACtB,YAAA,eAAe,EAAE,IAAI;AACrB,YAAA,gBAAgB,EAAE,OAAO;AACzB,YAAA,eAAe,EAAE,IAAI;AACtB;UACD,EAAE;IAER,MAAM,WAAW,GAAG;AAClB,UAAE,CAAC,KAAyC,KAAI;AAC5C,YAAA,IAAI;AACF,gBAAA,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;YAC9B;AAAE,YAAA,MAAM;;YAER;AACA,YAAA,OAAO,GAAG,KAAK,CAAC;QAClB;UACA,OAAO;AAEX,IAAA,MAAM,gBAAgB,GAAG,UAAU,CACjC,EAAE,uBAAuB,EAAE,SAAS,EAAE,EACtC,SAAS,CACV;IAED,QACEA,6BAAC,aAAa,EAAA,EACZ,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,IAAI,CAAC,CAAC,cAAc,EACxC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,IAET,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,MAC1BA,cAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAA,GACM,SAAS,KACT,yBAAyB,EAAA,kBAAA,EACX,aAAa,EAAA,cAAA,EACjB,OAAO,IAAI,SAAS,EAAA,YAAA,EACtB,SAAS,GAAG,SAAS,IAAK,KAAgB,GAAG,SAAS,EAAA,iBAAA,EACjD,cAAc,EAC/B,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EAAA,CACV,CACH,CACa;AAEpB,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;;;"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/input/Input.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport { InputTextBase } from \"@components/input-text-base\"\nimport classNames from \"classnames\"\nimport React, { forwardRef, type InputHTMLAttributes } from \"react\"\n\nexport type InputSize = \"lg\" | \"md\"\n\nexport type InputType =\n | \"email\"\n | \"file\"\n | \"number\"\n | \"password\"\n | \"search\"\n | \"tel\"\n | \"text\"\n | \"url\"\n\ninterface InputBaseProps {\n /** Helper text displayed below the input. Styled as an error when `invalid`. */\n description?: React.ReactNode\n /** Whether the input is in an invalid state. */\n invalid?: boolean\n /** If true, all text is selected when the input receives focus. */\n selectTextOnFocus?: boolean\n /** The size of the input. */\n size?: InputSize\n /** Supported input types — defaults to 'text' */\n type?: InputType\n}\n\ninterface InputWithAutoWidth {\n /** If true, the input width grows to fit content. Mutually exclusive with `expand`. */\n autoWidth?: boolean\n expand?: never\n}\n\ninterface InputWithExpand {\n autoWidth?: never\n /** If true, sets `data-flex-expand` so the input grows/shrinks to fill a `Flex` row. Mutually exclusive with `autoWidth`. */\n expand?: boolean\n}\n\ntype InputSizingProps = InputWithAutoWidth | InputWithExpand\n\ninterface InputWithVisibleLabel extends InputBaseProps {\n /** If true, the label is visually hidden and set as aria-label. */\n hideLabel?: false\n /** The label text for the input. */\n label: React.ReactNode\n}\n\ninterface InputWithHiddenLabel extends InputBaseProps {\n /** If true, the label is visually hidden and set as aria-label. */\n hideLabel: true\n /** The label text for the input. Must be a string when hidden. */\n label: string\n}\n\ninterface InputWithAriaLabelledBy extends InputBaseProps {\n \"aria-labelledby\": string\n hideLabel?: never\n label?: never\n}\n\nexport type InputProps =\n | InputWithAriaLabelledBy\n | InputWithHiddenLabel\n | InputWithVisibleLabel\n\n/**\n * Combines standard HTML input attributes with custom Input props.\n * Omits 'size' and 'type' from HTML attributes to avoid conflict with our strict types.\n */\nexport type InputElementProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n keyof InputProps | keyof InputSizingProps | \"size\" | \"type\"\n> &\n InputProps &\n InputSizingProps\n\n/**\n * A text input component that renders as an HTML `<input>` with a label and\n * optional description. Supports the standard native input types\n * (`text`, `email`, `password`, `search`, `tel`, `url`, `number`, `file`),\n * invalid state, and `lg`/`md` sizing.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/components-input--docs | Storybook Documentation}\n * @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}\n */\nexport const Input = forwardRef<HTMLInputElement, InputElementProps>(\n function Input(\n {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n autoComplete,\n autoWidth,\n className,\n description,\n expand,\n hideLabel,\n id,\n invalid,\n label,\n onFocus,\n selectTextOnFocus,\n size = \"md\",\n type = \"text\",\n ...restProps\n }: InputElementProps,\n ref\n ) {\n const autoCompleteBlockingProps =\n autoComplete === \"off\"\n ? {\n \"data-1p-ignore\": true,\n \"data-bwignore\": true,\n \"data-form-type\": \"other\",\n \"data-lpignore\": true,\n }\n : {}\n\n const handleFocus = selectTextOnFocus\n ? (event: React.FocusEvent<HTMLInputElement>) => {\n try {\n event.currentTarget.select()\n } catch {\n // Some input types (e.g. number) do not support text selection.\n }\n onFocus?.(event)\n }\n : onFocus\n\n const wrapperClassName = classNames(\n { \"tds-input--auto-width\": autoWidth },\n className\n )\n\n return (\n <InputTextBase\n className={wrapperClassName}\n description={description}\n expand={expand}\n hideLabel={hideLabel || !!ariaLabelledBy}\n id={id}\n invalid={invalid}\n label={label}\n size={size}\n >\n {({ descriptionId, inputId }) => (\n <input\n {...restProps}\n {...autoCompleteBlockingProps}\n aria-describedby={descriptionId}\n aria-invalid={invalid || undefined}\n aria-label={hideLabel ? ariaLabel || (label as string) : ariaLabel}\n aria-labelledby={ariaLabelledBy}\n autoComplete={autoComplete}\n id={inputId}\n onFocus={handleFocus}\n ref={ref}\n type={type}\n />\n )}\n </InputTextBase>\n )\n }\n)\n\nInput.displayName = \"Input\"\n"],"names":["React"],"mappings":";;;;AAiFA;;;;;;;;;AASG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,SAAS,KAAK,CACZ,EACE,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,MAAM,EACN,SAAS,EACT,EAAE,EACF,OAAO,EACP,KAAK,EACL,OAAO,EACP,iBAAiB,EACjB,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,MAAM,EACb,GAAG,SAAS,EACM,EACpB,GAAG,EAAA;AAEH,IAAA,MAAM,yBAAyB,GAC7B,YAAY,KAAK;AACf,UAAE;AACE,YAAA,gBAAgB,EAAE,IAAI;AACtB,YAAA,eAAe,EAAE,IAAI;AACrB,YAAA,gBAAgB,EAAE,OAAO;AACzB,YAAA,eAAe,EAAE,IAAI;AACtB;UACD,EAAE;IAER,MAAM,WAAW,GAAG;AAClB,UAAE,CAAC,KAAyC,KAAI;AAC5C,YAAA,IAAI;AACF,gBAAA,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;YAC9B;AAAE,YAAA,MAAM;;YAER;AACA,YAAA,OAAO,GAAG,KAAK,CAAC;QAClB;UACA,OAAO;AAEX,IAAA,MAAM,gBAAgB,GAAG,UAAU,CACjC,EAAE,uBAAuB,EAAE,SAAS,EAAE,EACtC,SAAS,CACV;IAED,QACEA,6BAAC,aAAa,EAAA,EACZ,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,IAAI,CAAC,CAAC,cAAc,EACxC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,IAET,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,MAC1BA,cAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAA,GACM,SAAS,KACT,yBAAyB,EAAA,kBAAA,EACX,aAAa,EAAA,cAAA,EACjB,OAAO,IAAI,SAAS,EAAA,YAAA,EACtB,SAAS,GAAG,SAAS,IAAK,KAAgB,GAAG,SAAS,EAAA,iBAAA,EACjD,cAAc,EAC/B,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EAAA,CACV,CACH,CACa;AAEpB,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;;;"}
@@ -25,7 +25,7 @@ export type PopoverElementProps = PopoverProps;
25
25
  * `Modal`.
26
26
  *
27
27
  * @component
28
- * @see {@link https://app.notion.com/p/planningcenter/RFC-Tapestry-Popover-3baabbce69a2802e8fe8e65a7f72821c | RFC}
28
+ * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/components-popover--docs | Storybook Documentation}
29
29
  */
30
30
  export declare function Popover({ children, defaultOpen, onOpenChange, open, }: PopoverElementProps): React.JSX.Element;
31
31
  export interface PopoverTriggerProps {
@@ -14,7 +14,7 @@ import { DialogTrigger, PopoverContext, Popover as Popover$1, Dialog, Pressable
14
14
  * `Modal`.
15
15
  *
16
16
  * @component
17
- * @see {@link https://app.notion.com/p/planningcenter/RFC-Tapestry-Popover-3baabbce69a2802e8fe8e65a7f72821c | RFC}
17
+ * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/components-popover--docs | Storybook Documentation}
18
18
  */
19
19
  function Popover({ children, defaultOpen, onOpenChange, open, }) {
20
20
  return (React__default.createElement(DialogTrigger, { defaultOpen: defaultOpen, isOpen: open, onOpenChange: onOpenChange }, children));
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n createContext,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useRef,\n} from \"react\"\nimport { FocusScope, useInteractOutside, usePreventScroll } from \"react-aria\"\nimport { OverlayTriggerStateContext } from \"react-aria-components/Dialog\"\nimport type { PopoverProps as AriaPopoverProps } from \"react-aria-components/Popover\"\nimport {\n Dialog,\n DialogTrigger,\n Popover as AriaPopover,\n PopoverContext as AriaPopoverContext,\n Pressable,\n} from \"react-aria-components/Popover\"\n\nexport interface PopoverProps {\n /** A `<PopoverTrigger>` followed by a `<PopoverContent>`. */\n children: ReactNode\n /** Initial open state for the uncontrolled case. Useful for stories and tests. */\n defaultOpen?: boolean\n /**\n * Fires whenever the surface opens or closes — trigger press, Escape,\n * outside press, or `close()`. Required when `open` is set.\n */\n onOpenChange?: (open: boolean) => void\n /** Controlled open state. Renamed from React Aria's `isOpen`. Omit for uncontrolled. */\n open?: boolean\n}\n\nexport type PopoverElementProps = PopoverProps\n\n/**\n * A generic popover surface anchored to a trigger button. Unlike `Dropdown`\n * (a semantic `role=\"menu\"` action list), `Popover` renders arbitrary content\n * — a search field, a form, a list, plain text.\n *\n * **Rule of thumb:** a flat list of actions or links → `Dropdown`. Anything\n * else anchored to a button → `Popover`. Owns the screen until resolved →\n * `Modal`.\n *\n * @component\n * @see {@link https://app.notion.com/p/planningcenter/RFC-Tapestry-Popover-3baabbce69a2802e8fe8e65a7f72821c | RFC}\n */\nexport function Popover({\n children,\n defaultOpen,\n onOpenChange,\n open,\n}: PopoverElementProps) {\n return (\n <DialogTrigger\n defaultOpen={defaultOpen}\n isOpen={open}\n onOpenChange={onOpenChange}\n >\n {children}\n </DialogTrigger>\n )\n}\n\nexport interface PopoverTriggerProps {\n /**\n * Exactly one Tapestry button element — `Button`, `IconButton`,\n * `DropdownButton`, `DropdownIconButton`, `ActionsDropdownIconButton`, or\n * `PageHeaderActionsDropdownButton`. Receives `aria-expanded`,\n * `aria-controls`, `id`, and press wiring via `Pressable` — the same RAC\n * mechanism `Dropdown`'s trigger already uses. Must render a real `<button>`.\n */\n children: ReactElement\n}\n\nexport type PopoverTriggerElementProps = PopoverTriggerProps\n\ntype PressableChild = ComponentProps<typeof Pressable>[\"children\"]\n\n/**\n * Wraps a single Tapestry button and bridges it to React Aria's\n * `DialogTrigger` via `<Pressable>`.\n *\n * @component\n */\nexport function PopoverTrigger({ children }: PopoverTriggerElementProps) {\n return <Pressable>{children as PressableChild}</Pressable>\n}\n\nconst PopoverCloseContext = createContext<() => void>(() => {})\n\n/**\n * Returns the enclosing `<PopoverContent>`'s `close` function. Call it from\n * any descendant to close the surface — e.g. a plain `<Button onClick={close}>`.\n */\nexport function usePopoverClose(): () => void {\n return useContext(PopoverCloseContext)\n}\n\nexport interface PopoverContentProps {\n /**\n * Accessible name for the surface. Defaults to the trigger's accessible\n * name (React Aria points `aria-labelledby` at the trigger's id). Set this\n * when the surface needs a different name than the trigger.\n */\n \"aria-label\"?: string\n /** Arbitrary content. */\n children: ReactNode\n /** Appended to `tds-popover` on the positioned surface. */\n className?: string\n /**\n * Defaults to `true`. When `true`, the surface contains focus, hides\n * outside content from assistive tech, and blocks page scroll while open —\n * the right default for most popovers. Set to `false` for lighter-weight\n * dismissal behavior (maps to React Aria's `isNonModal`, whose own doc\n * comment scopes it to \"components such as combobox\" — this is why it\n * isn't the default). `<Dialog>` always renders regardless of this prop;\n * `modal` only toggles containment, not whether a dialog role exists.\n *\n * `modal={false}` still blocks page scroll while open — React Aria's own\n * scroll-close behavior for non-modal popovers can't be disabled, so\n * scrolling is locked instead, the same way `Dropdown`'s menu does.\n */\n modal?: boolean\n /**\n * Position relative to the trigger, in React Aria's space-separated form.\n * Defaults to `'bottom start'`. Flips automatically when there isn't room.\n */\n placement?: AriaPopoverProps[\"placement\"]\n}\n\nexport type PopoverContentElementProps = PopoverContentProps\n\n/**\n * The popover surface for a `<Popover>`. Wraps React Aria's `<Popover>` and\n * `<Dialog>` and contains arbitrary content.\n *\n * @component\n */\nexport function PopoverContent({\n \"aria-label\": ariaLabel,\n children,\n className,\n modal = true,\n placement = \"bottom start\",\n}: PopoverContentElementProps) {\n const popoverRef = useRef<HTMLElement>(null)\n const state = useContext(OverlayTriggerStateContext)\n const close = useCallback(() => state?.close(), [state])\n\n const popoverContext = useContext(AriaPopoverContext)\n const triggerRef =\n popoverContext && \"triggerRef\" in popoverContext\n ? popoverContext.triggerRef\n : undefined\n\n useInteractOutside({\n isDisabled: modal || !state?.isOpen,\n onInteractOutside: (event) => {\n if (triggerRef?.current?.contains(event.target as Node)) return\n close()\n },\n ref: popoverRef,\n })\n usePreventScroll({ isDisabled: modal || !state?.isOpen })\n\n return (\n <AriaPopover\n className={classNames(\"tds-popover\", className)}\n isNonModal={!modal}\n placement={placement}\n ref={popoverRef}\n shouldCloseOnInteractOutside={modal ? undefined : () => false}\n >\n <FocusScope contain={!modal}>\n <Dialog aria-label={ariaLabel} className=\"tds-popover-content\">\n <PopoverCloseContext.Provider value={close}>\n {children}\n </PopoverCloseContext.Provider>\n </Dialog>\n </FocusScope>\n </AriaPopover>\n )\n}\n"],"names":["React","AriaPopoverContext","AriaPopover"],"mappings":";;;;;;AAuCA;;;;;;;;;;;AAWG;AACG,SAAU,OAAO,CAAC,EACtB,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,IAAI,GACgB,EAAA;AACpB,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,aAAa,IACZ,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,IAAI,EACZ,YAAY,EAAE,YAAY,IAEzB,QAAQ,CACK;AAEpB;AAiBA;;;;;AAKG;AACG,SAAU,cAAc,CAAC,EAAE,QAAQ,EAA8B,EAAA;AACrE,IAAA,OAAOA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,IAAA,EAAE,QAA0B,CAAa;AAC5D;AAEA,MAAM,mBAAmB,GAAG,aAAa,CAAa,MAAK,EAAE,CAAC,CAAC;AAE/D;;;AAGG;SACa,eAAe,GAAA;AAC7B,IAAA,OAAO,UAAU,CAAC,mBAAmB,CAAC;AACxC;AAoCA;;;;;AAKG;SACa,cAAc,CAAC,EAC7B,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,SAAS,EACT,KAAK,GAAG,IAAI,EACZ,SAAS,GAAG,cAAc,GACC,EAAA;AAC3B,IAAA,MAAM,UAAU,GAAG,MAAM,CAAc,IAAI,CAAC;AAC5C,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,0BAA0B,CAAC;AACpD,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAExD,IAAA,MAAM,cAAc,GAAG,UAAU,CAACC,cAAkB,CAAC;AACrD,IAAA,MAAM,UAAU,GACd,cAAc,IAAI,YAAY,IAAI;UAC9B,cAAc,CAAC;UACf,SAAS;AAEf,IAAA,kBAAkB,CAAC;AACjB,QAAA,UAAU,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,MAAM;AACnC,QAAA,iBAAiB,EAAE,CAAC,KAAK,KAAI;YAC3B,IAAI,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC;gBAAE;AACzD,YAAA,KAAK,EAAE;QACT,CAAC;AACD,QAAA,GAAG,EAAE,UAAU;AAChB,KAAA,CAAC;AACF,IAAA,gBAAgB,CAAC,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;AAEzD,IAAA,QACED,cAAA,CAAA,aAAA,CAACE,SAAW,EAAA,EACV,SAAS,EAAE,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,EAC/C,UAAU,EAAE,CAAC,KAAK,EAClB,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,UAAU,EACf,4BAA4B,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,KAAK,EAAA;AAE7D,QAAAF,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,OAAO,EAAE,CAAC,KAAK,EAAA;AACzB,YAAAA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAA,YAAA,EAAa,SAAS,EAAE,SAAS,EAAC,qBAAqB,EAAA;AAC5D,gBAAAA,cAAA,CAAA,aAAA,CAAC,mBAAmB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,EACvC,QAAQ,CACoB,CACxB,CACE,CACD;AAElB;;;;"}
1
+ {"version":3,"file":"Popover.js","sources":["../../../src/components/popover/Popover.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n createContext,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useRef,\n} from \"react\"\nimport { FocusScope, useInteractOutside, usePreventScroll } from \"react-aria\"\nimport { OverlayTriggerStateContext } from \"react-aria-components/Dialog\"\nimport type { PopoverProps as AriaPopoverProps } from \"react-aria-components/Popover\"\nimport {\n Dialog,\n DialogTrigger,\n Popover as AriaPopover,\n PopoverContext as AriaPopoverContext,\n Pressable,\n} from \"react-aria-components/Popover\"\n\nexport interface PopoverProps {\n /** A `<PopoverTrigger>` followed by a `<PopoverContent>`. */\n children: ReactNode\n /** Initial open state for the uncontrolled case. Useful for stories and tests. */\n defaultOpen?: boolean\n /**\n * Fires whenever the surface opens or closes — trigger press, Escape,\n * outside press, or `close()`. Required when `open` is set.\n */\n onOpenChange?: (open: boolean) => void\n /** Controlled open state. Renamed from React Aria's `isOpen`. Omit for uncontrolled. */\n open?: boolean\n}\n\nexport type PopoverElementProps = PopoverProps\n\n/**\n * A generic popover surface anchored to a trigger button. Unlike `Dropdown`\n * (a semantic `role=\"menu\"` action list), `Popover` renders arbitrary content\n * — a search field, a form, a list, plain text.\n *\n * **Rule of thumb:** a flat list of actions or links → `Dropdown`. Anything\n * else anchored to a button → `Popover`. Owns the screen until resolved →\n * `Modal`.\n *\n * @component\n * @see {@link https://planningcenter.github.io/tapestry/?path=/docs/components-popover--docs | Storybook Documentation}\n */\nexport function Popover({\n children,\n defaultOpen,\n onOpenChange,\n open,\n}: PopoverElementProps) {\n return (\n <DialogTrigger\n defaultOpen={defaultOpen}\n isOpen={open}\n onOpenChange={onOpenChange}\n >\n {children}\n </DialogTrigger>\n )\n}\n\nexport interface PopoverTriggerProps {\n /**\n * Exactly one Tapestry button element — `Button`, `IconButton`,\n * `DropdownButton`, `DropdownIconButton`, `ActionsDropdownIconButton`, or\n * `PageHeaderActionsDropdownButton`. Receives `aria-expanded`,\n * `aria-controls`, `id`, and press wiring via `Pressable` — the same RAC\n * mechanism `Dropdown`'s trigger already uses. Must render a real `<button>`.\n */\n children: ReactElement\n}\n\nexport type PopoverTriggerElementProps = PopoverTriggerProps\n\ntype PressableChild = ComponentProps<typeof Pressable>[\"children\"]\n\n/**\n * Wraps a single Tapestry button and bridges it to React Aria's\n * `DialogTrigger` via `<Pressable>`.\n *\n * @component\n */\nexport function PopoverTrigger({ children }: PopoverTriggerElementProps) {\n return <Pressable>{children as PressableChild}</Pressable>\n}\n\nconst PopoverCloseContext = createContext<() => void>(() => {})\n\n/**\n * Returns the enclosing `<PopoverContent>`'s `close` function. Call it from\n * any descendant to close the surface — e.g. a plain `<Button onClick={close}>`.\n */\nexport function usePopoverClose(): () => void {\n return useContext(PopoverCloseContext)\n}\n\nexport interface PopoverContentProps {\n /**\n * Accessible name for the surface. Defaults to the trigger's accessible\n * name (React Aria points `aria-labelledby` at the trigger's id). Set this\n * when the surface needs a different name than the trigger.\n */\n \"aria-label\"?: string\n /** Arbitrary content. */\n children: ReactNode\n /** Appended to `tds-popover` on the positioned surface. */\n className?: string\n /**\n * Defaults to `true`. When `true`, the surface contains focus, hides\n * outside content from assistive tech, and blocks page scroll while open —\n * the right default for most popovers. Set to `false` for lighter-weight\n * dismissal behavior (maps to React Aria's `isNonModal`, whose own doc\n * comment scopes it to \"components such as combobox\" — this is why it\n * isn't the default). `<Dialog>` always renders regardless of this prop;\n * `modal` only toggles containment, not whether a dialog role exists.\n *\n * `modal={false}` still blocks page scroll while open — React Aria's own\n * scroll-close behavior for non-modal popovers can't be disabled, so\n * scrolling is locked instead, the same way `Dropdown`'s menu does.\n */\n modal?: boolean\n /**\n * Position relative to the trigger, in React Aria's space-separated form.\n * Defaults to `'bottom start'`. Flips automatically when there isn't room.\n */\n placement?: AriaPopoverProps[\"placement\"]\n}\n\nexport type PopoverContentElementProps = PopoverContentProps\n\n/**\n * The popover surface for a `<Popover>`. Wraps React Aria's `<Popover>` and\n * `<Dialog>` and contains arbitrary content.\n *\n * @component\n */\nexport function PopoverContent({\n \"aria-label\": ariaLabel,\n children,\n className,\n modal = true,\n placement = \"bottom start\",\n}: PopoverContentElementProps) {\n const popoverRef = useRef<HTMLElement>(null)\n const state = useContext(OverlayTriggerStateContext)\n const close = useCallback(() => state?.close(), [state])\n\n const popoverContext = useContext(AriaPopoverContext)\n const triggerRef =\n popoverContext && \"triggerRef\" in popoverContext\n ? popoverContext.triggerRef\n : undefined\n\n useInteractOutside({\n isDisabled: modal || !state?.isOpen,\n onInteractOutside: (event) => {\n if (triggerRef?.current?.contains(event.target as Node)) return\n close()\n },\n ref: popoverRef,\n })\n usePreventScroll({ isDisabled: modal || !state?.isOpen })\n\n return (\n <AriaPopover\n className={classNames(\"tds-popover\", className)}\n isNonModal={!modal}\n placement={placement}\n ref={popoverRef}\n shouldCloseOnInteractOutside={modal ? undefined : () => false}\n >\n <FocusScope contain={!modal}>\n <Dialog aria-label={ariaLabel} className=\"tds-popover-content\">\n <PopoverCloseContext.Provider value={close}>\n {children}\n </PopoverCloseContext.Provider>\n </Dialog>\n </FocusScope>\n </AriaPopover>\n )\n}\n"],"names":["React","AriaPopoverContext","AriaPopover"],"mappings":";;;;;;AAuCA;;;;;;;;;;;AAWG;AACG,SAAU,OAAO,CAAC,EACtB,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,IAAI,GACgB,EAAA;AACpB,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,aAAa,IACZ,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,IAAI,EACZ,YAAY,EAAE,YAAY,IAEzB,QAAQ,CACK;AAEpB;AAiBA;;;;;AAKG;AACG,SAAU,cAAc,CAAC,EAAE,QAAQ,EAA8B,EAAA;AACrE,IAAA,OAAOA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,IAAA,EAAE,QAA0B,CAAa;AAC5D;AAEA,MAAM,mBAAmB,GAAG,aAAa,CAAa,MAAK,EAAE,CAAC,CAAC;AAE/D;;;AAGG;SACa,eAAe,GAAA;AAC7B,IAAA,OAAO,UAAU,CAAC,mBAAmB,CAAC;AACxC;AAoCA;;;;;AAKG;SACa,cAAc,CAAC,EAC7B,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,SAAS,EACT,KAAK,GAAG,IAAI,EACZ,SAAS,GAAG,cAAc,GACC,EAAA;AAC3B,IAAA,MAAM,UAAU,GAAG,MAAM,CAAc,IAAI,CAAC;AAC5C,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,0BAA0B,CAAC;AACpD,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAExD,IAAA,MAAM,cAAc,GAAG,UAAU,CAACC,cAAkB,CAAC;AACrD,IAAA,MAAM,UAAU,GACd,cAAc,IAAI,YAAY,IAAI;UAC9B,cAAc,CAAC;UACf,SAAS;AAEf,IAAA,kBAAkB,CAAC;AACjB,QAAA,UAAU,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,MAAM;AACnC,QAAA,iBAAiB,EAAE,CAAC,KAAK,KAAI;YAC3B,IAAI,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC;gBAAE;AACzD,YAAA,KAAK,EAAE;QACT,CAAC;AACD,QAAA,GAAG,EAAE,UAAU;AAChB,KAAA,CAAC;AACF,IAAA,gBAAgB,CAAC,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;AAEzD,IAAA,QACED,cAAA,CAAA,aAAA,CAACE,SAAW,EAAA,EACV,SAAS,EAAE,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,EAC/C,UAAU,EAAE,CAAC,KAAK,EAClB,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,UAAU,EACf,4BAA4B,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,KAAK,EAAA;AAE7D,QAAAF,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,OAAO,EAAE,CAAC,KAAK,EAAA;AACzB,YAAAA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAA,YAAA,EAAa,SAAS,EAAE,SAAS,EAAC,qBAAqB,EAAA;AAC5D,gBAAAA,cAAA,CAAA,aAAA,CAAC,mBAAmB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,EACvC,QAAQ,CACoB,CACxB,CACE,CACD;AAElB;;;;"}
package/dist/index.css CHANGED
@@ -3922,8 +3922,10 @@ tds-sidenav-section:not(.hydrated) > [slot="ssr"]{
3922
3922
  }
3923
3923
 
3924
3924
  .tds-dropdown-popover{
3925
+ inline-size:-moz-max-content;
3926
+ inline-size:max-content;
3925
3927
  min-inline-size:10rem;
3926
- max-inline-size:24rem;
3928
+ max-inline-size:min(24rem, 100vi);
3927
3929
  padding:var(--t-spacing-1);
3928
3930
  overflow:auto;
3929
3931
  overscroll-behavior:none;
@@ -4757,6 +4759,50 @@ a.tds-dropdown-item:is(:hover, :active){
4757
4759
  inline-size:1em;
4758
4760
  block-size:2em;
4759
4761
  }
4762
+
4763
+ [type="file"]:is(.tds-input input){
4764
+ padding-block:var(--t-spacing-half);
4765
+ padding-inline-start:var(--t-spacing-half);
4766
+ }
4767
+
4768
+ [type="file"]:is(.tds-input input):not(:disabled){
4769
+ color:var(--t-text-color-secondary);
4770
+ }
4771
+
4772
+ [type="file"]:is(.tds-input input)::file-selector-button{
4773
+ --_file-btn-padding-block:3px;
4774
+
4775
+ padding-block:var(--_file-btn-padding-block);
4776
+ padding-inline:12px;
4777
+ margin-inline-end:12px;
4778
+ font:inherit;
4779
+ line-height:calc(var(--tds-input-min-height) - (var(--t-form-border-width) * 2 + var(--t-border-width) * 2 + var(--_file-btn-padding-block) * 2 + var(--t-spacing-half) * 2));
4780
+ color:var(--t-text-color-status-neutral);
4781
+ cursor:pointer;
4782
+ background-color:var(--t-fill-color-button-neutral-solid);
4783
+ border:var(--t-border-width) solid var(--t-fill-color-button-neutral-solid);
4784
+ border-radius:var(--t-border-radius-md);
4785
+ transition-timing-function:var(--t-ease-in-out);
4786
+ transition-duration:var(--t-duration-200);
4787
+ transition-property:color, background-color, border-color;
4788
+ }
4789
+
4790
+ [type="file"]:is(.tds-input input):hover::file-selector-button{
4791
+ background-color:var(--t-fill-color-button-neutral-solid-hover);
4792
+ border-color:var(--t-fill-color-button-neutral-solid-hover);
4793
+ }
4794
+
4795
+ [type="file"]:is(.tds-input input):active::file-selector-button{
4796
+ background-color:var(--t-fill-color-button-neutral-solid-active);
4797
+ border-color:var(--t-fill-color-button-neutral-solid-active);
4798
+ }
4799
+
4800
+ [type="file"]:is(.tds-input input):disabled::file-selector-button{
4801
+ color:var(--t-text-color-disabled);
4802
+ pointer-events:none;
4803
+ background-color:var(--t-fill-color-button-neutral-solid-disabled);
4804
+ border-color:var(--t-fill-color-button-neutral-solid-disabled);
4805
+ }
4760
4806
  @supports (field-sizing: content){
4761
4807
  .tds-input--auto-width{
4762
4808
  inline-size:-moz-fit-content;
@@ -5115,6 +5161,48 @@ a.tds-dropdown-item:is(:hover, :active){
5115
5161
  margin-inline-end:var(--tds-number-stepper-button-offset);
5116
5162
  }
5117
5163
 
5164
+ .tds-popover{
5165
+ max-inline-size:24rem;
5166
+ overflow:auto;
5167
+ overscroll-behavior:none;
5168
+ outline:0;
5169
+ scrollbar-color:#0004 var(--t-surface-color-card);
5170
+ scrollbar-width:thin;
5171
+ background:var(--t-surface-color-card);
5172
+ background-clip:padding-box;
5173
+ border:1px solid var(--t-border-color);
5174
+ border-radius:var(--t-border-radius);
5175
+ box-shadow:0 10px 15px -3px hsl(0 0% 0% / .05), 0 4px 6px -4px hsl(0 0% 0% / .05);
5176
+ }
5177
+
5178
+ @media (prefers-reduced-motion: no-preference){
5179
+ .tds-popover[data-entering]{
5180
+ animation:tds-popover var(--t-duration-300) var(--t-ease-out);
5181
+ }
5182
+
5183
+ .tds-popover[data-exiting]{
5184
+ animation:tds-popover var(--t-duration-200) var(--t-ease-in) reverse;
5185
+ }
5186
+
5187
+ .tds-popover[data-entering],.tds-popover[data-exiting]{
5188
+ will-change:opacity, transform;
5189
+ }
5190
+
5191
+ @keyframes tds-popover{
5192
+ from{
5193
+ opacity:0;
5194
+ transform:translateY(-8px);
5195
+ }
5196
+ }
5197
+ }
5198
+
5199
+ .tds-popover-content{
5200
+ display:flex;
5201
+ flex-direction:column;
5202
+ padding:var(--t-spacing-1);
5203
+ outline:0;
5204
+ }
5205
+
5118
5206
  .tds-radio{
5119
5207
  --tds-radio-font-size:var(--t-font-size-md);
5120
5208
  --tds-radio-cursor:pointer;