@kth/style 0.1.0 → 0.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.
Files changed (69) hide show
  1. package/README.md +28 -22
  2. package/dist/cjs/components/MenuPanel.d.ts +13 -0
  3. package/dist/cjs/index.d.ts +1 -3
  4. package/dist/cjs/index.js +54 -127
  5. package/dist/cjs/react.d.ts +1 -5
  6. package/dist/cjs/react.js +3 -175
  7. package/dist/esm/components/MenuPanel.d.ts +13 -0
  8. package/dist/esm/index.d.ts +1 -3
  9. package/dist/esm/index.js +54 -125
  10. package/dist/esm/react.d.ts +1 -5
  11. package/dist/esm/react.js +3 -147
  12. package/package.json +2 -12
  13. package/scss/components/a11y-nav.scss +31 -0
  14. package/scss/components/button.scss +18 -54
  15. package/scss/components/entrances.scss +40 -0
  16. package/scss/components/header.scss +40 -0
  17. package/scss/components/kpm.scss +10 -0
  18. package/scss/components/logotype.scss +28 -0
  19. package/scss/components/mega-menu.scss +33 -0
  20. package/scss/components/menu-item.scss +40 -0
  21. package/scss/components/menu-panel.scss +32 -0
  22. package/scss/components/search.scss +3 -1
  23. package/scss/components/visually-hidden.scss +11 -0
  24. package/scss/tokens/colors.scss +0 -3
  25. package/scss/tokens/icons.scss +11 -10
  26. package/scss/tokens/spacing.scss +0 -65
  27. package/scss/utils/mixins.scss +5 -0
  28. package/scss/utils/prose.scss +10 -5
  29. package/scss/utils/reset.scss +35 -21
  30. package/dist/cjs/components/Button.d.ts +0 -20
  31. package/dist/cjs/components/ModalNavigationPanel.d.ts +0 -4
  32. package/dist/cjs/components/NavigationPanel.d.ts +0 -7
  33. package/dist/cjs/components/Radio.d.ts +0 -20
  34. package/dist/cjs/components/Select.d.ts +0 -34
  35. package/dist/cjs/components/Tabs.d.ts +0 -1
  36. package/dist/cjs/components/react/PersonalMenuPanel.d.ts +0 -19
  37. package/dist/cjs/components/react/Tabs.d.ts +0 -34
  38. package/dist/cjs/icons/400/ArrowBack.d.ts +0 -4
  39. package/dist/cjs/icons/400/Check.d.ts +0 -4
  40. package/dist/cjs/icons/500/ArrowForward.d.ts +0 -4
  41. package/dist/cjs/stories/Button.stories.d.ts +0 -14
  42. package/dist/cjs/stories/ContentTabs.stories.d.ts +0 -12
  43. package/dist/cjs/stories/FilterTabs.stories.d.ts +0 -12
  44. package/dist/cjs/stories/InlineIcons.stories.d.ts +0 -9
  45. package/dist/cjs/stories/Select.stories.d.ts +0 -14
  46. package/dist/esm/components/Button.d.ts +0 -20
  47. package/dist/esm/components/ModalNavigationPanel.d.ts +0 -4
  48. package/dist/esm/components/NavigationPanel.d.ts +0 -7
  49. package/dist/esm/components/Radio.d.ts +0 -20
  50. package/dist/esm/components/Select.d.ts +0 -34
  51. package/dist/esm/components/Tabs.d.ts +0 -1
  52. package/dist/esm/components/react/PersonalMenuPanel.d.ts +0 -19
  53. package/dist/esm/components/react/Tabs.d.ts +0 -34
  54. package/dist/esm/icons/400/ArrowBack.d.ts +0 -4
  55. package/dist/esm/icons/400/Check.d.ts +0 -4
  56. package/dist/esm/icons/500/ArrowForward.d.ts +0 -4
  57. package/dist/esm/stories/Button.stories.d.ts +0 -14
  58. package/dist/esm/stories/ContentTabs.stories.d.ts +0 -12
  59. package/dist/esm/stories/FilterTabs.stories.d.ts +0 -12
  60. package/dist/esm/stories/InlineIcons.stories.d.ts +0 -9
  61. package/dist/esm/stories/Select.stories.d.ts +0 -14
  62. package/scss/components/checkbox.scss +0 -63
  63. package/scss/components/details.scss +0 -40
  64. package/scss/components/fieldset.scss +0 -60
  65. package/scss/components/form-control.scss +0 -25
  66. package/scss/components/header-menu-item.scss +0 -38
  67. package/scss/components/input.scss +0 -21
  68. package/scss/components/main-header.scss +0 -105
  69. package/scss/components/select.scss +0 -46
package/README.md CHANGED
@@ -1,24 +1,30 @@
1
1
  # @kth/style
2
2
 
3
- **WORK IN PROGRESS**. Styles and components used across KTH.
4
-
5
- ## Requirements
6
-
7
- - Sass
8
- - React
9
-
10
- ## Getting started
11
-
12
- 1. Install `@kth/style` from npm:
13
-
14
- ```
15
- npm i @kth/style
16
- ```
17
-
18
- 2. In your Sass file, import and include the sizes mixin:
19
-
20
- ```scss
21
- @use "node_modules/@kth/style/scss/utils" as sizes;
22
-
23
- @include utils.sizes;
24
- ```
3
+ Styles and components used across KTH.
4
+
5
+ Documentation available in the [KTH Style website](https://kthstyledemoref.z6.web.core.windows.net/style)
6
+
7
+ ## Structure
8
+
9
+ ```
10
+ @kth/style
11
+ ├── src/
12
+ │ ├── index.ts
13
+ │ ├── components
14
+ └── react-components
15
+ ├── scss/
16
+ ├── components
17
+ │ ├── tokens
18
+ │ └── utils
19
+ ├── assets
20
+ ├── ...
21
+ ├── package.json
22
+ └── rollup.config.mjs
23
+ ```
24
+
25
+ - `scss` contains all CSS. Those can be imported as they are
26
+ - `src` contains source for JavaScript components. Written in JavaScript
27
+ - `src/components` are the components that do not use React
28
+ - `src/react-components` are the React components
29
+ - `index.ts` and `react.ts` re-export the content in the respective `components` directories
30
+ - `assets` are static assets like the fonts and logotype. This is meant to be exposed by apps using KTH Style
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Close all <dialog>s (modal and non-modal) in a document
3
+ */
4
+ export declare function closeAllDialogs(): void;
5
+ /**
6
+ * Add mouse and keyboard event listeners to a menu panel (<dialog>)
7
+ * @param dialog A <dialog> element
8
+ */
9
+ export declare function addEventListeners(dialog: HTMLDialogElement): void;
10
+ export declare class MenuPanel {
11
+ static init(container: HTMLElement | null, items: NodeListOf<Element>): void;
12
+ static initModal(items: NodeListOf<Element>): void;
13
+ }
@@ -1,3 +1 @@
1
- export { setNavigationPanels } from "./components/NavigationPanel";
2
- export { setModalNavigationPanels } from "./components/ModalNavigationPanel";
3
- export { initTabs } from "./components/Tabs";
1
+ export { MenuPanel } from "./components/MenuPanel";
package/dist/cjs/index.js CHANGED
@@ -1,59 +1,5 @@
1
1
  'use strict';
2
2
 
3
- /**
4
- * Close all <dialog>s (modal and non-modal) in a document
5
- */
6
- function closeAllDialogs$1() {
7
- document.querySelectorAll("dialog").forEach((dialog) => dialog.close());
8
- }
9
- /**
10
- * Add open/close functionality to a set of navigation panels
11
- *
12
- * @param container The element containing all the menus
13
- * @param items A list of all menu elements
14
- */
15
- function setNavigationPanels(container, items) {
16
- if (!container) {
17
- return;
18
- }
19
- for (const item of items) {
20
- if (!(item instanceof HTMLElement)) {
21
- continue;
22
- }
23
- const dialog = item.nextElementSibling;
24
- if (!(dialog instanceof HTMLDialogElement)) {
25
- continue;
26
- }
27
- dialog.addEventListener("keydown", (e) => {
28
- if (e.key === "Escape") {
29
- closeAllDialogs$1();
30
- }
31
- });
32
- const closeButton = dialog.querySelector(".close");
33
- if (closeButton instanceof HTMLButtonElement) {
34
- closeButton.addEventListener("click", () => {
35
- closeAllDialogs$1();
36
- });
37
- }
38
- item.addEventListener("click", (e) => {
39
- e.preventDefault();
40
- if (!dialog.open) {
41
- closeAllDialogs$1();
42
- dialog.show();
43
- }
44
- else {
45
- closeAllDialogs$1();
46
- }
47
- });
48
- }
49
- container.addEventListener("focusout", function (e) {
50
- const target = e.relatedTarget;
51
- if (target && target instanceof Node && !container.contains(target)) {
52
- closeAllDialogs$1();
53
- }
54
- });
55
- }
56
-
57
3
  /**
58
4
  * Close all <dialog>s (modal and non-modal) in a document
59
5
  */
@@ -61,90 +7,71 @@ function closeAllDialogs() {
61
7
  document.querySelectorAll("dialog").forEach((dialog) => dialog.close());
62
8
  }
63
9
  /**
64
- * Add open/close functionality to a set of navigation panels
10
+ * Add mouse and keyboard event listeners to a menu panel (<dialog>)
11
+ * @param dialog A <dialog> element
65
12
  */
66
- function setModalNavigationPanels(items) {
67
- for (const item of items) {
68
- if (!(item instanceof HTMLElement)) {
69
- continue;
13
+ function addEventListeners(dialog) {
14
+ const closeButton = dialog.querySelector(".kth-button.close");
15
+ const backButton = dialog.querySelector(".kth-button.back");
16
+ dialog.addEventListener("keydown", (e) => {
17
+ if (e.key === "Escape") {
18
+ dialog.close();
70
19
  }
71
- const dialog = item.nextElementSibling;
72
- if (!(dialog instanceof HTMLDialogElement)) {
73
- continue;
74
- }
75
- dialog.addEventListener("keydown", (e) => {
76
- e.stopPropagation();
77
- if (e.key === "Escape") {
78
- dialog.close();
79
- }
80
- });
81
- const closeButton = dialog.querySelector(".close");
82
- if (closeButton instanceof HTMLButtonElement) {
83
- closeButton.addEventListener("click", () => {
84
- closeAllDialogs();
85
- });
86
- }
87
- item.addEventListener("click", (e) => {
88
- e.preventDefault();
89
- // closeAllDialogs();
90
- dialog.showModal();
20
+ });
21
+ if (closeButton instanceof HTMLButtonElement) {
22
+ closeButton.addEventListener("click", () => {
23
+ closeAllDialogs();
91
24
  });
92
25
  }
93
- }
94
-
95
- function getPanel(tab) {
96
- const panelId = tab.getAttribute("aria-controls");
97
- if (!panelId) {
98
- throw new Error();
99
- }
100
- const panel = document.getElementById(panelId);
101
- if (!(panel instanceof HTMLElement)) {
102
- throw new Error();
103
- }
104
- return panel;
105
- }
106
- function closeAllTabs(tabs) {
107
- for (const tab of tabs) {
108
- if (tab instanceof HTMLElement) {
109
- tab.ariaSelected = "false";
110
- const panel = getPanel(tab);
111
- if (panel) {
112
- panel.hidden = true;
113
- }
114
- }
26
+ if (backButton instanceof HTMLButtonElement) {
27
+ backButton.addEventListener("click", () => {
28
+ dialog.close();
29
+ });
115
30
  }
116
31
  }
117
- function initTabs(container) {
118
- if (!(container instanceof HTMLElement)) {
119
- return;
120
- }
121
- const tablist = container.querySelector("[role=tablist]");
122
- if (!tablist) {
123
- return;
124
- }
125
- const tabs = tablist.querySelectorAll("[role=tab]");
126
- function openTab(tab) {
127
- const panel = getPanel(tab);
128
- if (!panel) {
32
+ class MenuPanel {
33
+ static init(container, items) {
34
+ if (!container)
129
35
  return;
36
+ for (const item of items) {
37
+ if (!(item instanceof HTMLElement))
38
+ continue;
39
+ const dialog = item.nextElementSibling;
40
+ if (!(dialog instanceof HTMLDialogElement))
41
+ continue;
42
+ addEventListeners(dialog);
43
+ item.addEventListener("click", (e) => {
44
+ e.preventDefault();
45
+ if (!dialog.open) {
46
+ closeAllDialogs();
47
+ dialog.show();
48
+ }
49
+ else {
50
+ closeAllDialogs();
51
+ }
52
+ });
130
53
  }
131
- tab.ariaSelected = "true";
132
- panel.hidden = false;
54
+ container.addEventListener("focusout", function (e) {
55
+ const target = e.relatedTarget;
56
+ if (target && target instanceof Node && !container.contains(target)) {
57
+ closeAllDialogs();
58
+ }
59
+ });
133
60
  }
134
- for (const tab of tabs) {
135
- if (tab instanceof HTMLElement) {
136
- tab.addEventListener("click", () => {
137
- closeAllTabs(tabs);
138
- openTab(tab);
61
+ static initModal(items) {
62
+ for (const item of items) {
63
+ if (!(item instanceof HTMLElement))
64
+ continue;
65
+ const dialog = item.nextElementSibling;
66
+ if (!(dialog instanceof HTMLDialogElement))
67
+ continue;
68
+ addEventListeners(dialog);
69
+ item.addEventListener("click", (e) => {
70
+ e.preventDefault();
71
+ dialog.showModal();
139
72
  });
140
73
  }
141
74
  }
142
- if (tabs[0] instanceof HTMLElement) {
143
- closeAllTabs(tabs);
144
- openTab(tabs[0]);
145
- }
146
75
  }
147
76
 
148
- exports.initTabs = initTabs;
149
- exports.setModalNavigationPanels = setModalNavigationPanels;
150
- exports.setNavigationPanels = setNavigationPanels;
77
+ exports.MenuPanel = MenuPanel;
@@ -1,5 +1 @@
1
- export { Tab, ContentTabs, NavigationTabs } from "./components/react/Tabs";
2
- export { Select, Option, OptionGroup } from "./components/Select";
3
- export { BackButton, Button, ForwardButton } from "./components/Button";
4
- export { default as IconArrowBack } from "./icons/400/ArrowBack";
5
- export { default as IconCheck } from "./icons/400/Check";
1
+ export default function hello(): string;
package/dist/cjs/react.js CHANGED
@@ -1,179 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
-
5
- function _interopNamespaceDefault(e) {
6
- var n = Object.create(null);
7
- if (e) {
8
- Object.keys(e).forEach(function (k) {
9
- if (k !== 'default') {
10
- var d = Object.getOwnPropertyDescriptor(e, k);
11
- Object.defineProperty(n, k, d.get ? d : {
12
- enumerable: true,
13
- get: function () { return e[k]; }
14
- });
15
- }
16
- });
17
- }
18
- n.default = e;
19
- return Object.freeze(n);
20
- }
21
-
22
- var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
23
-
24
- function getValueFromUrl(key) {
25
- const url = new URL(location.href);
26
- if (key) {
27
- return url.searchParams.get(key);
28
- }
29
- else {
30
- return url.hash === "" ? null : url.hash.slice(1);
31
- }
32
- }
33
- /**
34
- * Sync state with URL hash or query parameter.
35
- * @param defaultValue Default state value
36
- * @param key Query parameter to use. Hash if empty
37
- * @param enableUrl Will sync with URL if true (this function behaves the same
38
- * as `React.useState` if false)
39
- */
40
- function useUrlState(defaultValue = "", key = "", enableUrl = false) {
41
- const initialValue = (enableUrl && getValueFromUrl(key)) || defaultValue;
42
- const [value, _setValue] = React.useState(initialValue);
43
- React.useEffect(() => {
44
- function updateValue() {
45
- if (enableUrl) {
46
- _setValue(getValueFromUrl(key) || defaultValue);
47
- }
48
- }
49
- window.addEventListener("popstate", updateValue);
50
- return () => {
51
- window.removeEventListener("popstate", updateValue);
52
- };
53
- });
54
- function setValue(value) {
55
- _setValue(value);
56
- const url = new URL(location.href);
57
- if (key !== "") {
58
- url.searchParams.set(key, value);
59
- }
60
- else {
61
- url.hash = "#" + value;
62
- }
63
- if (enableUrl) {
64
- history.pushState(undefined, "", url);
65
- }
66
- }
67
- return [value, setValue];
68
- }
69
- function handleKeyDown(event, index, tabs, setActiveTab) {
70
- event.preventDefault();
71
- switch (event.key) {
72
- case "ArrowLeft":
73
- case "ArrowUp":
74
- if (index > 0) {
75
- setActiveTab(tabs[index - 1].props.id);
76
- }
77
- break;
78
- case "ArrowRight":
79
- case "ArrowDown":
80
- if (index < tabs.length - 1) {
81
- setActiveTab(tabs[index + 1].props.id);
82
- }
83
- break;
84
- case "Home":
85
- setActiveTab(tabs[0].props.id);
86
- break;
87
- case "End":
88
- setActiveTab(tabs[tabs.length - 1].props.id);
89
- break;
90
- }
91
- }
92
- function useFocus(element) {
93
- element?.scrollIntoView({ block: "nearest", inline: "nearest" });
94
- element?.focus();
95
- }
96
- /**
97
- * Highly customizable Tabs component made for testing purposes.
98
- * You should use {@link NavigationTabs} or {@link ContentTabs} instead.
99
- */
100
- function GenericTabs({ classPrefix, children, id, defaultValue, url = "none", }) {
101
- const ref = React.useRef(null);
102
- const [activeTab, setActiveTab] = useUrlState(defaultValue, url === "query" ? id : "", url === "query" || url === "hash");
103
- let activeTabIndex = children.findIndex((c) => c.props.id === activeTab);
104
- if (activeTabIndex === -1) {
105
- activeTabIndex = 0;
106
- }
107
- useFocus(ref.current?.querySelector(`#${activeTab}-tab`));
108
- return (React.createElement(React.Fragment, null,
109
- React.createElement("div", { ref: ref, className: `${classPrefix}`, id: id },
110
- React.createElement("ul", { className: `${classPrefix}__tablist`, role: "tablist" }, children.map((child, index) => (React.createElement("li", { role: "presentation", className: `${classPrefix}__tab-element` },
111
- React.createElement("button", { key: child.props.id, role: "tab", "aria-selected": index === activeTabIndex, "aria-controls": child.props.id, id: `${child.props.id}-tab`, className: `${classPrefix}__tab`, tabIndex: index === activeTabIndex ? 0 : -1, onKeyDown: (event) => {
112
- handleKeyDown(event, index, children, setActiveTab);
113
- }, onClick: (event) => {
114
- event.preventDefault();
115
- setActiveTab(child.props.id);
116
- } }, child.props.title)))))),
117
- children.map((child, index) => (React.createElement("div", { className: `${classPrefix}__tabpanel`, role: "tabpanel", "aria-labelledby": `${child.props.id}-tab`, id: child.props.id, key: index, hidden: index !== activeTabIndex }, child)))));
118
- }
119
- function NavigationTabs({ id, children, url = "query", defaultValue, }) {
120
- return (React.createElement(GenericTabs, { id: id, children: children, url: url, defaultValue: defaultValue, classPrefix: "kth-navigation-tabs" }));
121
- }
122
- function ContentTabs({ id, children, url = "hash", defaultValue, }) {
123
- return (React.createElement(GenericTabs, { id: id, children: children, url: url, defaultValue: defaultValue, classPrefix: "kth-content-tabs" }));
124
- }
125
- function Tab({ children }) {
126
- return React.createElement(React.Fragment, null, children);
3
+ function hello() {
4
+ return "world";
127
5
  }
128
6
 
129
- function Select({ name, label, description, value, onChange, children, error, }) {
130
- const id = `select-${name}`;
131
- return (React.createElement("div", { className: "kth-select" },
132
- React.createElement("label", { htmlFor: id }, label),
133
- description && React.createElement("p", { id: `${id}-description` }, description),
134
- React.createElement("select", { id: id, "aria-describedby": description && `${id}-description`, name: name, value: value, onChange: (e) => onChange(e.target.value), "aria-invalid": error !== undefined ? "true" : "false" }, children),
135
- error && (React.createElement("p", { className: "kth-select__error", role: "alert" }, error))));
136
- }
137
- function OptionGroup({ label, children }) {
138
- return React.createElement("optgroup", { label: label }, children);
139
- }
140
- function Option({ value, children }) {
141
- return React.createElement("option", { value: value }, children);
142
- }
143
-
144
- const SvgArrowBack = (props) => (React__namespace.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1.25em", height: "1.25em", viewBox: "0 0 20 20", ...props },
145
- React__namespace.createElement("path", { fill: "currentColor", d: "m10 16-6-6 6-6 1.063 1.063L6.875 9.25H16v1.5H6.875l4.188 4.188L10 16Z" })));
146
-
147
- const SvgArrowForward = (props) => (React__namespace.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1.25em", height: "1.25em", viewBox: "0 0 20 20", ...props },
148
- React__namespace.createElement("path", { fill: "currentColor", d: "m10 16.075-1.227-1.227 3.983-3.983h-8.83v-1.73h8.83L8.773 5.152 10 3.925 16.075 10 10 16.075Z" })));
149
-
150
- /** A button with just text */
151
- function Button({ children, onClick, appearance }) {
152
- const className = ["kth-button", appearance].join(" ");
153
- return (React.createElement("button", { onClick: onClick, className: className }, children));
154
- }
155
- function BackButton({ children, onClick }) {
156
- return (React.createElement("button", { onClick: onClick, className: "kth-button tertiary" },
157
- React.createElement(SvgArrowBack, null),
158
- children));
159
- }
160
- function ForwardButton({ children, onClick }) {
161
- return (React.createElement("button", { onClick: onClick, className: "kth-button primary" },
162
- children,
163
- React.createElement(SvgArrowForward, null)));
164
- }
165
-
166
- const SvgCheck = (props) => (React__namespace.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1.25em", height: "1.25em", viewBox: "0 0 20 20", ...props },
167
- React__namespace.createElement("path", { fill: "currentColor", d: "M8.23 14.063 4.707 10.52 5.75 9.479l2.48 2.459 6.02-6L15.292 7l-7.063 7.063Z" })));
168
-
169
- exports.BackButton = BackButton;
170
- exports.Button = Button;
171
- exports.ContentTabs = ContentTabs;
172
- exports.ForwardButton = ForwardButton;
173
- exports.IconArrowBack = SvgArrowBack;
174
- exports.IconCheck = SvgCheck;
175
- exports.NavigationTabs = NavigationTabs;
176
- exports.Option = Option;
177
- exports.OptionGroup = OptionGroup;
178
- exports.Select = Select;
179
- exports.Tab = Tab;
7
+ module.exports = hello;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Close all <dialog>s (modal and non-modal) in a document
3
+ */
4
+ export declare function closeAllDialogs(): void;
5
+ /**
6
+ * Add mouse and keyboard event listeners to a menu panel (<dialog>)
7
+ * @param dialog A <dialog> element
8
+ */
9
+ export declare function addEventListeners(dialog: HTMLDialogElement): void;
10
+ export declare class MenuPanel {
11
+ static init(container: HTMLElement | null, items: NodeListOf<Element>): void;
12
+ static initModal(items: NodeListOf<Element>): void;
13
+ }
@@ -1,3 +1 @@
1
- export { setNavigationPanels } from "./components/NavigationPanel";
2
- export { setModalNavigationPanels } from "./components/ModalNavigationPanel";
3
- export { initTabs } from "./components/Tabs";
1
+ export { MenuPanel } from "./components/MenuPanel";