@uva-glass/component-library 3.50.1 → 3.50.3

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.
@@ -1 +1 @@
1
- ._slider_wrapper_136tg_1{align-items:center;display:flex;gap:1rem;width:100%}._slider_button_136tg_8{align-items:center;appearance:none;aspect-ratio:1 / 1;background:none;border:1px solid transparent;border-radius:.25rem;color:var(--color-grey-700);cursor:pointer;display:flex;height:2rem;justify-content:center;width:2rem}._slider_button_136tg_8:focus-visible{outline:.125rem dotted var(--color-navy-600);outline-offset:.125rem}._slider_button_136tg_8:hover{border-color:var(--color-grey-700)}._slider_button_136tg_8:disabled,._slider_button_136tg_8:disabled:hover{border:none;cursor:not-allowed}._slider_trackwrapper_136tg_38{display:flex;position:relative;width:100%}._slider_balloon_136tg_44{color:var(--color-grey-700);position:absolute;text-align:center;top:-1.8125rem;white-space:nowrap}._slider_input_136tg_52{appearance:none;background:var(--color-grey-400);flex-grow:1;height:.25rem}._slider_input_136tg_52:focus-visible{outline:.125rem dotted var(--color-navy-600);outline-offset:.125rem}._slider_input_136tg_52:disabled{cursor:not-allowed}._slider_input_136tg_52::-webkit-slider-runnable-track{appearance:none;color:var(--color-navy-600);cursor:pointer;height:2rem;margin-top:-.125rem}._slider_input_136tg_52:disabled::-webkit-slider-runnable-track{cursor:not-allowed}._slider_input_136tg_52::-webkit-slider-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-800);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(.5rem + 1px);position:relative;width:var(--thumb-size)}._slider_input_136tg_52:disabled::-webkit-slider-thumb,._slider_input_136tg_52:disabled:hover::-webkit-slider-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_136tg_52::-moz-range-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-800);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(-.25rem - 1px);position:relative;width:var(--thumb-size)}._slider_input_136tg_52:disabled::-moz-range-thumb,._slider_input_136tg_52:hover:disabled::-moz-range-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_136tg_52::-ms-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-800);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(-.25rem - 1px);position:relative;width:var(--thumb-size)}._slider_input_136tg_52:disabled::-ms-thumb,._slider_input_136tg_52:hover:disabled::-ms-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_136tg_52::-webkit-slider-thumb:hover{background:var(--color-navy-200)}._slider_input_136tg_52::-moz-range-thumb:hover{background:var(--color-navy-200)}._slider_input_136tg_52::-ms-thumb:hover{background:var(--color-navy-200)}._slider_input_136tg_52::-moz-range-progress{background-color:var(--color-navy-600)}._slider_input_136tg_52::-moz-range-track{background-color:var(--color-grey-400)}._slider_input_136tg_52::-ms-fill-lower{background-color:var(--color-navy-600)}._slider_input_136tg_52::-ms-fill-upper{background-color:var(--color-grey-400)}
1
+ ._slider_wrapper_euug7_1{align-items:center;display:flex;gap:1rem;width:100%}._slider_button_euug7_8{align-items:center;appearance:none;aspect-ratio:1 / 1;background:none;border:1px solid transparent;border-radius:.25rem;color:var(--color-grey-700);cursor:pointer;display:flex;height:2rem;justify-content:center;width:2rem}._slider_button_euug7_8:focus-visible{outline:.125rem dotted var(--color-navy-600);outline-offset:.125rem}._slider_button_euug7_8:hover{border-color:var(--color-grey-700)}._slider_button_euug7_8:disabled,._slider_button_euug7_8:disabled:hover{border:none;cursor:not-allowed}._slider_trackwrapper_euug7_38{display:flex;position:relative;width:100%}._slider_balloon_euug7_44{color:var(--color-grey-700);position:absolute;text-align:center;top:-1.8125rem;white-space:nowrap}._slider_input_euug7_52{appearance:none;background:var(--color-grey-400);flex-grow:1;height:.25rem}._slider_input_euug7_52:focus-visible{outline:.125rem dotted var(--color-navy-600);outline-offset:.125rem}._slider_input_euug7_52:disabled{cursor:not-allowed}._slider_input_euug7_52::-webkit-slider-runnable-track{appearance:none;color:var(--color-navy-600);cursor:pointer;height:2rem;margin-top:-.125rem}._slider_input_euug7_52:disabled::-webkit-slider-runnable-track{cursor:not-allowed}._slider_input_euug7_52::-webkit-slider-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-600);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(.5rem + 1px);position:relative;width:var(--thumb-size)}._slider_input_euug7_52:disabled::-webkit-slider-thumb,._slider_input_euug7_52:disabled:hover::-webkit-slider-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_euug7_52::-moz-range-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-600);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(-.25rem - 1px);position:relative;width:var(--thumb-size)}._slider_input_euug7_52:disabled::-moz-range-thumb,._slider_input_euug7_52:hover:disabled::-moz-range-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_euug7_52::-ms-thumb{appearance:none;background:var(--color-uva-white);border:2px solid var(--color-navy-600);border-radius:.125rem;cursor:pointer;height:var(--thumb-size);margin-top:calc(-.25rem - 1px);position:relative;width:var(--thumb-size)}._slider_input_euug7_52:disabled::-ms-thumb,._slider_input_euug7_52:hover:disabled::-ms-thumb{background:var(--color-grey-700);border:2px solid var(--color-grey-700);cursor:not-allowed}._slider_input_euug7_52::-webkit-slider-thumb:hover{background:var(--color-navy-200);border:2px solid var(--color-navy-800)}._slider_input_euug7_52::-moz-range-thumb:hover{background:var(--color-navy-200);border:2px solid var(--color-navy-800)}._slider_input_euug7_52::-ms-thumb:hover{background:var(--color-navy-200);border:2px solid var(--color-navy-800)}._slider_input_euug7_52::-moz-range-progress{background-color:var(--color-navy-600)}._slider_input_euug7_52::-moz-range-track{background-color:var(--color-grey-400)}._slider_input_euug7_52::-ms-fill-lower{background-color:var(--color-navy-600)}._slider_input_euug7_52::-ms-fill-upper{background-color:var(--color-grey-400)}
@@ -2,7 +2,7 @@ import { jsxs as m, jsx as a } from "react/jsx-runtime";
2
2
  import { useState as S, useRef as v, useEffectEvent as x, useEffect as B } from "react";
3
3
  import { c as H } from "../../clsx-OuTLNxxd.js";
4
4
  import { Icon as E } from "../Icon/Icon.js";
5
- import '../../assets/Slider.css';const T = "_slider_wrapper_136tg_1", j = "_slider_button_136tg_8", C = "_slider_trackwrapper_136tg_38", D = "_slider_balloon_136tg_44", F = "_slider_input_136tg_52", l = {
5
+ import '../../assets/Slider.css';const T = "_slider_wrapper_euug7_1", j = "_slider_button_euug7_8", C = "_slider_trackwrapper_euug7_38", D = "_slider_balloon_euug7_44", F = "_slider_input_euug7_52", l = {
6
6
  slider_wrapper: T,
7
7
  slider_button: j,
8
8
  slider_trackwrapper: C,
@@ -14,37 +14,37 @@ import '../../assets/Slider.css';const T = "_slider_wrapper_136tg_1", j = "_slid
14
14
  value: i,
15
15
  step: k = 1,
16
16
  units: c,
17
- navigationLabels: d,
17
+ navigationLabels: u,
18
18
  disabled: s = !1,
19
- onChange: u
19
+ onChange: d
20
20
  }) => {
21
- const [n, f] = S(i !== void 0 ? i : (t + o) * w), [V, P] = S(""), _ = v(null), g = v(null), b = v(null), N = (e) => {
22
- const r = n + e * k;
23
- r >= t && r <= o && (f(r), h(r), y(r), u && u(r));
24
- }, R = (e) => {
25
- const r = Number(e.target.value);
26
- f(r), h(r), y(r), u && u(r);
27
- }, h = (e) => {
21
+ const [n, f] = S(i !== void 0 ? i : (t + o) * w), [V, P] = S(""), _ = v(null), g = v(null), b = v(null), N = (r) => {
22
+ const e = n + r * k;
23
+ e >= t && e <= o && (f(e), h(e), y(e), d && d(e));
24
+ }, R = (r) => {
25
+ const e = Number(r.target.value);
26
+ f(e), h(e), y(e), d && d(e);
27
+ }, h = (r) => {
28
28
  if (!_.current) return;
29
- const r = (e - t) / (o - t) * I;
29
+ const e = (r - t) / (o - t) * I;
30
30
  s ? _.current.style.background = `linear-gradient(
31
31
  to right,
32
32
  var(--color-grey-700) 0%,
33
- var(--color-grey-700) ${r}%,
34
- var(--color-grey-400) ${r}%,
33
+ var(--color-grey-700) ${e}%,
34
+ var(--color-grey-400) ${e}%,
35
35
  var(--color-grey-400) 100%)` : _.current.style.background = `linear-gradient(
36
36
  to right,
37
37
  var(--color-navy-600) 0%,
38
- var(--color-navy-600) ${r}%,
39
- var(--color-grey-400) ${r}%,
38
+ var(--color-navy-600) ${e}%,
39
+ var(--color-grey-400) ${e}%,
40
40
  var(--color-grey-400) 100%)`;
41
- }, y = (e) => {
41
+ }, y = (r) => {
42
42
  if (g.current && b.current) {
43
- const r = b.current.clientWidth, $ = g.current.clientWidth - p, W = (e - t) / (o - t) * $ - (r - p) * w, z = Math.max(0, Math.min(W, $ - r + p * w));
43
+ const e = b.current.clientWidth, $ = g.current.clientWidth - p, W = (r - t) / (o - t) * $ - (e - p) * w, z = Math.max(0, Math.min(W, $ - e + p * w));
44
44
  P(`${z}px`);
45
45
  }
46
- }, M = x((e) => {
47
- f(e), h(e), y(e);
46
+ }, M = x((r) => {
47
+ f(r), h(r), y(r);
48
48
  });
49
49
  return B(() => {
50
50
  i !== void 0 && M(i);
@@ -55,7 +55,7 @@ import '../../assets/Slider.css';const T = "_slider_wrapper_136tg_1", j = "_slid
55
55
  type: "button",
56
56
  className: l.slider_button,
57
57
  onClick: () => N(-1),
58
- "aria-label": d?.decrease ? d.decrease : "Verlaag waarde",
58
+ "aria-label": u?.decrease ? u.decrease : "Verlaag waarde",
59
59
  disabled: s,
60
60
  children: /* @__PURE__ */ a(E, { name: "Minus", size: 20 })
61
61
  }
@@ -100,7 +100,7 @@ import '../../assets/Slider.css';const T = "_slider_wrapper_136tg_1", j = "_slid
100
100
  type: "button",
101
101
  className: l.slider_button,
102
102
  onClick: () => N(1),
103
- "aria-label": d?.increase ? d.increase : "Verhoog waarde",
103
+ "aria-label": u?.increase ? u.increase : "Verhoog waarde",
104
104
  disabled: s,
105
105
  children: /* @__PURE__ */ a(E, { name: "Plus", size: 20 })
106
106
  }
@@ -1,51 +1,54 @@
1
- import { jsx as t, jsxs as j } from "react/jsx-runtime";
2
- import { useState as d, useRef as O, useMemo as x, useEffect as h } from "react";
3
- import { createPortal as A } from "react-dom";
4
- import { useOverlay as C, usePreventScroll as D, OverlayContainer as L } from "@react-aria/overlays";
5
- import { FocusScope as $ } from "@react-aria/focus";
6
- import { WeekSelectorButton as q } from "./components/WeekSelectorButton.js";
7
- import { WeekSelectorOptionContainer as E } from "./components/WeekSelectorOptionContainer.js";
8
- import { WeekSelectorOption as K } from "./components/WeekSelectorOption.js";
9
- import { s as M } from "../../WeekSelector.module-Clco7jTs.js";
1
+ import { jsx as t, jsxs as F } from "react/jsx-runtime";
2
+ import { useState as b, useRef as k, useMemo as $, useEffect as y } from "react";
3
+ import { createPortal as x } from "react-dom";
4
+ import { useOverlay as A, usePreventScroll as C, OverlayContainer as D } from "@react-aria/overlays";
5
+ import { FocusScope as L } from "@react-aria/focus";
6
+ import { WeekSelectorButton as E } from "./components/WeekSelectorButton.js";
7
+ import { WeekSelectorOptionContainer as K } from "./components/WeekSelectorOptionContainer.js";
8
+ import { WeekSelectorOption as M } from "./components/WeekSelectorOption.js";
9
+ import { s as O } from "../../WeekSelector.module-Clco7jTs.js";
10
10
  import { Backdrop as P } from "../Backdrop/Backdrop.js";
11
11
  import { useOnClickOutside as R } from "../hooks/useOnClickOutside.js";
12
12
  const Z = ({
13
13
  weeks: r,
14
14
  currentPeriod: i = 0,
15
15
  defaultSelection: n,
16
- weekPrefix: k,
17
- optionsHeader: y,
18
- periodLabels: N,
19
- onSelectWeek: v,
20
- portalContainerRef: m,
21
- optionContainerOffset: u = []
16
+ weekPrefix: h,
17
+ optionsHeader: N,
18
+ periodLabels: v,
19
+ onSelectWeek: W,
20
+ portalContainerRef: u,
21
+ optionContainerOffset: m = []
22
22
  }) => {
23
- const [p, a] = d(null), [o, l] = d(!1), f = O(null), s = O(null), W = x(() => Object.keys(r ?? {}), [r]);
24
- h(() => {
23
+ const [a, p] = b(null), [o, l] = b(!1), f = k(null), s = k(null), B = $(() => Object.keys(r ?? {}), [r]);
24
+ y(() => {
25
25
  if (n) {
26
26
  for (const e in r)
27
27
  if (r[e].some((c) => c.calendarWeekNumber === n && !c.isBlocked) && Number(e) > i) {
28
- a(n);
28
+ p(n);
29
29
  return;
30
30
  }
31
31
  }
32
32
  for (const e in r) {
33
- const c = r[e].find((g) => !g.isBlocked);
33
+ const c = r[e].find((q) => !q.isBlocked);
34
34
  if (c && Number(e) > i) {
35
- a(c.calendarWeekNumber);
35
+ p(c.calendarWeekNumber);
36
36
  return;
37
37
  }
38
38
  }
39
- }, [r, i, n]), h(() => {
40
- o && s.current && requestAnimationFrame(() => {
41
- s.current?.focus();
39
+ }, [r, i, n]), y(() => {
40
+ o && requestAnimationFrame(() => {
41
+ const e = s.current?.querySelector(
42
+ `.${O["week-selector-option-week--selected"]}`
43
+ );
44
+ e ? e.focus() : s.current?.querySelector("button:not(:disabled)")?.focus();
42
45
  });
43
- }, [o]);
44
- const B = () => `${k} ${p ?? n ?? "?"}`;
46
+ }, [o, a]);
47
+ const S = () => `${h} ${a ?? n ?? "?"}`;
45
48
  R(f, (e) => {
46
49
  s.current && s.current.contains(e.target) || l(!1);
47
50
  });
48
- const { overlayProps: F, underlayProps: S } = C(
51
+ const { overlayProps: g, underlayProps: j } = A(
49
52
  {
50
53
  isOpen: o,
51
54
  isDismissable: !0,
@@ -53,40 +56,40 @@ const Z = ({
53
56
  },
54
57
  s
55
58
  );
56
- D({ isDisabled: !o || !m?.current });
57
- const b = /* @__PURE__ */ t(
58
- E,
59
+ C({ isDisabled: !o || !u?.current });
60
+ const d = /* @__PURE__ */ t(
61
+ K,
59
62
  {
60
- header: y,
61
- periodLabels: N,
63
+ header: N,
64
+ periodLabels: v,
62
65
  ref: s,
63
- ...u.length === 2 ? {
66
+ ...m.length === 2 ? {
64
67
  style: {
65
- top: u[0],
66
- left: u[1]
68
+ top: m[0],
69
+ left: m[1]
67
70
  }
68
71
  } : {},
69
- children: W.map((e) => /* @__PURE__ */ t(
70
- K,
72
+ children: B.map((e) => /* @__PURE__ */ t(
73
+ M,
71
74
  {
72
75
  periodIndex: e,
73
76
  weeks: r,
74
77
  disabled: Number(e) <= i,
75
- selectedOption: p,
76
- setSelectedOption: a,
77
- onSelectWeek: v,
78
+ selectedOption: a,
79
+ setSelectedOption: p,
80
+ onSelectWeek: W,
78
81
  setIsOpen: l
79
82
  },
80
83
  e
81
84
  ))
82
85
  }
83
86
  );
84
- return /* @__PURE__ */ j("div", { className: M["week-selector"], tabIndex: -1, ref: f, children: [
85
- /* @__PURE__ */ t(q, { label: B(), onClick: () => l(!o) }),
86
- o && (m?.current ? A(
87
- /* @__PURE__ */ t(L, { children: /* @__PURE__ */ t(P, { ...S, children: /* @__PURE__ */ t($, { contain: !0, restoreFocus: !0, autoFocus: !0, children: /* @__PURE__ */ t("div", { ...F, children: b }) }) }) }),
88
- m.current
89
- ) : b)
87
+ return /* @__PURE__ */ F("div", { className: O["week-selector"], tabIndex: -1, ref: f, children: [
88
+ /* @__PURE__ */ t(E, { label: S(), onClick: () => l(!o) }),
89
+ o && (u?.current ? x(
90
+ /* @__PURE__ */ t(D, { children: /* @__PURE__ */ t(P, { ...j, children: /* @__PURE__ */ t(L, { contain: !0, restoreFocus: !0, children: /* @__PURE__ */ t("div", { ...g, children: d }) }) }) }),
91
+ u.current
92
+ ) : d)
90
93
  ] });
91
94
  };
92
95
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"WeekSelector.js","sources":["../../../src/components/WeekSelector/WeekSelector.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { OverlayContainer, useOverlay, usePreventScroll } from '@react-aria/overlays';\r\nimport { FocusScope } from '@react-aria/focus';\r\n\r\nimport type { CSSProperties, RefObject } from 'react';\r\n\r\nimport { WeekSelectorButton } from './components/WeekSelectorButton';\r\nimport { WeekSelectorOptionContainer } from './components/WeekSelectorOptionContainer';\r\nimport { WeekSelectorOption } from './components/WeekSelectorOption';\r\nimport styles from './WeekSelector.module.css';\r\n\r\nimport { Backdrop } from 'components/Backdrop';\r\nimport { useOnClickOutside } from 'components/hooks/useOnClickOutside';\r\n\r\nexport type PeriodWeek = {\r\n academicWeekNumber: number;\r\n calendarWeekNumber: number;\r\n isBlocked: boolean;\r\n period: number;\r\n startDate: string;\r\n endDate: string;\r\n weekNumber: number;\r\n};\r\n\r\nexport interface WeekSelectorProps {\r\n /** Object with periodnumbers with array of weeks in period */\r\n weeks: Record<string, PeriodWeek[]>;\r\n /** Current period to disable previous periods */\r\n currentPeriod?: number;\r\n /** Default selected week */\r\n defaultSelection?: number;\r\n /** Prefix for the week button label */\r\n weekPrefix: string;\r\n /** Labels for each period */\r\n periodLabels: string[];\r\n /** Header text for the options container */\r\n optionsHeader: string;\r\n /** Callback function when a week is selected */\r\n onSelectWeek: (weeknumber: number) => void;\r\n /** Ref for the dropdown portal target */\r\n portalContainerRef?: RefObject<HTMLElement | null>;\r\n /** Optional WeekSelectorOptionContainer offset values [top, bottom] */\r\n optionContainerOffset?: number[];\r\n}\r\n\r\nexport const WeekSelector = ({\r\n weeks,\r\n currentPeriod = 0,\r\n defaultSelection,\r\n weekPrefix,\r\n optionsHeader,\r\n periodLabels,\r\n onSelectWeek,\r\n portalContainerRef,\r\n optionContainerOffset = [],\r\n}: WeekSelectorProps) => {\r\n const [selectedOption, setSelectedOption] = useState<number | null>(null);\r\n const [isOpen, setIsOpen] = useState<boolean>(false);\r\n const wrapperRef = useRef<HTMLDivElement>(null);\r\n const optionContainerRef = useRef<HTMLDivElement>(null);\r\n const periodKeys = useMemo(() => Object.keys(weeks ?? {}), [weeks]);\r\n\r\n useEffect(() => {\r\n if (defaultSelection) {\r\n for (const period in weeks) {\r\n if (\r\n weeks[period].some((week) => week.calendarWeekNumber === defaultSelection && !week.isBlocked) &&\r\n Number(period) > currentPeriod\r\n ) {\r\n setSelectedOption(defaultSelection);\r\n return;\r\n }\r\n }\r\n }\r\n for (const period in weeks) {\r\n const firstAvailableWeek = weeks[period].find((week) => !week.isBlocked);\r\n if (firstAvailableWeek && Number(period) > currentPeriod) {\r\n setSelectedOption(firstAvailableWeek.calendarWeekNumber);\r\n return;\r\n }\r\n }\r\n }, [weeks, currentPeriod, defaultSelection]);\r\n\r\n useEffect(() => {\r\n if (isOpen && optionContainerRef.current) {\r\n requestAnimationFrame(() => {\r\n optionContainerRef.current?.focus();\r\n });\r\n }\r\n }, [isOpen]);\r\n\r\n const getButtonLabel = () => {\r\n const weekNumber = selectedOption ?? defaultSelection ?? '?';\r\n return `${weekPrefix} ${weekNumber}`;\r\n };\r\n\r\n useOnClickOutside(wrapperRef as RefObject<HTMLElement>, (event) => {\r\n if (optionContainerRef.current && optionContainerRef.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n setIsOpen(false);\r\n });\r\n\r\n const { overlayProps, underlayProps } = useOverlay(\r\n {\r\n isOpen,\r\n isDismissable: true,\r\n onClose: () => setIsOpen(false),\r\n },\r\n optionContainerRef\r\n );\r\n\r\n usePreventScroll({ isDisabled: !isOpen || !portalContainerRef?.current });\r\n\r\n const OptionList = (\r\n <WeekSelectorOptionContainer\r\n header={optionsHeader}\r\n periodLabels={periodLabels}\r\n ref={optionContainerRef}\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n {...(optionContainerOffset.length === 2\r\n ? {\r\n style: {\r\n top: optionContainerOffset[0],\r\n left: optionContainerOffset[1],\r\n } as CSSProperties,\r\n }\r\n : {})}\r\n >\r\n {periodKeys.map((periodIndex) => (\r\n <WeekSelectorOption\r\n key={periodIndex}\r\n periodIndex={periodIndex}\r\n weeks={weeks}\r\n disabled={Number(periodIndex) <= currentPeriod}\r\n selectedOption={selectedOption}\r\n setSelectedOption={setSelectedOption}\r\n onSelectWeek={onSelectWeek}\r\n setIsOpen={setIsOpen}\r\n />\r\n ))}\r\n </WeekSelectorOptionContainer>\r\n );\r\n\r\n return (\r\n <div className={styles['week-selector']} tabIndex={-1} ref={wrapperRef}>\r\n <WeekSelectorButton label={getButtonLabel()} onClick={() => setIsOpen(!isOpen)} />\r\n\r\n {isOpen &&\r\n (portalContainerRef?.current\r\n ? createPortal(\r\n <OverlayContainer>\r\n <Backdrop {...underlayProps}>\r\n <FocusScope contain restoreFocus autoFocus>\r\n <div {...overlayProps}>{OptionList}</div>\r\n </FocusScope>\r\n </Backdrop>\r\n </OverlayContainer>,\r\n portalContainerRef.current\r\n )\r\n : OptionList)}\r\n </div>\r\n );\r\n};\r\n"],"names":["WeekSelector","weeks","currentPeriod","defaultSelection","weekPrefix","optionsHeader","periodLabels","onSelectWeek","portalContainerRef","optionContainerOffset","selectedOption","setSelectedOption","useState","isOpen","setIsOpen","wrapperRef","useRef","optionContainerRef","periodKeys","useMemo","useEffect","period","week","firstAvailableWeek","getButtonLabel","useOnClickOutside","event","overlayProps","underlayProps","useOverlay","usePreventScroll","OptionList","jsx","WeekSelectorOptionContainer","periodIndex","WeekSelectorOption","jsxs","styles","WeekSelectorButton","createPortal","OverlayContainer","Backdrop","FocusScope"],"mappings":";;;;;;;;;;;AA8CO,MAAMA,IAAe,CAAC;AAAA,EAC3B,OAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,uBAAAC,IAAwB,CAAA;AAC1B,MAAyB;AACvB,QAAM,CAACC,GAAgBC,CAAiB,IAAIC,EAAwB,IAAI,GAClE,CAACC,GAAQC,CAAS,IAAIF,EAAkB,EAAK,GAC7CG,IAAaC,EAAuB,IAAI,GACxCC,IAAqBD,EAAuB,IAAI,GAChDE,IAAaC,EAAQ,MAAM,OAAO,KAAKlB,KAAS,CAAA,CAAE,GAAG,CAACA,CAAK,CAAC;AAElE,EAAAmB,EAAU,MAAM;AACd,QAAIjB;AACF,iBAAWkB,KAAUpB;AACnB,YACEA,EAAMoB,CAAM,EAAE,KAAK,CAACC,MAASA,EAAK,uBAAuBnB,KAAoB,CAACmB,EAAK,SAAS,KAC5F,OAAOD,CAAM,IAAInB,GACjB;AACA,UAAAS,EAAkBR,CAAgB;AAClC;AAAA,QACF;AAAA;AAGJ,eAAWkB,KAAUpB,GAAO;AAC1B,YAAMsB,IAAqBtB,EAAMoB,CAAM,EAAE,KAAK,CAACC,MAAS,CAACA,EAAK,SAAS;AACvE,UAAIC,KAAsB,OAAOF,CAAM,IAAInB,GAAe;AACxD,QAAAS,EAAkBY,EAAmB,kBAAkB;AACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAACtB,GAAOC,GAAeC,CAAgB,CAAC,GAE3CiB,EAAU,MAAM;AACd,IAAIP,KAAUI,EAAmB,WAC/B,sBAAsB,MAAM;AAC1B,MAAAA,EAAmB,SAAS,MAAA;AAAA,IAC9B,CAAC;AAAA,EAEL,GAAG,CAACJ,CAAM,CAAC;AAEX,QAAMW,IAAiB,MAEd,GAAGpB,CAAU,IADDM,KAAkBP,KAAoB,GACvB;AAGpC,EAAAsB,EAAkBV,GAAsC,CAACW,MAAU;AACjE,IAAIT,EAAmB,WAAWA,EAAmB,QAAQ,SAASS,EAAM,MAAc,KAG1FZ,EAAU,EAAK;AAAA,EACjB,CAAC;AAED,QAAM,EAAE,cAAAa,GAAc,eAAAC,EAAA,IAAkBC;AAAA,IACtC;AAAA,MACE,QAAAhB;AAAA,MACA,eAAe;AAAA,MACf,SAAS,MAAMC,EAAU,EAAK;AAAA,IAAA;AAAA,IAEhCG;AAAA,EAAA;AAGF,EAAAa,EAAiB,EAAE,YAAY,CAACjB,KAAU,CAACL,GAAoB,SAAS;AAExE,QAAMuB,IACJ,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,QAAQ5B;AAAA,MACR,cAAAC;AAAA,MACA,KAAKW;AAAA,MAEJ,GAAIR,EAAsB,WAAW,IAClC;AAAA,QACE,OAAO;AAAA,UACL,KAAKA,EAAsB,CAAC;AAAA,UAC5B,MAAMA,EAAsB,CAAC;AAAA,QAAA;AAAA,MAC/B,IAEF,CAAA;AAAA,MAEH,UAAAS,EAAW,IAAI,CAACgB,MACf,gBAAAF;AAAA,QAACG;AAAA,QAAA;AAAA,UAEC,aAAAD;AAAA,UACA,OAAAjC;AAAA,UACA,UAAU,OAAOiC,CAAW,KAAKhC;AAAA,UACjC,gBAAAQ;AAAA,UACA,mBAAAC;AAAA,UACA,cAAAJ;AAAA,UACA,WAAAO;AAAA,QAAA;AAAA,QAPKoB;AAAA,MAAA,CASR;AAAA,IAAA;AAAA,EAAA;AAIL,SACE,gBAAAE,EAAC,SAAI,WAAWC,EAAO,eAAe,GAAG,UAAU,IAAI,KAAKtB,GAC1D,UAAA;AAAA,IAAA,gBAAAiB,EAACM,GAAA,EAAmB,OAAOd,EAAA,GAAkB,SAAS,MAAMV,EAAU,CAACD,CAAM,GAAG;AAAA,IAE/EA,MACEL,GAAoB,UACjB+B;AAAA,MACE,gBAAAP,EAACQ,KACC,UAAA,gBAAAR,EAACS,GAAA,EAAU,GAAGb,GACZ,UAAA,gBAAAI,EAACU,KAAW,SAAO,IAAC,cAAY,IAAC,WAAS,IACxC,UAAA,gBAAAV,EAAC,OAAA,EAAK,GAAGL,GAAe,UAAAI,EAAA,CAAW,EAAA,CACrC,EAAA,CACF,EAAA,CACF;AAAA,MACAvB,EAAmB;AAAA,IAAA,IAErBuB;AAAA,EAAA,GACR;AAEJ;"}
1
+ {"version":3,"file":"WeekSelector.js","sources":["../../../src/components/WeekSelector/WeekSelector.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { OverlayContainer, useOverlay, usePreventScroll } from '@react-aria/overlays';\r\nimport { FocusScope } from '@react-aria/focus';\r\n\r\nimport type { CSSProperties, RefObject } from 'react';\r\n\r\nimport { WeekSelectorButton } from './components/WeekSelectorButton';\r\nimport { WeekSelectorOptionContainer } from './components/WeekSelectorOptionContainer';\r\nimport { WeekSelectorOption } from './components/WeekSelectorOption';\r\nimport styles from './WeekSelector.module.css';\r\n\r\nimport { Backdrop } from 'components/Backdrop';\r\nimport { useOnClickOutside } from 'components/hooks/useOnClickOutside';\r\n\r\nexport type PeriodWeek = {\r\n academicWeekNumber: number;\r\n calendarWeekNumber: number;\r\n isBlocked: boolean;\r\n period: number;\r\n startDate: string;\r\n endDate: string;\r\n weekNumber: number;\r\n};\r\n\r\nexport interface WeekSelectorProps {\r\n /** Object with periodnumbers with array of weeks in period */\r\n weeks: Record<string, PeriodWeek[]>;\r\n /** Current period to disable previous periods */\r\n currentPeriod?: number;\r\n /** Default selected week */\r\n defaultSelection?: number;\r\n /** Prefix for the week button label */\r\n weekPrefix: string;\r\n /** Labels for each period */\r\n periodLabels: string[];\r\n /** Header text for the options container */\r\n optionsHeader: string;\r\n /** Callback function when a week is selected */\r\n onSelectWeek: (weeknumber: number) => void;\r\n /** Ref for the dropdown portal target */\r\n portalContainerRef?: RefObject<HTMLElement | null>;\r\n /** Optional WeekSelectorOptionContainer offset values [top, bottom] */\r\n optionContainerOffset?: number[];\r\n}\r\n\r\nexport const WeekSelector = ({\r\n weeks,\r\n currentPeriod = 0,\r\n defaultSelection,\r\n weekPrefix,\r\n optionsHeader,\r\n periodLabels,\r\n onSelectWeek,\r\n portalContainerRef,\r\n optionContainerOffset = [],\r\n}: WeekSelectorProps) => {\r\n const [selectedOption, setSelectedOption] = useState<number | null>(null);\r\n const [isOpen, setIsOpen] = useState<boolean>(false);\r\n const wrapperRef = useRef<HTMLDivElement>(null);\r\n const optionContainerRef = useRef<HTMLDivElement>(null);\r\n const periodKeys = useMemo(() => Object.keys(weeks ?? {}), [weeks]);\r\n\r\n useEffect(() => {\r\n if (defaultSelection) {\r\n for (const period in weeks) {\r\n if (\r\n weeks[period].some((week) => week.calendarWeekNumber === defaultSelection && !week.isBlocked) &&\r\n Number(period) > currentPeriod\r\n ) {\r\n setSelectedOption(defaultSelection);\r\n return;\r\n }\r\n }\r\n }\r\n for (const period in weeks) {\r\n const firstAvailableWeek = weeks[period].find((week) => !week.isBlocked);\r\n if (firstAvailableWeek && Number(period) > currentPeriod) {\r\n setSelectedOption(firstAvailableWeek.calendarWeekNumber);\r\n return;\r\n }\r\n }\r\n }, [weeks, currentPeriod, defaultSelection]);\r\n\r\n useEffect(() => {\r\n if (isOpen) {\r\n requestAnimationFrame(() => {\r\n const selectedButton = optionContainerRef.current?.querySelector<HTMLButtonElement>(\r\n `.${styles['week-selector-option-week--selected']}`\r\n );\r\n if (selectedButton) {\r\n selectedButton.focus();\r\n } else {\r\n optionContainerRef.current?.querySelector<HTMLButtonElement>('button:not(:disabled)')?.focus();\r\n }\r\n });\r\n }\r\n }, [isOpen, selectedOption]);\r\n\r\n const getButtonLabel = () => {\r\n const weekNumber = selectedOption ?? defaultSelection ?? '?';\r\n return `${weekPrefix} ${weekNumber}`;\r\n };\r\n\r\n useOnClickOutside(wrapperRef as RefObject<HTMLElement>, (event) => {\r\n if (optionContainerRef.current && optionContainerRef.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n setIsOpen(false);\r\n });\r\n\r\n const { overlayProps, underlayProps } = useOverlay(\r\n {\r\n isOpen,\r\n isDismissable: true,\r\n onClose: () => setIsOpen(false),\r\n },\r\n optionContainerRef\r\n );\r\n\r\n usePreventScroll({ isDisabled: !isOpen || !portalContainerRef?.current });\r\n\r\n const OptionList = (\r\n <WeekSelectorOptionContainer\r\n header={optionsHeader}\r\n periodLabels={periodLabels}\r\n ref={optionContainerRef}\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n {...(optionContainerOffset.length === 2\r\n ? {\r\n style: {\r\n top: optionContainerOffset[0],\r\n left: optionContainerOffset[1],\r\n } as CSSProperties,\r\n }\r\n : {})}\r\n >\r\n {periodKeys.map((periodIndex) => (\r\n <WeekSelectorOption\r\n key={periodIndex}\r\n periodIndex={periodIndex}\r\n weeks={weeks}\r\n disabled={Number(periodIndex) <= currentPeriod}\r\n selectedOption={selectedOption}\r\n setSelectedOption={setSelectedOption}\r\n onSelectWeek={onSelectWeek}\r\n setIsOpen={setIsOpen}\r\n />\r\n ))}\r\n </WeekSelectorOptionContainer>\r\n );\r\n\r\n return (\r\n <div className={styles['week-selector']} tabIndex={-1} ref={wrapperRef}>\r\n <WeekSelectorButton label={getButtonLabel()} onClick={() => setIsOpen(!isOpen)} />\r\n\r\n {isOpen &&\r\n (portalContainerRef?.current\r\n ? createPortal(\r\n <OverlayContainer>\r\n <Backdrop {...underlayProps}>\r\n <FocusScope contain restoreFocus>\r\n <div {...overlayProps}>{OptionList}</div>\r\n </FocusScope>\r\n </Backdrop>\r\n </OverlayContainer>,\r\n portalContainerRef.current\r\n )\r\n : OptionList)}\r\n </div>\r\n );\r\n};\r\n"],"names":["WeekSelector","weeks","currentPeriod","defaultSelection","weekPrefix","optionsHeader","periodLabels","onSelectWeek","portalContainerRef","optionContainerOffset","selectedOption","setSelectedOption","useState","isOpen","setIsOpen","wrapperRef","useRef","optionContainerRef","periodKeys","useMemo","useEffect","period","week","firstAvailableWeek","selectedButton","styles","getButtonLabel","useOnClickOutside","event","overlayProps","underlayProps","useOverlay","usePreventScroll","OptionList","jsx","WeekSelectorOptionContainer","periodIndex","WeekSelectorOption","jsxs","WeekSelectorButton","createPortal","OverlayContainer","Backdrop","FocusScope"],"mappings":";;;;;;;;;;;AA8CO,MAAMA,IAAe,CAAC;AAAA,EAC3B,OAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,uBAAAC,IAAwB,CAAA;AAC1B,MAAyB;AACvB,QAAM,CAACC,GAAgBC,CAAiB,IAAIC,EAAwB,IAAI,GAClE,CAACC,GAAQC,CAAS,IAAIF,EAAkB,EAAK,GAC7CG,IAAaC,EAAuB,IAAI,GACxCC,IAAqBD,EAAuB,IAAI,GAChDE,IAAaC,EAAQ,MAAM,OAAO,KAAKlB,KAAS,CAAA,CAAE,GAAG,CAACA,CAAK,CAAC;AAElE,EAAAmB,EAAU,MAAM;AACd,QAAIjB;AACF,iBAAWkB,KAAUpB;AACnB,YACEA,EAAMoB,CAAM,EAAE,KAAK,CAACC,MAASA,EAAK,uBAAuBnB,KAAoB,CAACmB,EAAK,SAAS,KAC5F,OAAOD,CAAM,IAAInB,GACjB;AACA,UAAAS,EAAkBR,CAAgB;AAClC;AAAA,QACF;AAAA;AAGJ,eAAWkB,KAAUpB,GAAO;AAC1B,YAAMsB,IAAqBtB,EAAMoB,CAAM,EAAE,KAAK,CAACC,MAAS,CAACA,EAAK,SAAS;AACvE,UAAIC,KAAsB,OAAOF,CAAM,IAAInB,GAAe;AACxD,QAAAS,EAAkBY,EAAmB,kBAAkB;AACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAACtB,GAAOC,GAAeC,CAAgB,CAAC,GAE3CiB,EAAU,MAAM;AACd,IAAIP,KACF,sBAAsB,MAAM;AAC1B,YAAMW,IAAiBP,EAAmB,SAAS;AAAA,QACjD,IAAIQ,EAAO,qCAAqC,CAAC;AAAA,MAAA;AAEnD,MAAID,IACFA,EAAe,MAAA,IAEfP,EAAmB,SAAS,cAAiC,uBAAuB,GAAG,MAAA;AAAA,IAE3F,CAAC;AAAA,EAEL,GAAG,CAACJ,GAAQH,CAAc,CAAC;AAE3B,QAAMgB,IAAiB,MAEd,GAAGtB,CAAU,IADDM,KAAkBP,KAAoB,GACvB;AAGpC,EAAAwB,EAAkBZ,GAAsC,CAACa,MAAU;AACjE,IAAIX,EAAmB,WAAWA,EAAmB,QAAQ,SAASW,EAAM,MAAc,KAG1Fd,EAAU,EAAK;AAAA,EACjB,CAAC;AAED,QAAM,EAAE,cAAAe,GAAc,eAAAC,EAAA,IAAkBC;AAAA,IACtC;AAAA,MACE,QAAAlB;AAAA,MACA,eAAe;AAAA,MACf,SAAS,MAAMC,EAAU,EAAK;AAAA,IAAA;AAAA,IAEhCG;AAAA,EAAA;AAGF,EAAAe,EAAiB,EAAE,YAAY,CAACnB,KAAU,CAACL,GAAoB,SAAS;AAExE,QAAMyB,IACJ,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,QAAQ9B;AAAA,MACR,cAAAC;AAAA,MACA,KAAKW;AAAA,MAEJ,GAAIR,EAAsB,WAAW,IAClC;AAAA,QACE,OAAO;AAAA,UACL,KAAKA,EAAsB,CAAC;AAAA,UAC5B,MAAMA,EAAsB,CAAC;AAAA,QAAA;AAAA,MAC/B,IAEF,CAAA;AAAA,MAEH,UAAAS,EAAW,IAAI,CAACkB,MACf,gBAAAF;AAAA,QAACG;AAAA,QAAA;AAAA,UAEC,aAAAD;AAAA,UACA,OAAAnC;AAAA,UACA,UAAU,OAAOmC,CAAW,KAAKlC;AAAA,UACjC,gBAAAQ;AAAA,UACA,mBAAAC;AAAA,UACA,cAAAJ;AAAA,UACA,WAAAO;AAAA,QAAA;AAAA,QAPKsB;AAAA,MAAA,CASR;AAAA,IAAA;AAAA,EAAA;AAIL,SACE,gBAAAE,EAAC,SAAI,WAAWb,EAAO,eAAe,GAAG,UAAU,IAAI,KAAKV,GAC1D,UAAA;AAAA,IAAA,gBAAAmB,EAACK,GAAA,EAAmB,OAAOb,EAAA,GAAkB,SAAS,MAAMZ,EAAU,CAACD,CAAM,GAAG;AAAA,IAE/EA,MACEL,GAAoB,UACjBgC;AAAA,wBACGC,GAAA,EACC,UAAA,gBAAAP,EAACQ,KAAU,GAAGZ,GACZ,4BAACa,GAAA,EAAW,SAAO,IAAC,cAAY,IAC9B,4BAAC,OAAA,EAAK,GAAGd,GAAe,UAAAI,EAAA,CAAW,GACrC,GACF,EAAA,CACF;AAAA,MACAzB,EAAmB;AAAA,IAAA,IAErByB;AAAA,EAAA,GACR;AAEJ;"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@uva-glass/component-library",
3
3
  "author": "Team Glass - Frontend vrienden",
4
4
  "private": false,
5
- "version": "3.50.1",
5
+ "version": "3.50.3",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",