@planningcenter/tapestry 3.7.0-rc.0 → 3.8.0-qa-1049.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DataTable/DataTable.d.ts +67 -0
- package/dist/components/DataTable/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable/DataTable.js +39 -0
- package/dist/components/DataTable/DataTable.js.map +1 -0
- package/dist/components/DataTable/index.d.ts +4 -0
- package/dist/components/DataTable/index.d.ts.map +1 -0
- package/dist/components/dropdown/Dropdown.d.ts +8 -1
- package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
- package/dist/components/dropdown/Dropdown.js +2 -2
- package/dist/components/dropdown/Dropdown.js.map +1 -1
- package/dist/reactRender.css +1866 -1835
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +1866 -1835
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/unstable.css +31 -0
- package/dist/unstable.css.map +1 -1
- package/dist/unstable.d.ts +1 -0
- package/dist/unstable.d.ts.map +1 -1
- package/dist/unstable.js +1 -0
- package/dist/unstable.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import "./index.css";
|
|
2
|
+
import type { CombineAriaPropsWithCustomProps } from "../../utilities/reactAriaProps";
|
|
3
|
+
import React, { type ReactNode } from "react";
|
|
4
|
+
import { type TableProps as AriaTableProps } from "react-aria-components/Table";
|
|
5
|
+
export type DataTableColumnType = "boolean" | "currency" | "custom" | "date" | "enum" | "number" | "string";
|
|
6
|
+
interface BaseColumn {
|
|
7
|
+
/** Determines how items align in the table. */
|
|
8
|
+
align?: "center" | "end" | "start";
|
|
9
|
+
/** Human-readable column header label. */
|
|
10
|
+
headerLabel: string;
|
|
11
|
+
/**
|
|
12
|
+
* Visually hides the header label. The text is still rendered (visually
|
|
13
|
+
* hidden via CSS) so it remains announced to assistive tech.
|
|
14
|
+
*/
|
|
15
|
+
hideLabel?: boolean;
|
|
16
|
+
/** Key used to look up the value in each row by default. */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Enables filtering on this column. See Filtering. */
|
|
19
|
+
queryable?: boolean;
|
|
20
|
+
/** Custom cell renderer. Defaults to `row[column.name]`. */
|
|
21
|
+
render?: (row: unknown) => ReactNode;
|
|
22
|
+
/** Enables the resizing of that column. */
|
|
23
|
+
resizable?: boolean;
|
|
24
|
+
/** Enables sorting on this column. */
|
|
25
|
+
sortable?: boolean;
|
|
26
|
+
/** Determines rendering and filter behavior. */
|
|
27
|
+
type: DataTableColumnType;
|
|
28
|
+
}
|
|
29
|
+
export interface EnumColumn extends BaseColumn {
|
|
30
|
+
enumValues: string[];
|
|
31
|
+
type: "enum";
|
|
32
|
+
}
|
|
33
|
+
export interface NumberColumn extends BaseColumn {
|
|
34
|
+
max?: number;
|
|
35
|
+
min?: number;
|
|
36
|
+
step?: number;
|
|
37
|
+
type: "number";
|
|
38
|
+
}
|
|
39
|
+
export type DataTableColumn = BaseColumn | EnumColumn | NumberColumn;
|
|
40
|
+
export interface DataTableProps {
|
|
41
|
+
/** Columns define what data is displayed and how. */
|
|
42
|
+
columns: DataTableColumn[];
|
|
43
|
+
/** The array of rows to display. */
|
|
44
|
+
data: unknown[];
|
|
45
|
+
/** Rendered in place of the table body when there is no data. */
|
|
46
|
+
emptyState?: ReactNode;
|
|
47
|
+
/** Returns a stable identity for each row. Defaults to `row.id`. */
|
|
48
|
+
getRowId?: (row: unknown) => number | string;
|
|
49
|
+
}
|
|
50
|
+
type AriaTablePropsToOmit = "children" | "slot";
|
|
51
|
+
type AriaTablePropsToInclude = never;
|
|
52
|
+
export type DataTableElementProps = CombineAriaPropsWithCustomProps<AriaTableProps, DataTableProps, AriaTablePropsToOmit, AriaTablePropsToInclude>;
|
|
53
|
+
/**
|
|
54
|
+
* A table for displaying tabular data. Built on React Aria's `Table`.
|
|
55
|
+
*
|
|
56
|
+
* This is an early skeleton: only column headers and string cell values are
|
|
57
|
+
* rendered. Sorting, filtering, pagination, selection, and other RFC
|
|
58
|
+
* features are not yet implemented.
|
|
59
|
+
*
|
|
60
|
+
* @component
|
|
61
|
+
*/
|
|
62
|
+
export declare const DataTable: {
|
|
63
|
+
({ className, columns, data, emptyState, getRowId, ...restProps }: DataTableElementProps): React.JSX.Element;
|
|
64
|
+
displayName: string;
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=DataTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAEhF,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,EAOL,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,6BAA6B,CAAA;AAEpC,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,UAAU,GACV,QAAQ,GACR,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,CAAA;AAEZ,UAAU,UAAU;IAClB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;IAClC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,SAAS,CAAA;IACpC,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gDAAgD;IAChD,IAAI,EAAE,mBAAmB,CAAA;CAC1B;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,CAAA;AAEpE,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,oCAAoC;IACpC,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,iEAAiE;IACjE,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,MAAM,CAAA;CAC7C;AAED,KAAK,oBAAoB,GAAG,UAAU,GAAG,MAAM,CAAA;AAE/C,KAAK,uBAAuB,GAAG,KAAK,CAAA;AAEpC,MAAM,MAAM,qBAAqB,GAAG,+BAA+B,CACjE,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,uBAAuB,CACxB,CAAA;AAkBD;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS;uEAOnB,qBAAqB;;CA4CvB,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { Table, TableHeader, Column, TableBody, Row, Cell } from 'react-aria-components/Table';
|
|
4
|
+
|
|
5
|
+
function getCellValue(row, column) {
|
|
6
|
+
if (column.render)
|
|
7
|
+
return column.render(row);
|
|
8
|
+
const value = row?.[column.name];
|
|
9
|
+
return value === undefined || value === null ? "" : String(value);
|
|
10
|
+
}
|
|
11
|
+
function getRowKey(row, index, getRowId) {
|
|
12
|
+
if (getRowId)
|
|
13
|
+
return getRowId(row);
|
|
14
|
+
const id = row?.id;
|
|
15
|
+
return typeof id === "number" || typeof id === "string" ? id : index;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A table for displaying tabular data. Built on React Aria's `Table`.
|
|
19
|
+
*
|
|
20
|
+
* This is an early skeleton: only column headers and string cell values are
|
|
21
|
+
* rendered. Sorting, filtering, pagination, selection, and other RFC
|
|
22
|
+
* features are not yet implemented.
|
|
23
|
+
*
|
|
24
|
+
* @component
|
|
25
|
+
*/
|
|
26
|
+
const DataTable = ({ className, columns, data, emptyState, getRowId, ...restProps }) => {
|
|
27
|
+
const combinedClassName = classNames("tds-data-table", className);
|
|
28
|
+
return (React__default.createElement("div", { className: "tds-data-table-wrapper" },
|
|
29
|
+
React__default.createElement(Table, { ...restProps, className: combinedClassName },
|
|
30
|
+
React__default.createElement(TableHeader, { className: "tds-data-table-header" }, columns.map((column, index) => (React__default.createElement(Column, { key: column.name, id: column.name, isRowHeader: index === 0, className: "tds-data-table-column" }, column.hideLabel ? (React__default.createElement("span", { className: "tds-data-table-column-label--hidden" }, column.headerLabel)) : (column.headerLabel))))),
|
|
31
|
+
React__default.createElement(TableBody, { className: "tds-data-table-body", renderEmptyState: emptyState ? () => emptyState : undefined }, data.map((row, rowIndex) => {
|
|
32
|
+
const rowKey = getRowKey(row, rowIndex, getRowId);
|
|
33
|
+
return (React__default.createElement(Row, { key: rowKey, id: rowKey, className: "tds-data-table-row" }, columns.map((column) => (React__default.createElement(Cell, { key: column.name, className: "tds-data-table-cell" }, getCellValue(row, column))))));
|
|
34
|
+
})))));
|
|
35
|
+
};
|
|
36
|
+
DataTable.displayName = "DataTable";
|
|
37
|
+
|
|
38
|
+
export { DataTable };
|
|
39
|
+
//# sourceMappingURL=DataTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport classNames from \"classnames\"\nimport React, { type ReactNode } from \"react\"\nimport {\n Cell,\n Column,\n Row,\n Table,\n TableBody,\n TableHeader,\n type TableProps as AriaTableProps,\n} from \"react-aria-components/Table\"\n\nexport type DataTableColumnType =\n | \"boolean\"\n | \"currency\"\n | \"custom\"\n | \"date\"\n | \"enum\"\n | \"number\"\n | \"string\"\n\ninterface BaseColumn {\n /** Determines how items align in the table. */\n align?: \"center\" | \"end\" | \"start\"\n /** Human-readable column header label. */\n headerLabel: string\n /**\n * Visually hides the header label. The text is still rendered (visually\n * hidden via CSS) so it remains announced to assistive tech.\n */\n hideLabel?: boolean\n /** Key used to look up the value in each row by default. */\n name: string\n /** Enables filtering on this column. See Filtering. */\n queryable?: boolean\n /** Custom cell renderer. Defaults to `row[column.name]`. */\n render?: (row: unknown) => ReactNode\n /** Enables the resizing of that column. */\n resizable?: boolean\n /** Enables sorting on this column. */\n sortable?: boolean\n /** Determines rendering and filter behavior. */\n type: DataTableColumnType\n}\n\nexport interface EnumColumn extends BaseColumn {\n enumValues: string[]\n type: \"enum\"\n}\n\nexport interface NumberColumn extends BaseColumn {\n max?: number\n min?: number\n step?: number\n type: \"number\"\n}\n\nexport type DataTableColumn = BaseColumn | EnumColumn | NumberColumn\n\nexport interface DataTableProps {\n /** Columns define what data is displayed and how. */\n columns: DataTableColumn[]\n /** The array of rows to display. */\n data: unknown[]\n /** Rendered in place of the table body when there is no data. */\n emptyState?: ReactNode\n /** Returns a stable identity for each row. Defaults to `row.id`. */\n getRowId?: (row: unknown) => number | string\n}\n\ntype AriaTablePropsToOmit = \"children\" | \"slot\"\n\ntype AriaTablePropsToInclude = never\n\nexport type DataTableElementProps = CombineAriaPropsWithCustomProps<\n AriaTableProps,\n DataTableProps,\n AriaTablePropsToOmit,\n AriaTablePropsToInclude\n>\n\nfunction getCellValue(row: unknown, column: DataTableColumn): ReactNode {\n if (column.render) return column.render(row)\n const value = (row as Record<string, unknown>)?.[column.name]\n return value === undefined || value === null ? \"\" : String(value)\n}\n\nfunction getRowKey(\n row: unknown,\n index: number,\n getRowId?: (row: unknown) => number | string\n): number | string {\n if (getRowId) return getRowId(row)\n const id = (row as Record<string, unknown>)?.id\n return typeof id === \"number\" || typeof id === \"string\" ? id : index\n}\n\n/**\n * A table for displaying tabular data. Built on React Aria's `Table`.\n *\n * This is an early skeleton: only column headers and string cell values are\n * rendered. Sorting, filtering, pagination, selection, and other RFC\n * features are not yet implemented.\n *\n * @component\n */\nexport const DataTable = ({\n className,\n columns,\n data,\n emptyState,\n getRowId,\n ...restProps\n}: DataTableElementProps) => {\n const combinedClassName = classNames(\"tds-data-table\", className)\n\n return (\n <div className=\"tds-data-table-wrapper\">\n <Table {...restProps} className={combinedClassName}>\n <TableHeader className=\"tds-data-table-header\">\n {columns.map((column, index) => (\n <Column\n key={column.name}\n id={column.name}\n isRowHeader={index === 0}\n className=\"tds-data-table-column\"\n >\n {column.hideLabel ? (\n <span className=\"tds-data-table-column-label--hidden\">\n {column.headerLabel}\n </span>\n ) : (\n column.headerLabel\n )}\n </Column>\n ))}\n </TableHeader>\n <TableBody\n className=\"tds-data-table-body\"\n renderEmptyState={emptyState ? () => emptyState : undefined}\n >\n {data.map((row, rowIndex) => {\n const rowKey = getRowKey(row, rowIndex, getRowId)\n return (\n <Row key={rowKey} id={rowKey} className=\"tds-data-table-row\">\n {columns.map((column) => (\n <Cell key={column.name} className=\"tds-data-table-cell\">\n {getCellValue(row, column)}\n </Cell>\n ))}\n </Row>\n )\n })}\n </TableBody>\n </Table>\n </div>\n )\n}\n\nDataTable.displayName = \"DataTable\"\n"],"names":["React"],"mappings":";;;;AAoFA,SAAS,YAAY,CAAC,GAAY,EAAE,MAAuB,EAAA;IACzD,IAAI,MAAM,CAAC,MAAM;AAAE,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAC5C,MAAM,KAAK,GAAI,GAA+B,GAAG,MAAM,CAAC,IAAI,CAAC;AAC7D,IAAA,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;AACnE;AAEA,SAAS,SAAS,CAChB,GAAY,EACZ,KAAa,EACb,QAA4C,EAAA;AAE5C,IAAA,IAAI,QAAQ;AAAE,QAAA,OAAO,QAAQ,CAAC,GAAG,CAAC;AAClC,IAAA,MAAM,EAAE,GAAI,GAA+B,EAAE,EAAE;AAC/C,IAAA,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ,GAAG,EAAE,GAAG,KAAK;AACtE;AAEA;;;;;;;;AAQG;MACU,SAAS,GAAG,CAAC,EACxB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,GAAG,SAAS,EACU,KAAI;IAC1B,MAAM,iBAAiB,GAAG,UAAU,CAAC,gBAAgB,EAAE,SAAS,CAAC;AAEjE,IAAA,QACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wBAAwB,EAAA;AACrC,QAAAA,cAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAA,GAAK,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAA;AAChD,YAAAA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAC,SAAS,EAAC,uBAAuB,EAAA,EAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MACzBA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EACL,GAAG,EAAE,MAAM,CAAC,IAAI,EAChB,EAAE,EAAE,MAAM,CAAC,IAAI,EACf,WAAW,EAAE,KAAK,KAAK,CAAC,EACxB,SAAS,EAAC,uBAAuB,EAAA,EAEhC,MAAM,CAAC,SAAS,IACfA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,qCAAqC,EAAA,EAClD,MAAM,CAAC,WAAW,CACd,KAEP,MAAM,CAAC,WAAW,CACnB,CACM,CACV,CAAC,CACU;AACd,YAAAA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EACR,SAAS,EAAC,qBAAqB,EAC/B,gBAAgB,EAAE,UAAU,GAAG,MAAM,UAAU,GAAG,SAAS,EAAA,EAE1D,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAI;gBAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC;gBACjD,QACEA,6BAAC,GAAG,EAAA,EAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAC,oBAAoB,EAAA,EACzD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAClBA,cAAA,CAAA,aAAA,CAAC,IAAI,IAAC,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAC,qBAAqB,IACpD,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CACrB,CACR,CAAC,CACE;AAEV,YAAA,CAAC,CAAC,CACQ,CACN,CACJ;AAEV;AAEA,SAAS,CAAC,WAAW,GAAG,WAAW;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -93,6 +93,13 @@ export interface DropdownActionProps extends DropdownItemBaseProps {
|
|
|
93
93
|
id: Key;
|
|
94
94
|
/** Callback fired when the item is activated. */
|
|
95
95
|
onAction: () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Runs `onAction` after the menu has been told to close, instead of
|
|
98
|
+
* before. Use this when `onAction` needs to move focus elsewhere — e.g.
|
|
99
|
+
* focusing a nearby input — otherwise the menu's own focus handling on
|
|
100
|
+
* close can override it.
|
|
101
|
+
*/
|
|
102
|
+
runAfterClose?: boolean;
|
|
96
103
|
}
|
|
97
104
|
type AriaActionPropsToOmit = "href" | "isDisabled" | "rel" | "routerOptions" | "target" | "value";
|
|
98
105
|
type AriaActionPropsToInclude = "textValue";
|
|
@@ -105,7 +112,7 @@ export type DropdownActionElementProps<T extends object = object> = CombineAriaP
|
|
|
105
112
|
*
|
|
106
113
|
* @component
|
|
107
114
|
*/
|
|
108
|
-
export declare function DropdownAction<T extends object>({ className, destructive, disabled, staffOnly, ...restProps }: DropdownActionElementProps<T>): React.JSX.Element;
|
|
115
|
+
export declare function DropdownAction<T extends object>({ className, destructive, disabled, onAction, runAfterClose, staffOnly, ...restProps }: DropdownActionElementProps<T>): React.JSX.Element;
|
|
109
116
|
export interface DropdownLinkProps extends DropdownItemBaseProps {
|
|
110
117
|
/** If `true`, sets `target="_blank"` and `rel="noreferrer noopener"`. */
|
|
111
118
|
external?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/dropdown/Dropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAA;AAEhF,OAAO,KAAK,EAAE,EAEZ,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,EACV,GAAG,EACH,aAAa,EACb,gBAAgB,EAChB,YAAY,EACb,MAAM,uBAAuB,CAAA;AAc9B,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAA;IACnB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,oBAAoB,qBAO3E;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAA;IACnB,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAA;CAC9B;AAED,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,CAAA;AAExD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,EAAE,EACF,SAA0B,GAC3B,EAAE,wBAAwB,qBAM1B;AAED,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,EAAE,YAAY,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAWD,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,oBAAoB,qBAM3E;AAED,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAChE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,EAAE,EAAE,GAAG,CAAA;IACP,iDAAiD;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/dropdown/Dropdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -55,11 +55,11 @@ function DropdownTrigger({ children, disabled }) {
|
|
|
55
55
|
*
|
|
56
56
|
* @component
|
|
57
57
|
*/
|
|
58
|
-
function DropdownAction({ className, destructive, disabled, staffOnly, ...restProps }) {
|
|
58
|
+
function DropdownAction({ className, destructive, disabled, onAction, runAfterClose, staffOnly, ...restProps }) {
|
|
59
59
|
return (React__default.createElement(MenuItem, { ...restProps, className: classNames("tds-dropdown-item", {
|
|
60
60
|
"tds-dropdown-item--destructive": destructive,
|
|
61
61
|
"tds-dropdown-item--staff-only": staffOnly,
|
|
62
|
-
}, className), isDisabled: disabled }));
|
|
62
|
+
}, className), isDisabled: disabled, onAction: runAfterClose ? () => queueMicrotask(onAction) : onAction }));
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* A `<Dropdown>` item that navigates to a URL. Renders an RA `<MenuItem>` as
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","sources":["../../../src/components/dropdown/Dropdown.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n type ReactElement,\n type ReactNode,\n} from \"react\"\nimport type {\n Key,\n MenuItemProps,\n MenuSectionProps,\n PopoverProps,\n} from \"react-aria-components\"\nimport {\n Header,\n Menu,\n MenuItem,\n MenuSection,\n MenuTrigger,\n Popover,\n Pressable,\n Separator,\n} from \"react-aria-components/Menu\"\n\nimport { DropdownTriggerContext } from \"./DropdownTriggerContext\"\n\nexport type DropdownPlacement = NonNullable<PopoverProps[\"placement\"]>\n\nexport interface DropdownProps {\n /**\n * A `<DropdownTrigger>` followed by a `<DropdownMenu>` containing the items.\n */\n children: ReactNode\n /** Fires when the menu closes. */\n onClose?: () => void\n /** Fires when the menu opens. Useful for analytics or lazy data prep. */\n onOpen?: () => void\n}\n\nexport type DropdownElementProps = DropdownProps\n\n/**\n * An action menu — a button that, when activated, reveals a list of actions or\n * navigation links. Composed of a `<DropdownTrigger>` wrapping a Tapestry\n * dropdown-trigger button (`DropdownButton`, `DropdownIconButton`, or\n * `PageHeaderActionsDropdownButton`) and a `<DropdownMenu>` containing\n * `<DropdownAction>`, `<DropdownLink>`, `<DropdownSection>`, and\n * `<DropdownSeparator>` items.\n *\n * **Dropdown vs Select.** Use `Dropdown` to trigger an action (\"Edit\",\n * \"Delete\") or navigate (\"Go to documentation\"). Use `Select` to collect a\n * value that is bound to form data or component state. They look visually\n * similar but follow different ARIA patterns (Menu vs Combobox/Listbox) and\n * are not interchangeable.\n *\n * Built on React Aria's `MenuTrigger` primitive; popover positioning and menu\n * identity live on `<DropdownMenu>`.\n *\n * @component\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menu/ | W3C APG Menu Pattern}\n * @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}\n */\nexport function Dropdown({ children, onClose, onOpen }: DropdownElementProps) {\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) onOpen?.()\n else onClose?.()\n }\n\n return <MenuTrigger onOpenChange={handleOpenChange}>{children}</MenuTrigger>\n}\n\nexport interface DropdownMenuProps {\n /**\n * `<DropdownAction>` / `<DropdownLink>` / `<DropdownSection>` /\n * `<DropdownSeparator>` elements.\n */\n children: ReactNode\n /** Override for the underlying `<Menu>` element id. */\n id?: string\n /**\n * Popover position relative to the trigger. Uses React Aria's\n * space-separated format (e.g., `\"bottom start\"`, `\"top end\"`,\n * `\"left top\"`). Defaults to `\"bottom start\"`.\n */\n placement?: DropdownPlacement\n}\n\nexport type DropdownMenuElementProps = DropdownMenuProps\n\n/**\n * The popover surface for a `<Dropdown>`. Wraps React Aria's `<Popover>` and\n * `<Menu>` and contains the menu items.\n *\n * @component\n */\nexport function DropdownMenu({\n children,\n id,\n placement = \"bottom start\",\n}: DropdownMenuElementProps) {\n return (\n <Popover className=\"tds-dropdown-popover\" placement={placement}>\n <Menu id={id}>{children}</Menu>\n </Popover>\n )\n}\n\nexport interface DropdownTriggerProps {\n /**\n * A single Tapestry dropdown-trigger button element (`DropdownButton`,\n * `DropdownIconButton`, or `PageHeaderActionsDropdownButton`).\n */\n children: ReactElement\n /**\n * Whether the trigger is disabled. This is the single source of truth for the\n * trigger's disabled state — a `disabled` set directly on the child button\n * does not win.\n */\n disabled?: boolean\n}\n\n/**\n * Wraps a single Tapestry dropdown-trigger button and bridges it to React\n * Aria's `MenuTrigger` via `<Pressable>`.\n * Uses context to pass `disabled` to the trigger button.\n *\n * @component\n */\ntype PressableChild = ComponentProps<typeof Pressable>[\"children\"]\n\nexport function DropdownTrigger({ children, disabled }: DropdownTriggerProps) {\n return (\n <DropdownTriggerContext.Provider value={{ disabled }}>\n <Pressable isDisabled={disabled}>{children as PressableChild}</Pressable>\n </DropdownTriggerContext.Provider>\n )\n}\n\nexport interface DropdownItemBaseProps {\n /** Applies destructive styling. */\n destructive?: boolean\n /** Applies staff-only visual treatment. */\n staffOnly?: boolean\n}\n\nexport interface DropdownActionProps extends DropdownItemBaseProps {\n /**\n * Disables the item. Renamed to React Aria's `isDisabled` inside the\n * wrapper. Disabled items are skipped by keyboard traversal and won't fire\n * `onAction`.\n */\n disabled?: boolean\n /**\n * Stable identifier — required by React Aria's collection model for keying\n * and focus tracking.\n */\n id: Key\n /** Callback fired when the item is activated. */\n onAction: () => void\n}\n\ntype AriaActionPropsToOmit =\n | \"href\"\n | \"isDisabled\"\n | \"rel\"\n | \"routerOptions\"\n | \"target\"\n | \"value\"\ntype AriaActionPropsToInclude = \"textValue\"\n\nexport type DropdownActionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuItemProps<T>,\n DropdownActionProps,\n AriaActionPropsToOmit,\n AriaActionPropsToInclude\n >\n\n/**\n * A `<Dropdown>` item that fires a callback when activated. Renders an RA\n * `<MenuItem>` (`role=\"menuitem\"`). Children are passed through and can use\n * the slot convention (`slot=\"label\" | \"prefix\" | \"suffix\" | \"description\"`)\n * for structured content.\n *\n * @component\n */\nexport function DropdownAction<T extends object>({\n className,\n destructive,\n disabled,\n staffOnly,\n ...restProps\n}: DropdownActionElementProps<T>) {\n return (\n <MenuItem\n {...restProps}\n className={classNames(\n \"tds-dropdown-item\",\n {\n \"tds-dropdown-item--destructive\": destructive,\n \"tds-dropdown-item--staff-only\": staffOnly,\n },\n className\n )}\n isDisabled={disabled}\n />\n )\n}\n\nexport interface DropdownLinkProps extends DropdownItemBaseProps {\n /** If `true`, sets `target=\"_blank\"` and `rel=\"noreferrer noopener\"`. */\n external?: boolean\n /** Destination URL. */\n href: string\n /**\n * Stable identifier — required by React Aria's collection model for keying\n * and focus tracking.\n */\n id: Key\n}\n\ntype AriaLinkPropsToOmit =\n | \"isDisabled\"\n | \"onAction\"\n | \"rel\"\n | \"target\"\n | \"value\"\ntype AriaLinkPropsToInclude = \"href\" | \"routerOptions\" | \"textValue\"\n\nexport type DropdownLinkElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuItemProps<T>,\n DropdownLinkProps,\n AriaLinkPropsToOmit,\n AriaLinkPropsToInclude\n >\n\n/**\n * A `<Dropdown>` item that navigates to a URL. Renders an RA `<MenuItem>` as\n * an anchor (`<a role=\"menuitem\" href=\"…\">`). Pass `external` to open in a\n * new tab with `rel=\"noreferrer noopener\"`.\n *\n * `disabled` is intentionally not accepted — HTML has no native disabled state\n * for anchors, and a \"disabled link\" has no accessible analog. If a link\n * shouldn't be activatable, omit it.\n *\n * @component\n */\nexport function DropdownLink<T extends object>({\n className,\n destructive,\n external,\n staffOnly,\n ...restProps\n}: DropdownLinkElementProps<T>) {\n const externalProps = external\n ? { rel: \"noreferrer noopener\", target: \"_blank\" as const }\n : null\n return (\n <MenuItem\n {...restProps}\n {...externalProps}\n className={classNames(\n \"tds-dropdown-item\",\n {\n \"tds-dropdown-item--destructive\": destructive,\n \"tds-dropdown-item--staff-only\": staffOnly,\n },\n className\n )}\n />\n )\n}\n\nexport interface DropdownSectionProps {\n /** The items rendered within the section. */\n children: ReactNode\n /**\n * Heading rendered above the section's items. Required — RA renders the\n * section as `role=\"group\"` and the heading provides the group's\n * accessible name via `aria-labelledby`.\n */\n title: string\n}\n\nexport type DropdownSectionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuSectionProps<T>,\n DropdownSectionProps,\n \"value\",\n never\n >\n\n/**\n * A grouped section within a `<Dropdown>`. Renders an RA `<MenuSection>`\n * (`role=\"group\"`) with an optional `<Header>` heading when `title` is set.\n *\n * @component\n */\nexport function DropdownSection<T extends object>({\n children,\n className,\n title,\n ...restProps\n}: DropdownSectionElementProps<T>) {\n return (\n <MenuSection\n {...restProps}\n className={classNames(\"tds-dropdown-section\", className)}\n >\n <Header className=\"tds-dropdown-section-label\">{title}</Header>\n {children}\n </MenuSection>\n )\n}\n\nexport type DropdownSeparatorElementProps = Record<string, never>\n\n/**\n * A divider between items in a `<Dropdown>`. Renders an RA `<Separator>`\n * (`role=\"separator\"`).\n *\n * @component\n */\nexport function DropdownSeparator() {\n return <Separator className=\"tds-dropdown-separator\" />\n}\n"],"names":["React"],"mappings":";;;;;AA2CA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAwB,EAAA;AAC1E,IAAA,MAAM,gBAAgB,GAAG,CAAC,MAAe,KAAI;AAC3C,QAAA,IAAI,MAAM;YAAE,MAAM,IAAI;;YACjB,OAAO,IAAI;AAClB,IAAA,CAAC;IAED,OAAOA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAC,YAAY,EAAE,gBAAgB,EAAA,EAAG,QAAQ,CAAe;AAC9E;AAoBA;;;;;AAKG;AACG,SAAU,YAAY,CAAC,EAC3B,QAAQ,EACR,EAAE,EACF,SAAS,GAAG,cAAc,GACD,EAAA;IACzB,QACEA,cAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,SAAS,EAAC,sBAAsB,EAAC,SAAS,EAAE,SAAS,EAAA;QAC5DA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,EAAE,EAAE,EAAE,IAAG,QAAQ,CAAQ,CACvB;AAEd;SAyBgB,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAwB,EAAA;IAC1E,QACEA,cAAA,CAAA,aAAA,CAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAA;QAClDA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EAAC,UAAU,EAAE,QAAQ,IAAG,QAA0B,CAAa,CACzC;AAEtC;AA0CA;;;;;;;AAOG;AACG,SAAU,cAAc,CAAmB,EAC/C,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,GAAG,SAAS,EACkB,EAAA;IAC9B,QACEA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAA,GACH,SAAS,EACb,SAAS,EAAE,UAAU,CACnB,mBAAmB,EACnB;AACE,YAAA,gCAAgC,EAAE,WAAW;AAC7C,YAAA,+BAA+B,EAAE,SAAS;SAC3C,EACD,SAAS,CACV,EACD,UAAU,EAAE,QAAQ,EAAA,CACpB;AAEN;AA8BA;;;;;;;;;;AAUG;AACG,SAAU,YAAY,CAAmB,EAC7C,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,GAAG,SAAS,EACgB,EAAA;IAC5B,MAAM,aAAa,GAAG;UAClB,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAiB;UACvD,IAAI;AACR,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAA,GACH,SAAS,EAAA,GACT,aAAa,EACjB,SAAS,EAAE,UAAU,CACnB,mBAAmB,EACnB;AACE,YAAA,gCAAgC,EAAE,WAAW;AAC7C,YAAA,+BAA+B,EAAE,SAAS;AAC3C,SAAA,EACD,SAAS,CACV,EAAA,CACD;AAEN;AAqBA;;;;;AAKG;AACG,SAAU,eAAe,CAAmB,EAChD,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,SAAS,EACmB,EAAA;AAC/B,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,GACN,SAAS,EACb,SAAS,EAAE,UAAU,CAAC,sBAAsB,EAAE,SAAS,CAAC,EAAA;AAExD,QAAAA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,SAAS,EAAC,4BAA4B,EAAA,EAAE,KAAK,CAAU;QAC9D,QAAQ,CACG;AAElB;AAIA;;;;;AAKG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAOA,6BAAC,SAAS,EAAA,EAAC,SAAS,EAAC,wBAAwB,GAAG;AACzD;;;;"}
|
|
1
|
+
{"version":3,"file":"Dropdown.js","sources":["../../../src/components/dropdown/Dropdown.tsx"],"sourcesContent":["import \"./index.css\"\n\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n type ReactElement,\n type ReactNode,\n} from \"react\"\nimport type {\n Key,\n MenuItemProps,\n MenuSectionProps,\n PopoverProps,\n} from \"react-aria-components\"\nimport {\n Header,\n Menu,\n MenuItem,\n MenuSection,\n MenuTrigger,\n Popover,\n Pressable,\n Separator,\n} from \"react-aria-components/Menu\"\n\nimport { DropdownTriggerContext } from \"./DropdownTriggerContext\"\n\nexport type DropdownPlacement = NonNullable<PopoverProps[\"placement\"]>\n\nexport interface DropdownProps {\n /**\n * A `<DropdownTrigger>` followed by a `<DropdownMenu>` containing the items.\n */\n children: ReactNode\n /** Fires when the menu closes. */\n onClose?: () => void\n /** Fires when the menu opens. Useful for analytics or lazy data prep. */\n onOpen?: () => void\n}\n\nexport type DropdownElementProps = DropdownProps\n\n/**\n * An action menu — a button that, when activated, reveals a list of actions or\n * navigation links. Composed of a `<DropdownTrigger>` wrapping a Tapestry\n * dropdown-trigger button (`DropdownButton`, `DropdownIconButton`, or\n * `PageHeaderActionsDropdownButton`) and a `<DropdownMenu>` containing\n * `<DropdownAction>`, `<DropdownLink>`, `<DropdownSection>`, and\n * `<DropdownSeparator>` items.\n *\n * **Dropdown vs Select.** Use `Dropdown` to trigger an action (\"Edit\",\n * \"Delete\") or navigate (\"Go to documentation\"). Use `Select` to collect a\n * value that is bound to form data or component state. They look visually\n * similar but follow different ARIA patterns (Menu vs Combobox/Listbox) and\n * are not interchangeable.\n *\n * Built on React Aria's `MenuTrigger` primitive; popover positioning and menu\n * identity live on `<DropdownMenu>`.\n *\n * @component\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menu/ | W3C APG Menu Pattern}\n * @see {@link https://github.com/planningcenter/tapestry/tree/main/packages/tapestry-migration-cli | Migration CLI: Available}\n */\nexport function Dropdown({ children, onClose, onOpen }: DropdownElementProps) {\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) onOpen?.()\n else onClose?.()\n }\n\n return <MenuTrigger onOpenChange={handleOpenChange}>{children}</MenuTrigger>\n}\n\nexport interface DropdownMenuProps {\n /**\n * `<DropdownAction>` / `<DropdownLink>` / `<DropdownSection>` /\n * `<DropdownSeparator>` elements.\n */\n children: ReactNode\n /** Override for the underlying `<Menu>` element id. */\n id?: string\n /**\n * Popover position relative to the trigger. Uses React Aria's\n * space-separated format (e.g., `\"bottom start\"`, `\"top end\"`,\n * `\"left top\"`). Defaults to `\"bottom start\"`.\n */\n placement?: DropdownPlacement\n}\n\nexport type DropdownMenuElementProps = DropdownMenuProps\n\n/**\n * The popover surface for a `<Dropdown>`. Wraps React Aria's `<Popover>` and\n * `<Menu>` and contains the menu items.\n *\n * @component\n */\nexport function DropdownMenu({\n children,\n id,\n placement = \"bottom start\",\n}: DropdownMenuElementProps) {\n return (\n <Popover className=\"tds-dropdown-popover\" placement={placement}>\n <Menu id={id}>{children}</Menu>\n </Popover>\n )\n}\n\nexport interface DropdownTriggerProps {\n /**\n * A single Tapestry dropdown-trigger button element (`DropdownButton`,\n * `DropdownIconButton`, or `PageHeaderActionsDropdownButton`).\n */\n children: ReactElement\n /**\n * Whether the trigger is disabled. This is the single source of truth for the\n * trigger's disabled state — a `disabled` set directly on the child button\n * does not win.\n */\n disabled?: boolean\n}\n\n/**\n * Wraps a single Tapestry dropdown-trigger button and bridges it to React\n * Aria's `MenuTrigger` via `<Pressable>`.\n * Uses context to pass `disabled` to the trigger button.\n *\n * @component\n */\ntype PressableChild = ComponentProps<typeof Pressable>[\"children\"]\n\nexport function DropdownTrigger({ children, disabled }: DropdownTriggerProps) {\n return (\n <DropdownTriggerContext.Provider value={{ disabled }}>\n <Pressable isDisabled={disabled}>{children as PressableChild}</Pressable>\n </DropdownTriggerContext.Provider>\n )\n}\n\nexport interface DropdownItemBaseProps {\n /** Applies destructive styling. */\n destructive?: boolean\n /** Applies staff-only visual treatment. */\n staffOnly?: boolean\n}\n\nexport interface DropdownActionProps extends DropdownItemBaseProps {\n /**\n * Disables the item. Renamed to React Aria's `isDisabled` inside the\n * wrapper. Disabled items are skipped by keyboard traversal and won't fire\n * `onAction`.\n */\n disabled?: boolean\n /**\n * Stable identifier — required by React Aria's collection model for keying\n * and focus tracking.\n */\n id: Key\n /** Callback fired when the item is activated. */\n onAction: () => void\n /**\n * Runs `onAction` after the menu has been told to close, instead of\n * before. Use this when `onAction` needs to move focus elsewhere — e.g.\n * focusing a nearby input — otherwise the menu's own focus handling on\n * close can override it.\n */\n runAfterClose?: boolean\n}\n\ntype AriaActionPropsToOmit =\n | \"href\"\n | \"isDisabled\"\n | \"rel\"\n | \"routerOptions\"\n | \"target\"\n | \"value\"\ntype AriaActionPropsToInclude = \"textValue\"\n\nexport type DropdownActionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuItemProps<T>,\n DropdownActionProps,\n AriaActionPropsToOmit,\n AriaActionPropsToInclude\n >\n\n/**\n * A `<Dropdown>` item that fires a callback when activated. Renders an RA\n * `<MenuItem>` (`role=\"menuitem\"`). Children are passed through and can use\n * the slot convention (`slot=\"label\" | \"prefix\" | \"suffix\" | \"description\"`)\n * for structured content.\n *\n * @component\n */\nexport function DropdownAction<T extends object>({\n className,\n destructive,\n disabled,\n onAction,\n runAfterClose,\n staffOnly,\n ...restProps\n}: DropdownActionElementProps<T>) {\n return (\n <MenuItem\n {...restProps}\n className={classNames(\n \"tds-dropdown-item\",\n {\n \"tds-dropdown-item--destructive\": destructive,\n \"tds-dropdown-item--staff-only\": staffOnly,\n },\n className\n )}\n isDisabled={disabled}\n onAction={runAfterClose ? () => queueMicrotask(onAction) : onAction}\n />\n )\n}\n\nexport interface DropdownLinkProps extends DropdownItemBaseProps {\n /** If `true`, sets `target=\"_blank\"` and `rel=\"noreferrer noopener\"`. */\n external?: boolean\n /** Destination URL. */\n href: string\n /**\n * Stable identifier — required by React Aria's collection model for keying\n * and focus tracking.\n */\n id: Key\n}\n\ntype AriaLinkPropsToOmit =\n | \"isDisabled\"\n | \"onAction\"\n | \"rel\"\n | \"target\"\n | \"value\"\ntype AriaLinkPropsToInclude = \"href\" | \"routerOptions\" | \"textValue\"\n\nexport type DropdownLinkElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuItemProps<T>,\n DropdownLinkProps,\n AriaLinkPropsToOmit,\n AriaLinkPropsToInclude\n >\n\n/**\n * A `<Dropdown>` item that navigates to a URL. Renders an RA `<MenuItem>` as\n * an anchor (`<a role=\"menuitem\" href=\"…\">`). Pass `external` to open in a\n * new tab with `rel=\"noreferrer noopener\"`.\n *\n * `disabled` is intentionally not accepted — HTML has no native disabled state\n * for anchors, and a \"disabled link\" has no accessible analog. If a link\n * shouldn't be activatable, omit it.\n *\n * @component\n */\nexport function DropdownLink<T extends object>({\n className,\n destructive,\n external,\n staffOnly,\n ...restProps\n}: DropdownLinkElementProps<T>) {\n const externalProps = external\n ? { rel: \"noreferrer noopener\", target: \"_blank\" as const }\n : null\n return (\n <MenuItem\n {...restProps}\n {...externalProps}\n className={classNames(\n \"tds-dropdown-item\",\n {\n \"tds-dropdown-item--destructive\": destructive,\n \"tds-dropdown-item--staff-only\": staffOnly,\n },\n className\n )}\n />\n )\n}\n\nexport interface DropdownSectionProps {\n /** The items rendered within the section. */\n children: ReactNode\n /**\n * Heading rendered above the section's items. Required — RA renders the\n * section as `role=\"group\"` and the heading provides the group's\n * accessible name via `aria-labelledby`.\n */\n title: string\n}\n\nexport type DropdownSectionElementProps<T extends object = object> =\n CombineAriaPropsWithCustomProps<\n MenuSectionProps<T>,\n DropdownSectionProps,\n \"value\",\n never\n >\n\n/**\n * A grouped section within a `<Dropdown>`. Renders an RA `<MenuSection>`\n * (`role=\"group\"`) with an optional `<Header>` heading when `title` is set.\n *\n * @component\n */\nexport function DropdownSection<T extends object>({\n children,\n className,\n title,\n ...restProps\n}: DropdownSectionElementProps<T>) {\n return (\n <MenuSection\n {...restProps}\n className={classNames(\"tds-dropdown-section\", className)}\n >\n <Header className=\"tds-dropdown-section-label\">{title}</Header>\n {children}\n </MenuSection>\n )\n}\n\nexport type DropdownSeparatorElementProps = Record<string, never>\n\n/**\n * A divider between items in a `<Dropdown>`. Renders an RA `<Separator>`\n * (`role=\"separator\"`).\n *\n * @component\n */\nexport function DropdownSeparator() {\n return <Separator className=\"tds-dropdown-separator\" />\n}\n"],"names":["React"],"mappings":";;;;;AA2CA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAwB,EAAA;AAC1E,IAAA,MAAM,gBAAgB,GAAG,CAAC,MAAe,KAAI;AAC3C,QAAA,IAAI,MAAM;YAAE,MAAM,IAAI;;YACjB,OAAO,IAAI;AAClB,IAAA,CAAC;IAED,OAAOA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAC,YAAY,EAAE,gBAAgB,EAAA,EAAG,QAAQ,CAAe;AAC9E;AAoBA;;;;;AAKG;AACG,SAAU,YAAY,CAAC,EAC3B,QAAQ,EACR,EAAE,EACF,SAAS,GAAG,cAAc,GACD,EAAA;IACzB,QACEA,cAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,SAAS,EAAC,sBAAsB,EAAC,SAAS,EAAE,SAAS,EAAA;QAC5DA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,EAAE,EAAE,EAAE,IAAG,QAAQ,CAAQ,CACvB;AAEd;SAyBgB,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAwB,EAAA;IAC1E,QACEA,cAAA,CAAA,aAAA,CAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAA;QAClDA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,EAAC,UAAU,EAAE,QAAQ,IAAG,QAA0B,CAAa,CACzC;AAEtC;AAiDA;;;;;;;AAOG;SACa,cAAc,CAAmB,EAC/C,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,SAAS,EACT,GAAG,SAAS,EACkB,EAAA;IAC9B,QACEA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAA,GACH,SAAS,EACb,SAAS,EAAE,UAAU,CACnB,mBAAmB,EACnB;AACE,YAAA,gCAAgC,EAAE,WAAW;AAC7C,YAAA,+BAA+B,EAAE,SAAS;SAC3C,EACD,SAAS,CACV,EACD,UAAU,EAAE,QAAQ,EACpB,QAAQ,EAAE,aAAa,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,GAAG,QAAQ,EAAA,CACnE;AAEN;AA8BA;;;;;;;;;;AAUG;AACG,SAAU,YAAY,CAAmB,EAC7C,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,GAAG,SAAS,EACgB,EAAA;IAC5B,MAAM,aAAa,GAAG;UAClB,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAiB;UACvD,IAAI;AACR,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAA,GACH,SAAS,EAAA,GACT,aAAa,EACjB,SAAS,EAAE,UAAU,CACnB,mBAAmB,EACnB;AACE,YAAA,gCAAgC,EAAE,WAAW;AAC7C,YAAA,+BAA+B,EAAE,SAAS;AAC3C,SAAA,EACD,SAAS,CACV,EAAA,CACD;AAEN;AAqBA;;;;;AAKG;AACG,SAAU,eAAe,CAAmB,EAChD,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,SAAS,EACmB,EAAA;AAC/B,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,GACN,SAAS,EACb,SAAS,EAAE,UAAU,CAAC,sBAAsB,EAAE,SAAS,CAAC,EAAA;AAExD,QAAAA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,SAAS,EAAC,4BAA4B,EAAA,EAAE,KAAK,CAAU;QAC9D,QAAQ,CACG;AAElB;AAIA;;;;;AAKG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAOA,6BAAC,SAAS,EAAA,EAAC,SAAS,EAAC,wBAAwB,GAAG;AACzD;;;;"}
|