@launchpad-ui/filter 0.4.6-alpha.0 → 0.4.6-alpha.1

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.
@@ -0,0 +1,26 @@
1
+ import type { FilterOption } from './FilterMenu';
2
+ import type { ChangeEvent, ReactNode } from 'react';
3
+ declare type AppliedFilterProps = {
4
+ searchValue?: string;
5
+ onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;
6
+ onClearFilter?(): void;
7
+ searchPlaceholder?: string;
8
+ name?: ReactNode;
9
+ description: ReactNode;
10
+ options: FilterOption[];
11
+ className?: string;
12
+ onStateChange?({ isOpen }: {
13
+ isOpen?: boolean;
14
+ }): void;
15
+ isSelected?: boolean;
16
+ onSelect?(item: FilterOption): void;
17
+ isEmpty?: boolean;
18
+ isLoading?: boolean;
19
+ onClickFilterButton?(): void;
20
+ searchAriaLabel?: string;
21
+ 'data-test-id'?: string;
22
+ };
23
+ declare const AppliedFilter: ({ searchValue, onSearchChange, searchPlaceholder, name, description, options, className, isEmpty, isLoading, onClickFilterButton, onClearFilter, searchAriaLabel, "data-test-id": testId, ...props }: AppliedFilterProps) => JSX.Element;
24
+ export type { AppliedFilterProps };
25
+ export { AppliedFilter };
26
+ //# sourceMappingURL=AppliedFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppliedFilter.d.ts","sourceRoot":"","sources":["../src/AppliedFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUpD,aAAK,kBAAkB,GAAG;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAC5D,aAAa,CAAC,IAAI,IAAI,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mBAAmB,CAAC,IAAI,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,aAAa,yMAehB,kBAAkB,gBA6BpB,CAAC;AAEF,YAAY,EAAE,kBAAkB,EAAE,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+ import './styles/Filter.css';
3
+ declare type AppliedFilterButtonProps = {
4
+ name?: ReactNode;
5
+ className?: string;
6
+ isSelected?: boolean;
7
+ children: ReactNode;
8
+ onClickFilterButton?(): void;
9
+ };
10
+ declare const AppliedFilterButton: import("react").ForwardRefExoticComponent<AppliedFilterButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
11
+ export type { AppliedFilterButtonProps };
12
+ export { AppliedFilterButton };
13
+ //# sourceMappingURL=AppliedFilterButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppliedFilterButton.d.ts","sourceRoot":"","sources":["../src/AppliedFilterButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,qBAAqB,CAAC;AAE7B,aAAK,wBAAwB,GAAG;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,mBAAmB,CAAC,IAAI,IAAI,CAAC;CAC9B,CAAC;AAIF,QAAA,MAAM,mBAAmB,wHAwBvB,CAAC;AAIH,YAAY,EAAE,wBAAwB,EAAE,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { FilterOption } from './FilterMenu';
2
+ import type { MenuProps } from '@launchpad-ui/menu';
3
+ import type { ChangeEvent, ReactNode } from 'react';
4
+ declare type FilterProps = Pick<MenuProps<string>, 'size' | 'enableVirtualization'> & {
5
+ searchValue?: string;
6
+ onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;
7
+ searchPlaceholder?: string;
8
+ searchAriaLabel?: string;
9
+ name: ReactNode;
10
+ hideName?: boolean;
11
+ description: ReactNode;
12
+ options: FilterOption[];
13
+ isClearable?: boolean;
14
+ onClear?(): void;
15
+ className?: string;
16
+ onStateChange?({ isOpen }: {
17
+ isOpen?: boolean;
18
+ }): void;
19
+ isSelected?: boolean;
20
+ onSelect?(item: FilterOption): void;
21
+ isEmpty?: boolean;
22
+ isLoading?: boolean;
23
+ onClickFilterButton?(): void;
24
+ disabledOptionTooltip?: string;
25
+ 'data-test-id'?: string;
26
+ triggerTestId?: string;
27
+ };
28
+ declare const Filter: ({ searchValue, onSearchChange, searchPlaceholder, searchAriaLabel, name, hideName, description, options, isClearable, onClear, isSelected, className, isEmpty, isLoading, onClickFilterButton, disabledOptionTooltip, "data-test-id": testId, size, enableVirtualization, ...props }: FilterProps) => JSX.Element;
29
+ export { Filter };
30
+ export type { FilterProps };
31
+ //# sourceMappingURL=Filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../src/Filter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAC;AAUpE,aAAK,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAAC,GAAG;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mBAAmB,CAAC,IAAI,IAAI,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,MAAM,yRAqBT,WAAW,gBAsCb,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ReactNode, SyntheticEvent } from 'react';
2
+ import './styles/Filter.css';
3
+ declare type FilterButtonProps = {
4
+ name: ReactNode;
5
+ hideName?: boolean;
6
+ isClearable?: boolean;
7
+ onClear?(event: SyntheticEvent): void;
8
+ className?: string;
9
+ isSelected?: boolean;
10
+ clearTooltip?: string | JSX.Element;
11
+ children?: ReactNode;
12
+ onClickFilterButton?(): void;
13
+ 'data-test-id'?: string;
14
+ };
15
+ declare const FilterButton: import("react").ForwardRefExoticComponent<FilterButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
16
+ export { FilterButton };
17
+ export type { FilterButtonProps };
18
+ //# sourceMappingURL=FilterButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterButton.d.ts","sourceRoot":"","sources":["../src/FilterButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AASvD,OAAO,qBAAqB,CAAC;AAE7B,aAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mBAAmB,CAAC,IAAI,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,QAAA,MAAM,YAAY,iHA4DhB,CAAC;AAQH,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { MenuProps } from '@launchpad-ui/menu';
2
+ import type { ChangeEvent, ReactNode } from 'react';
3
+ declare type FilterOption<T = any> = {
4
+ name?: ReactNode;
5
+ isDisabled?: boolean;
6
+ isDivider?: boolean;
7
+ isChecked?: boolean;
8
+ value: T | null;
9
+ projKey?: string;
10
+ nested?: boolean;
11
+ groupHeader?: boolean;
12
+ };
13
+ declare type FilterMenuProps = Pick<MenuProps<string>, 'enableVirtualization' | 'size'> & {
14
+ options: FilterOption[];
15
+ onClearFilter?(): void;
16
+ enableSearch?: boolean;
17
+ searchValue?: string;
18
+ searchPlaceholder?: string;
19
+ searchAriaLabel?: string;
20
+ onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;
21
+ onSelect?(): void;
22
+ isLoading?: boolean;
23
+ disabledOptionTooltip?: string;
24
+ };
25
+ declare const FilterMenu: ({ options, onClearFilter, enableSearch, searchValue, searchPlaceholder, searchAriaLabel, onSelect, onSearchChange, isLoading, disabledOptionTooltip, enableVirtualization, size, }: FilterMenuProps) => JSX.Element;
26
+ export { FilterMenu };
27
+ export type { FilterOption, FilterMenuProps };
28
+ //# sourceMappingURL=FilterMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterMenu.d.ts","sourceRoot":"","sources":["../src/FilterMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOpD,aAAK,YAAY,CAAC,CAAC,GAAG,GAAG,IAAI;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,aAAK,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC,GAAG;IAChF,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,CAAC,IAAI,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAC5D,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,QAAA,MAAM,UAAU,uLAab,eAAe,gBA+CjB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type { AppliedFilterProps } from './AppliedFilter';
2
+ export type { FilterProps } from './Filter';
3
+ export type { FilterButtonProps } from './FilterButton';
4
+ export type { FilterOption } from './FilterMenu';
5
+ export { AppliedFilter } from './AppliedFilter';
6
+ export { Filter } from './Filter';
7
+ export { FilterButton } from './FilterButton';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,259 @@
1
+ import './style.css';
2
+ import { Dropdown } from "@launchpad-ui/dropdown";
3
+ import { cx } from "classix";
4
+ import { ExpandMore, Check, Close } from "@launchpad-ui/icons";
5
+ import { forwardRef, Children, useId } from "react";
6
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
7
+ import { Button, IconButton } from "@launchpad-ui/button";
8
+ import { Menu, MenuSearch, MenuDivider, MenuItem } from "@launchpad-ui/menu";
9
+ import { Tooltip } from "@launchpad-ui/tooltip";
10
+ import { VisuallyHidden } from "@react-aria/visually-hidden";
11
+ const Filter$1 = "";
12
+ const AppliedFilterButton = forwardRef((props, ref) => {
13
+ const {
14
+ name,
15
+ className,
16
+ isSelected,
17
+ children,
18
+ onClickFilterButton
19
+ } = props;
20
+ const hasDescription = Children.count(children) !== 0;
21
+ return /* @__PURE__ */ jsx("div", {
22
+ className: "AppliedFilter-buttonContainer",
23
+ children: /* @__PURE__ */ jsxs("button", {
24
+ "aria-haspopup": true,
25
+ className: cx("AppliedFilter-button", isSelected && "isSelected", className),
26
+ ref,
27
+ onClick: onClickFilterButton,
28
+ children: [name && /* @__PURE__ */ jsxs("span", {
29
+ className: "AppliedFilter-name",
30
+ children: [name, hasDescription && ":"]
31
+ }), hasDescription && /* @__PURE__ */ jsx("span", {
32
+ className: "AppliedFilter-description",
33
+ children
34
+ }), /* @__PURE__ */ jsx(ExpandMore, {
35
+ size: "small"
36
+ })]
37
+ })
38
+ });
39
+ });
40
+ AppliedFilterButton.displayName = "AppliedFilterButton";
41
+ const FilterMenu = ({
42
+ options,
43
+ onClearFilter,
44
+ enableSearch,
45
+ searchValue,
46
+ searchPlaceholder,
47
+ searchAriaLabel,
48
+ onSelect,
49
+ onSearchChange,
50
+ isLoading = false,
51
+ disabledOptionTooltip,
52
+ enableVirtualization,
53
+ size
54
+ }) => {
55
+ const filterOptions = isLoading ? [{
56
+ name: "loading...",
57
+ value: "loading...",
58
+ isDisabled: true
59
+ }] : options;
60
+ return /* @__PURE__ */ jsxs(Fragment, {
61
+ children: [onClearFilter && /* @__PURE__ */ jsx(Button, {
62
+ tabIndex: 0,
63
+ className: "Menu-clear",
64
+ onClick: onClearFilter,
65
+ kind: "link",
66
+ children: "CLEAR FILTER"
67
+ }), /* @__PURE__ */ jsxs(Menu, {
68
+ enableVirtualization,
69
+ size,
70
+ onSelect,
71
+ children: [enableSearch && /* @__PURE__ */ jsx(MenuSearch, {
72
+ value: searchValue,
73
+ placeholder: searchPlaceholder,
74
+ onChange: onSearchChange,
75
+ ariaLabel: searchAriaLabel
76
+ }), filterOptions.map((option, index) => {
77
+ if (option.isDivider) {
78
+ return /* @__PURE__ */ jsx(MenuDivider, {}, `divider-${index}`);
79
+ }
80
+ return /* @__PURE__ */ jsx(MenuItem, {
81
+ item: option,
82
+ disabled: option.isDisabled,
83
+ icon: option.isChecked ? Check : null,
84
+ role: "menuitemradio",
85
+ "aria-checked": option.isChecked ? "true" : void 0,
86
+ nested: option.nested,
87
+ groupHeader: option.groupHeader,
88
+ tooltip: option.isDisabled && disabledOptionTooltip ? disabledOptionTooltip : void 0,
89
+ tooltipPlacement: "right",
90
+ children: option.name
91
+ }, option.value);
92
+ })]
93
+ })]
94
+ });
95
+ };
96
+ const SEARCH_INPUT_THRESHOLD$1 = 4;
97
+ const AppliedFilter = ({
98
+ searchValue,
99
+ onSearchChange,
100
+ searchPlaceholder,
101
+ name,
102
+ description,
103
+ options,
104
+ className,
105
+ isEmpty,
106
+ isLoading,
107
+ onClickFilterButton,
108
+ onClearFilter,
109
+ searchAriaLabel,
110
+ "data-test-id": testId = "applied-filter",
111
+ ...props
112
+ }) => {
113
+ const enableSearch = onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD$1 || !isEmpty);
114
+ const dropdownClasses = cx("Filter-target", className);
115
+ return /* @__PURE__ */ jsxs(Dropdown, {
116
+ targetClassName: dropdownClasses,
117
+ placement: "bottom-start",
118
+ enableArrow: false,
119
+ "data-test-id": testId,
120
+ ...props,
121
+ children: [/* @__PURE__ */ jsx(AppliedFilterButton, {
122
+ name,
123
+ onClickFilterButton,
124
+ children: description
125
+ }), /* @__PURE__ */ jsx(FilterMenu, {
126
+ options,
127
+ searchValue,
128
+ searchPlaceholder,
129
+ enableSearch,
130
+ searchAriaLabel,
131
+ onSearchChange,
132
+ onClearFilter,
133
+ isLoading
134
+ })]
135
+ });
136
+ };
137
+ const FilterButton = forwardRef((props, ref) => {
138
+ const {
139
+ children,
140
+ name,
141
+ hideName,
142
+ isClearable,
143
+ clearTooltip,
144
+ onClear,
145
+ isSelected,
146
+ onClickFilterButton,
147
+ className,
148
+ "data-test-id": testId = "filter-button",
149
+ ...rest
150
+ } = props;
151
+ const nameId = useId();
152
+ const descriptionId = useId();
153
+ const hasDescription = Children.count(children) !== 0;
154
+ const nameElement = /* @__PURE__ */ jsxs("span", {
155
+ className: "Filter-name",
156
+ children: [name, hasDescription && ":"]
157
+ });
158
+ return /* @__PURE__ */ jsxs("div", {
159
+ className: "Filter-buttonContainer",
160
+ "data-test-id": testId,
161
+ children: [/* @__PURE__ */ jsxs("button", {
162
+ ...rest,
163
+ "aria-labelledby": `${nameId} ${hasDescription ? descriptionId : ""}`,
164
+ "aria-haspopup": true,
165
+ className: cx("Filter-button", className, (isClearable || isSelected) && "is-clearable"),
166
+ ref,
167
+ onClick: onClickFilterButton,
168
+ children: [hideName ? /* @__PURE__ */ jsx(VisuallyHidden, {
169
+ id: nameId,
170
+ children: nameElement
171
+ }) : /* @__PURE__ */ jsx("span", {
172
+ id: nameId,
173
+ children: nameElement
174
+ }), hasDescription && /* @__PURE__ */ jsx("span", {
175
+ id: descriptionId,
176
+ className: "Filter-description",
177
+ children
178
+ }), !isClearable && /* @__PURE__ */ jsx(ExpandMore, {
179
+ size: "small"
180
+ })]
181
+ }), isClearable && /* @__PURE__ */ jsx(Tooltip, {
182
+ targetClassName: "Filter-clearTooltip",
183
+ content: clearTooltip,
184
+ children: /* @__PURE__ */ jsx(IconButton, {
185
+ "aria-label": "Clear filter",
186
+ className: "Filter-clear",
187
+ icon: /* @__PURE__ */ jsx(Close, {
188
+ size: "tiny"
189
+ }),
190
+ onClick: onClear
191
+ })
192
+ })]
193
+ });
194
+ });
195
+ FilterButton.defaultProps = {
196
+ clearTooltip: "Clear filter"
197
+ };
198
+ FilterButton.displayName = "FilterButton";
199
+ const SEARCH_INPUT_THRESHOLD = 4;
200
+ const Filter = ({
201
+ searchValue,
202
+ onSearchChange,
203
+ searchPlaceholder,
204
+ searchAriaLabel,
205
+ name,
206
+ hideName,
207
+ description,
208
+ options,
209
+ isClearable,
210
+ onClear,
211
+ isSelected,
212
+ className,
213
+ isEmpty,
214
+ isLoading,
215
+ onClickFilterButton,
216
+ disabledOptionTooltip,
217
+ "data-test-id": testId = "filter",
218
+ size,
219
+ enableVirtualization,
220
+ ...props
221
+ }) => {
222
+ const enableSearch = onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);
223
+ const dropdownClasses = cx("Filter", "Filter-target", className);
224
+ const handleClear = (event) => {
225
+ event.preventDefault();
226
+ onClear == null ? void 0 : onClear();
227
+ };
228
+ return /* @__PURE__ */ jsxs(Dropdown, {
229
+ targetClassName: dropdownClasses,
230
+ ...props,
231
+ children: [/* @__PURE__ */ jsx(FilterButton, {
232
+ isClearable,
233
+ onClear: handleClear,
234
+ name,
235
+ hideName,
236
+ isSelected,
237
+ onClickFilterButton,
238
+ "data-test-id": testId,
239
+ children: description
240
+ }), /* @__PURE__ */ jsx(FilterMenu, {
241
+ options,
242
+ searchValue,
243
+ searchPlaceholder,
244
+ searchAriaLabel,
245
+ enableSearch,
246
+ onSearchChange,
247
+ isLoading,
248
+ disabledOptionTooltip,
249
+ size,
250
+ enableVirtualization
251
+ })]
252
+ });
253
+ };
254
+ export {
255
+ AppliedFilter,
256
+ Filter,
257
+ FilterButton
258
+ };
259
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../src/AppliedFilterButton.tsx","../src/FilterMenu.tsx","../src/AppliedFilter.tsx","../src/FilterButton.tsx","../src/Filter.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { cx } from 'classix';\nimport { Children, forwardRef } from 'react';\n\nimport './styles/Filter.css';\n\ntype AppliedFilterButtonProps = {\n name?: ReactNode;\n className?: string;\n isSelected?: boolean;\n children: ReactNode;\n onClickFilterButton?(): void;\n};\n\ntype Ref = HTMLButtonElement;\n\nconst AppliedFilterButton = forwardRef<Ref, AppliedFilterButtonProps>((props, ref) => {\n const { name, className, isSelected, children, onClickFilterButton } = props;\n\n const hasDescription = Children.count(children) !== 0;\n\n return (\n <div className=\"AppliedFilter-buttonContainer\">\n <button\n aria-haspopup\n className={cx('AppliedFilter-button', isSelected && 'isSelected', className)}\n ref={ref}\n onClick={onClickFilterButton}\n >\n {name && (\n <span className=\"AppliedFilter-name\">\n {name}\n {hasDescription && ':'}\n </span>\n )}\n {hasDescription && <span className=\"AppliedFilter-description\">{children}</span>}\n <ExpandMore size=\"small\" />\n </button>\n </div>\n );\n});\n\nAppliedFilterButton.displayName = 'AppliedFilterButton';\n\nexport type { AppliedFilterButtonProps };\nexport { AppliedFilterButton };\n","import type { MenuProps } from '@launchpad-ui/menu';\nimport type { ChangeEvent, ReactNode } from 'react';\n\nimport { Button } from '@launchpad-ui/button';\nimport { Check } from '@launchpad-ui/icons';\nimport { Menu, MenuDivider, MenuItem, MenuSearch } from '@launchpad-ui/menu';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FilterOption<T = any> = {\n name?: ReactNode;\n isDisabled?: boolean;\n isDivider?: boolean;\n isChecked?: boolean;\n value: T | null;\n projKey?: string;\n nested?: boolean;\n groupHeader?: boolean;\n};\n\ntype FilterMenuProps = Pick<MenuProps<string>, 'enableVirtualization' | 'size'> & {\n options: FilterOption[];\n onClearFilter?(): void;\n enableSearch?: boolean;\n searchValue?: string;\n searchPlaceholder?: string;\n searchAriaLabel?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n onSelect?(): void;\n isLoading?: boolean;\n disabledOptionTooltip?: string;\n};\n\nconst FilterMenu = ({\n options,\n onClearFilter,\n enableSearch,\n searchValue,\n searchPlaceholder,\n searchAriaLabel,\n onSelect,\n onSearchChange,\n isLoading = false,\n disabledOptionTooltip,\n enableVirtualization,\n size,\n}: FilterMenuProps) => {\n const filterOptions = isLoading\n ? [{ name: 'loading...', value: 'loading...', isDisabled: true }]\n : options;\n\n return (\n <>\n {onClearFilter && (\n <Button tabIndex={0} className=\"Menu-clear\" onClick={onClearFilter} kind=\"link\">\n CLEAR FILTER\n </Button>\n )}\n <Menu enableVirtualization={enableVirtualization} size={size} onSelect={onSelect}>\n {enableSearch && (\n <MenuSearch\n value={searchValue}\n placeholder={searchPlaceholder}\n onChange={onSearchChange}\n ariaLabel={searchAriaLabel}\n />\n )}\n {filterOptions.map((option, index) => {\n if (option.isDivider) {\n return <MenuDivider key={`divider-${index}`} />;\n }\n return (\n <MenuItem\n item={option}\n disabled={option.isDisabled}\n icon={option.isChecked ? Check : null}\n key={option.value}\n role=\"menuitemradio\"\n aria-checked={option.isChecked ? 'true' : undefined}\n nested={option.nested}\n groupHeader={option.groupHeader}\n tooltip={\n option.isDisabled && disabledOptionTooltip ? disabledOptionTooltip : undefined\n }\n tooltipPlacement=\"right\"\n >\n {option.name}\n </MenuItem>\n );\n })}\n </Menu>\n </>\n );\n};\n\nexport { FilterMenu };\nexport type { FilterOption, FilterMenuProps };\n","import type { FilterOption } from './FilterMenu';\nimport type { ChangeEvent, ReactNode } from 'react';\n\nimport { Dropdown } from '@launchpad-ui/dropdown';\nimport { cx } from 'classix';\n\nimport { AppliedFilterButton } from './AppliedFilterButton';\nimport { FilterMenu } from './FilterMenu';\n\nconst SEARCH_INPUT_THRESHOLD = 4;\n\ntype AppliedFilterProps = {\n searchValue?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n onClearFilter?(): void;\n searchPlaceholder?: string;\n name?: ReactNode;\n description: ReactNode;\n options: FilterOption[];\n className?: string;\n onStateChange?({ isOpen }: { isOpen?: boolean }): void;\n isSelected?: boolean;\n onSelect?(item: FilterOption): void;\n isEmpty?: boolean;\n isLoading?: boolean;\n onClickFilterButton?(): void;\n searchAriaLabel?: string;\n 'data-test-id'?: string;\n};\n\nconst AppliedFilter = ({\n searchValue,\n onSearchChange,\n searchPlaceholder,\n name,\n description,\n options,\n className,\n isEmpty,\n isLoading,\n onClickFilterButton,\n onClearFilter,\n searchAriaLabel,\n 'data-test-id': testId = 'applied-filter',\n ...props\n}: AppliedFilterProps) => {\n const enableSearch =\n onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);\n\n const dropdownClasses = cx('Filter-target', className);\n return (\n <Dropdown\n targetClassName={dropdownClasses}\n placement=\"bottom-start\"\n enableArrow={false}\n data-test-id={testId}\n {...props}\n >\n <AppliedFilterButton name={name} onClickFilterButton={onClickFilterButton}>\n {description}\n </AppliedFilterButton>\n\n <FilterMenu\n options={options}\n searchValue={searchValue}\n searchPlaceholder={searchPlaceholder}\n enableSearch={enableSearch}\n searchAriaLabel={searchAriaLabel}\n onSearchChange={onSearchChange}\n onClearFilter={onClearFilter}\n isLoading={isLoading}\n />\n </Dropdown>\n );\n};\n\nexport type { AppliedFilterProps };\nexport { AppliedFilter };\n","import type { ReactNode, SyntheticEvent } from 'react';\n\nimport { IconButton } from '@launchpad-ui/button';\nimport { Close, ExpandMore } from '@launchpad-ui/icons';\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { cx } from 'classix';\nimport { Children, forwardRef, useId } from 'react';\n\nimport './styles/Filter.css';\n\ntype FilterButtonProps = {\n name: ReactNode;\n hideName?: boolean;\n isClearable?: boolean;\n onClear?(event: SyntheticEvent): void;\n className?: string;\n isSelected?: boolean;\n clearTooltip?: string | JSX.Element;\n children?: ReactNode;\n onClickFilterButton?(): void;\n 'data-test-id'?: string;\n};\n\ntype Ref = HTMLButtonElement;\n\nconst FilterButton = forwardRef<Ref, FilterButtonProps>((props, ref) => {\n const {\n children,\n name,\n hideName,\n isClearable,\n clearTooltip,\n onClear,\n isSelected,\n onClickFilterButton,\n className,\n 'data-test-id': testId = 'filter-button',\n ...rest\n } = props;\n const nameId = useId();\n const descriptionId = useId();\n\n const hasDescription = Children.count(children) !== 0;\n\n const nameElement = (\n <span className=\"Filter-name\">\n {name}\n {hasDescription && ':'}\n </span>\n );\n\n return (\n <div className=\"Filter-buttonContainer\" data-test-id={testId}>\n <button\n {...rest}\n aria-labelledby={`${nameId} ${hasDescription ? descriptionId : ''}`}\n aria-haspopup\n className={cx('Filter-button', className, (isClearable || isSelected) && 'is-clearable')}\n ref={ref}\n onClick={onClickFilterButton}\n >\n {hideName ? (\n <VisuallyHidden id={nameId}>{nameElement}</VisuallyHidden>\n ) : (\n <span id={nameId}>{nameElement}</span>\n )}\n {hasDescription && (\n <span id={descriptionId} className=\"Filter-description\">\n {children}\n </span>\n )}\n {!isClearable && <ExpandMore size=\"small\" />}\n </button>\n {isClearable && (\n <Tooltip targetClassName=\"Filter-clearTooltip\" content={clearTooltip}>\n <IconButton\n aria-label=\"Clear filter\"\n className=\"Filter-clear\"\n icon={<Close size=\"tiny\" />}\n onClick={onClear}\n />\n </Tooltip>\n )}\n </div>\n );\n});\n\nFilterButton.defaultProps = {\n clearTooltip: 'Clear filter',\n};\n\nFilterButton.displayName = 'FilterButton';\n\nexport { FilterButton };\nexport type { FilterButtonProps };\n","import type { FilterOption } from './FilterMenu';\nimport type { MenuProps } from '@launchpad-ui/menu';\nimport type { ChangeEvent, ReactNode, SyntheticEvent } from 'react';\n\nimport { Dropdown } from '@launchpad-ui/dropdown';\nimport { cx } from 'classix';\n\nimport { FilterButton } from './FilterButton';\nimport { FilterMenu } from './FilterMenu';\n\nconst SEARCH_INPUT_THRESHOLD = 4;\n\ntype FilterProps = Pick<MenuProps<string>, 'size' | 'enableVirtualization'> & {\n searchValue?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n searchPlaceholder?: string;\n searchAriaLabel?: string;\n name: ReactNode;\n hideName?: boolean;\n description: ReactNode;\n options: FilterOption[];\n isClearable?: boolean;\n onClear?(): void;\n className?: string;\n onStateChange?({ isOpen }: { isOpen?: boolean }): void;\n isSelected?: boolean;\n onSelect?(item: FilterOption): void;\n isEmpty?: boolean;\n isLoading?: boolean;\n onClickFilterButton?(): void;\n disabledOptionTooltip?: string;\n 'data-test-id'?: string;\n triggerTestId?: string;\n};\n\nconst Filter = ({\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAriaLabel,\n name,\n hideName,\n description,\n options,\n isClearable,\n onClear,\n isSelected,\n className,\n isEmpty,\n isLoading,\n onClickFilterButton,\n disabledOptionTooltip,\n 'data-test-id': testId = 'filter',\n size,\n enableVirtualization,\n ...props\n}: FilterProps) => {\n const enableSearch =\n onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);\n\n const dropdownClasses = cx('Filter', 'Filter-target', className);\n\n const handleClear = (event: SyntheticEvent) => {\n event.preventDefault();\n onClear?.();\n };\n\n return (\n <Dropdown targetClassName={dropdownClasses} {...props}>\n <FilterButton\n isClearable={isClearable}\n onClear={handleClear}\n name={name}\n hideName={hideName}\n isSelected={isSelected}\n onClickFilterButton={onClickFilterButton}\n data-test-id={testId}\n >\n {description}\n </FilterButton>\n <FilterMenu\n options={options}\n searchValue={searchValue}\n searchPlaceholder={searchPlaceholder}\n searchAriaLabel={searchAriaLabel}\n enableSearch={enableSearch}\n onSearchChange={onSearchChange}\n isLoading={isLoading}\n disabledOptionTooltip={disabledOptionTooltip}\n size={size}\n enableVirtualization={enableVirtualization}\n />\n </Dropdown>\n );\n};\n\nexport { Filter };\nexport type { FilterProps };\n"],"names":["AppliedFilterButton","forwardRef","props","ref","name","className","isSelected","children","onClickFilterButton","hasDescription","Children","count","cx","_jsxs","_jsx","displayName","FilterMenu","options","onClearFilter","enableSearch","searchValue","searchPlaceholder","searchAriaLabel","onSelect","onSearchChange","isLoading","disabledOptionTooltip","enableVirtualization","size","filterOptions","value","isDisabled","_Fragment","map","option","index","isDivider","isChecked","Check","undefined","nested","groupHeader","SEARCH_INPUT_THRESHOLD","AppliedFilter","description","isEmpty","testId","length","dropdownClasses","FilterButton","hideName","isClearable","clearTooltip","onClear","rest","nameId","useId","descriptionId","nameElement","defaultProps","Filter","handleClear","event","preventDefault"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,259 @@
1
+ require('./style.css');
2
+ "use strict";
3
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
4
+ const dropdown = require("@launchpad-ui/dropdown");
5
+ const classix = require("classix");
6
+ const icons = require("@launchpad-ui/icons");
7
+ const react = require("react");
8
+ const jsxRuntime = require("react/jsx-runtime");
9
+ const button = require("@launchpad-ui/button");
10
+ const menu = require("@launchpad-ui/menu");
11
+ const tooltip = require("@launchpad-ui/tooltip");
12
+ const visuallyHidden = require("@react-aria/visually-hidden");
13
+ const Filter$1 = "";
14
+ const AppliedFilterButton = react.forwardRef((props, ref) => {
15
+ const {
16
+ name,
17
+ className,
18
+ isSelected,
19
+ children,
20
+ onClickFilterButton
21
+ } = props;
22
+ const hasDescription = react.Children.count(children) !== 0;
23
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
24
+ className: "AppliedFilter-buttonContainer",
25
+ children: /* @__PURE__ */ jsxRuntime.jsxs("button", {
26
+ "aria-haspopup": true,
27
+ className: classix.cx("AppliedFilter-button", isSelected && "isSelected", className),
28
+ ref,
29
+ onClick: onClickFilterButton,
30
+ children: [name && /* @__PURE__ */ jsxRuntime.jsxs("span", {
31
+ className: "AppliedFilter-name",
32
+ children: [name, hasDescription && ":"]
33
+ }), hasDescription && /* @__PURE__ */ jsxRuntime.jsx("span", {
34
+ className: "AppliedFilter-description",
35
+ children
36
+ }), /* @__PURE__ */ jsxRuntime.jsx(icons.ExpandMore, {
37
+ size: "small"
38
+ })]
39
+ })
40
+ });
41
+ });
42
+ AppliedFilterButton.displayName = "AppliedFilterButton";
43
+ const FilterMenu = ({
44
+ options,
45
+ onClearFilter,
46
+ enableSearch,
47
+ searchValue,
48
+ searchPlaceholder,
49
+ searchAriaLabel,
50
+ onSelect,
51
+ onSearchChange,
52
+ isLoading = false,
53
+ disabledOptionTooltip,
54
+ enableVirtualization,
55
+ size
56
+ }) => {
57
+ const filterOptions = isLoading ? [{
58
+ name: "loading...",
59
+ value: "loading...",
60
+ isDisabled: true
61
+ }] : options;
62
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
63
+ children: [onClearFilter && /* @__PURE__ */ jsxRuntime.jsx(button.Button, {
64
+ tabIndex: 0,
65
+ className: "Menu-clear",
66
+ onClick: onClearFilter,
67
+ kind: "link",
68
+ children: "CLEAR FILTER"
69
+ }), /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
70
+ enableVirtualization,
71
+ size,
72
+ onSelect,
73
+ children: [enableSearch && /* @__PURE__ */ jsxRuntime.jsx(menu.MenuSearch, {
74
+ value: searchValue,
75
+ placeholder: searchPlaceholder,
76
+ onChange: onSearchChange,
77
+ ariaLabel: searchAriaLabel
78
+ }), filterOptions.map((option, index) => {
79
+ if (option.isDivider) {
80
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}, `divider-${index}`);
81
+ }
82
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
83
+ item: option,
84
+ disabled: option.isDisabled,
85
+ icon: option.isChecked ? icons.Check : null,
86
+ role: "menuitemradio",
87
+ "aria-checked": option.isChecked ? "true" : void 0,
88
+ nested: option.nested,
89
+ groupHeader: option.groupHeader,
90
+ tooltip: option.isDisabled && disabledOptionTooltip ? disabledOptionTooltip : void 0,
91
+ tooltipPlacement: "right",
92
+ children: option.name
93
+ }, option.value);
94
+ })]
95
+ })]
96
+ });
97
+ };
98
+ const SEARCH_INPUT_THRESHOLD$1 = 4;
99
+ const AppliedFilter = ({
100
+ searchValue,
101
+ onSearchChange,
102
+ searchPlaceholder,
103
+ name,
104
+ description,
105
+ options,
106
+ className,
107
+ isEmpty,
108
+ isLoading,
109
+ onClickFilterButton,
110
+ onClearFilter,
111
+ searchAriaLabel,
112
+ "data-test-id": testId = "applied-filter",
113
+ ...props
114
+ }) => {
115
+ const enableSearch = onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD$1 || !isEmpty);
116
+ const dropdownClasses = classix.cx("Filter-target", className);
117
+ return /* @__PURE__ */ jsxRuntime.jsxs(dropdown.Dropdown, {
118
+ targetClassName: dropdownClasses,
119
+ placement: "bottom-start",
120
+ enableArrow: false,
121
+ "data-test-id": testId,
122
+ ...props,
123
+ children: [/* @__PURE__ */ jsxRuntime.jsx(AppliedFilterButton, {
124
+ name,
125
+ onClickFilterButton,
126
+ children: description
127
+ }), /* @__PURE__ */ jsxRuntime.jsx(FilterMenu, {
128
+ options,
129
+ searchValue,
130
+ searchPlaceholder,
131
+ enableSearch,
132
+ searchAriaLabel,
133
+ onSearchChange,
134
+ onClearFilter,
135
+ isLoading
136
+ })]
137
+ });
138
+ };
139
+ const FilterButton = react.forwardRef((props, ref) => {
140
+ const {
141
+ children,
142
+ name,
143
+ hideName,
144
+ isClearable,
145
+ clearTooltip,
146
+ onClear,
147
+ isSelected,
148
+ onClickFilterButton,
149
+ className,
150
+ "data-test-id": testId = "filter-button",
151
+ ...rest
152
+ } = props;
153
+ const nameId = react.useId();
154
+ const descriptionId = react.useId();
155
+ const hasDescription = react.Children.count(children) !== 0;
156
+ const nameElement = /* @__PURE__ */ jsxRuntime.jsxs("span", {
157
+ className: "Filter-name",
158
+ children: [name, hasDescription && ":"]
159
+ });
160
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", {
161
+ className: "Filter-buttonContainer",
162
+ "data-test-id": testId,
163
+ children: [/* @__PURE__ */ jsxRuntime.jsxs("button", {
164
+ ...rest,
165
+ "aria-labelledby": `${nameId} ${hasDescription ? descriptionId : ""}`,
166
+ "aria-haspopup": true,
167
+ className: classix.cx("Filter-button", className, (isClearable || isSelected) && "is-clearable"),
168
+ ref,
169
+ onClick: onClickFilterButton,
170
+ children: [hideName ? /* @__PURE__ */ jsxRuntime.jsx(visuallyHidden.VisuallyHidden, {
171
+ id: nameId,
172
+ children: nameElement
173
+ }) : /* @__PURE__ */ jsxRuntime.jsx("span", {
174
+ id: nameId,
175
+ children: nameElement
176
+ }), hasDescription && /* @__PURE__ */ jsxRuntime.jsx("span", {
177
+ id: descriptionId,
178
+ className: "Filter-description",
179
+ children
180
+ }), !isClearable && /* @__PURE__ */ jsxRuntime.jsx(icons.ExpandMore, {
181
+ size: "small"
182
+ })]
183
+ }), isClearable && /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip, {
184
+ targetClassName: "Filter-clearTooltip",
185
+ content: clearTooltip,
186
+ children: /* @__PURE__ */ jsxRuntime.jsx(button.IconButton, {
187
+ "aria-label": "Clear filter",
188
+ className: "Filter-clear",
189
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Close, {
190
+ size: "tiny"
191
+ }),
192
+ onClick: onClear
193
+ })
194
+ })]
195
+ });
196
+ });
197
+ FilterButton.defaultProps = {
198
+ clearTooltip: "Clear filter"
199
+ };
200
+ FilterButton.displayName = "FilterButton";
201
+ const SEARCH_INPUT_THRESHOLD = 4;
202
+ const Filter = ({
203
+ searchValue,
204
+ onSearchChange,
205
+ searchPlaceholder,
206
+ searchAriaLabel,
207
+ name,
208
+ hideName,
209
+ description,
210
+ options,
211
+ isClearable,
212
+ onClear,
213
+ isSelected,
214
+ className,
215
+ isEmpty,
216
+ isLoading,
217
+ onClickFilterButton,
218
+ disabledOptionTooltip,
219
+ "data-test-id": testId = "filter",
220
+ size,
221
+ enableVirtualization,
222
+ ...props
223
+ }) => {
224
+ const enableSearch = onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);
225
+ const dropdownClasses = classix.cx("Filter", "Filter-target", className);
226
+ const handleClear = (event) => {
227
+ event.preventDefault();
228
+ onClear == null ? void 0 : onClear();
229
+ };
230
+ return /* @__PURE__ */ jsxRuntime.jsxs(dropdown.Dropdown, {
231
+ targetClassName: dropdownClasses,
232
+ ...props,
233
+ children: [/* @__PURE__ */ jsxRuntime.jsx(FilterButton, {
234
+ isClearable,
235
+ onClear: handleClear,
236
+ name,
237
+ hideName,
238
+ isSelected,
239
+ onClickFilterButton,
240
+ "data-test-id": testId,
241
+ children: description
242
+ }), /* @__PURE__ */ jsxRuntime.jsx(FilterMenu, {
243
+ options,
244
+ searchValue,
245
+ searchPlaceholder,
246
+ searchAriaLabel,
247
+ enableSearch,
248
+ onSearchChange,
249
+ isLoading,
250
+ disabledOptionTooltip,
251
+ size,
252
+ enableVirtualization
253
+ })]
254
+ });
255
+ };
256
+ exports.AppliedFilter = AppliedFilter;
257
+ exports.Filter = Filter;
258
+ exports.FilterButton = FilterButton;
259
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/AppliedFilterButton.tsx","../src/FilterMenu.tsx","../src/AppliedFilter.tsx","../src/FilterButton.tsx","../src/Filter.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { ExpandMore } from '@launchpad-ui/icons';\nimport { cx } from 'classix';\nimport { Children, forwardRef } from 'react';\n\nimport './styles/Filter.css';\n\ntype AppliedFilterButtonProps = {\n name?: ReactNode;\n className?: string;\n isSelected?: boolean;\n children: ReactNode;\n onClickFilterButton?(): void;\n};\n\ntype Ref = HTMLButtonElement;\n\nconst AppliedFilterButton = forwardRef<Ref, AppliedFilterButtonProps>((props, ref) => {\n const { name, className, isSelected, children, onClickFilterButton } = props;\n\n const hasDescription = Children.count(children) !== 0;\n\n return (\n <div className=\"AppliedFilter-buttonContainer\">\n <button\n aria-haspopup\n className={cx('AppliedFilter-button', isSelected && 'isSelected', className)}\n ref={ref}\n onClick={onClickFilterButton}\n >\n {name && (\n <span className=\"AppliedFilter-name\">\n {name}\n {hasDescription && ':'}\n </span>\n )}\n {hasDescription && <span className=\"AppliedFilter-description\">{children}</span>}\n <ExpandMore size=\"small\" />\n </button>\n </div>\n );\n});\n\nAppliedFilterButton.displayName = 'AppliedFilterButton';\n\nexport type { AppliedFilterButtonProps };\nexport { AppliedFilterButton };\n","import type { MenuProps } from '@launchpad-ui/menu';\nimport type { ChangeEvent, ReactNode } from 'react';\n\nimport { Button } from '@launchpad-ui/button';\nimport { Check } from '@launchpad-ui/icons';\nimport { Menu, MenuDivider, MenuItem, MenuSearch } from '@launchpad-ui/menu';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FilterOption<T = any> = {\n name?: ReactNode;\n isDisabled?: boolean;\n isDivider?: boolean;\n isChecked?: boolean;\n value: T | null;\n projKey?: string;\n nested?: boolean;\n groupHeader?: boolean;\n};\n\ntype FilterMenuProps = Pick<MenuProps<string>, 'enableVirtualization' | 'size'> & {\n options: FilterOption[];\n onClearFilter?(): void;\n enableSearch?: boolean;\n searchValue?: string;\n searchPlaceholder?: string;\n searchAriaLabel?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n onSelect?(): void;\n isLoading?: boolean;\n disabledOptionTooltip?: string;\n};\n\nconst FilterMenu = ({\n options,\n onClearFilter,\n enableSearch,\n searchValue,\n searchPlaceholder,\n searchAriaLabel,\n onSelect,\n onSearchChange,\n isLoading = false,\n disabledOptionTooltip,\n enableVirtualization,\n size,\n}: FilterMenuProps) => {\n const filterOptions = isLoading\n ? [{ name: 'loading...', value: 'loading...', isDisabled: true }]\n : options;\n\n return (\n <>\n {onClearFilter && (\n <Button tabIndex={0} className=\"Menu-clear\" onClick={onClearFilter} kind=\"link\">\n CLEAR FILTER\n </Button>\n )}\n <Menu enableVirtualization={enableVirtualization} size={size} onSelect={onSelect}>\n {enableSearch && (\n <MenuSearch\n value={searchValue}\n placeholder={searchPlaceholder}\n onChange={onSearchChange}\n ariaLabel={searchAriaLabel}\n />\n )}\n {filterOptions.map((option, index) => {\n if (option.isDivider) {\n return <MenuDivider key={`divider-${index}`} />;\n }\n return (\n <MenuItem\n item={option}\n disabled={option.isDisabled}\n icon={option.isChecked ? Check : null}\n key={option.value}\n role=\"menuitemradio\"\n aria-checked={option.isChecked ? 'true' : undefined}\n nested={option.nested}\n groupHeader={option.groupHeader}\n tooltip={\n option.isDisabled && disabledOptionTooltip ? disabledOptionTooltip : undefined\n }\n tooltipPlacement=\"right\"\n >\n {option.name}\n </MenuItem>\n );\n })}\n </Menu>\n </>\n );\n};\n\nexport { FilterMenu };\nexport type { FilterOption, FilterMenuProps };\n","import type { FilterOption } from './FilterMenu';\nimport type { ChangeEvent, ReactNode } from 'react';\n\nimport { Dropdown } from '@launchpad-ui/dropdown';\nimport { cx } from 'classix';\n\nimport { AppliedFilterButton } from './AppliedFilterButton';\nimport { FilterMenu } from './FilterMenu';\n\nconst SEARCH_INPUT_THRESHOLD = 4;\n\ntype AppliedFilterProps = {\n searchValue?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n onClearFilter?(): void;\n searchPlaceholder?: string;\n name?: ReactNode;\n description: ReactNode;\n options: FilterOption[];\n className?: string;\n onStateChange?({ isOpen }: { isOpen?: boolean }): void;\n isSelected?: boolean;\n onSelect?(item: FilterOption): void;\n isEmpty?: boolean;\n isLoading?: boolean;\n onClickFilterButton?(): void;\n searchAriaLabel?: string;\n 'data-test-id'?: string;\n};\n\nconst AppliedFilter = ({\n searchValue,\n onSearchChange,\n searchPlaceholder,\n name,\n description,\n options,\n className,\n isEmpty,\n isLoading,\n onClickFilterButton,\n onClearFilter,\n searchAriaLabel,\n 'data-test-id': testId = 'applied-filter',\n ...props\n}: AppliedFilterProps) => {\n const enableSearch =\n onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);\n\n const dropdownClasses = cx('Filter-target', className);\n return (\n <Dropdown\n targetClassName={dropdownClasses}\n placement=\"bottom-start\"\n enableArrow={false}\n data-test-id={testId}\n {...props}\n >\n <AppliedFilterButton name={name} onClickFilterButton={onClickFilterButton}>\n {description}\n </AppliedFilterButton>\n\n <FilterMenu\n options={options}\n searchValue={searchValue}\n searchPlaceholder={searchPlaceholder}\n enableSearch={enableSearch}\n searchAriaLabel={searchAriaLabel}\n onSearchChange={onSearchChange}\n onClearFilter={onClearFilter}\n isLoading={isLoading}\n />\n </Dropdown>\n );\n};\n\nexport type { AppliedFilterProps };\nexport { AppliedFilter };\n","import type { ReactNode, SyntheticEvent } from 'react';\n\nimport { IconButton } from '@launchpad-ui/button';\nimport { Close, ExpandMore } from '@launchpad-ui/icons';\nimport { Tooltip } from '@launchpad-ui/tooltip';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { cx } from 'classix';\nimport { Children, forwardRef, useId } from 'react';\n\nimport './styles/Filter.css';\n\ntype FilterButtonProps = {\n name: ReactNode;\n hideName?: boolean;\n isClearable?: boolean;\n onClear?(event: SyntheticEvent): void;\n className?: string;\n isSelected?: boolean;\n clearTooltip?: string | JSX.Element;\n children?: ReactNode;\n onClickFilterButton?(): void;\n 'data-test-id'?: string;\n};\n\ntype Ref = HTMLButtonElement;\n\nconst FilterButton = forwardRef<Ref, FilterButtonProps>((props, ref) => {\n const {\n children,\n name,\n hideName,\n isClearable,\n clearTooltip,\n onClear,\n isSelected,\n onClickFilterButton,\n className,\n 'data-test-id': testId = 'filter-button',\n ...rest\n } = props;\n const nameId = useId();\n const descriptionId = useId();\n\n const hasDescription = Children.count(children) !== 0;\n\n const nameElement = (\n <span className=\"Filter-name\">\n {name}\n {hasDescription && ':'}\n </span>\n );\n\n return (\n <div className=\"Filter-buttonContainer\" data-test-id={testId}>\n <button\n {...rest}\n aria-labelledby={`${nameId} ${hasDescription ? descriptionId : ''}`}\n aria-haspopup\n className={cx('Filter-button', className, (isClearable || isSelected) && 'is-clearable')}\n ref={ref}\n onClick={onClickFilterButton}\n >\n {hideName ? (\n <VisuallyHidden id={nameId}>{nameElement}</VisuallyHidden>\n ) : (\n <span id={nameId}>{nameElement}</span>\n )}\n {hasDescription && (\n <span id={descriptionId} className=\"Filter-description\">\n {children}\n </span>\n )}\n {!isClearable && <ExpandMore size=\"small\" />}\n </button>\n {isClearable && (\n <Tooltip targetClassName=\"Filter-clearTooltip\" content={clearTooltip}>\n <IconButton\n aria-label=\"Clear filter\"\n className=\"Filter-clear\"\n icon={<Close size=\"tiny\" />}\n onClick={onClear}\n />\n </Tooltip>\n )}\n </div>\n );\n});\n\nFilterButton.defaultProps = {\n clearTooltip: 'Clear filter',\n};\n\nFilterButton.displayName = 'FilterButton';\n\nexport { FilterButton };\nexport type { FilterButtonProps };\n","import type { FilterOption } from './FilterMenu';\nimport type { MenuProps } from '@launchpad-ui/menu';\nimport type { ChangeEvent, ReactNode, SyntheticEvent } from 'react';\n\nimport { Dropdown } from '@launchpad-ui/dropdown';\nimport { cx } from 'classix';\n\nimport { FilterButton } from './FilterButton';\nimport { FilterMenu } from './FilterMenu';\n\nconst SEARCH_INPUT_THRESHOLD = 4;\n\ntype FilterProps = Pick<MenuProps<string>, 'size' | 'enableVirtualization'> & {\n searchValue?: string;\n onSearchChange?(event: ChangeEvent<HTMLInputElement>): void;\n searchPlaceholder?: string;\n searchAriaLabel?: string;\n name: ReactNode;\n hideName?: boolean;\n description: ReactNode;\n options: FilterOption[];\n isClearable?: boolean;\n onClear?(): void;\n className?: string;\n onStateChange?({ isOpen }: { isOpen?: boolean }): void;\n isSelected?: boolean;\n onSelect?(item: FilterOption): void;\n isEmpty?: boolean;\n isLoading?: boolean;\n onClickFilterButton?(): void;\n disabledOptionTooltip?: string;\n 'data-test-id'?: string;\n triggerTestId?: string;\n};\n\nconst Filter = ({\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAriaLabel,\n name,\n hideName,\n description,\n options,\n isClearable,\n onClear,\n isSelected,\n className,\n isEmpty,\n isLoading,\n onClickFilterButton,\n disabledOptionTooltip,\n 'data-test-id': testId = 'filter',\n size,\n enableVirtualization,\n ...props\n}: FilterProps) => {\n const enableSearch =\n onSearchChange && (!!searchValue || options.length > SEARCH_INPUT_THRESHOLD || !isEmpty);\n\n const dropdownClasses = cx('Filter', 'Filter-target', className);\n\n const handleClear = (event: SyntheticEvent) => {\n event.preventDefault();\n onClear?.();\n };\n\n return (\n <Dropdown targetClassName={dropdownClasses} {...props}>\n <FilterButton\n isClearable={isClearable}\n onClear={handleClear}\n name={name}\n hideName={hideName}\n isSelected={isSelected}\n onClickFilterButton={onClickFilterButton}\n data-test-id={testId}\n >\n {description}\n </FilterButton>\n <FilterMenu\n options={options}\n searchValue={searchValue}\n searchPlaceholder={searchPlaceholder}\n searchAriaLabel={searchAriaLabel}\n enableSearch={enableSearch}\n onSearchChange={onSearchChange}\n isLoading={isLoading}\n disabledOptionTooltip={disabledOptionTooltip}\n size={size}\n enableVirtualization={enableVirtualization}\n />\n </Dropdown>\n );\n};\n\nexport { Filter };\nexport type { FilterProps };\n"],"names":["AppliedFilterButton","forwardRef","props","ref","name","className","isSelected","children","onClickFilterButton","hasDescription","Children","count","cx","_jsxs","_jsx","ExpandMore","displayName","FilterMenu","options","onClearFilter","enableSearch","searchValue","searchPlaceholder","searchAriaLabel","onSelect","onSearchChange","isLoading","disabledOptionTooltip","enableVirtualization","size","filterOptions","value","isDisabled","_Fragment","Button","Menu","MenuSearch","map","option","index","isDivider","MenuDivider","MenuItem","isChecked","Check","undefined","nested","groupHeader","SEARCH_INPUT_THRESHOLD","AppliedFilter","description","isEmpty","testId","length","dropdownClasses","Dropdown","FilterButton","hideName","isClearable","clearTooltip","onClear","rest","nameId","useId","descriptionId","nameElement","VisuallyHidden","Tooltip","IconButton","Close","defaultProps","Filter","handleClear","event","preventDefault"],"mappings":"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"}
package/dist/style.css ADDED
@@ -0,0 +1,178 @@
1
+ .Filter {
2
+ font-family: var(--font-family-base);
3
+ }
4
+
5
+ .Filter-buttonContainer {
6
+ cursor: pointer;
7
+ display: inline-flex;
8
+ align-items: center;
9
+ position: relative;
10
+ }
11
+
12
+ .Filter-button {
13
+ cursor: pointer;
14
+ border-radius: var(--border-radius);
15
+ padding-top: 0;
16
+ padding-bottom: 0;
17
+ line-height: 3.2rem;
18
+ display: flex;
19
+ align-items: center;
20
+ margin: 0;
21
+ color: var(--color-text);
22
+ background-color: var(--color-white);
23
+ }
24
+
25
+ .AppliedFilter-button {
26
+ color: var(--color-text);
27
+ height: 2rem;
28
+ background-color: var(--color-gray-100);
29
+ padding: 0.2rem 0.6rem;
30
+ border-radius: 0.2rem;
31
+ display: flex;
32
+ }
33
+
34
+ .Filter-button,
35
+ .AppliedFilter-button {
36
+ font-family: inherit;
37
+ font-size: 1.3rem;
38
+ cursor: pointer;
39
+ border-width: 1px;
40
+ border-style: solid;
41
+ border-color: var(--color-white);
42
+ }
43
+
44
+ .Filter-button:hover, .AppliedFilter-button:hover {
45
+ background-color: var(--color-background-hover);
46
+ border-color: var(--color-border);
47
+ }
48
+
49
+ .Filter-button:focus, .AppliedFilter-button:focus {
50
+ box-shadow: 0 0 0 2px var(--color-white), 0 0 0 4px var(--color-focus);
51
+ border-color: var(--color-border);
52
+ outline: none;
53
+ }
54
+
55
+ .Filter-button:focus:not(.focus-visible), .AppliedFilter-button:focus:not(.focus-visible) {
56
+ box-shadow: none;
57
+ box-shadow: initial;
58
+ border-color: var(--color-white);
59
+ }
60
+
61
+ .Filter-button:focus:not(.focus-visible), .AppliedFilter-button:focus:not(.focus-visible) {
62
+ box-shadow: none;
63
+ box-shadow: initial;
64
+ border-color: var(--color-white);
65
+ }
66
+
67
+ .Filter-button:focus:not(.focus-visible), .AppliedFilter-button:focus:not(.focus-visible) {
68
+ box-shadow: none;
69
+ box-shadow: initial;
70
+ border-color: var(--color-white);
71
+ }
72
+
73
+ .Filter-button:focus:not(:focus-visible), .AppliedFilter-button:focus:not(:focus-visible) {
74
+ box-shadow: none;
75
+ box-shadow: initial;
76
+ border-color: var(--color-white);
77
+ }
78
+
79
+ .is-clearable {
80
+ background-color: var(--color-blue-200);
81
+ padding-right: 3.1rem;
82
+ }
83
+
84
+ .Filter-name {
85
+ margin-right: 0.5rem;
86
+ font-weight: var(--font-weight-medium);
87
+ }
88
+
89
+ .AppliedFilter-name {
90
+ margin-right: 0.3rem;
91
+ }
92
+
93
+ .Filter-description {
94
+ color: var(--color-text);
95
+ font-weight: var(--font-weight-medium);
96
+ }
97
+
98
+ .Filter-button .Filter-description,
99
+ .AppliedFilter-button .AppliedFilter-description {
100
+ margin-right: 0.5rem;
101
+ max-width: 16rem;
102
+ overflow: hidden;
103
+ text-overflow: ellipsis;
104
+ white-space: nowrap;
105
+ }
106
+
107
+ .Filter-description .Gravatar:first-child {
108
+ margin-right: 0.5rem;
109
+ }
110
+
111
+ .Filter-clear {
112
+ cursor: pointer;
113
+ padding: 0.3rem;
114
+ }
115
+
116
+ .Filter-target--usage {
117
+ border: 1px solid var(--color-text-subtle-secondary);
118
+ }
119
+
120
+ .Filter-button.is-clearable {
121
+ background-color: var(--color-blue-200);
122
+ padding-right: 3.1rem;
123
+ }
124
+
125
+ .Filter-button.is-clearable:focus,
126
+ .Filter-button.is-clearable:hover,
127
+ .Filter-button.is-clearable:active {
128
+ background-color: var(--color-blue-300);
129
+ }
130
+
131
+ .Filter-button.is-clearable:focus:not(.focus-visible) {
132
+ background-color: transparent;
133
+ background-color: initial;
134
+ }
135
+
136
+ .Filter-button.is-clearable:focus:not(.focus-visible) {
137
+ background-color: transparent;
138
+ background-color: initial;
139
+ }
140
+
141
+ .Filter-button.is-clearable:focus:not(.focus-visible) {
142
+ background-color: transparent;
143
+ background-color: initial;
144
+ }
145
+
146
+ .Filter-button.is-clearable:focus:not(:focus-visible) {
147
+ background-color: transparent;
148
+ background-color: initial;
149
+ }
150
+
151
+ .Filter-button.is-clearable:focus:not(.focus-visible):hover {
152
+ background-color: var(--color-blue-300);
153
+ }
154
+
155
+ .Filter-button.is-clearable:focus:not(:focus-visible):hover {
156
+ background-color: var(--color-blue-300);
157
+ }
158
+
159
+ .Filter-button:hover:not(.is-clearable),
160
+ .Filter-button:focus:not(.is-clearable),
161
+ [data-state='open'] .Filter-button:not(.is-clearable) {
162
+ background-color: var(--color-background-hover);
163
+ border-color: var(--color-text-subtle-secondary);
164
+ }
165
+
166
+ .Filter-button:focus:not(.focus-visible):not(.is-clearable):hover {
167
+ background-color: var(--color-background-hover);
168
+ }
169
+
170
+ .Filter-button:focus:not(:focus-visible):not(.is-clearable):hover {
171
+ background-color: var(--color-background-hover);
172
+ }
173
+
174
+ .Filter-clearTooltip {
175
+ line-height: 1;
176
+ position: absolute;
177
+ right: 0.7rem;
178
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchpad-ui/filter",
3
- "version": "0.4.6-alpha.0",
3
+ "version": "0.4.6-alpha.1",
4
4
  "status": "beta",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,11 +27,11 @@
27
27
  "source": "src/index.ts",
28
28
  "dependencies": {
29
29
  "@launchpad-ui/button": "~0.7.1",
30
- "@launchpad-ui/dropdown": "~0.5.4-alpha.0",
31
- "@launchpad-ui/icons": "~0.5.4-alpha.0",
32
- "@launchpad-ui/menu": "~0.6.6-alpha.0",
30
+ "@launchpad-ui/dropdown": "~0.5.4-alpha.1",
31
+ "@launchpad-ui/icons": "~0.5.4-alpha.1",
32
+ "@launchpad-ui/menu": "~0.6.6-alpha.1",
33
33
  "@launchpad-ui/tokens": "~0.1.5",
34
- "@launchpad-ui/tooltip": "~0.6.5-alpha.0",
34
+ "@launchpad-ui/tooltip": "~0.6.5-alpha.1",
35
35
  "@react-aria/visually-hidden": "^3.4.0",
36
36
  "classix": "^2.1.13"
37
37
  },