@scottish-government/designsystem-react 0.3.0 → 0.5.0

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 (62) hide show
  1. package/@types/common/AbstractNotificationBanner.d.ts +17 -0
  2. package/@types/components/Table.d.ts +8 -0
  3. package/@types/components/Tabs.d.ts +22 -0
  4. package/@types/components/TaskList.d.ts +1 -1
  5. package/dist/common/abstract-notification-banner.jsx +63 -0
  6. package/dist/components/accordion/accordion.jsx +2 -3
  7. package/dist/components/breadcrumbs/breadcrumbs.jsx +2 -2
  8. package/dist/components/cookie-banner/cookie-banner.jsx +21 -0
  9. package/dist/components/notification-banner/notification-banner.jsx +7 -34
  10. package/dist/components/page-metadata/page-metadata.jsx +2 -3
  11. package/dist/components/table/table.jsx +24 -0
  12. package/dist/components/tabs/tabs.jsx +99 -0
  13. package/dist/components/task-list/task-list.jsx +6 -7
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/utils/slugify.js +15 -0
  16. package/package.json +1 -1
  17. package/src/common/abstract-notification-banner.test.tsx +126 -0
  18. package/src/common/abstract-notification-banner.tsx +87 -0
  19. package/src/common/conditional-wrapper.test.tsx +1 -1
  20. package/src/common/screen-reader-text.test.tsx +1 -1
  21. package/src/common/wrapper-tag.test.tsx +3 -3
  22. package/src/components/accordion/accordion.test.tsx +40 -40
  23. package/src/components/accordion/accordion.tsx +4 -2
  24. package/src/components/aspect-box/aspect-box.test.tsx +7 -7
  25. package/src/components/breadcrumbs/breadcrumbs.tsx +0 -2
  26. package/src/components/checkbox/checkbox.test.tsx +8 -8
  27. package/src/components/confirmation-message/confirmation-message.test.tsx +1 -1
  28. package/src/components/cookie-banner/cookie-banner.test.tsx +25 -0
  29. package/src/components/cookie-banner/cookie-banner.tsx +36 -0
  30. package/src/components/details/details.test.tsx +7 -7
  31. package/src/components/inset-text/inset-text.test.tsx +1 -1
  32. package/src/components/notification-banner/notification-banner.test.tsx +13 -73
  33. package/src/components/notification-banner/notification-banner.tsx +13 -41
  34. package/src/components/notification-panel/notification-panel.test.tsx +6 -6
  35. package/src/components/page-header/page-header.test.tsx +2 -2
  36. package/src/components/page-metadata/page-metadata.test.tsx +12 -12
  37. package/src/components/page-metadata/page-metadata.tsx +4 -2
  38. package/src/components/pagination/pagination.test.tsx +28 -30
  39. package/src/components/phase-banner/phase-banner.test.tsx +8 -8
  40. package/src/components/question/question.test.tsx +3 -3
  41. package/src/components/radio-button/radio-button.test.tsx +7 -7
  42. package/src/components/select/select.test.tsx +9 -9
  43. package/src/components/sequential-navigation/sequential-navigation.test.tsx +4 -4
  44. package/src/components/side-navigation/side-navigation.test.tsx +1 -1
  45. package/src/components/site-header/site-header.test.tsx +22 -22
  46. package/src/components/site-search/site-search.test.tsx +9 -9
  47. package/src/components/skip-links/skip-links.test.tsx +3 -3
  48. package/src/components/summary-card/summary-card.test.tsx +2 -2
  49. package/src/components/summary-list/summary-list.test.tsx +35 -16
  50. package/src/components/table/table.test.tsx +77 -0
  51. package/src/components/table/table.tsx +36 -0
  52. package/src/components/tabs/tabs.test.tsx +258 -0
  53. package/src/components/tabs/tabs.tsx +110 -0
  54. package/src/components/task-list/task-list.test.tsx +81 -83
  55. package/src/components/task-list/task-list.tsx +9 -5
  56. package/src/components/text-input/text-input.test.tsx +6 -6
  57. package/src/components/textarea/textarea.test.tsx +2 -2
  58. package/src/components/warning-text/warning-text.test.tsx +1 -1
  59. package/src/utils/slugify.ts +13 -0
  60. package/vite.config.ts +6 -1
  61. package/vitest-setup.ts +1 -1
  62. package/@types/components/NotificationBanner.d.ts +0 -9
@@ -0,0 +1,17 @@
1
+ declare namespace SGDS.Common {
2
+ namespace AbstractNotificationBanner {
3
+ interface Buttons extends React.AllHTMLAttributes<HTMLDivElement> {
4
+ children: React.ReactNode
5
+ }
6
+ }
7
+
8
+ interface AbstractNotificationBanner extends React.AllHTMLAttributes<HTMLDivElement> {
9
+ close?: boolean,
10
+ hasIcon?: boolean,
11
+ icon?: IconName,
12
+ iconColour?: boolean,
13
+ iconInverse?: boolean,
14
+ title: string,
15
+ ref?: any
16
+ }
17
+ }
@@ -0,0 +1,8 @@
1
+ declare namespace SGDS.Component {
2
+ type SmallScreen = 'scrolling' | 'boxes';
3
+
4
+ interface Table extends React.AllHTMLAttributes<HTMLTableElement> {
5
+ className?: string,
6
+ smallscreen?: SmallScreen
7
+ }
8
+ }
@@ -0,0 +1,22 @@
1
+ declare namespace SGDS.Component {
2
+ namespace Tabs {
3
+ interface Item extends React.AllHTMLAttributes<HTMLElement> {
4
+ bordered?: boolean,
5
+ id: string,
6
+ tabLabel: string
7
+ }
8
+
9
+ interface TabListItem extends React.AllHTMLAttributes<HTMLLIElement> {
10
+ title: string,
11
+ href: string
12
+ }
13
+ }
14
+
15
+ interface Tabs extends React.AllHTMLAttributes<HTMLElement> {
16
+ baseId: string,
17
+ bordered?: boolean,
18
+ headerLevel?: SGDS.HeaderLevel,
19
+ manual?: boolean,
20
+ title: string
21
+ }
22
+ }
@@ -5,7 +5,7 @@ declare namespace SGDS.Component {
5
5
  title: string
6
6
  }
7
7
 
8
- interface Task extends React.AllHTMLAttributes<HTMLElement> {
8
+ interface Item extends React.AllHTMLAttributes<HTMLElement> {
9
9
  href?: string,
10
10
  id?: string,
11
11
  isComplete?: boolean,
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = require("react");
7
+ const icon_1 = __importDefault(require("./icon"));
8
+ const screen_reader_text_1 = __importDefault(require("./screen-reader-text"));
9
+ const Buttons = ({ children }) => {
10
+ return (<>{children}</>);
11
+ };
12
+ const AbstractNotificationBanner = ({ children, className, close, icon, iconColour, iconInverse, title = 'Information', ...props }) => {
13
+ let content = [];
14
+ let buttons;
15
+ react_1.Children.forEach(children, (child) => {
16
+ if ((0, react_1.isValidElement)(child) && child.type === Buttons) {
17
+ buttons = child;
18
+ }
19
+ else {
20
+ content.push(child);
21
+ }
22
+ });
23
+ return (<div className={[
24
+ 'ds_notification',
25
+ className
26
+ ].join(' ')} data-module="ds-notification" {...props}>
27
+ <div className="ds_wrapper">
28
+ <div className={[
29
+ 'ds_notification__content',
30
+ close && 'ds_notification__content--has-close'
31
+ ].join(' ')}>
32
+ <h2 className="visually-hidden">{title}</h2>
33
+
34
+ {icon &&
35
+ <span className={[
36
+ 'ds_notification__icon',
37
+ iconInverse && 'ds_notification__icon--inverse',
38
+ iconColour && 'ds_notification__icon--colour'
39
+ ].join(' ')} aria-hidden="true">
40
+ <icon_1.default icon={icon}/>
41
+ </span>}
42
+
43
+ <div className="ds_notification__text">
44
+ {content}
45
+ </div>
46
+
47
+ {close &&
48
+ <button type="button" className="ds_notification__close js-close-notification">
49
+ <screen_reader_text_1.default>Close this notification</screen_reader_text_1.default>
50
+ <icon_1.default fill icon="Close" aria-hidden="true"/>
51
+ </button>}
52
+
53
+ {buttons &&
54
+ <div className="ds_button-group">
55
+ {buttons}
56
+ </div>}
57
+ </div>
58
+ </div>
59
+ </div>);
60
+ };
61
+ AbstractNotificationBanner.displayName = 'AbstractNotificationBanner';
62
+ AbstractNotificationBanner.Buttons = Buttons;
63
+ exports.default = AbstractNotificationBanner;
@@ -36,7 +36,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.AccordionItem = void 0;
40
39
  const react_1 = __importStar(require("react"));
41
40
  const wrapper_tag_1 = __importDefault(require("../../common/wrapper-tag"));
42
41
  // @ts-ignore
@@ -67,7 +66,6 @@ const AccordionItem = ({ children, className, headerLevel = 'h3', id: rawId, ope
67
66
  </div>
68
67
  </div>);
69
68
  };
70
- exports.AccordionItem = AccordionItem;
71
69
  const Accordion = ({ children, className, headerLevel = 'h3', hideOpenAll, ...props }) => {
72
70
  const ref = (0, react_1.useRef)(null);
73
71
  (0, react_1.useEffect)(() => {
@@ -99,5 +97,6 @@ const Accordion = ({ children, className, headerLevel = 'h3', hideOpenAll, ...pr
99
97
  </div>);
100
98
  };
101
99
  Accordion.displayName = 'Accordion';
102
- exports.AccordionItem.displayName = 'AccordionItem';
100
+ AccordionItem.displayName = 'AccordionItem';
101
+ Accordion.Item = AccordionItem;
103
102
  exports.default = Accordion;
@@ -17,8 +17,8 @@ const Breadcrumb = ({ hidden, href, title }) => {
17
17
  * @param {Object} props - Properties for the element
18
18
  * @returns {JSX.Element} - The element
19
19
  */
20
- const Breadcrumbs = ({ className, hideLastItem, items, ...props }) => {
21
- return (<nav aria-label="Breadcrumb" className={className} {...props}>
20
+ const Breadcrumbs = ({ hideLastItem, items, ...props }) => {
21
+ return (<nav aria-label="Breadcrumb" {...props}>
22
22
  <ol className="ds_breadcrumbs">
23
23
  {items && items.map((item, index) => (<Breadcrumb title={item.title} href={item.href} hidden={(hideLastItem) && index + 1 === items.length} key={'breadcrumb' + index}/>))}
24
24
  </ol>
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const abstract_notification_banner_1 = __importDefault(require("../../common/abstract-notification-banner"));
7
+ const CookieBanner = ({ children, className, title, ...props }) => {
8
+ return (<>
9
+ <abstract_notification_banner_1.default className={[
10
+ 'ds_notification--large',
11
+ 'ds_notification--cookie',
12
+ 'js-initial-cookie-content',
13
+ className
14
+ ].join(' ')} data-module="ds-cookie-notification" title={title} {...props}>
15
+ {children}
16
+ </abstract_notification_banner_1.default>
17
+ </>);
18
+ };
19
+ CookieBanner.displayName = 'CookieBanner';
20
+ CookieBanner.Buttons = abstract_notification_banner_1.default.Buttons;
21
+ exports.default = CookieBanner;
@@ -4,50 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = require("react");
7
+ const abstract_notification_banner_1 = __importDefault(require("../../common/abstract-notification-banner"));
7
8
  // @ts-ignore
8
9
  const notification_banner_1 = __importDefault(require("@scottish-government/design-system/src/components/notification-banner/notification-banner"));
9
- const icon_1 = __importDefault(require("../../common/icon"));
10
- const screen_reader_text_1 = __importDefault(require("../../common/screen-reader-text"));
11
- const NotificationBanner = ({ children, className, close, icon, iconColour, iconInverse, title = 'Information', ...props }) => {
10
+ const NotificationBanner = ({ children, className, close, icon, iconColour, iconInverse, title, ...props }) => {
12
11
  const ref = (0, react_1.useRef)(null);
13
12
  (0, react_1.useEffect)(() => {
14
13
  if (ref.current) {
15
14
  new notification_banner_1.default(ref.current).init();
16
15
  }
17
16
  }, [ref]);
18
- return (<div className={[
19
- 'ds_notification',
17
+ return (<abstract_notification_banner_1.default className={[
20
18
  'ds_reversed',
21
19
  className
22
- ].join(' ')} data-module="ds-notification" ref={ref} {...props}>
23
- <div className="ds_wrapper">
24
- <div className={[
25
- 'ds_notification__content',
26
- close && 'ds_notification__content--has-close'
27
- ].join(' ')}>
28
- <h2 className="visually-hidden">{title}</h2>
29
-
30
- {icon &&
31
- <span className={[
32
- 'ds_notification__icon',
33
- iconInverse && 'ds_notification__icon--inverse',
34
- iconColour && 'ds_notification__icon--colour'
35
- ].join(' ')} aria-hidden="true">
36
- <icon_1.default icon="PriorityHigh"/>
37
- </span>}
38
-
39
- <div className="ds_notification__text">
40
- {children}
41
- </div>
42
-
43
- {close &&
44
- <button type="button" className="ds_notification__close js-close-notification">
45
- <screen_reader_text_1.default>Close this notification</screen_reader_text_1.default>
46
- <icon_1.default fill icon="Close" aria-hidden="true"/>
47
- </button>}
48
- </div>
49
- </div>
50
- </div>);
20
+ ].join(' ')} close={close} icon={icon ? "PriorityHigh" : undefined} iconColour={iconColour} iconInverse={iconInverse} ref={ref} title="Information" {...props}>
21
+ {children}
22
+ </abstract_notification_banner_1.default>);
51
23
  };
52
24
  NotificationBanner.displayName = 'NotificationBanner';
25
+ NotificationBanner.Buttons = abstract_notification_banner_1.default.Buttons;
53
26
  exports.default = NotificationBanner;
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MetadataItem = void 0;
4
3
  const MetadataItem = ({ children, className, name, ...props }) => {
5
4
  return (<div className={[
6
5
  'ds_metadata__item',
@@ -12,7 +11,6 @@ const MetadataItem = ({ children, className, name, ...props }) => {
12
11
  </dd>
13
12
  </div>);
14
13
  };
15
- exports.MetadataItem = MetadataItem;
16
14
  const Metadata = ({ children, className, inline, ...props }) => {
17
15
  return (<dl className={[
18
16
  'ds_metadata',
@@ -23,5 +21,6 @@ const Metadata = ({ children, className, inline, ...props }) => {
23
21
  </dl>);
24
22
  };
25
23
  Metadata.displayName = 'Metadata';
26
- exports.MetadataItem.displayName = 'MetadataItem';
24
+ MetadataItem.displayName = 'MetadataItem';
25
+ Metadata.Item = MetadataItem;
27
26
  exports.default = Metadata;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = require("react");
7
+ // @ts-ignore
8
+ const table_1 = __importDefault(require("@scottish-government/design-system/src/components/table/table"));
9
+ const Table = ({ children, className, smallscreen, ...props }) => {
10
+ const ref = (0, react_1.useRef)(null);
11
+ (0, react_1.useEffect)(() => {
12
+ if (ref.current) {
13
+ new table_1.default().init();
14
+ }
15
+ }, [ref]);
16
+ return (<table className={[
17
+ 'ds_table',
18
+ className
19
+ ].join(' ')} data-smallscreen={smallscreen} ref={ref} {...props}>
20
+ {children}
21
+ </table>);
22
+ };
23
+ Table.displayName = 'Table';
24
+ exports.default = Table;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const react_1 = __importStar(require("react"));
40
+ const wrapper_tag_1 = __importDefault(require("../../common/wrapper-tag"));
41
+ // @ts-ignore
42
+ const tabs_1 = __importDefault(require("@scottish-government/design-system/src/components/tabs/tabs"));
43
+ const slugify_1 = __importDefault(require("../../utils/slugify"));
44
+ const TabItem = ({ bordered, children, className, id, tabLabel, ...props }) => {
45
+ return (<div className={[
46
+ 'ds_tabs__content',
47
+ bordered && 'ds_tabs__content--bordered',
48
+ className
49
+ ].join(' ')} id={id} {...props}>
50
+ {children}
51
+ </div>);
52
+ };
53
+ const TabListItem = ({ title, href }) => {
54
+ return (<li className="ds_tabs__tab">
55
+ <a className="ds_tabs__tab-link" href={href}>{title}</a>
56
+ </li>);
57
+ };
58
+ const Tabs = ({ baseId = 'tabs', bordered = true, children, className, headerLevel = 'h2', manual = false, title = 'Contents', ...props }) => {
59
+ const ref = (0, react_1.useRef)(null);
60
+ const headingId = `${baseId}-heading`;
61
+ (0, react_1.useEffect)(() => {
62
+ if (ref.current) {
63
+ new tabs_1.default(ref.current).init();
64
+ }
65
+ }, [ref]);
66
+ const processedItems = react_1.Children.map(children, child => {
67
+ if ((0, react_1.isValidElement)(child) && child.type === TabItem) {
68
+ let thisChild = child;
69
+ return react_1.default.cloneElement(thisChild, {
70
+ bordered: bordered,
71
+ id: thisChild.props.id || `${baseId}-${(0, slugify_1.default)(thisChild.props.tabLabel)}`,
72
+ });
73
+ }
74
+ });
75
+ const tabListItems = react_1.Children.map(processedItems, child => {
76
+ if ((0, react_1.isValidElement)(child) && child.type === TabItem) {
77
+ return react_1.default.createElement(TabListItem, { title: child.props.tabLabel, href: `#${child.props.id}` });
78
+ }
79
+ });
80
+ return (<div className={[
81
+ 'ds_tabs',
82
+ manual && 'ds_tabs--manual',
83
+ className
84
+ ].join(' ')} ref={ref} {...props}>
85
+ <wrapper_tag_1.default id={headingId} className="ds_tabs__title" tagName={headerLevel}>
86
+ {title}
87
+ </wrapper_tag_1.default>
88
+
89
+ <ul className="ds_tabs__list" aria-labelledby={headingId}>
90
+ {tabListItems}
91
+ </ul>
92
+
93
+ {processedItems}
94
+ </div>);
95
+ };
96
+ Tabs.displayName = 'Tabs';
97
+ TabItem.displayName = 'TabItem';
98
+ Tabs.Item = TabItem;
99
+ exports.default = Tabs;
@@ -3,13 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TaskGroup = exports.Task = void 0;
7
6
  const react_1 = require("react");
8
7
  const conditional_wrapper_1 = __importDefault(require("../../common/conditional-wrapper"));
9
8
  const hint_text_1 = __importDefault(require("../../common/hint-text"));
10
9
  const screen_reader_text_1 = __importDefault(require("../../common/screen-reader-text"));
11
10
  const tag_1 = __importDefault(require("../tag/tag"));
12
- const Task = ({ children, className, href, id, isComplete = false, statusText, tagColour = 'grey', title, ...props }) => {
11
+ const TaskItem = ({ children, className, href, id, isComplete = false, statusText, tagColour = 'grey', title, ...props }) => {
13
12
  if (isComplete) {
14
13
  tagColour = 'green';
15
14
  }
@@ -31,7 +30,6 @@ const Task = ({ children, className, href, id, isComplete = false, statusText, t
31
30
  <tag_1.default aria-hidden="true" colour={tagColour} title={statusText}/>}
32
31
  </li>);
33
32
  };
34
- exports.Task = Task;
35
33
  /**
36
34
  * @param {Object} props
37
35
  * @param {string} props.intro - Intro text
@@ -50,13 +48,12 @@ const TaskGroup = ({ children, className, intro, title, ...props }) => {
50
48
  </ul>
51
49
  </li>);
52
50
  };
53
- exports.TaskGroup = TaskGroup;
54
51
  const TaskList = ({ children, className, headingId = 'task-list', title, ...props }) => {
55
52
  let taskCount = 0;
56
53
  let incompleteTaskIds = [];
57
54
  let completedTasksCount = 0;
58
55
  function processChild(item) {
59
- if (item.type.displayName === 'Task') {
56
+ if (item.type.displayName === 'TaskItem') {
60
57
  taskCount = taskCount + 1;
61
58
  if (item.props.isComplete) {
62
59
  completedTasksCount = completedTasksCount + 1;
@@ -91,6 +88,8 @@ const TaskList = ({ children, className, headingId = 'task-list', title, ...prop
91
88
  </div>);
92
89
  };
93
90
  TaskList.displayName = 'TaskList';
94
- exports.Task.displayName = 'Task';
95
- exports.TaskGroup.displayName = 'TaskGroup';
91
+ TaskItem.displayName = 'TaskItem';
92
+ TaskGroup.displayName = 'TaskGroup';
93
+ TaskList.Item = TaskItem;
94
+ TaskList.Group = TaskGroup;
96
95
  exports.default = TaskList;