@purpurds/autocomplete 5.10.1 → 5.11.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.
@@ -1 +1 @@
1
- {"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../src/useAutocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGhE,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,GAAG;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,MAAM,IAAI;IAIrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAI/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAItE,EAAE,EAAE,MAAM,CAAC;IAIX,YAAY,EAAE,MAAM,CAAC;IAIrB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAInC,aAAa,CAAC,EAAE,SAAS,CAAC;IAI1B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAIxC,WAAW,CAAC,EAAE,OAAO,CAAC;IAItB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAI3C,OAAO,EAAE,CAAC,EAAE,CAAC;IAIb,cAAc,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,eAAe,sPAgBzB,uBAAuB,CAAC,CAAC;;;;;;;;kCA4KW,CAAC,SAAS,MAAM,KAAG,gBAAgB;;CAqDzE,CAAC"}
1
+ {"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../src/useAutocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGhE,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,GAAG;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,MAAM,IAAI;IAIrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAI/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAItE,EAAE,EAAE,MAAM,CAAC;IAIX,YAAY,EAAE,MAAM,CAAC;IAIrB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAInC,aAAa,CAAC,EAAE,SAAS,CAAC;IAI1B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAIxC,WAAW,CAAC,EAAE,OAAO,CAAC;IAItB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAI3C,OAAO,EAAE,CAAC,EAAE,CAAC;IAIb,cAAc,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,mOAgB7C,sBAAsB,CAAC,CAAC,CAAC;;;;;;;;kCA4KW,CAAC,SAAS,MAAM,KAAG,gBAAgB;;CAqDzE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAkC,MAAM,OAAO,CAAC;AAGzE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrB,GAAG,EAAE,CAAC;AAEP,eAAO,MAAM,mBAAmB,aAAc,CAAC,KAAG,iBAAiB,CAAC,CAEnE,CAAC;AAEF,eAAO,MAAM,iBAAiB,YAAa,WAAW,GAAG,IAAI,YAAY,MAAM,IAAI,SAgBlF,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAkC,MAAM,OAAO,CAAC;AAGzE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrB,GAAG,EAAE,CAAC;AAEP,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,CAAC,KAAG,gBAAgB,CAAC,CAAC,CAEnE,CAAC;AAEF,eAAO,MAAM,iBAAiB,YAAa,WAAW,GAAG,IAAI,YAAY,MAAM,IAAI,SAgBlF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purpurds/autocomplete",
3
- "version": "5.10.1",
3
+ "version": "5.11.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "main": "./dist/autocomplete.cjs.js",
6
6
  "types": "./dist/autocomplete.d.ts",
@@ -15,38 +15,39 @@
15
15
  "source": "src/autocomplete.tsx",
16
16
  "dependencies": {
17
17
  "classnames": "~2.5.0",
18
- "@purpurds/paragraph": "5.10.1",
19
- "@purpurds/tokens": "5.10.1",
20
- "@purpurds/icon": "5.10.1",
21
- "@purpurds/text-field": "5.10.1"
18
+ "@purpurds/icon": "5.11.1",
19
+ "@purpurds/paragraph": "5.11.1",
20
+ "@purpurds/tokens": "5.11.1",
21
+ "@purpurds/text-field": "5.11.1"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@rushstack/eslint-patch": "~1.10.0",
25
- "@storybook/blocks": "~7.6.0",
26
- "@storybook/client-api": "~7.6.0",
27
- "@storybook/react": "~7.6.0",
25
+ "@storybook/blocks": "^8.2.6",
26
+ "@storybook/preview-api": "^8.2.6",
27
+ "@storybook/react": "^8.2.6",
28
28
  "@telia/base-rig": "~8.2.0",
29
29
  "@telia/react-rig": "~3.2.0",
30
30
  "@testing-library/dom": "~9.3.3",
31
31
  "@testing-library/jest-dom": "~6.4.0",
32
32
  "@testing-library/react": "~14.3.0",
33
33
  "@types/node": "20.12.12",
34
- "@types/react-dom": "~18.3.0",
35
- "@types/react": "~18.3.0",
34
+ "@types/react-dom": "^18.3.0",
35
+ "@types/react": "^18.3.3",
36
36
  "eslint-plugin-testing-library": "~6.2.0",
37
- "eslint": "~8.57.0",
37
+ "eslint": "^8.57.0",
38
38
  "jsdom": "~22.1.0",
39
39
  "lint-staged": "~10.5.3",
40
40
  "prettier": "~2.8.8",
41
- "react-dom": "~18.3.0",
42
- "react": "~18.3.0",
43
- "typescript": "~5.4.2",
44
- "vite": "~5.2.2",
41
+ "react-dom": "^18.3.1",
42
+ "react": "^18.3.1",
43
+ "storybook": "^8.2.6",
44
+ "typescript": "^5.5.4",
45
+ "vite": "5.3.4",
45
46
  "vitest": "~1.5.0",
46
- "@purpurds/icon": "5.10.1",
47
- "@purpurds/button": "5.10.1",
48
- "@purpurds/search-field": "5.10.1",
49
- "@purpurds/component-rig": "1.0.0"
47
+ "@purpurds/button": "5.11.1",
48
+ "@purpurds/icon": "5.11.1",
49
+ "@purpurds/component-rig": "1.0.0",
50
+ "@purpurds/search-field": "5.11.1"
50
51
  },
51
52
  "scripts": {
52
53
  "build:dev": "vite",
@@ -2,11 +2,11 @@ import React from "react";
2
2
  import { Paragraph } from "@purpurds/paragraph";
3
3
  import { SearchField } from "@purpurds/search-field";
4
4
  import { TextField } from "@purpurds/text-field";
5
- import { useArgs, useState } from "@storybook/client-api";
5
+ import { useArgs, useState } from "@storybook/preview-api";
6
6
  import type { Meta, StoryObj } from "@storybook/react";
7
7
 
8
- import "@purpurds/button/styles";
9
8
  import "@purpurds/icon/styles";
9
+ import "@purpurds/button/styles";
10
10
  import "@purpurds/search-field/styles";
11
11
  import "@purpurds/text-field/styles";
12
12
  import { Autocomplete } from "./autocomplete";
@@ -34,7 +34,7 @@ const options = [
34
34
  { id: "19", label: "Strawberry" },
35
35
  ];
36
36
 
37
- const meta: Meta<typeof Autocomplete> = {
37
+ const meta = {
38
38
  title: "Inputs/Autocomplete",
39
39
  component: Autocomplete,
40
40
  args: {
@@ -63,7 +63,7 @@ const meta: Meta<typeof Autocomplete> = {
63
63
  </div>
64
64
  ),
65
65
  ],
66
- };
66
+ } satisfies Meta<typeof Autocomplete>;
67
67
 
68
68
  export default meta;
69
69
  type Story = StoryObj<typeof Autocomplete>;
@@ -74,6 +74,34 @@ export const WithTextField: Story = {
74
74
  },
75
75
  argTypes: {
76
76
  listboxMaxHeight: { type: "string" },
77
+
78
+ options: {
79
+ description: `
80
+ type Option = {
81
+ label: string;
82
+ id: string;
83
+ value?: string;
84
+ disabled?: boolean;
85
+ };`,
86
+
87
+ table: { type: { summary: "<T extends Option>[]" } },
88
+ },
89
+ },
90
+ parameters: {
91
+ docs: {
92
+ source: {
93
+ code: `
94
+ <Autocomplete
95
+ selectedOption={selectedOption}
96
+ onSelect={(selectedOption) => updateArgs({ selectedOption })}
97
+ renderInput={(inputProps) => (
98
+ <TextField
99
+ {...inputProps}
100
+ />
101
+ )}
102
+ />`,
103
+ },
104
+ },
77
105
  },
78
106
  render: ({ ...args }) => {
79
107
  const [{ selectedOption }, updateArgs] = useArgs(); // eslint-disable-line react-hooks/rules-of-hooks
@@ -106,6 +134,22 @@ export const WithSearchField: Story = {
106
134
  inputValue: { table: { disabled: true } },
107
135
  onInputChange: { table: { disabled: true } },
108
136
  },
137
+ parameters: {
138
+ docs: {
139
+ source: {
140
+ code: `
141
+ <Autocomplete
142
+ selectedOption={selectedOption}
143
+ onSelect={(selectedOption) => updateArgs({ selectedOption })}
144
+ renderInput={(inputProps) => (
145
+ <SearchField
146
+ {...inputProps}
147
+ />
148
+ )}
149
+ />`,
150
+ },
151
+ },
152
+ },
109
153
  render: ({ ...args }) => {
110
154
  const [inputValue, setInputValue] = useState(""); // eslint-disable-line react-hooks/rules-of-hooks
111
155
  const [{ selectedOption }, updateArgs] = useArgs(); // eslint-disable-line react-hooks/rules-of-hooks
@@ -131,7 +175,7 @@ export const WithSearchField: Story = {
131
175
  updateArgs({ selectedOption: undefined });
132
176
  }}
133
177
  placeholder="Find your fruit"
134
- clearButtonAllyLabel="Rensa sökfältet"
178
+ clearButtonAllyLabel="Clear search field"
135
179
  variant="button-attached"
136
180
  iconOnlySearchButton
137
181
  searchButtonLabel="Search"
@@ -151,6 +195,42 @@ export const WithRenderOption: Story = {
151
195
  inputValue: { table: { disabled: true } },
152
196
  onInputChange: { table: { disabled: true } },
153
197
  },
198
+ parameters: {
199
+ docs: {
200
+ source: {
201
+ code: `
202
+ <Autocomplete
203
+ selectedOption={selectedOption}
204
+ onSelect={(selectedOption) => updateArgs({ selectedOption })}
205
+ renderInput={(inputProps) => (
206
+ <TextField
207
+ {...inputProps}
208
+ />
209
+ )}
210
+ renderOption={(option) => {
211
+ const optionText = option.label;
212
+ if (!inputValue.trim()) {
213
+ return optionText;
214
+ }
215
+
216
+ const escapeRegExp = (str = "") => str.replace(/([.?*+^$[\\]\\(){}|-])/g, "\\$1");
217
+ const regex = new RegExp(\`(\${escapeRegExp(inputValue)})\`, "gi");
218
+ const parts = optionText.split(regex);
219
+
220
+ return (
221
+ <Paragraph>
222
+ {parts
223
+ .filter((part) => part)
224
+ .map((part, i) =>
225
+ regex.test(part) ? <strong key={i}>{part}</strong> : <span key={i}>{part}</span>
226
+ )}
227
+ </Paragraph>
228
+ );
229
+ }}
230
+ />`,
231
+ },
232
+ },
233
+ },
154
234
  render: ({ ...args }) => {
155
235
  const [inputValue, setInputValue] = useState(""); // eslint-disable-line react-hooks/rules-of-hooks
156
236
  const [{ selectedOption }, updateArgs] = useArgs(); // eslint-disable-line react-hooks/rules-of-hooks
@@ -1,8 +1,7 @@
1
1
  import type { ComponentPropsWithRef, ForwardedRef, ReactNode } from "react";
2
- import React, { cloneElement, forwardRef, isValidElement } from "react";
2
+ import React, { cloneElement, forwardRef } from "react";
3
3
  import { IconChevronDown } from "@purpurds/icon";
4
- import type { TextFieldProps } from "@purpurds/text-field";
5
- import { TextField } from "@purpurds/text-field";
4
+ import { isTextField } from "@purpurds/text-field";
6
5
  import c from "classnames/bind";
7
6
 
8
7
  import styles from "./autocomplete.module.scss";
@@ -66,12 +65,7 @@ const AutocompleteComponent = <T extends Option>(
66
65
 
67
66
  const getInputComponent = () => {
68
67
  const input = renderInput(inputProps);
69
- const isCombobox =
70
- combobox &&
71
- noOptionsText &&
72
- input &&
73
- isValidElement<TextFieldProps>(input) &&
74
- input.type === TextField;
68
+ const isCombobox = combobox && noOptionsText && input && isTextField(input);
75
69
 
76
70
  if (isCombobox) {
77
71
  const endAdornment = (
@@ -245,7 +245,7 @@ export const useAutocomplete = <T extends Option>({
245
245
 
246
246
  const handleOnBlur = () => {
247
247
  if (combobox) {
248
- setInternalInputValue(selectedOption?.label ?? "");
248
+ populateInputField(selectedOption?.label ?? "");
249
249
  }
250
250
  };
251
251