@bitrise/bitkit 10.8.0 → 10.9.2

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit",
3
3
  "description": "Bitrise React component library",
4
- "version": "10.8.0",
4
+ "version": "10.9.2",
5
5
  "repository": "git@github.com:bitrise-io/bitkit.git",
6
6
  "main": "src/index.ts",
7
7
  "license": "UNLICENSED",
@@ -21,8 +21,11 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@chakra-ui/react": "^2.2.4",
24
+ "@chakra-ui/react-utils": "^2.0.1",
25
+ "@chakra-ui/utils": "^2.0.4",
24
26
  "@emotion/react": "^11.9.3",
25
27
  "@emotion/styled": "^11.9.3",
28
+ "@floating-ui/react-dom-interactions": "^0.8.1",
26
29
  "@popperjs/core": "^2.11.5",
27
30
  "classnames": "^2.3.1",
28
31
  "clipboard": "^2.0.11",
@@ -58,10 +61,14 @@
58
61
  "@storybook/testing-library": "^0.0.13",
59
62
  "@storybook/theming": "^6.5.9",
60
63
  "@svgr/core": "^6.3.0",
64
+ "@testing-library/dom": "^8.16.0",
65
+ "@testing-library/jest-dom": "^5.16.4",
66
+ "@testing-library/react": "^13.3.0",
67
+ "@testing-library/user-event": "^14.3.0",
61
68
  "@types/cheerio": "^0.22.31",
62
69
  "@types/clipboard": "^2.0.1",
63
70
  "@types/enzyme": "^3.10.12",
64
- "@types/jest": "^27.5.2",
71
+ "@types/jest": "^28.1.6",
65
72
  "@types/luxon": "^2.4.0",
66
73
  "@types/react": "18.0.15",
67
74
  "@types/react-dom": "^18.0.6",
@@ -87,12 +94,14 @@
87
94
  "glob": "^8.0.3",
88
95
  "husky": "^7.0.4",
89
96
  "identity-obj-proxy": "^3.0.0",
90
- "jest": "^27.5.1",
97
+ "jest": "^28.1.3",
98
+ "jest-environment-jsdom": "^28.1.3",
91
99
  "jsdom": "^19.0.0",
92
100
  "prettier": "^2.7.1",
101
+ "react-hook-form": "^7.33.1",
93
102
  "recast": "^0.21.1",
94
103
  "semantic-release": "^19.0.3",
95
- "ts-jest": "^27.1.5",
104
+ "ts-jest": "^28.0.7",
96
105
  "ts-node": "^10.9.1",
97
106
  "tsconfig-paths-webpack-plugin": "^3.5.2",
98
107
  "typescript": "^4.7.4",
@@ -110,12 +119,13 @@
110
119
  "moduleNameMapper": {
111
120
  "^.+\\.css$": "identity-obj-proxy"
112
121
  },
113
- "setupFiles": [
114
- "./jest.setup.js"
122
+ "setupFilesAfterEnv": [
123
+ "./spec/jest.setup.ts"
115
124
  ],
116
125
  "transform": {
117
126
  "\\.tsx?$": "ts-jest"
118
- }
127
+ },
128
+ "testEnvironment": "./spec/test-env.js"
119
129
  },
120
130
  "resolutions": {
121
131
  "**/ast-types": "npm:@gkz/ast-types",
@@ -0,0 +1,42 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ import { createStylesContext } from '@chakra-ui/react';
3
+ import { createContext } from '@chakra-ui/react-utils';
4
+
5
+ const [DropdownStylesProvider, useDropdownStyles] = createStylesContext('Dropdown');
6
+
7
+ export type DropdownEventArgs<T> = { value: T; index: number | undefined; label: ReactNode };
8
+
9
+ type DropdownContext<T> = {
10
+ formValue: T;
11
+ onOptionSelected: (arg: DropdownEventArgs<T>) => void;
12
+ listRef: React.RefObject<(HTMLElement | null)[]>;
13
+ searchValue: string;
14
+ searchRef: React.Ref<HTMLInputElement>;
15
+ searchOnChange: (sv: string) => void;
16
+ searchOnSubmit: () => void;
17
+ filter?: string;
18
+ activeIndex?: number | null;
19
+ getItemProps: (x: object) => object;
20
+ };
21
+
22
+ const [DropdownContextProvider, useDropdownContext] = createContext<DropdownContext<unknown>>();
23
+
24
+ function useDropdownContextTyped<T>(): DropdownContext<T> {
25
+ return useDropdownContext() as unknown as DropdownContext<T>;
26
+ }
27
+
28
+ const DropdownProvider = <T,>({
29
+ styles,
30
+ context,
31
+ children,
32
+ }: {
33
+ styles: ComponentProps<typeof DropdownStylesProvider>['value'];
34
+ children: ReactNode;
35
+ context: DropdownContext<T>;
36
+ }) => (
37
+ <DropdownContextProvider value={context as DropdownContext<unknown>}>
38
+ <DropdownStylesProvider value={styles}>{children}</DropdownStylesProvider>
39
+ </DropdownContextProvider>
40
+ );
41
+
42
+ export { DropdownProvider, useDropdownContextTyped as useDropdownContext, useDropdownStyles };
@@ -0,0 +1,110 @@
1
+ import { ReactNode, useState } from 'react';
2
+ import { ComponentStoryFn } from '@storybook/react';
3
+ import Notification from '../Notification/Notification';
4
+ import Avatar from '../Avatar/Avatar';
5
+ import Dropdown, {
6
+ DropdownGroup,
7
+ DropdownOption,
8
+ DropdownDetailedOption,
9
+ NoResultsFound,
10
+ DropdownSearch,
11
+ } from './Dropdown';
12
+
13
+ export default {
14
+ title: 'Components/Dropdown',
15
+ component: Dropdown,
16
+ };
17
+
18
+ const opts = [
19
+ { value: 'x1', label: 'text1' },
20
+ { value: 'x2', label: 'text2' },
21
+ { value: 'x3', label: 'text3' },
22
+ { value: 'x4', label: 'text4' },
23
+ ];
24
+ export const CustomSearch = () => {
25
+ const [searchValue, setSearchValue] = useState('');
26
+ const [options, setOptions] = useState<ReactNode[]>([]);
27
+ const searchOnChange = (nv: string) => {
28
+ setSearchValue(nv);
29
+ setOptions(
30
+ opts
31
+ .filter((opt) => opt.label.includes(nv))
32
+ .map((opt) => (
33
+ <DropdownOption value={opt.value} key={opt.value}>
34
+ {opt.label}
35
+ </DropdownOption>
36
+ )),
37
+ );
38
+ };
39
+ return <Dropdown search={<DropdownSearch value={searchValue} onChange={searchOnChange} />}>{options}</Dropdown>;
40
+ };
41
+ export const CustomSearchError = () => {
42
+ return (
43
+ <Dropdown search={<DropdownSearch />}>
44
+ <NoResultsFound>
45
+ <Notification status="error">Error</Notification>
46
+ </NoResultsFound>
47
+ </Dropdown>
48
+ );
49
+ };
50
+
51
+ export const WithDetail = () => {
52
+ return (
53
+ <Dropdown>
54
+ <DropdownDetailedOption value="user1" icon={<Avatar name="some" />} title="hello" subtitle="sub" />
55
+ </Dropdown>
56
+ );
57
+ };
58
+
59
+ export const WithLongOptions = () => {
60
+ return (
61
+ <Dropdown defaultValue="y" w="150px">
62
+ <DropdownOption value="y">
63
+ some very long option text longer than the component with verylongwordwithoutbreakopportunities
64
+ </DropdownOption>
65
+ <DropdownOption>some very long option text longer than the component</DropdownOption>
66
+ </Dropdown>
67
+ );
68
+ };
69
+
70
+ export const WithoutSearch = () => {
71
+ return (
72
+ <Dropdown search={false}>
73
+ <DropdownOption>opt1</DropdownOption>
74
+ <DropdownOption>opt2</DropdownOption>
75
+ <DropdownOption>opt3</DropdownOption>
76
+ </Dropdown>
77
+ );
78
+ };
79
+
80
+ export const Default: ComponentStoryFn<typeof Dropdown> = (args) => {
81
+ return (
82
+ <form
83
+ onSubmit={(ev) => {
84
+ ev.preventDefault();
85
+ const data = new FormData(ev.target as HTMLFormElement);
86
+ console.log(data.get('dropdown'));
87
+ }}
88
+ >
89
+ <Dropdown aria-label="test" name="dropdown" w="800px" {...args}>
90
+ <DropdownOption>Unset</DropdownOption>
91
+ <DropdownOption value="x1">text1</DropdownOption>
92
+ <DropdownOption value="x2">text2</DropdownOption>
93
+ <DropdownOption value="x3">text3</DropdownOption>
94
+ <DropdownOption value="x4">text4</DropdownOption>
95
+ <DropdownGroup label="test">
96
+ <DropdownOption value="x5">text5</DropdownOption>
97
+ <DropdownOption value="x6">text6</DropdownOption>
98
+ <DropdownOption value="x7">text7</DropdownOption>
99
+ </DropdownGroup>
100
+ <DropdownOption value="v1">
101
+ <div>label</div>
102
+ </DropdownOption>
103
+ <DropdownOption value="v2">
104
+ <div>label</div>
105
+ </DropdownOption>
106
+ </Dropdown>
107
+ <button type="submit">Send</button>
108
+ </form>
109
+ );
110
+ };