@grantbii/design-system 2.0.0 → 3.0.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.
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { SystemIcon, ToggleButton, ToggleButtonGroup, ToggleButtonGroupItem, Tooltip, TooltipContent, TooltipTrigger, } from "@/.";
3
+ import { expect, userEvent, within } from "storybook/test";
4
+ const meta = {
5
+ title: "Molecules/Toggle Button",
6
+ component: ToggleButton,
7
+ tags: ["autodocs"],
8
+ args: {
9
+ disabled: false,
10
+ size: "medium",
11
+ },
12
+ argTypes: {
13
+ children: {
14
+ description: "Icon or text displayed inside the toggle button.",
15
+ control: false,
16
+ },
17
+ pressed: {
18
+ description: "Pressed state when the toggle is controlled.",
19
+ control: "boolean",
20
+ },
21
+ onPressedChange: {
22
+ description: "Called when the pressed state changes.",
23
+ control: false,
24
+ },
25
+ size: {
26
+ description: "Size of the toggle button.",
27
+ table: { defaultValue: { summary: '"medium"' } },
28
+ control: "radio",
29
+ options: ["small", "medium", "large"],
30
+ },
31
+ disabled: {
32
+ description: "Prevents the toggle button from being pressed.",
33
+ table: { defaultValue: { summary: "false" } },
34
+ control: "boolean",
35
+ },
36
+ title: {
37
+ description: "Native browser tooltip text for the button.",
38
+ control: "text",
39
+ },
40
+ type: {
41
+ description: "Native button behavior when used inside a form.",
42
+ table: { defaultValue: { summary: '"button"' } },
43
+ control: "radio",
44
+ options: ["button", "submit", "reset"],
45
+ },
46
+ },
47
+ };
48
+ export default meta;
49
+ export const Icon = {
50
+ args: { title: "Bookmark" },
51
+ render: (args) => (_jsx(ToggleButton, { ...args, children: _jsx(SystemIcon.BookmarkSimpleIcon, {}) })),
52
+ play: async ({ canvasElement }) => {
53
+ const toggleButton = within(canvasElement).getByRole("button");
54
+ await expect(toggleButton).toHaveAttribute("data-state", "off");
55
+ await userEvent.click(toggleButton);
56
+ await expect(toggleButton).toHaveAttribute("data-state", "on");
57
+ await userEvent.click(toggleButton);
58
+ await expect(toggleButton).toHaveAttribute("data-state", "off");
59
+ },
60
+ };
61
+ export const WithTooltip = {
62
+ render: (args) => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { children: _jsx(ToggleButton, { ...args, children: _jsx(SystemIcon.BookmarkSimpleIcon, {}) }) }), _jsx(TooltipContent, { sideOffset: 8, children: "Bookmark" })] })),
63
+ };
64
+ export const Text = {
65
+ render: (args) => _jsx(ToggleButton, { ...args, children: "Bookmark" }),
66
+ };
67
+ export const IconGroup = {
68
+ args: { size: "small" },
69
+ render: (args) => (_jsxs(ToggleButtonGroup, { defaultValue: "bookmark", disabled: args.disabled, size: args.size, children: [_jsx(ToggleButtonGroupItem, { value: "bookmark", title: "Bookmarks", children: _jsx(SystemIcon.BookmarkSimpleIcon, {}) }), _jsx(ToggleButtonGroupItem, { value: "grid", title: "Grid view", children: _jsx(SystemIcon.GridFourIcon, {}) }), _jsx(ToggleButtonGroupItem, { value: "list", title: "List view", children: _jsx(SystemIcon.ListIcon, {}) })] })),
70
+ };
71
+ export const TextGroup = {
72
+ args: { size: "small" },
73
+ render: (args) => (_jsxs(ToggleButtonGroup, { defaultValue: "first", disabled: args.disabled, size: args.size, children: [_jsx(ToggleButtonGroupItem, { value: "first", children: "Bookmark" }), _jsx(ToggleButtonGroupItem, { value: "second", children: "Bookmark" }), _jsx(ToggleButtonGroupItem, { value: "third", children: "Bookmark" })] })),
74
+ };
75
+ export const Disabled = {
76
+ args: { disabled: true, title: "Bookmark" },
77
+ render: Icon.render,
78
+ };
79
+ //# sourceMappingURL=ToggleButton.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToggleButton.stories.js","sourceRoot":"","sources":["../../../stories/molecules/ToggleButton.stories.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n SystemIcon,\n ToggleButton,\n ToggleButtonGroup,\n ToggleButtonGroupItem,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/.\";\nimport type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\nimport { expect, userEvent, within } from \"storybook/test\";\n\nconst meta: Meta<typeof ToggleButton> = {\n title: \"Molecules/Toggle Button\",\n component: ToggleButton,\n tags: [\"autodocs\"],\n args: {\n disabled: false,\n size: \"medium\",\n },\n argTypes: {\n children: {\n description: \"Icon or text displayed inside the toggle button.\",\n control: false,\n },\n pressed: {\n description: \"Pressed state when the toggle is controlled.\",\n control: \"boolean\",\n },\n onPressedChange: {\n description: \"Called when the pressed state changes.\",\n control: false,\n },\n size: {\n description: \"Size of the toggle button.\",\n table: { defaultValue: { summary: '\"medium\"' } },\n control: \"radio\",\n options: [\"small\", \"medium\", \"large\"],\n },\n disabled: {\n description: \"Prevents the toggle button from being pressed.\",\n table: { defaultValue: { summary: \"false\" } },\n control: \"boolean\",\n },\n title: {\n description: \"Native browser tooltip text for the button.\",\n control: \"text\",\n },\n type: {\n description: \"Native button behavior when used inside a form.\",\n table: { defaultValue: { summary: '\"button\"' } },\n control: \"radio\",\n options: [\"button\", \"submit\", \"reset\"],\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\nexport const Icon: Story = {\n args: { title: \"Bookmark\" },\n render: (args) => (\n <ToggleButton {...args}>\n <SystemIcon.BookmarkSimpleIcon />\n </ToggleButton>\n ),\n play: async ({ canvasElement }) => {\n const toggleButton = within(canvasElement).getByRole(\"button\");\n await expect(toggleButton).toHaveAttribute(\"data-state\", \"off\");\n await userEvent.click(toggleButton);\n await expect(toggleButton).toHaveAttribute(\"data-state\", \"on\");\n await userEvent.click(toggleButton);\n await expect(toggleButton).toHaveAttribute(\"data-state\", \"off\");\n },\n};\n\nexport const WithTooltip: Story = {\n render: (args) => (\n <Tooltip>\n <TooltipTrigger>\n <ToggleButton {...args}>\n <SystemIcon.BookmarkSimpleIcon />\n </ToggleButton>\n </TooltipTrigger>\n <TooltipContent sideOffset={8}>Bookmark</TooltipContent>\n </Tooltip>\n ),\n};\n\nexport const Text: Story = {\n render: (args) => <ToggleButton {...args}>Bookmark</ToggleButton>,\n};\n\nexport const IconGroup: Story = {\n args: { size: \"small\" },\n render: (args) => (\n <ToggleButtonGroup\n defaultValue=\"bookmark\"\n disabled={args.disabled}\n size={args.size}\n >\n <ToggleButtonGroupItem value=\"bookmark\" title=\"Bookmarks\">\n <SystemIcon.BookmarkSimpleIcon />\n </ToggleButtonGroupItem>\n <ToggleButtonGroupItem value=\"grid\" title=\"Grid view\">\n <SystemIcon.GridFourIcon />\n </ToggleButtonGroupItem>\n <ToggleButtonGroupItem value=\"list\" title=\"List view\">\n <SystemIcon.ListIcon />\n </ToggleButtonGroupItem>\n </ToggleButtonGroup>\n ),\n};\n\nexport const TextGroup: Story = {\n args: { size: \"small\" },\n render: (args) => (\n <ToggleButtonGroup\n defaultValue=\"first\"\n disabled={args.disabled}\n size={args.size}\n >\n <ToggleButtonGroupItem value=\"first\">Bookmark</ToggleButtonGroupItem>\n <ToggleButtonGroupItem value=\"second\">Bookmark</ToggleButtonGroupItem>\n <ToggleButtonGroupItem value=\"third\">Bookmark</ToggleButtonGroupItem>\n </ToggleButtonGroup>\n ),\n};\n\nexport const Disabled: Story = {\n args: { disabled: true, title: \"Bookmark\" },\n render: Icon.render,\n};\n"]}
@@ -0,0 +1,11 @@
1
+ import { type TooltipContentProps } from "@/.";
2
+ import type { ReactNode } from "react";
3
+ import type { Meta, StoryObj } from "@storybook/nextjs-vite";
4
+ type TooltipExampleProps = Omit<TooltipContentProps, "children"> & {
5
+ content: ReactNode;
6
+ };
7
+ declare const TooltipExample: ({ content, ...tooltipContentProps }: TooltipExampleProps) => import("react").JSX.Element;
8
+ declare const meta: Meta<typeof TooltipExample>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof meta>;
11
+ export declare const Default: Story;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Tooltip, TooltipContent, TooltipTrigger, } from "@/.";
3
+ const TooltipExample = ({ content, ...tooltipContentProps }) => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { children: _jsx(Button, { label: "Hover me" }) }), _jsx(TooltipContent, { ...tooltipContentProps, children: content })] }));
4
+ const meta = {
5
+ title: "Molecules/Tooltip",
6
+ component: TooltipExample,
7
+ tags: ["autodocs"],
8
+ args: {
9
+ content: "A message which appears when a cursor is positioned over an element.",
10
+ side: "top",
11
+ sideOffset: 8,
12
+ },
13
+ argTypes: {
14
+ content: {
15
+ description: "Content displayed inside the tooltip.",
16
+ control: "text",
17
+ },
18
+ side: {
19
+ description: "Preferred side of the trigger where the tooltip is displayed. It may change to remain visible within the viewport.",
20
+ control: "radio",
21
+ options: ["top", "right", "bottom", "left"],
22
+ table: { defaultValue: { summary: '"top"' } },
23
+ },
24
+ sideOffset: {
25
+ description: "Distance in pixels between the tooltip and its trigger.",
26
+ control: { type: "number", min: 0, step: 1 },
27
+ table: { defaultValue: { summary: "0" } },
28
+ },
29
+ },
30
+ };
31
+ export default meta;
32
+ export const Default = {};
33
+ //# sourceMappingURL=Tooltip.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.stories.js","sourceRoot":"","sources":["../../../stories/molecules/Tooltip.stories.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,OAAO,EACP,cAAc,EACd,cAAc,GAEf,MAAM,KAAK,CAAC;AAQb,MAAM,cAAc,GAAG,CAAC,EACtB,OAAO,EACP,GAAG,mBAAmB,EACF,EAAE,EAAE,CAAC,CACzB,MAAC,OAAO,eACN,KAAC,cAAc,cACb,KAAC,MAAM,IAAC,KAAK,EAAC,UAAU,GAAG,GACZ,EACjB,KAAC,cAAc,OAAK,mBAAmB,YAAG,OAAO,GAAkB,IAC3D,CACX,CAAC;AAEF,MAAM,IAAI,GAAgC;IACxC,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,cAAc;IACzB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,IAAI,EAAE;QACJ,OAAO,EACL,sEAAsE;QACxE,IAAI,EAAE,KAAK;QACX,UAAU,EAAE,CAAC;KACd;IACD,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,WAAW,EAAE,uCAAuC;YACpD,OAAO,EAAE,MAAM;SAChB;QACD,IAAI,EAAE;YACJ,WAAW,EACT,oHAAoH;YACtH,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;YAC3C,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;SAC9C;QACD,UAAU,EAAE;YACV,WAAW,EAAE,yDAAyD;YACtE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;YAC5C,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;SAC1C;KACF;CACF,CAAC;AAEF,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,OAAO,GAAU,EAAE,CAAC","sourcesContent":["import {\n Button,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n type TooltipContentProps,\n} from \"@/.\";\nimport type { ReactNode } from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\n\ntype TooltipExampleProps = Omit<TooltipContentProps, \"children\"> & {\n content: ReactNode;\n};\n\nconst TooltipExample = ({\n content,\n ...tooltipContentProps\n}: TooltipExampleProps) => (\n <Tooltip>\n <TooltipTrigger>\n <Button label=\"Hover me\" />\n </TooltipTrigger>\n <TooltipContent {...tooltipContentProps}>{content}</TooltipContent>\n </Tooltip>\n);\n\nconst meta: Meta<typeof TooltipExample> = {\n title: \"Molecules/Tooltip\",\n component: TooltipExample,\n tags: [\"autodocs\"],\n args: {\n content:\n \"A message which appears when a cursor is positioned over an element.\",\n side: \"top\",\n sideOffset: 8,\n },\n argTypes: {\n content: {\n description: \"Content displayed inside the tooltip.\",\n control: \"text\",\n },\n side: {\n description:\n \"Preferred side of the trigger where the tooltip is displayed. It may change to remain visible within the viewport.\",\n control: \"radio\",\n options: [\"top\", \"right\", \"bottom\", \"left\"],\n table: { defaultValue: { summary: '\"top\"' } },\n },\n sideOffset: {\n description: \"Distance in pixels between the tooltip and its trigger.\",\n control: { type: \"number\", min: 0, step: 1 },\n table: { defaultValue: { summary: \"0\" } },\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\nexport const Default: Story = {};\n"]}
@@ -1,10 +1,12 @@
1
+ import { type DropdownProps } from "@/.";
1
2
  import type { Meta, StoryObj } from "@storybook/nextjs-vite";
2
- type ExampleProps = {
3
+ type ExampleProps = DropdownProps & {
3
4
  controlled: boolean;
4
5
  };
5
- declare const DropdownExample: ({ controlled }: ExampleProps) => import("react").JSX.Element;
6
+ declare const DropdownExample: ({ controlled, onChange, ...props }: ExampleProps) => import("react").JSX.Element;
6
7
  declare const meta: Meta<typeof DropdownExample>;
7
8
  export default meta;
8
9
  type Story = StoryObj<typeof meta>;
9
10
  export declare const Controlled: Story;
10
11
  export declare const Uncontrolled: Story;
12
+ export declare const FitContent: Story;
@@ -1,39 +1,96 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Dropdown, enumToOptions } from "@/.";
3
3
  import { Objective } from "@grantbii/ui-core/grant/enums";
4
- import { parseEnum } from "@grantbii/ui-core/enums";
5
4
  import { useState } from "react";
6
- const DropdownExample = ({ controlled }) => {
7
- const [selectedObjective, setSelectedObjective] = useState(Objective.UNKNOWN);
8
- const controlledProps = {
9
- ...baseProps,
10
- value: selectedObjective === Objective.UNKNOWN ? "" : selectedObjective,
11
- onChange: (event) => setSelectedObjective(parseEnum(event.target.value, Objective)),
5
+ import { expect, fn, userEvent, within } from "storybook/test";
6
+ const DropdownExample = ({ controlled, onChange, ...props }) => {
7
+ const [value, setValue] = useState(props.defaultValue ?? "");
8
+ const handleChange = (nextValue) => {
9
+ setValue(nextValue);
10
+ onChange?.(nextValue);
12
11
  };
13
- return _jsx(Dropdown, { ...(controlled ? controlledProps : uncontrolledProps) });
14
- };
15
- const baseProps = {
16
- options: enumToOptions(Objective),
17
- defaultLabel: "Select grant objective",
18
- };
19
- const uncontrolledProps = {
20
- ...baseProps,
21
- defaultValue: "",
12
+ return (_jsx(Dropdown, { ...props, ...(controlled
13
+ ? { value: props.value ?? value, onChange: handleChange }
14
+ : { onChange }) }));
22
15
  };
23
16
  const meta = {
24
17
  title: "Organisms/Dropdown",
25
18
  component: DropdownExample,
26
19
  tags: ["autodocs"],
20
+ args: {
21
+ controlled: false,
22
+ options: enumToOptions(Objective).slice(0, 5),
23
+ placeholder: "Select grant objective",
24
+ defaultValue: "",
25
+ disabled: false,
26
+ width: 320,
27
+ name: "objective",
28
+ onChange: fn(),
29
+ },
30
+ argTypes: {
31
+ controlled: {
32
+ description: "Controls whether the selected value is managed by React state or by the Dropdown itself.",
33
+ table: { defaultValue: { summary: "false" } },
34
+ },
35
+ options: {
36
+ description: "Options displayed in the dropdown panel.",
37
+ control: "object",
38
+ },
39
+ placeholder: {
40
+ description: "Label displayed when no option is selected.",
41
+ table: { defaultValue: { summary: '"Select an option"' } },
42
+ control: "text",
43
+ },
44
+ value: {
45
+ description: "Selected value when the Dropdown is controlled.",
46
+ control: "text",
47
+ },
48
+ defaultValue: {
49
+ description: "Initial selected value when the Dropdown is uncontrolled.",
50
+ table: { defaultValue: { summary: '""' } },
51
+ control: "text",
52
+ },
53
+ onChange: {
54
+ description: "Called with the selected option value.",
55
+ control: false,
56
+ },
57
+ disabled: {
58
+ description: "Disables the dropdown trigger and form value.",
59
+ table: { defaultValue: { summary: "false" } },
60
+ control: "boolean",
61
+ },
62
+ width: {
63
+ description: "Width of the trigger and dropdown container.",
64
+ table: { defaultValue: { summary: '"100%"' } },
65
+ control: "text",
66
+ },
67
+ name: {
68
+ description: "Form field name used to submit the selected value.",
69
+ control: "text",
70
+ },
71
+ form: {
72
+ description: "ID of the form associated with the hidden form field.",
73
+ control: "text",
74
+ },
75
+ },
27
76
  };
28
77
  export default meta;
29
78
  export const Controlled = {
30
79
  args: {
31
80
  controlled: true,
32
81
  },
82
+ play: async ({ canvasElement }) => {
83
+ const canvas = within(canvasElement);
84
+ const trigger = canvas.getByRole("button");
85
+ await userEvent.click(trigger);
86
+ await userEvent.click(canvas.getAllByRole("option")[0]);
87
+ await expect(trigger).not.toHaveTextContent("Select grant objective");
88
+ },
33
89
  };
34
- export const Uncontrolled = {
90
+ export const Uncontrolled = {};
91
+ export const FitContent = {
35
92
  args: {
36
- controlled: false,
93
+ width: "fit-content",
37
94
  },
38
95
  };
39
96
  //# sourceMappingURL=Dropdown.stories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.stories.js","sourceRoot":"","sources":["../../../stories/organisms/Dropdown.stories.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAsB,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAMjC,MAAM,eAAe,GAAG,CAAC,EAAE,UAAU,EAAgB,EAAE,EAAE;IACvD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE9E,MAAM,eAAe,GAAkB;QACrC,GAAG,SAAS;QACZ,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB;QACvE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,oBAAoB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;KACjE,CAAC;IAEF,OAAO,KAAC,QAAQ,OAAK,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAI,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,SAAS,GAAkB;IAC/B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC;IACjC,YAAY,EAAE,wBAAwB;CACvC,CAAC;AAEF,MAAM,iBAAiB,GAAkB;IACvC,GAAG,SAAS;IACZ,YAAY,EAAE,EAAE;CACjB,CAAC;AAEF,MAAM,IAAI,GAAiC;IACzC,KAAK,EAAE,oBAAoB;IAC3B,SAAS,EAAE,eAAe;IAC1B,IAAI,EAAE,CAAC,UAAU,CAAC;CACnB,CAAC;AAEF,eAAe,IAAI,CAAC;AAIpB,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,IAAI;KACjB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAU;IACjC,IAAI,EAAE;QACJ,UAAU,EAAE,KAAK;KAClB;CACF,CAAC","sourcesContent":["import { Dropdown, enumToOptions, type DropdownProps } from \"@/.\";\nimport { Objective } from \"@grantbii/ui-core/grant/enums\";\nimport { parseEnum } from \"@grantbii/ui-core/enums\";\nimport type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\nimport { useState } from \"react\";\n\ntype ExampleProps = {\n controlled: boolean;\n};\n\nconst DropdownExample = ({ controlled }: ExampleProps) => {\n const [selectedObjective, setSelectedObjective] = useState(Objective.UNKNOWN);\n\n const controlledProps: DropdownProps = {\n ...baseProps,\n value: selectedObjective === Objective.UNKNOWN ? \"\" : selectedObjective,\n onChange: (event) =>\n setSelectedObjective(parseEnum(event.target.value, Objective)),\n };\n\n return <Dropdown {...(controlled ? controlledProps : uncontrolledProps)} />;\n};\n\nconst baseProps: DropdownProps = {\n options: enumToOptions(Objective),\n defaultLabel: \"Select grant objective\",\n};\n\nconst uncontrolledProps: DropdownProps = {\n ...baseProps,\n defaultValue: \"\",\n};\n\nconst meta: Meta<typeof DropdownExample> = {\n title: \"Organisms/Dropdown\",\n component: DropdownExample,\n tags: [\"autodocs\"],\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\nexport const Controlled: Story = {\n args: {\n controlled: true,\n },\n};\n\nexport const Uncontrolled: Story = {\n args: {\n controlled: false,\n },\n};\n"]}
1
+ {"version":3,"file":"Dropdown.stories.js","sourceRoot":"","sources":["../../../stories/organisms/Dropdown.stories.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Dropdown, enumToOptions, type DropdownProps } from \"@/.\";\nimport { Objective } from \"@grantbii/ui-core/grant/enums\";\nimport type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\nimport { useState } from \"react\";\nimport { expect, fn, userEvent, within } from \"storybook/test\";\n\ntype ExampleProps = DropdownProps & {\n controlled: boolean;\n};\n\nconst DropdownExample = ({ controlled, onChange, ...props }: ExampleProps) => {\n const [value, setValue] = useState(props.defaultValue ?? \"\");\n\n const handleChange = (nextValue: string) => {\n setValue(nextValue);\n onChange?.(nextValue);\n };\n\n return (\n <Dropdown\n {...props}\n {...(controlled\n ? { value: props.value ?? value, onChange: handleChange }\n : { onChange })}\n />\n );\n};\n\nconst meta: Meta<typeof DropdownExample> = {\n title: \"Organisms/Dropdown\",\n component: DropdownExample,\n tags: [\"autodocs\"],\n args: {\n controlled: false,\n options: enumToOptions(Objective).slice(0, 5),\n placeholder: \"Select grant objective\",\n defaultValue: \"\",\n disabled: false,\n width: 320,\n name: \"objective\",\n onChange: fn(),\n },\n argTypes: {\n controlled: {\n description:\n \"Controls whether the selected value is managed by React state or by the Dropdown itself.\",\n table: { defaultValue: { summary: \"false\" } },\n },\n options: {\n description: \"Options displayed in the dropdown panel.\",\n control: \"object\",\n },\n placeholder: {\n description: \"Label displayed when no option is selected.\",\n table: { defaultValue: { summary: '\"Select an option\"' } },\n control: \"text\",\n },\n value: {\n description: \"Selected value when the Dropdown is controlled.\",\n control: \"text\",\n },\n defaultValue: {\n description: \"Initial selected value when the Dropdown is uncontrolled.\",\n table: { defaultValue: { summary: '\"\"' } },\n control: \"text\",\n },\n onChange: {\n description: \"Called with the selected option value.\",\n control: false,\n },\n disabled: {\n description: \"Disables the dropdown trigger and form value.\",\n table: { defaultValue: { summary: \"false\" } },\n control: \"boolean\",\n },\n width: {\n description: \"Width of the trigger and dropdown container.\",\n table: { defaultValue: { summary: '\"100%\"' } },\n control: \"text\",\n },\n name: {\n description: \"Form field name used to submit the selected value.\",\n control: \"text\",\n },\n form: {\n description: \"ID of the form associated with the hidden form field.\",\n control: \"text\",\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\nexport const Controlled: Story = {\n args: {\n controlled: true,\n },\n play: async ({ canvasElement }) => {\n const canvas = within(canvasElement);\n const trigger = canvas.getByRole(\"button\");\n await userEvent.click(trigger);\n await userEvent.click(canvas.getAllByRole(\"option\")[0]);\n await expect(trigger).not.toHaveTextContent(\"Select grant objective\");\n },\n};\n\nexport const Uncontrolled: Story = {};\n\nexport const FitContent: Story = {\n args: {\n width: \"fit-content\",\n },\n};\n"]}