@openedx/paragon 22.1.1 → 22.2.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.
@@ -0,0 +1,5 @@
1
+ export * from './es5';
2
+
3
+ import * as allIcons from './es5';
4
+
5
+ export type IconName = keyof typeof allIcons;
@@ -0,0 +1 @@
1
+ export * from './es5';
@@ -5,7 +5,7 @@
5
5
  "main": "index.js",
6
6
  "sideEffects": false,
7
7
  "scripts": {
8
- "build": "node copy-mui-icons.js && node copy-brand-icons.js && svgr svg --out-dir jsx && babel jsx -d es5",
8
+ "build": "node copy-mui-icons.js && node copy-brand-icons.js && svgr svg --out-dir jsx && babel jsx -d es5 && echo '// @ts-nocheck' > es5/index.ts && cat es5/index.js >> es5/index.ts",
9
9
  "test": "echo \"Error: no test specified\" && exit 1"
10
10
  },
11
11
  "keywords": [],
@@ -22,5 +22,11 @@
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": "^16.8.6 || ^17.0.2"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "import": "./index.mjs",
29
+ "types": "./index.d.ts"
30
+ }
25
31
  }
26
32
  }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@openedx/paragon",
3
- "version": "22.1.1",
3
+ "version": "22.2.1",
4
4
  "description": "Accessible, responsive UI component library based on Bootstrap.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
7
8
  "license": "Apache-2.0",
8
9
  "publishConfig": {
9
10
  "access": "public"
@@ -47,7 +48,7 @@
47
48
  "build-types": "tsc --emitDeclarationOnly",
48
49
  "playroom:start": "npm run playroom:start --workspace=www",
49
50
  "playroom:build": "npm run playroom:build --workspace=www",
50
- "prepare": "husky install"
51
+ "prepare": "husky || true"
51
52
  },
52
53
  "dependencies": {
53
54
  "@fortawesome/fontawesome-svg-core": "^6.1.1",
@@ -107,6 +108,8 @@
107
108
  "@types/jest": "^29.5.10",
108
109
  "@types/react": "17.0.0",
109
110
  "@types/react-dom": "17.0.11",
111
+ "@types/react-responsive": "^8.0.8",
112
+ "@types/react-table": "^7.7.19",
110
113
  "@types/react-test-renderer": "^18.0.0",
111
114
  "@types/uuid": "^9.0.0",
112
115
  "@typescript-eslint/eslint-plugin": "^5.22.0",
@@ -123,7 +126,7 @@
123
126
  "eslint-plugin-jsx-a11y": "6.7.1",
124
127
  "eslint-plugin-react": "7.32.2",
125
128
  "eslint-plugin-react-hooks": "4.6.0",
126
- "husky": "^8.0.1",
129
+ "husky": "^9.0.11",
127
130
  "identity-obj-proxy": "^3.0.0",
128
131
  "jest": "^28.1.3",
129
132
  "jest-cli": "^28.1.2",
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
+ import * as ParagonIcons from '../../icons';
4
+ import { type IconName } from '../../icons';
3
5
 
4
6
  import Icon from './index';
5
7
 
@@ -14,7 +16,41 @@ function BlankSrc() {
14
16
  return <div />;
15
17
  }
16
18
 
19
+ /** A compile time check. Whatever React elements this wraps won't run at runtime. */
20
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
21
+ function CompileCheck(_props: { children: React.ReactNode }) { return null; }
22
+
23
+ describe('IconName type', () => {
24
+ it('has correct typing', () => {
25
+ /* eslint-disable @typescript-eslint/no-unused-vars */
26
+
27
+ const realName: IconName = 'ArrowCircleDown';
28
+ // @ts-expect-error This should be a compile-time error, as 'FooBarIcon' doesn't exist.
29
+ const wrongName: IconName = 'FooBarIcon';
30
+
31
+ /* eslint-enable @typescript-eslint/no-unused-vars */
32
+ });
33
+ });
34
+
17
35
  describe('<Icon />', () => {
36
+ it('has correct typing', () => {
37
+ <CompileCheck>
38
+ {/* Correct usage */}
39
+ <Icon src={ParagonIcons.ArrowCircleDown} id="icon123" size="sm" />
40
+ {/* An empty <Icon /> is allowed; if not, the checks below would need to be modified. */}
41
+ <Icon />
42
+
43
+ {/* @ts-expect-error Using a non-existent icon from @openedx/paragon/icons is a type error */}
44
+ <Icon src={ParagonIcons.FooBarIcon} />
45
+ {/* @ts-expect-error The 'src' prop cannot be a string. */}
46
+ <Icon src="string" />
47
+ {/* @ts-expect-error Random props cannot be added */}
48
+ <Icon foo="bar" />
49
+ {/* @ts-expect-error This is not a valid size property */}
50
+ <Icon size="big" />
51
+ </CompileCheck>;
52
+ });
53
+
18
54
  describe('props received correctly', () => {
19
55
  it('receives required props', () => {
20
56
  const { container } = render(<Icon className={classNames} />);
@@ -66,5 +102,13 @@ describe('<Icon />', () => {
66
102
 
67
103
  expect(iconSpan.classList.contains('pgn__icon__xs')).toEqual(true);
68
104
  });
105
+
106
+ it('receives style or other arbitrary HTML properties correctly', () => {
107
+ const { container } = render(<Icon src={BlankSrc} style={{ color: 'red' }} size="xs" />);
108
+ const iconSpans = container.querySelectorAll('span');
109
+ const iconSpan = iconSpans[0];
110
+
111
+ expect(iconSpan.style.color).toEqual('red');
112
+ });
69
113
  });
70
114
  });
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
2
 
3
- export interface IconProps {
3
+ export interface IconProps extends React.ComponentPropsWithoutRef<'span'> {
4
4
  src?: React.ReactElement | Function;
5
5
  svgAttrs?: {
6
6
  'aria-label'?: string;
7
7
  'aria-labelledby'?: string;
8
8
  };
9
- id?: string;
9
+ id?: string | null;
10
10
  size?: 'xs' | 'sm' | 'md' | 'lg';
11
- className?: string;
11
+ className?: string | string[];
12
12
  hidden?: boolean;
13
13
  screenReaderText?: React.ReactNode;
14
14
  }
@@ -74,6 +74,16 @@
74
74
  margin-left: calc(#{$menu-item-icon-margin-left} * -1);
75
75
  }
76
76
  }
77
+
78
+ &.pgn__form-checkbox {
79
+ > input {
80
+ flex-shrink: 0; // When the menu item text is long, don't squish the checkbox, if present
81
+ }
82
+
83
+ > div {
84
+ overflow: hidden; // Ensure text gets truncated properly if needed
85
+ }
86
+ }
77
87
  }
78
88
  }
79
89
 
package/src/index.d.ts ADDED
@@ -0,0 +1,216 @@
1
+ /* eslint-disable max-len, one-var, one-var-declaration-per-line */
2
+ // each line in this file corresponds with the line in index.js
3
+
4
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
5
+ // Things that have types
6
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
7
+ export { default as Bubble } from './Bubble';
8
+ export { default as Chip, CHIP_PGN_CLASS } from './Chip';
9
+ export { default as ChipCarousel } from './ChipCarousel';
10
+ export { default as Icon } from './Icon';
11
+
12
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
13
+ // Things that don't have types
14
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
15
+ export const asInput: any; // from './asInput';
16
+ export const ActionRow: any; // from './ActionRow';
17
+ export const Alert: any, ALERT_CLOSE_LABEL_TEXT: string; // from './Alert';
18
+ export const Annotation: any; // from './Annotation';
19
+ export const Avatar: any; // from './Avatar';
20
+ export const AvatarButton: any; // from './AvatarButton';
21
+ export const Badge: any; // from './Badge';
22
+ export const Breadcrumb: any; // from './Breadcrumb';
23
+ export const Button: any, ButtonGroup: any, ButtonToolbar: any; // from './Button';
24
+ export const
25
+ Card: any,
26
+ CardColumns: any,
27
+ CardDeck: any,
28
+ CardImg: any,
29
+ CardGroup: any,
30
+ CardGrid: any,
31
+ CardCarousel: any,
32
+ CARD_VARIANTS: any;
33
+ // from './Card';
34
+ export const
35
+ Carousel: any, CarouselItem: any, CAROUSEL_NEXT_LABEL_TEXT: any, CAROUSEL_PREV_LABEL_TEXT: any;
36
+ // from './Carousel';
37
+ export const CheckBox: any; // from './CheckBox';
38
+ export const CheckBoxGroup: any; // from './CheckBoxGroup';
39
+ export const CloseButton: any; // from './CloseButton';
40
+ export const Container: any; // from './Container';
41
+ export const Layout: any, Col: any, Row: any; // from './Layout';
42
+ export const Collapse: any; // from './Collapse';
43
+ export const Collapsible: any; // from './Collapsible';
44
+ export const Scrollable: any; // from './Scrollable';
45
+ export const
46
+ Dropdown: any,
47
+ DropdownToggle: any,
48
+ DropdownButton: any,
49
+ SplitButton: any;
50
+ // from './Dropdown';
51
+ export const Fade: any; // from './Fade';
52
+ export const Fieldset: any; // from './Fieldset';
53
+ export const
54
+ Form: any,
55
+ RadioControl: any,
56
+ CheckboxControl: any,
57
+ SwitchControl: any,
58
+ FormSwitchSet: any,
59
+ FormControl: any,
60
+ FormControlDecoratorGroup: any,
61
+ FormControlFeedback: any,
62
+ FormCheck: any,
63
+ FormFile: any,
64
+ FormRadio: any,
65
+ FormRadioSet: any,
66
+ FormRadioSetContext: any,
67
+ FormGroup: any,
68
+ FormLabel: any,
69
+ useCheckboxSetValues: any,
70
+ FormText: any,
71
+ FormAutosuggest: any,
72
+ FormAutosuggestOption: any,
73
+ InputGroup: any;
74
+ // from './Form';
75
+ export const Hyperlink: any, HYPER_LINK_EXTERNAL_LINK_ALT_TEXT: string, HYPER_LINK_EXTERNAL_LINK_TITLE: string; // from './Hyperlink';
76
+ export const IconButton: any, IconButtonWithTooltip: any; // from './IconButton';
77
+ export const IconButtonToggle: any; // from './IconButtonToggle';
78
+ export const Input: any; // from './Input';
79
+ export const InputSelect: any; // from './InputSelect';
80
+ export const InputText: any; // from './InputText';
81
+ export const Image: any, Figure; // from './Image';
82
+ export const ListBox: any; // from './ListBox';
83
+ export const ListBoxOption: any; // from './ListBoxOption';
84
+ export const MailtoLink: any, MAIL_TO_LINK_EXTERNAL_LINK_ALTERNATIVE_TEXT: string, MAIL_TO_LINK_EXTERNAL_LINK_TITLE: string; // from './MailtoLink';
85
+ export const Media: any; // from './Media';
86
+ export const Menu: any; // from './Menu';
87
+ export const MenuItem: any; // from './Menu/MenuItem';
88
+ export const SelectMenu: any, SELECT_MENU_DEFAULT_MESSAGE: string; // from './Menu/SelectMenu';
89
+ export const Modal: any; // from './Modal';
90
+ export const ModalCloseButton: any; // from './Modal/ModalCloseButton';
91
+ export const FullscreenModal: any, FULLSCREEN_MODAL_CLOSE_LABEL: string; // from './Modal/FullscreenModal';
92
+ export const MarketingModal: any; // from './Modal/MarketingModal';
93
+ export const StandardModal: any, STANDARD_MODAL_CLOSE_LABEL: string; // from './Modal/StandardModal';
94
+ export const AlertModal: any; // from './Modal/AlertModal';
95
+ export const ModalLayer: any; // from './Modal/ModalLayer';
96
+ export const ModalDialog: any, MODAL_DIALOG_CLOSE_LABEL: string; // from './Modal/ModalDialog';
97
+ export const ModalPopup: any; // from './Modal/ModalPopup';
98
+ export const ModalContext: any; // from './Modal/ModalContext';
99
+ export const Portal: any; // from './Modal/Portal';
100
+ export const PopperElement: any; // from './Modal/PopperElement';
101
+
102
+ export const
103
+ Nav: any,
104
+ NavDropdown: any,
105
+ NavItem: any,
106
+ NavLink: any;
107
+ // from './Nav';
108
+ export const Navbar: any, NavbarBrand: any, NAVBAR_LABEL: string; // from './Navbar';
109
+ export const Overlay: any, OverlayTrigger: any; // from './Overlay';
110
+ export const PageBanner: any, PAGE_BANNER_DISMISS_ALT_TEXT: string; // from './PageBanner';
111
+ export const
112
+ Pagination: any,
113
+ PAGINATION_BUTTON_LABEL_PREV: string,
114
+ PAGINATION_BUTTON_ICON_BUTTON_NEXT_ALT: string,
115
+ PAGINATION_BUTTON_ICON_BUTTON_PREV_ALT: string,
116
+ PAGINATION_BUTTON_LABEL_PAGE_OF_COUNT: string,
117
+ PAGINATION_BUTTON_LABEL_CURRENT_PAGE: string,
118
+ PAGINATION_BUTTON_LABEL_NEXT: string,
119
+ PAGINATION_BUTTON_LABEL_PAGE: string;
120
+ // from './Pagination';
121
+ export const Popover: any, PopoverTitle: any, PopoverContent: any; // from './Popover';
122
+ export const ProgressBar: any; // from './ProgressBar';
123
+ export const ProductTour: any; // from './ProductTour';
124
+ export const RadioButtonGroup: any, RadioButton: any; // from './RadioButtonGroup';
125
+ export const ResponsiveEmbed: any; // from './ResponsiveEmbed';
126
+ export const
127
+ SearchField: any,
128
+ SEARCH_FIELD_SCREEN_READER_TEXT_LABEL: string,
129
+ SEARCH_FIELD_SCREEN_READER_TEXT_CLEAR_BUTTON: string,
130
+ SEARCH_FIELD_SCREEN_READER_TEXT_SUBMIT_BUTTON: string,
131
+ SEARCH_FIELD_BUTTON_TEXT: string;
132
+ // from './SearchField';
133
+ export const Sheet: any; // from './Sheet';
134
+ export const Spinner: any; // from './Spinner';
135
+ export const Stepper: any; // from './Stepper';
136
+ export const StatefulButton: any; // from './StatefulButton';
137
+ export const StatusAlert: any; // from './StatusAlert';
138
+ export const Table: any; // from './Table';
139
+ export const
140
+ Tabs: any,
141
+ Tab: any,
142
+ TabContainer: any,
143
+ TabContent: any,
144
+ TabPane: any;
145
+ // from './Tabs';
146
+ export const TextArea: any; // from './TextArea';
147
+ export const Toast: any, TOAST_CLOSE_LABEL_TEXT: string, TOAST_DELAY: number; // from './Toast';
148
+ export const Tooltip: any; // from './Tooltip';
149
+ export const ValidationFormGroup: any; // from './ValidationFormGroup';
150
+ export const TransitionReplace: any; // from './TransitionReplace';
151
+ export const ValidationMessage: any; // from './ValidationMessage';
152
+ export const DataTable: any; // from './DataTable';
153
+ export const TextFilter: any; // from './DataTable/filters/TextFilter';
154
+ export const CheckboxFilter: any; // from './DataTable/filters/CheckboxFilter';
155
+ export const DropdownFilter: any; // from './DataTable/filters/DropdownFilter';
156
+ export const MultiSelectDropdownFilter: any; // from './DataTable/filters/MultiSelectDropdownFilter';
157
+ export const TableHeaderCell: any; // from './DataTable/TableHeaderCell';
158
+ export const TableCell: any; // from './DataTable/TableCell';
159
+ export const TableFilters: any, TABLE_FILTERS_BUTTON_TEXT: string; // from './DataTable/TableFilters';
160
+ export const TableHeader: any; // from './DataTable/TableHeaderRow';
161
+ export const TableRow: any; // from './DataTable/TableRow';
162
+ export const TablePagination: any; // from './DataTable/TablePagination';
163
+ export const TablePaginationMinimal: any; // from './DataTable/TablePaginationMinimal';
164
+ export const DataTableContext: any; // from './DataTable/DataTableContext';
165
+ export const BulkActions: any; // from './DataTable/BulkActions';
166
+ export const TableControlBar: any; // from './DataTable/TableControlBar';
167
+ export const TableFooter: any; // from './DataTable/TableFooter';
168
+ export const CardView: any; // from './DataTable/CardView';
169
+ export const Skeleton: any, SkeletonTheme: any; // from './Skeleton/index';
170
+ export const Stack: any; // from './Stack';
171
+ export const ToggleButton: any, ToggleButtonGroup: any; // from './ToggleButton';
172
+ export const Sticky: any; // from './Sticky';
173
+ export const SelectableBox: any; // from './SelectableBox';
174
+ export const breakpoints: any; // from './utils/breakpoints';
175
+ export const Variant: any; // from './utils/constants';
176
+ export const useWindowSize: any; // from './hooks/useWindowSize';
177
+ export const useToggle: any; // from './hooks/useToggle';
178
+ export const useArrowKeyNavigation: any; // from './hooks/useArrowKeyNavigation';
179
+ export const useIndexOfLastVisibleChild: any; // from './hooks/useIndexOfLastVisibleChild';
180
+ export const useIsVisible: any; // from './hooks/useIsVisible';
181
+ export const
182
+ OverflowScrollContext: any,
183
+ OverflowScroll: any,
184
+ useOverflowScroll: any,
185
+ useOverflowScrollItems: any;
186
+ // from './OverflowScroll';
187
+ export const Dropzone: any; // from './Dropzone';
188
+ export const messages: any; // from './i18n';
189
+ export const Truncate: any; // from './Truncate';
190
+ export const ColorPicker: any; // from './ColorPicker';
191
+
192
+ // Pass through any needed whole third-party library functionality
193
+ // useTable for example is needed to use the DataTable component seamlessly
194
+ // rather than setting a peer dependency in this project, we opt to tightly
195
+ // couple these dependencies by passing through needed functionality.
196
+ export {
197
+ default as MediaQuery,
198
+ useMediaQuery,
199
+ Context as ResponsiveContext,
200
+ } from 'react-responsive';
201
+ export {
202
+ useTable,
203
+ useFilters,
204
+ useGlobalFilter,
205
+ useSortBy,
206
+ useGroupBy,
207
+ useExpanded,
208
+ usePagination,
209
+ useRowSelect,
210
+ useRowState,
211
+ useColumnOrder,
212
+ useResizeColumns,
213
+ useBlockLayout,
214
+ useAbsoluteLayout,
215
+ useFlexLayout,
216
+ } from 'react-table';
package/src/index.js CHANGED
@@ -1,3 +1,17 @@
1
+ // To keep this file in sync with the .d.ts file, it's in the same order
2
+ // and each line number is the same
3
+
4
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
5
+ // Things that have types
6
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
7
+ export { default as Bubble } from './Bubble';
8
+ export { default as Chip, CHIP_PGN_CLASS } from './Chip';
9
+ export { default as ChipCarousel } from './ChipCarousel';
10
+ export { default as Icon } from './Icon';
11
+
12
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
13
+ // Things that don't have types
14
+ // // // // // // // // // // // // // // // // // // // // // // // // // // //
1
15
  export { default as asInput } from './asInput';
2
16
  export { default as ActionRow } from './ActionRow';
3
17
  export { default as Alert, ALERT_CLOSE_LABEL_TEXT } from './Alert';
@@ -22,8 +36,6 @@ export {
22
36
  } from './Carousel';
23
37
  export { default as CheckBox } from './CheckBox';
24
38
  export { default as CheckBoxGroup } from './CheckBoxGroup';
25
- export { default as Chip, CHIP_PGN_CLASS } from './Chip';
26
- export { default as ChipCarousel } from './ChipCarousel';
27
39
  export { default as CloseButton } from './CloseButton';
28
40
  export { default as Container } from './Container';
29
41
  export { default as Layout, Col, Row } from './Layout';
@@ -61,7 +73,6 @@ export {
61
73
  InputGroup,
62
74
  } from './Form';
63
75
  export { default as Hyperlink, HYPER_LINK_EXTERNAL_LINK_ALT_TEXT, HYPER_LINK_EXTERNAL_LINK_TITLE } from './Hyperlink';
64
- export { default as Icon } from './Icon';
65
76
  export { default as IconButton, IconButtonWithTooltip } from './IconButton';
66
77
  export { default as IconButtonToggle } from './IconButtonToggle';
67
78
  export { default as Input } from './Input';
@@ -155,6 +166,7 @@ export { default as BulkActions } from './DataTable/BulkActions';
155
166
  export { default as TableControlBar } from './DataTable/TableControlBar';
156
167
  export { default as TableFooter } from './DataTable/TableFooter';
157
168
  export { default as CardView } from './DataTable/CardView';
169
+ export { default as Skeleton, SkeletonTheme } from './Skeleton/index';
158
170
  export { default as Stack } from './Stack';
159
171
  export { default as ToggleButton, ToggleButtonGroup } from './ToggleButton';
160
172
  export { default as Sticky } from './Sticky';
@@ -172,6 +184,10 @@ export {
172
184
  useOverflowScroll,
173
185
  useOverflowScrollItems,
174
186
  } from './OverflowScroll';
187
+ export { default as Dropzone } from './Dropzone';
188
+ export { default as messages } from './i18n';
189
+ export { default as Truncate } from './Truncate';
190
+ export { default as ColorPicker } from './ColorPicker';
175
191
 
176
192
  // Pass through any needed whole third-party library functionality
177
193
  // useTable for example is needed to use the DataTable component seamlessly
@@ -198,10 +214,3 @@ export {
198
214
  useAbsoluteLayout,
199
215
  useFlexLayout,
200
216
  } from 'react-table';
201
- export { default as Skeleton, SkeletonTheme } from './Skeleton/index';
202
- export { default as Bubble } from './Bubble';
203
- export { default as Dropzone } from './Dropzone';
204
-
205
- export { default as messages } from './i18n';
206
- export { default as Truncate } from './Truncate';
207
- export { default as ColorPicker } from './ColorPicker';