@kth/style 0.12.1 → 0.13.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.
@@ -3,12 +3,25 @@
3
3
  */
4
4
  export declare function closeAllDialogs(): void;
5
5
  /**
6
- * Add mouse and keyboard event listeners to a menu panel (<dialog>)
6
+ * Add basic mouse and keyboard event listeners to a dialog (<dialog>)
7
7
  * @param dialog A <dialog> element
8
8
  */
9
- export declare function addEventListeners(dialog: HTMLDialogElement, previousDialog?: HTMLDialogElement | null): void;
9
+ export declare function addEventListeners(dialog: HTMLDialogElement): void;
10
+ /**
11
+ * Add mouse and keyboard event listeners to a dialog (<dialog>) that is not a modal
12
+ * @param dialog A <dialog> element
13
+ * @param button Button or clickable element used to open the dialog
14
+ */
15
+ export declare function addNonModalEventListeners(dialog: HTMLDialogElement, button: HTMLElement): void;
16
+ /**
17
+ * Add mouse and keyboard event listeners to a modal (<dialog>)
18
+ * @param modal A <dialog> element
19
+ * @param previousModal A <dialog> element that was clicked to open the current modal
20
+ */
21
+ export declare function addModalEventListeners(modal: HTMLDialogElement, button: HTMLElement, previousModal?: HTMLDialogElement | null): void;
10
22
  export declare class MenuPanel {
11
23
  static init(container: HTMLElement | null, items: NodeListOf<Element>): void;
12
24
  static initModal(button: Element | null, modal: Element | null): void;
13
25
  static initModals(items: NodeListOf<Element>, previousModal?: Element | null): void;
26
+ static initTranslationModal(button: Element | null, modal: Element | null): void;
14
27
  }
package/dist/cjs/index.js CHANGED
@@ -7,17 +7,11 @@ function closeAllDialogs() {
7
7
  document.querySelectorAll("dialog").forEach((dialog) => dialog.close());
8
8
  }
9
9
  /**
10
- * Add mouse and keyboard event listeners to a menu panel (<dialog>)
10
+ * Add basic mouse and keyboard event listeners to a dialog (<dialog>)
11
11
  * @param dialog A <dialog> element
12
12
  */
13
- function addEventListeners(dialog, previousDialog) {
13
+ function addEventListeners(dialog) {
14
14
  const closeButton = dialog.querySelector(".kth-icon-button.close");
15
- const backButton = dialog.querySelector(".kth-button.back");
16
- dialog.addEventListener("click", (e) => {
17
- if (e.target === dialog) {
18
- closeAllDialogs();
19
- }
20
- });
21
15
  dialog.addEventListener("keydown", (e) => {
22
16
  if (e.key === "Escape") {
23
17
  dialog.close();
@@ -28,11 +22,53 @@ function addEventListeners(dialog, previousDialog) {
28
22
  closeAllDialogs();
29
23
  });
30
24
  }
25
+ }
26
+ /**
27
+ * Add mouse and keyboard event listeners to a dialog (<dialog>) that is not a modal
28
+ * @param dialog A <dialog> element
29
+ * @param button Button or clickable element used to open the dialog
30
+ */
31
+ function addNonModalEventListeners(dialog, button) {
32
+ addEventListeners(dialog);
33
+ button.addEventListener("click", (e) => {
34
+ e.preventDefault();
35
+ if (!dialog.open) {
36
+ closeAllDialogs();
37
+ dialog.show();
38
+ }
39
+ else {
40
+ closeAllDialogs();
41
+ }
42
+ });
43
+ // Close the dialog if clicking outside the modal
44
+ document.addEventListener("click", (e) => {
45
+ if (dialog.open &&
46
+ !e.composedPath().includes(button) &&
47
+ !e.composedPath().includes(dialog)) {
48
+ e.preventDefault();
49
+ closeAllDialogs();
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Add mouse and keyboard event listeners to a modal (<dialog>)
55
+ * @param modal A <dialog> element
56
+ * @param previousModal A <dialog> element that was clicked to open the current modal
57
+ */
58
+ function addModalEventListeners(modal, button, previousModal) {
59
+ const backButton = modal.querySelector(".kth-button.back");
60
+ addEventListeners(modal);
61
+ button.addEventListener("click", (e) => {
62
+ e.preventDefault();
63
+ closeAllDialogs();
64
+ modal.showModal();
65
+ });
66
+ // Close the current modal and open the previous modal with a back button
31
67
  if (backButton instanceof HTMLButtonElement) {
32
68
  backButton.addEventListener("click", () => {
33
- dialog.close();
34
- if (previousDialog) {
35
- previousDialog.showModal();
69
+ modal.close();
70
+ if (previousModal) {
71
+ previousModal.showModal();
36
72
  }
37
73
  });
38
74
  }
@@ -47,17 +83,7 @@ class MenuPanel {
47
83
  const dialog = item.nextElementSibling;
48
84
  if (!(dialog instanceof HTMLDialogElement))
49
85
  continue;
50
- addEventListeners(dialog);
51
- item.addEventListener("click", (e) => {
52
- e.preventDefault();
53
- if (!dialog.open) {
54
- closeAllDialogs();
55
- dialog.show();
56
- }
57
- else {
58
- closeAllDialogs();
59
- }
60
- });
86
+ addNonModalEventListeners(dialog, item);
61
87
  }
62
88
  container.addEventListener("focusout", function (e) {
63
89
  const target = e.relatedTarget;
@@ -71,11 +97,7 @@ class MenuPanel {
71
97
  return;
72
98
  if (!(modal instanceof HTMLDialogElement))
73
99
  return;
74
- addEventListeners(modal);
75
- button.addEventListener("click", (e) => {
76
- e.preventDefault();
77
- modal.showModal();
78
- });
100
+ addModalEventListeners(modal, button);
79
101
  }
80
102
  static initModals(items, previousModal) {
81
103
  if (previousModal && !(previousModal instanceof HTMLDialogElement))
@@ -87,12 +109,17 @@ class MenuPanel {
87
109
  const modal = document.querySelector(`.kth-mobile-menu[data-id='${dataId}']`);
88
110
  if (!(modal instanceof HTMLDialogElement))
89
111
  return;
90
- addEventListeners(modal, previousModal);
91
- item.addEventListener("click", (e) => {
92
- e.preventDefault();
93
- closeAllDialogs();
94
- modal.showModal();
95
- });
112
+ addModalEventListeners(modal, item, previousModal);
113
+ }
114
+ }
115
+ static initTranslationModal(button, modal) {
116
+ if (!(button instanceof HTMLElement))
117
+ return;
118
+ if (!(modal instanceof HTMLDialogElement))
119
+ return;
120
+ // Only open the modal if there is no href
121
+ if (!button.getAttribute("href")) {
122
+ addNonModalEventListeners(modal, button);
96
123
  }
97
124
  }
98
125
  }
@@ -3,12 +3,25 @@
3
3
  */
4
4
  export declare function closeAllDialogs(): void;
5
5
  /**
6
- * Add mouse and keyboard event listeners to a menu panel (<dialog>)
6
+ * Add basic mouse and keyboard event listeners to a dialog (<dialog>)
7
7
  * @param dialog A <dialog> element
8
8
  */
9
- export declare function addEventListeners(dialog: HTMLDialogElement, previousDialog?: HTMLDialogElement | null): void;
9
+ export declare function addEventListeners(dialog: HTMLDialogElement): void;
10
+ /**
11
+ * Add mouse and keyboard event listeners to a dialog (<dialog>) that is not a modal
12
+ * @param dialog A <dialog> element
13
+ * @param button Button or clickable element used to open the dialog
14
+ */
15
+ export declare function addNonModalEventListeners(dialog: HTMLDialogElement, button: HTMLElement): void;
16
+ /**
17
+ * Add mouse and keyboard event listeners to a modal (<dialog>)
18
+ * @param modal A <dialog> element
19
+ * @param previousModal A <dialog> element that was clicked to open the current modal
20
+ */
21
+ export declare function addModalEventListeners(modal: HTMLDialogElement, button: HTMLElement, previousModal?: HTMLDialogElement | null): void;
10
22
  export declare class MenuPanel {
11
23
  static init(container: HTMLElement | null, items: NodeListOf<Element>): void;
12
24
  static initModal(button: Element | null, modal: Element | null): void;
13
25
  static initModals(items: NodeListOf<Element>, previousModal?: Element | null): void;
26
+ static initTranslationModal(button: Element | null, modal: Element | null): void;
14
27
  }
package/dist/esm/index.js CHANGED
@@ -5,17 +5,11 @@ function closeAllDialogs() {
5
5
  document.querySelectorAll("dialog").forEach((dialog) => dialog.close());
6
6
  }
7
7
  /**
8
- * Add mouse and keyboard event listeners to a menu panel (<dialog>)
8
+ * Add basic mouse and keyboard event listeners to a dialog (<dialog>)
9
9
  * @param dialog A <dialog> element
10
10
  */
11
- function addEventListeners(dialog, previousDialog) {
11
+ function addEventListeners(dialog) {
12
12
  const closeButton = dialog.querySelector(".kth-icon-button.close");
13
- const backButton = dialog.querySelector(".kth-button.back");
14
- dialog.addEventListener("click", (e) => {
15
- if (e.target === dialog) {
16
- closeAllDialogs();
17
- }
18
- });
19
13
  dialog.addEventListener("keydown", (e) => {
20
14
  if (e.key === "Escape") {
21
15
  dialog.close();
@@ -26,11 +20,53 @@ function addEventListeners(dialog, previousDialog) {
26
20
  closeAllDialogs();
27
21
  });
28
22
  }
23
+ }
24
+ /**
25
+ * Add mouse and keyboard event listeners to a dialog (<dialog>) that is not a modal
26
+ * @param dialog A <dialog> element
27
+ * @param button Button or clickable element used to open the dialog
28
+ */
29
+ function addNonModalEventListeners(dialog, button) {
30
+ addEventListeners(dialog);
31
+ button.addEventListener("click", (e) => {
32
+ e.preventDefault();
33
+ if (!dialog.open) {
34
+ closeAllDialogs();
35
+ dialog.show();
36
+ }
37
+ else {
38
+ closeAllDialogs();
39
+ }
40
+ });
41
+ // Close the dialog if clicking outside the modal
42
+ document.addEventListener("click", (e) => {
43
+ if (dialog.open &&
44
+ !e.composedPath().includes(button) &&
45
+ !e.composedPath().includes(dialog)) {
46
+ e.preventDefault();
47
+ closeAllDialogs();
48
+ }
49
+ });
50
+ }
51
+ /**
52
+ * Add mouse and keyboard event listeners to a modal (<dialog>)
53
+ * @param modal A <dialog> element
54
+ * @param previousModal A <dialog> element that was clicked to open the current modal
55
+ */
56
+ function addModalEventListeners(modal, button, previousModal) {
57
+ const backButton = modal.querySelector(".kth-button.back");
58
+ addEventListeners(modal);
59
+ button.addEventListener("click", (e) => {
60
+ e.preventDefault();
61
+ closeAllDialogs();
62
+ modal.showModal();
63
+ });
64
+ // Close the current modal and open the previous modal with a back button
29
65
  if (backButton instanceof HTMLButtonElement) {
30
66
  backButton.addEventListener("click", () => {
31
- dialog.close();
32
- if (previousDialog) {
33
- previousDialog.showModal();
67
+ modal.close();
68
+ if (previousModal) {
69
+ previousModal.showModal();
34
70
  }
35
71
  });
36
72
  }
@@ -45,17 +81,7 @@ class MenuPanel {
45
81
  const dialog = item.nextElementSibling;
46
82
  if (!(dialog instanceof HTMLDialogElement))
47
83
  continue;
48
- addEventListeners(dialog);
49
- item.addEventListener("click", (e) => {
50
- e.preventDefault();
51
- if (!dialog.open) {
52
- closeAllDialogs();
53
- dialog.show();
54
- }
55
- else {
56
- closeAllDialogs();
57
- }
58
- });
84
+ addNonModalEventListeners(dialog, item);
59
85
  }
60
86
  container.addEventListener("focusout", function (e) {
61
87
  const target = e.relatedTarget;
@@ -69,11 +95,7 @@ class MenuPanel {
69
95
  return;
70
96
  if (!(modal instanceof HTMLDialogElement))
71
97
  return;
72
- addEventListeners(modal);
73
- button.addEventListener("click", (e) => {
74
- e.preventDefault();
75
- modal.showModal();
76
- });
98
+ addModalEventListeners(modal, button);
77
99
  }
78
100
  static initModals(items, previousModal) {
79
101
  if (previousModal && !(previousModal instanceof HTMLDialogElement))
@@ -85,12 +107,17 @@ class MenuPanel {
85
107
  const modal = document.querySelector(`.kth-mobile-menu[data-id='${dataId}']`);
86
108
  if (!(modal instanceof HTMLDialogElement))
87
109
  return;
88
- addEventListeners(modal, previousModal);
89
- item.addEventListener("click", (e) => {
90
- e.preventDefault();
91
- closeAllDialogs();
92
- modal.showModal();
93
- });
110
+ addModalEventListeners(modal, item, previousModal);
111
+ }
112
+ }
113
+ static initTranslationModal(button, modal) {
114
+ if (!(button instanceof HTMLElement))
115
+ return;
116
+ if (!(modal instanceof HTMLDialogElement))
117
+ return;
118
+ // Only open the modal if there is no href
119
+ if (!button.getAttribute("href")) {
120
+ addNonModalEventListeners(modal, button);
94
121
  }
95
122
  }
96
123
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kth/style",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "exports": {
@@ -23,26 +23,13 @@
23
23
  }
24
24
  }
25
25
 
26
- :root {
27
- --height-header: 6rem;
28
- }
29
-
30
26
  .kth-header {
31
- position: absolute;
32
-
33
- // TODO: convert to its own token
34
- z-index: 10;
35
- top: var(--height-kpm, 0);
36
27
  color: var(--color-text);
37
28
  background: var(--color-background);
38
29
  padding-block: spacing.$space-16;
39
30
  width: 100%;
40
31
  transition: padding-block 500ms cubic-bezier(0.05, 0.7, 0.1, 1);
41
32
 
42
- .kth-logotype {
43
- transition: all 200ms linear;
44
- }
45
-
46
33
  &__container {
47
34
  @include mixins.container;
48
35
  display: flex;
@@ -62,23 +49,4 @@
62
49
  display: none;
63
50
  }
64
51
  }
65
-
66
- // Fixed header in mobile
67
- @media (max-width: sizing.$breakpoint-64) {
68
- .kth-header {
69
- position: fixed;
70
- }
71
-
72
- .kth-header.collapsed {
73
- padding-block: spacing.$space-8;
74
-
75
- // TODO: Define this shadow as a token
76
- box-shadow: 0 0.125rem 0.5rem 0 rgb(0 0 0 /0.15);
77
-
78
- .kth-logotype {
79
- block-size: 0rem;
80
- opacity: 0;
81
- }
82
- }
83
- }
84
52
  }
@@ -1,18 +1,7 @@
1
1
  @use "../utils/mixins.scss";
2
2
 
3
3
  @layer kth-style {
4
- :root {
5
- --height-kpm: 2.5rem;
6
- }
7
-
8
4
  .kth-kpm {
9
- position: fixed;
10
- width: 100%;
11
- // TODO: Convert to its own token
12
- z-index: 10;
13
- background: var(--color-background);
14
- top: 0;
15
-
16
5
  &__container {
17
6
  @include mixins.container;
18
7
  display: flex;
@@ -4,16 +4,11 @@
4
4
  @layer kth-style {
5
5
  a.kth-logotype,
6
6
  figure.kth-logotype {
7
- overflow: hidden;
8
7
  display: inline-block;
9
8
  block-size: 4rem;
10
9
  inline-size: 4rem;
11
10
  border: none;
12
11
  margin: 0;
13
-
14
- @media (min-width: sizing.$breakpoint-64) {
15
- margin-inline-end: spacing.$space-32;
16
- }
17
12
  padding: 0;
18
13
 
19
14
  // Defensive measurement:
@@ -23,14 +18,6 @@
23
18
  > figure {
24
19
  block-size: 100%;
25
20
  inline-size: 100%;
26
- position: relative;
27
- }
28
-
29
- img {
30
- position: absolute;
31
- bottom: 0;
32
- block-size: 4rem;
33
- inline-size: 4rem;
34
21
  }
35
22
  }
36
23
  }
@@ -0,0 +1,49 @@
1
+ @use "../tokens/spacing";
2
+ @use "../tokens/colors";
3
+
4
+ @layer kth-style {
5
+ .kth-translation {
6
+ @include colors.theme-default;
7
+ width: 22.5rem;
8
+ left: auto;
9
+
10
+ // TODO: this formula should be a token
11
+ right: clamp(spacing.$space-16, calc(100vw / 30), spacing.$space-32);
12
+ background-color: var(--color-background);
13
+
14
+ // TODO: tokenize this shadow
15
+ box-shadow: 0 0.125rem 0.5rem 0 rgb(0 0 0 /0.15);
16
+ border: none;
17
+ padding: spacing.$space-16 spacing.$space-16 spacing.$space-32
18
+ spacing.$space-32;
19
+
20
+ // TODO: tokenize the breakpoint
21
+ @media (min-width: 82rem) {
22
+ // TODO: tokenize formula
23
+ // Remaining space to the right from the header's max-width + the heading's padding
24
+ right: calc((100vw - 82rem) / 2 + spacing.$space-32);
25
+ }
26
+
27
+ // Let the dialog take up the remaining space
28
+ @media (max-width: calc(22.5rem + spacing.$space-16 * 2)) {
29
+ right: spacing.$space-16;
30
+ left: spacing.$space-16;
31
+ width: auto;
32
+ }
33
+
34
+ &__content {
35
+ display: flex;
36
+ gap: spacing.$space-8;
37
+ flex-direction: column;
38
+
39
+ span,
40
+ a {
41
+ padding-right: spacing.$space-16;
42
+ }
43
+ }
44
+
45
+ .kth-icon-button {
46
+ align-self: end;
47
+ }
48
+ }
49
+ }
@@ -91,18 +91,6 @@ $generate-css: true !default;
91
91
  color: var(--color-text);
92
92
  background: var(--color-background);
93
93
  min-height: 100vh;
94
- margin-inline: 0;
95
-
96
- // `--height-kpm` is set by (new) KPM or `kpm.scss`
97
- // `--kpm-bar-height` is the old (current) name for the variable set by KPM
98
- // default value is 0 (no kpm at all)
99
-
100
- // `--height-header` is set when including `header.scss`
101
- // default value is 0 (no header)
102
- margin-block-start: calc(
103
- var(--height-kpm, var(--kpm-bar-height, 0rem)) +
104
- var(--height-header, 0rem)
105
- );
106
94
  }
107
95
 
108
96
  @include reset;