@cwellt_software/cwellt-reactjs-lib 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/index.cjs.js +20 -6
  2. package/dist/index.css +1 -1
  3. package/dist/index.d.ts +11 -0
  4. package/dist/index.es.js +20 -6
  5. package/dist/src/components/control/action/button/CwButton.stories.d.ts +28 -0
  6. package/dist/src/components/control/action/button/CwButton.stories.d.ts.map +1 -0
  7. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts +11 -0
  8. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts.map +1 -1
  9. package/dist/src/components/control/input/text/CwInputText.stories.d.ts +840 -0
  10. package/dist/src/components/control/input/text/CwInputText.stories.d.ts.map +1 -0
  11. package/dist/src/components/display/text/note/CwNote.stories.d.ts +51 -0
  12. package/dist/src/components/display/text/note/CwNote.stories.d.ts.map +1 -0
  13. package/dist/src/components/display/text/tag/CwChip.stories.d.ts +29 -0
  14. package/dist/src/components/display/text/tag/CwChip.stories.d.ts.map +1 -0
  15. package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
  16. package/dist/src/storybook/inputStoryArgs.d.ts +68 -0
  17. package/dist/src/storybook/inputStoryArgs.d.ts.map +1 -0
  18. package/dist/src/storybook/layoutStoryArgs.d.ts +60 -0
  19. package/dist/src/storybook/layoutStoryArgs.d.ts.map +1 -0
  20. package/dist/src/storybook/storySource.d.ts +22 -0
  21. package/dist/src/storybook/storySource.d.ts.map +1 -0
  22. package/dist/test/storybook/inputStoryArgs.test.d.ts +2 -0
  23. package/dist/test/storybook/inputStoryArgs.test.d.ts.map +1 -0
  24. package/dist/test/storybook/layoutStoryArgs.test.d.ts +2 -0
  25. package/dist/test/storybook/layoutStoryArgs.test.d.ts.map +1 -0
  26. package/package.json +1 -1
package/dist/index.es.js CHANGED
@@ -4966,21 +4966,29 @@ var styles$b = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-
4966
4966
  * @param {CwMultiFilterProps} props
4967
4967
  * @returns Set the `onChange` callback to a function to check for changes in the selected filters
4968
4968
  */
4969
- const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style }) => {
4969
+ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style, testId, initialTagVisibility = "all" }) => {
4970
4970
  const [inputTextValue, setInputTextValue] = useState("");
4971
4971
  const [isPanelOpen, setIsPanelOpen] = useState(false);
4972
4972
  const [selectedCategory, setSelectedCategory] = useState("All");
4973
+ // True once the user touches the current opening (any category click or a search); gates the cascade.
4974
+ const [hasInteracted, setHasInteracted] = useState(false);
4973
4975
  const componentRef = useRef(null);
4974
4976
  const inputRef = useRef(null);
4975
4977
  const wrapperRef = useRef(null);
4976
4978
  const { panelRef, panelStyle, renderPanel } = useDropdownPortal({
4977
4979
  anchorRef: wrapperRef,
4978
4980
  isOpen: isPanelOpen,
4979
- onClose: () => { setIsPanelOpen(false); setSelectedCategory("All"); setInputTextValue(""); },
4981
+ onClose: () => setIsPanelOpen(false),
4980
4982
  });
4983
+ // Single reset point for all transient panel state on close, whatever closed it - the clear-all
4984
+ // button closes the panel directly and bypasses onClose, so resetting here covers every path.
4981
4985
  useEffect(() => {
4982
- // Outside-click is now handled by useDropdownPortal
4983
- }, []);
4986
+ if (!isPanelOpen) {
4987
+ setHasInteracted(false);
4988
+ setSelectedCategory("All");
4989
+ setInputTextValue("");
4990
+ }
4991
+ }, [isPanelOpen]);
4984
4992
  const categoriesMappedToTags = () => {
4985
4993
  const categoriesMap = new Map();
4986
4994
  allTags.forEach(tag => {
@@ -4991,6 +4999,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
4991
4999
  return categoriesMap;
4992
5000
  };
4993
5001
  const displayTags = useMemo(() => {
5002
+ if (initialTagVisibility === "afterCategoryOrSearch" && !hasInteracted) {
5003
+ return [];
5004
+ }
4994
5005
  let tags = Array.from(allTags);
4995
5006
  if (selectedCategory !== "All") {
4996
5007
  tags = tags.filter(t => t.Category === selectedCategory);
@@ -5000,8 +5011,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5000
5011
  tags = tags.filter(t => t.Name.replaceAll(" ", "").toLowerCase().includes(input));
5001
5012
  }
5002
5013
  return tags;
5003
- }, [allTags, selectedCategory, inputTextValue]);
5014
+ }, [allTags, selectedCategory, inputTextValue, initialTagVisibility, hasInteracted]);
5004
5015
  const handleClickCategory = (category) => {
5016
+ setHasInteracted(true);
5005
5017
  setSelectedCategory(category);
5006
5018
  };
5007
5019
  const rgbAString = (r, g, b) => {
@@ -5026,6 +5038,8 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5026
5038
  const handleInputText = (input) => {
5027
5039
  if (selectedCategory !== "All")
5028
5040
  setSelectedCategory("All");
5041
+ if (input.trim() !== "")
5042
+ setHasInteracted(true);
5029
5043
  setInputTextValue(input.trimStart());
5030
5044
  };
5031
5045
  const addTag = (newTag) => {
@@ -5052,7 +5066,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5052
5066
  inputRef.current?.focus();
5053
5067
  }
5054
5068
  };
5055
- return (jsxs("form", { ref: componentRef, id: id, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5069
+ return (jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5056
5070
  e.preventDefault();
5057
5071
  }, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$b["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
5058
5072
  switch (e.key) {
@@ -0,0 +1,28 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ declare const meta: {
3
+ title: string;
4
+ component: import("react").ForwardRefExoticComponent<import("./CwButton").CwButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
5
+ args: {
6
+ text: string;
7
+ variant: "solid";
8
+ color: "primary";
9
+ size: "medium";
10
+ icon: string;
11
+ disabled: false;
12
+ };
13
+ argTypes: {
14
+ onClick: {
15
+ action: string;
16
+ };
17
+ };
18
+ };
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+ export declare const Default: Story;
22
+ /** Square button with the icon alone; the tooltip carries the label. Shown at rest and pressed. */
23
+ export declare const IconOnly: Story;
24
+ /** The badge overlays the top-right corner of any variant. */
25
+ export declare const WithBadge: Story;
26
+ /** Every variant crossed with every color, at the selected size. */
27
+ export declare const Matrix: Story;
28
+ //# sourceMappingURL=CwButton.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CwButton.stories.d.ts","sourceRoot":"","sources":["../../../../../../src/components/control/action/button/CwButton.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAM5D,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;CAcuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,mGAAmG;AACnG,eAAO,MAAM,QAAQ,EAAE,KAStB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,MAAM,EAAE,KAoBpB,CAAC"}
@@ -16,6 +16,17 @@ export interface CwMultiFilterProps {
16
16
  /** Additional CSS class for the container */
17
17
  className?: string;
18
18
  style?: React.CSSProperties;
19
+ /** `data-testid` on the root `<form>`, for e2e/Selenium anchoring. */
20
+ testId?: string;
21
+ /**
22
+ * Tag list shown when the panel opens.
23
+ * - `"all"` (default): the full list shows immediately.
24
+ * - `"afterCategoryOrSearch"`: the list opens empty until the user's first interaction (any
25
+ * category button, ALL CATEGORIES included, or a search term), then stays visible until the
26
+ * panel is closed and reopened. Category buttons stay visible throughout. Useful when one
27
+ * category holds a directory large enough to overload the panel.
28
+ */
29
+ initialTagVisibility?: "all" | "afterCategoryOrSearch";
19
30
  }
20
31
  /**
21
32
  * A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
@@ -1 +1 @@
1
- {"version":3,"file":"CwMultiFilter.d.ts","sourceRoot":"","sources":["../../../../../../src/components/control/choice/multi-filter/CwMultiFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,EAAwC,MAAM,OAAO,CAAC;AAIxE,OAAO,EAAoB,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGpH,MAAM,WAAW,kBAAkB;IAClC,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,sGAAsG;IACtG,oBAAoB,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACrE,uCAAuC;IACvC,OAAO,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAChC,4CAA4C;IAC5C,YAAY,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACzC,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0IG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA0OhD,CAAC"}
1
+ {"version":3,"file":"CwMultiFilter.d.ts","sourceRoot":"","sources":["../../../../../../src/components/control/choice/multi-filter/CwMultiFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,EAAwC,MAAM,OAAO,CAAC;AAIxE,OAAO,EAAoB,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGpH,MAAM,WAAW,kBAAkB;IAClC,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,sGAAsG;IACtG,oBAAoB,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACrE,uCAAuC;IACvC,OAAO,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAChC,4CAA4C;IAC5C,YAAY,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACzC,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,KAAK,GAAG,uBAAuB,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0IG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA0PhD,CAAC"}