@c-rex/components 0.1.28 → 0.1.30

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 (59) hide show
  1. package/package.json +9 -1
  2. package/src/article/article-action-bar.stories.tsx +15 -0
  3. package/src/article/article-content.stories.tsx +21 -0
  4. package/src/autocomplete.tsx +8 -5
  5. package/src/carousel/carousel.tsx +344 -0
  6. package/src/check-article-lang.tsx +5 -5
  7. package/src/directoryNodes/tree-of-content.stories.tsx +22 -0
  8. package/src/directoryNodes/tree-of-content.tsx +2 -2
  9. package/src/documents/result-list.stories.tsx +19 -0
  10. package/src/documents/result-list.tsx +23 -33
  11. package/src/favorites/bookmark-button.stories.tsx +19 -0
  12. package/src/favorites/favorite-button.stories.tsx +22 -0
  13. package/src/icons/file-icon.stories.tsx +19 -0
  14. package/src/icons/flag-icon.stories.tsx +25 -0
  15. package/src/icons/loading.stories.tsx +21 -0
  16. package/src/info/info-table.tsx +2 -69
  17. package/src/info/stories/info-table.stories.tsx +31 -0
  18. package/src/info/stories/shared.stories.tsx +24 -0
  19. package/src/navbar/language-switcher/content-language-switch.tsx +3 -7
  20. package/src/navbar/language-switcher/ui-language-switch.tsx +2 -2
  21. package/src/navbar/navbar.tsx +76 -35
  22. package/src/navbar/stories/navbar.stories.tsx +21 -6
  23. package/src/navbar/stories/settings.stories.tsx +15 -0
  24. package/src/navbar/stories/sign-in-out-btns.stories.tsx +15 -0
  25. package/src/navbar/stories/user-menu.stories.tsx +20 -0
  26. package/src/page-wrapper.tsx +10 -14
  27. package/src/renditions/file-download.stories.tsx +19 -0
  28. package/src/renditions/html.stories.tsx +19 -0
  29. package/src/renditions/html.tsx +12 -9
  30. package/src/renditions/image/container.stories.tsx +19 -0
  31. package/src/renditions/image/container.tsx +6 -3
  32. package/src/renditions/image/rendition.stories.tsx +19 -0
  33. package/src/renditions/image/rendition.tsx +9 -14
  34. package/src/restriction-menu/restriction-menu-item.tsx +89 -0
  35. package/src/restriction-menu/restriction-menu.tsx +157 -0
  36. package/src/results/cards.tsx +1 -1
  37. package/src/results/dialog-filter.tsx +30 -67
  38. package/src/results/filter-navbar.tsx +12 -15
  39. package/src/results/generic/table-result-list.stories.tsx +21 -0
  40. package/src/results/generic/table-result-list.tsx +31 -28
  41. package/src/results/stories/cards.stories.tsx +16 -8
  42. package/src/results/stories/dialog-filter.stories.tsx +20 -0
  43. package/src/results/stories/empty.stories.tsx +12 -1
  44. package/src/results/stories/filter-navbar.stories.tsx +19 -0
  45. package/src/results/stories/filter-sidebar.stories.tsx +20 -0
  46. package/src/results/stories/pagination.stories.tsx +24 -0
  47. package/src/results/stories/table-with-images.stories.tsx +19 -0
  48. package/src/results/stories/table.stories.tsx +32 -9
  49. package/src/results/table-with-images.tsx +2 -16
  50. package/src/search-input.tsx +33 -12
  51. package/src/stores/language-store.ts +33 -16
  52. package/src/stores/search-settings-store.ts +49 -8
  53. package/src/stories/autocomplete.stories.tsx +20 -0
  54. package/src/stories/breadcrumb.stories.tsx +72 -31
  55. package/src/stories/check-article-lang.stories.tsx +22 -0
  56. package/src/stories/render-article.stories.tsx +19 -0
  57. package/src/stories/search-input.stories.tsx +21 -0
  58. package/src/stories/share-button.stories.tsx +15 -0
  59. package/src/results/result-container.tsx +0 -70
@@ -1,35 +1,28 @@
1
1
  import { FC } from "react";
2
- import {
3
- DocumentModel,
4
- ExternalProductGraphicModel,
5
- FragmentModel,
6
- InformationUnitModel,
7
- PackageModel,
8
- TopicModel
9
- } from "@c-rex/interfaces";
10
- import { cn, getLanguage, getTitle, getType, getVersions } from "@c-rex/utils";
2
+ import { CommonItemsModel } from "@c-rex/interfaces";
3
+ import { cn, generateQueryParams, getLanguage, getTitle, getType } from "@c-rex/utils";
11
4
  import { Flag } from "@c-rex/components/flag";
12
5
  import { Badge } from "@c-rex/ui/badge";
13
- import { RESULT_TYPES } from "@c-rex/constants";
14
6
  import Link from "next/link";
15
7
  import { FileDownloadDropdown } from "@c-rex/components/file-download";
16
8
  import { getTranslations } from "next-intl/server";
9
+ import { QueryParams } from "@c-rex/types";
17
10
 
18
11
  interface Props {
19
- items: (
20
- DocumentModel |
21
- ExternalProductGraphicModel |
22
- FragmentModel |
23
- InformationUnitModel |
24
- PackageModel |
25
- TopicModel
26
- )[];
27
- query: string;
28
- linkPath: string;
12
+ items: CommonItemsModel[];
13
+ linkPattern: string;
14
+ addPackageId: boolean
29
15
  showFilesColumn?: boolean;
16
+ query?: string
30
17
  }
31
18
 
32
- export const GenericTableResultList: FC<Props> = async ({ items, query, linkPath, showFilesColumn = true }) => {
19
+ export const GenericTableResultList: FC<Props> = async ({
20
+ items,
21
+ linkPattern,
22
+ addPackageId,
23
+ query,
24
+ showFilesColumn = true,
25
+ }) => {
33
26
  const t = await getTranslations("results");
34
27
 
35
28
  return (
@@ -48,15 +41,25 @@ export const GenericTableResultList: FC<Props> = async ({ items, query, linkPath
48
41
  const itemType = getType(item.class);
49
42
  const language = getLanguage(item.languages);
50
43
  const packageId = item.packages && item.packages.length > 0 ? item.packages[0]?.shortId : null;
44
+ const queryParams: QueryParams[] = []
51
45
 
52
- const isDocument = itemType === RESULT_TYPES.DOCUMENT;
53
- const multipleVersions = getVersions(item.versionOf);
54
-
55
- let itemLink = `${linkPath}/${item.shortId}?q=${query}`
46
+ if (addPackageId && packageId) {
47
+ queryParams.push({
48
+ key: "package",
49
+ value: packageId,
50
+ })
51
+ }
56
52
 
57
- if (packageId) {
58
- itemLink += `&package=${packageId}`
53
+ if (query != undefined) {
54
+ queryParams.push({
55
+ key: "q",
56
+ value: query,
57
+ })
59
58
  }
59
+
60
+ const params = generateQueryParams(queryParams)
61
+ const link = linkPattern.replace("{id}", item.shortId!) + (params.length > 0 ? `?${params}` : "")
62
+
60
63
  return (
61
64
  <div
62
65
  className={cn(
@@ -66,7 +69,7 @@ export const GenericTableResultList: FC<Props> = async ({ items, query, linkPath
66
69
  key={index}
67
70
  >
68
71
  <div className="flex-1 p-2">
69
- <Link href={itemLink} className="hover:underline">{title}</Link>
72
+ <Link href={link} className="hover:underline">{title}</Link>
70
73
  </div>
71
74
 
72
75
  <div className="w-1/5 md:w-1/5 flex justify-center p-2">
@@ -9,11 +9,10 @@ const meta: Meta<typeof BlogView> = {
9
9
  },
10
10
  tags: ['autodocs'],
11
11
  };
12
-
13
12
  export default meta;
14
13
  type Story = StoryObj<typeof BlogView>;
15
14
 
16
- const mockItems = [
15
+ const items = [
17
16
  {
18
17
  id: '1',
19
18
  shortId: 'doc-1',
@@ -24,7 +23,8 @@ const mockItems = [
24
23
  languages: ['pt-BR'],
25
24
  type: 'document',
26
25
  renditions: [],
27
- directoryNodes: []
26
+ directoryNodes: [],
27
+ disabled: false,
28
28
  },
29
29
  {
30
30
  id: '2',
@@ -35,7 +35,8 @@ const mockItems = [
35
35
  languages: ['en-US'],
36
36
  type: 'document',
37
37
  renditions: [],
38
- directoryNodes: []
38
+ directoryNodes: [],
39
+ disabled: false,
39
40
  },
40
41
  {
41
42
  id: '3',
@@ -47,12 +48,19 @@ const mockItems = [
47
48
  languages: ['fr-FR'],
48
49
  type: 'document',
49
50
  renditions: [],
50
- directoryNodes: []
51
+ directoryNodes: [],
52
+ disabled: true,
51
53
  }
52
54
  ];
53
55
 
54
- export const Default: Story = {
56
+ export const Basic: Story = {
55
57
  args: {
56
- items: mockItems as any
57
- }
58
+ items,
59
+ },
60
+ };
61
+
62
+ export const WithDisabled: Story = {
63
+ args: {
64
+ items: items.map((item, i) => ({ ...item, disabled: i === 2 })),
65
+ },
58
66
  };
@@ -0,0 +1,20 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { DialogFilter } from '../dialog-filter';
3
+ import { Button } from '@c-rex/ui/button';
4
+
5
+ const meta: Meta<typeof DialogFilter> = {
6
+ title: 'Components/Results/DialogFilter',
7
+ component: DialogFilter,
8
+ parameters: {
9
+ layout: 'centered',
10
+ },
11
+ tags: ['autodocs'],
12
+ };
13
+ export default meta;
14
+ type Story = StoryObj<typeof DialogFilter>;
15
+
16
+ export const Basic: Story = {
17
+ args: {
18
+ trigger: <Button>Open Filter</Button>,
19
+ },
20
+ };
@@ -10,5 +10,16 @@ const meta = {
10
10
  export default meta;
11
11
  type Story = StoryObj<typeof meta>;
12
12
 
13
- export const Default: Story = {
13
+
14
+ export const Basic: Story = {};
15
+
16
+ export const CustomMessage: Story = {
17
+ render: () => (
18
+ <div style={{ maxWidth: 400 }}>
19
+ <Empty />
20
+ <div style={{ marginTop: 16, color: '#888' }}>
21
+ Nenhum resultado encontrado para sua busca personalizada.
22
+ </div>
23
+ </div>
24
+ ),
14
25
  };
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { FilterNavbar } from '../filter-navbar';
3
+
4
+ const meta: Meta<typeof FilterNavbar> = {
5
+ title: 'Components/Results/FilterNavbar',
6
+ component: FilterNavbar,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof FilterNavbar>;
14
+
15
+ export const Basic: Story = {
16
+ args: {
17
+ tags: {},
18
+ },
19
+ };
@@ -0,0 +1,20 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { FilterSidebar } from './index';
3
+
4
+ const meta: Meta<typeof FilterSidebar> = {
5
+ title: 'Components/Results/FilterSidebar',
6
+ component: FilterSidebar,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof FilterSidebar>;
14
+
15
+ export const Basic: Story = {
16
+ args: {
17
+ tags: {},
18
+ totalItemCount: 0,
19
+ },
20
+ };
@@ -0,0 +1,24 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Pagination } from '../pagination';
3
+
4
+ const meta: Meta<typeof Pagination> = {
5
+ title: 'Components/Results/Pagination',
6
+ component: Pagination,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof Pagination>;
14
+
15
+ export const Basic: Story = {
16
+ args: {
17
+ pageInfo: {
18
+ pageNumber: 1,
19
+ pageSize: 10,
20
+ totalPages: 5,
21
+ totalItems: 50,
22
+ },
23
+ },
24
+ };
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { TableWithImage } from '../table-with-images';
3
+
4
+ const meta: Meta<typeof TableWithImage> = {
5
+ title: 'Components/Results/TableWithImage',
6
+ component: TableWithImage,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof TableWithImage>;
14
+
15
+ export const Basic: Story = {
16
+ args: {
17
+ items: [],
18
+ },
19
+ };
@@ -13,17 +13,26 @@ const meta: Meta<typeof TableView> = {
13
13
  export default meta;
14
14
  type Story = StoryObj<typeof TableView>;
15
15
 
16
- const mockItems = [
16
+ const items = [
17
17
  {
18
18
  id: '1',
19
19
  labels: [
20
20
  { value: 'Installation Guide', language: 'en-US' },
21
- { value: 'Guide d\'installation', language: 'fr-FR' }
21
+ { value: "Guide d'installation", language: 'fr-FR' }
22
22
  ],
23
23
  languages: ['fr-FR'],
24
24
  type: 'document',
25
25
  renditions: [],
26
- directoryNodes: []
26
+ directoryNodes: [],
27
+ disabled: false,
28
+ link: '/docs/1',
29
+ language: 'fr-FR',
30
+ files: {
31
+ 'application/pdf': {
32
+ view: '/docs/1/view',
33
+ download: '/docs/1/download',
34
+ },
35
+ },
27
36
  },
28
37
  {
29
38
  id: '2',
@@ -34,7 +43,11 @@ const mockItems = [
34
43
  languages: ['es-ES'],
35
44
  type: 'document',
36
45
  renditions: [],
37
- directoryNodes: []
46
+ directoryNodes: [],
47
+ disabled: false,
48
+ link: '/docs/2',
49
+ language: 'es-ES',
50
+ files: {},
38
51
  },
39
52
  {
40
53
  id: '3',
@@ -44,12 +57,22 @@ const mockItems = [
44
57
  languages: ['en-US'],
45
58
  type: 'document',
46
59
  renditions: [],
47
- directoryNodes: []
48
- }
60
+ directoryNodes: [],
61
+ disabled: true,
62
+ link: '/docs/3',
63
+ language: 'en-US',
64
+ files: {},
65
+ },
49
66
  ];
50
67
 
51
- export const Default: Story = {
68
+ export const Basic: Story = {
69
+ args: {
70
+ items,
71
+ },
72
+ };
73
+
74
+ export const WithFilesAndDisabled: Story = {
52
75
  args: {
53
- items: mockItems as any
54
- }
76
+ items,
77
+ },
55
78
  };
@@ -1,12 +1,5 @@
1
1
  import { FC } from "react";
2
- import {
3
- DocumentModel,
4
- ExternalProductGraphicModel,
5
- FragmentModel,
6
- InformationUnitModel,
7
- PackageModel,
8
- TopicModel
9
- } from "@c-rex/interfaces";
2
+ import { CommonItemsModel } from "@c-rex/interfaces";
10
3
  import { FileStack } from "lucide-react";
11
4
  import { FileDownloadDropdown } from "../renditions/file-download";
12
5
  import { cn, getType, getTitle, getVersions } from "@c-rex/utils";
@@ -20,14 +13,7 @@ import { BookmarkButton } from "../favorites/bookmark-button";
20
13
  import { HtmlRendition } from "../renditions/html";
21
14
 
22
15
  interface TableWithImageProps {
23
- items: (
24
- DocumentModel |
25
- ExternalProductGraphicModel |
26
- FragmentModel |
27
- InformationUnitModel |
28
- PackageModel |
29
- TopicModel
30
- )[];
16
+ items: CommonItemsModel[];
31
17
  query?: string;
32
18
  markersList?: Favorite[];
33
19
  disabledResults?: ResultTypes[];
@@ -1,24 +1,48 @@
1
1
  "use client"
2
2
 
3
- import React, { FC, useState } from "react";
3
+ import React, { FC, useEffect, useState } from "react";
4
4
  import { FileCheck, FileX, Search } from "lucide-react";
5
5
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@c-rex/ui/tooltip";
6
6
  import { cn } from "@c-rex/utils";
7
- import { InformationUnitsSuggestions } from "./generated/suggestions";
7
+ import * as AutocompleteOptions from "./generated/suggestions";
8
8
  import { useQueryState } from "nuqs";
9
9
 
10
10
  type PlacedOn = "NAVBAR" | "BODY"
11
11
  type Props = {
12
- showInput: boolean
13
12
  showPkgFilter: boolean
14
13
  placedOn?: PlacedOn
14
+ onSelectPath: string;
15
+ autocompleteType: keyof typeof AutocompleteOptions;
16
+ //these two props are only used when showPkgFilter is false and has some values to override the default behavior
17
+ alternativeAutocompleteType?: keyof typeof AutocompleteOptions;
18
+ alternativeOnSelectPath?: string;
15
19
  }
16
20
 
17
- export const SearchInput: FC<Props> = ({ showInput, showPkgFilter, placedOn = "NAVBAR" }) => {
21
+
22
+
23
+ export const SearchInput: FC<Props> = ({
24
+ showPkgFilter,
25
+ autocompleteType,
26
+ onSelectPath,
27
+ placedOn = "NAVBAR",
28
+ alternativeAutocompleteType,
29
+ alternativeOnSelectPath
30
+ }) => {
18
31
  const [pkg, setPkg] = useQueryState("package");
19
32
  const [checked, setChecked] = useState<boolean>(true);
33
+ const [autocompleteComponentName, setAutocompleteComponentName] = useState<keyof typeof AutocompleteOptions>(autocompleteType);
34
+
35
+ const AutocompleteComponent = AutocompleteOptions[autocompleteComponentName] as FC<any>;
36
+
37
+
38
+ useEffect(() => {
39
+ if (checked) {
40
+ setAutocompleteComponentName(autocompleteType);
41
+ } else if (alternativeAutocompleteType) {
42
+ setAutocompleteComponentName(alternativeAutocompleteType);
43
+ }
44
+ }, [checked]);
20
45
 
21
- if (!showInput) return null
22
46
 
23
47
  return (
24
48
  <div className={cn(
@@ -27,15 +51,12 @@ export const SearchInput: FC<Props> = ({ showInput, showPkgFilter, placedOn = "N
27
51
  )}>
28
52
  <Search className="shrink-0 opacity-50" />
29
53
 
30
- {/*
31
- Add scope=pkgID if checked is true
32
- */}
33
- <InformationUnitsSuggestions
54
+ {/* Add scope=pkgID if checked is true */}
55
+ <AutocompleteComponent
34
56
  onSelectParams={
35
- (pkg && checked) ? [{ key: "packages", value: pkg }] : []
36
-
57
+ (pkg && checked && showPkgFilter) ? [{ key: "packages", value: pkg }] : []
37
58
  }
38
- onSelectPath="/information-units"
59
+ onSelectPath={checked ? onSelectPath : alternativeOnSelectPath}
39
60
  embedded
40
61
  />
41
62
 
@@ -1,26 +1,43 @@
1
1
  import { LanguageAndCountries } from "@c-rex/interfaces";
2
2
  import { create } from "zustand";
3
+ import { persist, createJSONStorage, StateStorage } from "zustand/middleware";
4
+
5
+ const cookieStorage: StateStorage = {
6
+ getItem: (name: string): string | null => {
7
+ if (typeof document === "undefined") return null;
8
+ const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
9
+ return match ? decodeURIComponent(match[2] as string) : null;
10
+ },
11
+ setItem: (name: string, value: string): void => {
12
+ if (typeof document === "undefined") return;
13
+ const maxAge = 60 * 60 * 24 * 365; // 1 year
14
+ document.cookie = `${name}=${encodeURIComponent(value)};path=/;max-age=${maxAge};SameSite=Lax`;
15
+ },
16
+ removeItem: (name: string): void => {
17
+ if (typeof document === "undefined") return;
18
+ document.cookie = `${name}=;path=/;max-age=0`;
19
+ },
20
+ };
3
21
 
4
22
  type LanguageStoreType = {
5
- contentLang: string;
6
23
  uiLang: string;
7
24
  availableLanguages: LanguageAndCountries[];
8
- setContentLang: (v: string) => void;
9
25
  setUiLang: (v: string) => void;
10
26
  setAvailableLanguages: (list: LanguageAndCountries[]) => void;
11
27
  };
12
28
 
13
- export const useLanguageStore = create<LanguageStoreType>((set) => ({
14
- contentLang: "",
15
- uiLang: "",
16
- availableLanguages: [],
17
- setContentLang: (v) => {
18
- set({ contentLang: v });
19
- },
20
- setUiLang: (v) => {
21
- set({ uiLang: v });
22
- },
23
- setAvailableLanguages: (list) => {
24
- set({ availableLanguages: list });
25
- },
26
- }));
29
+ export const useLanguageStore = create<LanguageStoreType>()(
30
+ persist((set) => ({
31
+ uiLang: "",
32
+ availableLanguages: [],
33
+ setUiLang: (v) => {
34
+ set({ uiLang: v });
35
+ },
36
+ setAvailableLanguages: (list) => {
37
+ set({ availableLanguages: list });
38
+ },
39
+ }), {
40
+ name: "c-rex-language-store",
41
+ storage: createJSONStorage(() => cookieStorage),
42
+ })
43
+ );
@@ -1,23 +1,64 @@
1
+ import { EN_LANG, OPERATOR_OPTIONS, WILD_CARD_OPTIONS } from "@c-rex/constants";
1
2
  import { OperatorType, WildCardType } from "@c-rex/types";
2
3
  import { create } from "zustand";
3
- import { persist } from "zustand/middleware";
4
+ import { persist, createJSONStorage, StateStorage } from "zustand/middleware";
4
5
 
5
- type SearchSettingsStore = {
6
- language: string[],
6
+ const cookieStorage: StateStorage = {
7
+ getItem: (name: string): string | null => {
8
+ if (typeof document === "undefined") return null;
9
+ const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
10
+ return match ? decodeURIComponent(match[2] as string) : null;
11
+ },
12
+ setItem: (name: string, value: string): void => {
13
+ if (typeof document === "undefined") return;
14
+ const maxAge = 60 * 60 * 24 * 365; // 1 year
15
+ document.cookie = `${name}=${encodeURIComponent(value)};path=/;max-age=${maxAge};SameSite=Lax`;
16
+ },
17
+ removeItem: (name: string): void => {
18
+ if (typeof document === "undefined") return;
19
+ document.cookie = `${name}=;path=/;max-age=0`;
20
+ },
21
+ };
22
+
23
+ export type SearchSettingsState = {
24
+ language: string,
7
25
  wildcard: WildCardType,
8
26
  operator: OperatorType,
9
27
  like: boolean,
10
- updatePreferences: (settings: Partial<Omit<SearchSettingsStore, "updatePreferences">>) => void,
28
+ }
29
+
30
+ export type SearchSettingsStore = SearchSettingsState & {
31
+ updatePreferences: (settings: Partial<SearchSettingsState>) => void,
32
+ }
33
+
34
+ export const defaultSearchSettings: SearchSettingsState = {
35
+ language: EN_LANG,
36
+ wildcard: WILD_CARD_OPTIONS.BOTH,
37
+ operator: OPERATOR_OPTIONS.OR,
38
+ like: false,
39
+ }
40
+
41
+ /**
42
+ * Helper function to read search settings from cookie on the server.
43
+ * Use this in Server Components with Next.js cookies() function.
44
+ * @param cookieValue - The raw cookie value from cookies().get("c-rex-search-settings")?.value
45
+ */
46
+ export function getSearchSettingsFromCookie(cookieValue: string | undefined): SearchSettingsState {
47
+ if (!cookieValue) return defaultSearchSettings;
48
+ try {
49
+ const parsed = JSON.parse(cookieValue);
50
+ return { ...defaultSearchSettings, ...parsed.state };
51
+ } catch {
52
+ return defaultSearchSettings;
53
+ }
11
54
  }
12
55
 
13
56
  export const useSearchSettingsStore = create<SearchSettingsStore>()(
14
57
  persist((set) => ({
15
- language: [],
16
- wildcard: "BOTH",
17
- operator: "OR",
18
- like: false,
58
+ ...defaultSearchSettings,
19
59
  updatePreferences: (settings) => set((state) => ({ ...state, ...settings })),
20
60
  }), {
21
61
  name: "c-rex-search-settings",
62
+ storage: createJSONStorage(() => cookieStorage),
22
63
  })
23
64
  );
@@ -0,0 +1,20 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { AutoComplete } from '../autocomplete';
3
+
4
+ const meta: Meta<typeof AutoComplete> = {
5
+ title: 'Components/AutoComplete',
6
+ component: AutoComplete,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof AutoComplete>;
14
+
15
+ export const Basic: Story = {
16
+ args: {
17
+ endpoint: '/api/suggestions',
18
+ onSelectPath: '/',
19
+ },
20
+ };