@uva-glass/component-library 2.0.2 → 2.1.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.
- package/dist/SelectListbox.module-D-jCitTr.js +25 -0
- package/dist/SelectListbox.module-D-jCitTr.js.map +1 -0
- package/dist/assets/FormInput.css +1 -1
- package/dist/assets/InputField.css +1 -1
- package/dist/assets/SelectListbox.css +1 -1
- package/dist/components/FormInput/FormInput.d.ts +4 -1
- package/dist/components/FormInput/FormInput.js +34 -33
- package/dist/components/FormInput/FormInput.js.map +1 -1
- package/dist/components/FormInput/FormInput.stories.d.ts +1 -0
- package/dist/components/FormInput/FormInput.stories.js +28 -13
- package/dist/components/FormInput/FormInput.stories.js.map +1 -1
- package/dist/components/InputField/InputField.d.ts +2 -0
- package/dist/components/InputField/InputField.js +34 -22
- package/dist/components/InputField/InputField.js.map +1 -1
- package/dist/components/SelectListbox/SelectListBox.stories.js +2 -2
- package/dist/components/SelectListbox/SelectListBox.stories.js.map +1 -1
- package/dist/components/SelectListbox/SelectListbox.d.ts +5 -3
- package/dist/components/SelectListbox/SelectListbox.js +31 -29
- package/dist/components/SelectListbox/SelectListbox.js.map +1 -1
- package/dist/components/SelectListbox/components/SelectButton.d.ts +2 -2
- package/dist/components/SelectListbox/components/SelectButton.js +1 -1
- package/dist/components/SelectListbox/components/SelectButton.js.map +1 -1
- package/dist/components/SelectListbox/components/SelectContainer.js +1 -1
- package/dist/components/SelectListbox/components/SelectOption.js +1 -1
- package/dist/components/SelectListbox/components/SelectOptionBox.js +1 -1
- package/dist/components/hooks/usePositionedFloaters.d.ts +1 -0
- package/dist/components/hooks/usePositionedFloaters.js +22 -20
- package/dist/components/hooks/usePositionedFloaters.js.map +1 -1
- package/package.json +3 -3
- package/dist/SelectListbox.module-CdK9mQmJ.js +0 -23
- package/dist/SelectListbox.module-CdK9mQmJ.js.map +0 -1
|
@@ -14,9 +14,11 @@ export interface SelectListboxProps {
|
|
|
14
14
|
/** `true` to render the labels in bold; otherwise, `false`. The default is `false`. */
|
|
15
15
|
buttonLabelBold?: boolean;
|
|
16
16
|
/** The variant of the select box. */
|
|
17
|
-
variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight';
|
|
17
|
+
variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight' | 'darkBorder';
|
|
18
|
+
/** If true sets the option dropdown min-width to the width of the select button. */
|
|
19
|
+
fullWidth?: boolean;
|
|
18
20
|
/** The size of the select box. */
|
|
19
|
-
size?: 'small' | 'default';
|
|
21
|
+
size?: 'small' | 'medium' | 'default';
|
|
20
22
|
/** `true` to align the right side of the options with the select box; otherwise, `false` to align on the left side. */
|
|
21
23
|
optionPositionRight?: boolean;
|
|
22
24
|
/** The breakpoint at which to switch to the mobile view. */
|
|
@@ -26,6 +28,6 @@ export interface SelectListboxProps {
|
|
|
26
28
|
}
|
|
27
29
|
/** Represents a component to render a select list box. */
|
|
28
30
|
export declare const SelectListbox: {
|
|
29
|
-
({ options, variant, size, optionPositionRight, defaultValue, maxOptionHeight, disabled, buttonLabelProp, buttonLabelBold, onChange, children, }: PropsWithChildren<SelectListboxProps>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
({ options, variant, fullWidth, size, optionPositionRight, defaultValue, maxOptionHeight, disabled, buttonLabelProp, buttonLabelBold, onChange, children, }: PropsWithChildren<SelectListboxProps>): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
SelectOption: ({ option, index, children }: import('./components/SelectOption').SelectOptionProps) => import("react/jsx-runtime").JSX.Element;
|
|
31
33
|
};
|
|
@@ -1,50 +1,52 @@
|
|
|
1
|
-
import { jsx as e, jsxs as
|
|
1
|
+
import { jsx as e, jsxs as b } from "react/jsx-runtime";
|
|
2
2
|
import { useState as t } from "react";
|
|
3
|
-
import { SelectProvider as
|
|
4
|
-
import { SelectButton as
|
|
5
|
-
import { SelectContainer as
|
|
6
|
-
import { SelectOptionBox as
|
|
7
|
-
import { SelectOption as
|
|
8
|
-
import { usePositionedFloaters as
|
|
9
|
-
const
|
|
3
|
+
import { SelectProvider as P } from "./SelectProvider.js";
|
|
4
|
+
import { SelectButton as B } from "./components/SelectButton.js";
|
|
5
|
+
import { SelectContainer as O } from "./components/SelectContainer.js";
|
|
6
|
+
import { SelectOptionBox as g } from "./components/SelectOptionBox.js";
|
|
7
|
+
import { SelectOption as j } from "./components/SelectOption.js";
|
|
8
|
+
import { usePositionedFloaters as k } from "../hooks/usePositionedFloaters.js";
|
|
9
|
+
const v = ({
|
|
10
10
|
options: o,
|
|
11
11
|
variant: i,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
fullWidth: r = !1,
|
|
13
|
+
size: n = "default",
|
|
14
|
+
optionPositionRight: l,
|
|
15
|
+
defaultValue: m = -1,
|
|
16
|
+
maxOptionHeight: s,
|
|
17
|
+
disabled: f,
|
|
17
18
|
buttonLabelProp: c = "label",
|
|
18
|
-
buttonLabelBold:
|
|
19
|
-
onChange:
|
|
19
|
+
buttonLabelBold: p,
|
|
20
|
+
onChange: a,
|
|
20
21
|
children: S
|
|
21
22
|
}) => {
|
|
22
|
-
const [
|
|
23
|
+
const [u, x] = t(null), [d, h] = t(null), { style: E } = k(u, d, {
|
|
23
24
|
mouseEvent: "click",
|
|
24
25
|
position: "bottomLeft",
|
|
25
26
|
offset: 4,
|
|
26
|
-
maxFixedHeight:
|
|
27
|
-
horizontalPosition:
|
|
28
|
-
mobileBreakpoint: "28rem"
|
|
27
|
+
maxFixedHeight: s,
|
|
28
|
+
horizontalPosition: l ? "right" : "left",
|
|
29
|
+
mobileBreakpoint: "28rem",
|
|
30
|
+
fullWidth: r
|
|
29
31
|
});
|
|
30
|
-
return /* @__PURE__ */ e(
|
|
32
|
+
return /* @__PURE__ */ e(P, { options: o, defaultValue: m, children: /* @__PURE__ */ b(O, { children: [
|
|
31
33
|
/* @__PURE__ */ e(
|
|
32
|
-
|
|
34
|
+
B,
|
|
33
35
|
{
|
|
34
|
-
disabled:
|
|
36
|
+
disabled: f,
|
|
35
37
|
buttonLabelProp: c,
|
|
36
|
-
buttonLabelBold:
|
|
38
|
+
buttonLabelBold: p,
|
|
37
39
|
variant: i,
|
|
38
|
-
size:
|
|
39
|
-
onChange:
|
|
40
|
-
ref:
|
|
40
|
+
size: n,
|
|
41
|
+
onChange: a,
|
|
42
|
+
ref: h
|
|
41
43
|
}
|
|
42
44
|
),
|
|
43
|
-
/* @__PURE__ */ e(
|
|
45
|
+
/* @__PURE__ */ e(g, { ref: x, ...E, children: S })
|
|
44
46
|
] }) });
|
|
45
47
|
};
|
|
46
|
-
|
|
48
|
+
v.SelectOption = j;
|
|
47
49
|
export {
|
|
48
|
-
|
|
50
|
+
v as SelectListbox
|
|
49
51
|
};
|
|
50
52
|
//# sourceMappingURL=SelectListbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectListbox.js","sources":["../../../src/components/SelectListbox/SelectListbox.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport type { PropsWithChildren } from 'react';\nimport type { OptionValue, SelectValue } from './SelectProvider';\n\nimport { SelectProvider } from './SelectProvider';\nimport { SelectButton } from './components/SelectButton';\nimport { SelectContainer } from './components/SelectContainer';\nimport { SelectOptionBox } from './components/SelectOptionBox';\nimport { SelectOption } from './components/SelectOption';\n\nimport { usePositionedFloaters } from 'components/hooks/usePositionedFloaters';\n\nexport interface SelectListboxProps {\n /** The possible options to select. */\n options: OptionValue[];\n /** The selected value by default. */\n defaultValue?: SelectValue;\n /** The max height of the options. */\n maxOptionHeight?: `${number}${'px' | 'rem'}`;\n /** `true` to disable the select box; otherwise, `false`. The default is `false`. */\n disabled?: boolean;\n /** The name of the property in the options structure that contains the label of the options. */\n buttonLabelProp?: string;\n /** `true` to render the labels in bold; otherwise, `false`. The default is `false`. */\n buttonLabelBold?: boolean;\n /** The variant of the select box. */\n variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight';\n /** The size of the select box. */\n size?: 'small' | 'default';\n /** `true` to align the right side of the options with the select box; otherwise, `false` to align on the left side. */\n optionPositionRight?: boolean;\n /** The breakpoint at which to switch to the mobile view. */\n mobileBreakpoint?: `${number}${'px' | 'rem'}`;\n /** The callback function that is invoked when an option is selected. */\n onChange?: (option: OptionValue) => void;\n}\n\n/** Represents a component to render a select list box. */\nexport const SelectListbox = ({\n options,\n variant,\n size = 'default',\n optionPositionRight,\n defaultValue = -1,\n maxOptionHeight,\n disabled,\n buttonLabelProp = 'label',\n buttonLabelBold,\n onChange,\n children,\n}: PropsWithChildren<SelectListboxProps>) => {\n const [positionElement, setPositionElement] = useState<HTMLElement | null>(null);\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n const { style: positionStyle } = usePositionedFloaters(positionElement, referenceElement, {\n mouseEvent: 'click',\n position: 'bottomLeft',\n offset: 4,\n maxFixedHeight: maxOptionHeight,\n horizontalPosition: optionPositionRight ? 'right' : 'left',\n mobileBreakpoint: '28rem',\n });\n\n return (\n <SelectProvider options={options} defaultValue={defaultValue}>\n <SelectContainer>\n <SelectButton\n disabled={disabled}\n buttonLabelProp={buttonLabelProp}\n buttonLabelBold={buttonLabelBold}\n variant={variant}\n size={size}\n onChange={onChange}\n ref={setReferenceElement}\n />\n\n <SelectOptionBox ref={setPositionElement} {...positionStyle}>\n {children}\n </SelectOptionBox>\n </SelectContainer>\n </SelectProvider>\n );\n};\n\nSelectListbox.SelectOption = SelectOption;\n"],"names":["SelectListbox","options","variant","size","optionPositionRight","defaultValue","maxOptionHeight","disabled","buttonLabelProp","buttonLabelBold","onChange","children","positionElement","setPositionElement","useState","referenceElement","setReferenceElement","positionStyle","usePositionedFloaters","jsx","SelectProvider","SelectContainer","SelectButton","SelectOptionBox","SelectOption"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"SelectListbox.js","sources":["../../../src/components/SelectListbox/SelectListbox.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport type { PropsWithChildren } from 'react';\nimport type { OptionValue, SelectValue } from './SelectProvider';\n\nimport { SelectProvider } from './SelectProvider';\nimport { SelectButton } from './components/SelectButton';\nimport { SelectContainer } from './components/SelectContainer';\nimport { SelectOptionBox } from './components/SelectOptionBox';\nimport { SelectOption } from './components/SelectOption';\n\nimport { usePositionedFloaters } from 'components/hooks/usePositionedFloaters';\n\nexport interface SelectListboxProps {\n /** The possible options to select. */\n options: OptionValue[];\n /** The selected value by default. */\n defaultValue?: SelectValue;\n /** The max height of the options. */\n maxOptionHeight?: `${number}${'px' | 'rem'}`;\n /** `true` to disable the select box; otherwise, `false`. The default is `false`. */\n disabled?: boolean;\n /** The name of the property in the options structure that contains the label of the options. */\n buttonLabelProp?: string;\n /** `true` to render the labels in bold; otherwise, `false`. The default is `false`. */\n buttonLabelBold?: boolean;\n /** The variant of the select box. */\n variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight' | 'darkBorder';\n /** If true sets the option dropdown min-width to the width of the select button. */\n fullWidth?: boolean;\n /** The size of the select box. */\n size?: 'small' | 'medium' | 'default';\n /** `true` to align the right side of the options with the select box; otherwise, `false` to align on the left side. */\n optionPositionRight?: boolean;\n /** The breakpoint at which to switch to the mobile view. */\n mobileBreakpoint?: `${number}${'px' | 'rem'}`;\n /** The callback function that is invoked when an option is selected. */\n onChange?: (option: OptionValue) => void;\n}\n\n/** Represents a component to render a select list box. */\nexport const SelectListbox = ({\n options,\n variant,\n fullWidth = false,\n size = 'default',\n optionPositionRight,\n defaultValue = -1,\n maxOptionHeight,\n disabled,\n buttonLabelProp = 'label',\n buttonLabelBold,\n onChange,\n children,\n}: PropsWithChildren<SelectListboxProps>) => {\n const [positionElement, setPositionElement] = useState<HTMLElement | null>(null);\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n const { style: positionStyle } = usePositionedFloaters(positionElement, referenceElement, {\n mouseEvent: 'click',\n position: 'bottomLeft',\n offset: 4,\n maxFixedHeight: maxOptionHeight,\n horizontalPosition: optionPositionRight ? 'right' : 'left',\n mobileBreakpoint: '28rem',\n fullWidth,\n });\n\n return (\n <SelectProvider options={options} defaultValue={defaultValue}>\n <SelectContainer>\n <SelectButton\n disabled={disabled}\n buttonLabelProp={buttonLabelProp}\n buttonLabelBold={buttonLabelBold}\n variant={variant}\n size={size}\n onChange={onChange}\n ref={setReferenceElement}\n />\n\n <SelectOptionBox ref={setPositionElement} {...positionStyle}>\n {children}\n </SelectOptionBox>\n </SelectContainer>\n </SelectProvider>\n );\n};\n\nSelectListbox.SelectOption = SelectOption;\n"],"names":["SelectListbox","options","variant","fullWidth","size","optionPositionRight","defaultValue","maxOptionHeight","disabled","buttonLabelProp","buttonLabelBold","onChange","children","positionElement","setPositionElement","useState","referenceElement","setReferenceElement","positionStyle","usePositionedFloaters","jsx","SelectProvider","SelectContainer","SelectButton","SelectOptionBox","SelectOption"],"mappings":";;;;;;;;AAyCO,MAAMA,IAAgB,CAAC;AAAA,EAC5B,SAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,MAAAC,IAAO;AAAA,EACP,qBAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,iBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,iBAAAC,IAAkB;AAAA,EAClB,iBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AACF,MAA6C;AAC3C,QAAM,CAACC,GAAiBC,CAAkB,IAAIC,EAA6B,IAAI,GACzE,CAACC,GAAkBC,CAAmB,IAAIF,EAA6B,IAAI,GAC3E,EAAE,OAAOG,EAAA,IAAkBC,EAAsBN,GAAiBG,GAAkB;AAAA,IACxF,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,gBAAgBT;AAAA,IAChB,oBAAoBF,IAAsB,UAAU;AAAA,IACpD,kBAAkB;AAAA,IAClB,WAAAF;AAAA,EAAA,CACD;AAED,SACG,gBAAAiB,EAAAC,GAAA,EAAe,SAAApB,GAAkB,cAAAK,GAChC,4BAACgB,GACC,EAAA,UAAA;AAAA,IAAA,gBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,UAAAf;AAAA,QACA,iBAAAC;AAAA,QACA,iBAAAC;AAAA,QACA,SAAAR;AAAA,QACA,MAAAE;AAAA,QACA,UAAAO;AAAA,QACA,KAAKM;AAAA,MAAA;AAAA,IACP;AAAA,sBAECO,GAAgB,EAAA,KAAKV,GAAqB,GAAGI,GAC3C,UAAAN,EACH,CAAA;AAAA,EAAA,EAAA,CACF,EACF,CAAA;AAEJ;AAEAZ,EAAc,eAAeyB;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OptionValue } from 'components/SelectListbox/SelectProvider';
|
|
2
2
|
export interface SelectButtonProps {
|
|
3
|
-
variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight';
|
|
4
|
-
size?: 'small' | 'default';
|
|
3
|
+
variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight' | 'darkBorder';
|
|
4
|
+
size?: 'small' | 'medium' | 'default';
|
|
5
5
|
onChange?: (option: OptionValue) => void;
|
|
6
6
|
buttonLabelProp?: string;
|
|
7
7
|
buttonLabelBold?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as a, jsxs as C } from "react/jsx-runtime";
|
|
2
2
|
import { c as f } from "../../../clsx-OuTLNxxd.js";
|
|
3
3
|
import { forwardRef as E, useRef as g, useEffect as c } from "react";
|
|
4
|
-
import { s as t } from "../../../SelectListbox.module-
|
|
4
|
+
import { s as t } from "../../../SelectListbox.module-D-jCitTr.js";
|
|
5
5
|
import { Icon as L } from "../../Icon/Icon.js";
|
|
6
6
|
import { useSelect as N } from "../SelectProvider.js";
|
|
7
7
|
const O = E((d, u) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectButton.js","sources":["../../../../src/components/SelectListbox/components/SelectButton.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, forwardRef } from 'react';\n\nimport type { KeyboardEvent } from 'react';\nimport type { OptionValue, SelectValue } from 'components/SelectListbox/SelectProvider';\n\nimport styles from 'components/SelectListbox/SelectListbox.module.css';\nimport { Icon } from 'components/Icon';\nimport { useSelect } from 'components/SelectListbox/SelectProvider';\n\nexport interface SelectButtonProps {\n variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight';\n size?: 'small' | 'default';\n onChange?: (option: OptionValue) => void;\n buttonLabelProp?: string;\n buttonLabelBold?: boolean;\n disabled?: boolean;\n}\n\nexport const SelectButton = forwardRef<HTMLButtonElement, SelectButtonProps>((props, ref) => {\n const { variant, size = 'default', onChange, buttonLabelProp = 'label', buttonLabelBold, disabled = false } = props;\n const buttonWrapper = useRef<HTMLSpanElement>(null);\n const isFirstRender = useRef(true);\n const { listboxId, isOpen, selectedValue, toggleListbox, setIsOpen, setActiveIndex, options } = useSelect() || {};\n\n const onTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n switch (event.key) {\n case 'Enter':\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n return;\n }\n break;\n case 'Escape':\n if (isOpen) {\n event.stopPropagation();\n setActiveIndex(options.findIndex((option) => option.value === selectedValue?.value));\n setIsOpen(false);\n }\n break;\n }\n };\n\n useEffect(() => {\n isOpen\n ? (buttonWrapper.current?.children[0] as HTMLButtonElement).blur()\n : !isFirstRender.current && (buttonWrapper.current?.children[0] as HTMLButtonElement).focus();\n }, [isOpen]);\n\n useEffect(() => {\n isFirstRender.current = false;\n\n return () => {\n isFirstRender.current = true;\n };\n }, []);\n\n useEffect(() => {\n if (onChange) onChange(selectedValue);\n }, [onChange, selectedValue]);\n\n return (\n <span ref={buttonWrapper}>\n <button\n className={clsx(styles['select-listbox-trigger'], styles[`select-listbox-trigger--${size}`], {\n [styles[`select-listbox-trigger--${variant}`]]: variant,\n [styles['select-listbox-trigger--bold']]: buttonLabelBold,\n })}\n type=\"button\"\n onClick={toggleListbox}\n onKeyDown={onTriggerKeyDown}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-label={`${selectedValue.label}`}\n disabled={disabled}\n aria-controls={listboxId}\n {...(ref && { ref: ref })}\n >\n <span className={styles['select-listbox-trigger-label']}>\n {selectedValue[buttonLabelProp as keyof SelectValue]}\n </span>\n\n <Icon\n className={clsx(styles['select-listbox-trigger-icon'], {\n [styles['select-listbox-trigger-icon--open']]: isOpen,\n })}\n name=\"CheveronDown\"\n size={16}\n />\n </button>\n </span>\n );\n});\n"],"names":["SelectButton","forwardRef","props","ref","variant","size","onChange","buttonLabelProp","buttonLabelBold","disabled","buttonWrapper","useRef","isFirstRender","listboxId","isOpen","selectedValue","toggleListbox","setIsOpen","setActiveIndex","options","useSelect","onTriggerKeyDown","event","option","useEffect","_a","_b","jsx","jsxs","clsx","styles","Icon"],"mappings":";;;;;;AAmBO,MAAMA,IAAeC,EAAiD,CAACC,GAAOC,MAAQ;AACrF,QAAA,EAAE,SAAAC,GAAS,MAAAC,IAAO,WAAW,UAAAC,GAAU,iBAAAC,IAAkB,SAAS,iBAAAC,GAAiB,UAAAC,IAAW,GAAU,IAAAP,GACxGQ,IAAgBC,EAAwB,IAAI,GAC5CC,IAAgBD,EAAO,EAAI,GAC3B,EAAE,WAAAE,GAAW,QAAAC,GAAQ,eAAAC,GAAe,eAAAC,GAAe,WAAAC,GAAW,gBAAAC,GAAgB,SAAAC,EAAQ,IAAIC,EAAU,KAAK,CAAC,GAE1GC,IAAmB,CAACC,MAA4C;AACpE,YAAQA,EAAM,KAAK;AAAA,MACjB,KAAK;AAEH,YADAA,EAAM,eAAe,GACjB,CAACR,GAAQ;AACX,UAAAG,EAAU,EAAI;AACd;AAAA,QAAA;AAEF;AAAA,MACF,KAAK;AACH,QAAIH,MACFQ,EAAM,gBAAgB,GACPJ,EAAAC,EAAQ,UAAU,CAACI,MAAWA,EAAO,WAAUR,KAAA,gBAAAA,EAAe,MAAK,CAAC,GACnFE,EAAU,EAAK;AAEjB;AAAA,IAAA;AAAA,EAEN;AAEA,SAAAO,EAAU,MAAM;;AACd,IAAAV,MACKW,IAAAf,EAAc,YAAd,gBAAAe,EAAuB,SAAS,IAAyB,KAAK,IAC/D,CAACb,EAAc,aAAYc,IAAAhB,EAAc,YAAd,gBAAAgB,EAAuB,SAAS,IAAyB,MAAM;AAAA,EAAA,GAC7F,CAACZ,CAAM,CAAC,GAEXU,EAAU,OACRZ,EAAc,UAAU,IAEjB,MAAM;AACX,IAAAA,EAAc,UAAU;AAAA,EAC1B,IACC,EAAE,GAELY,EAAU,MAAM;AACV,IAAAlB,OAAmBS,CAAa;AAAA,EAAA,GACnC,CAACT,GAAUS,CAAa,CAAC,GAG1B,gBAAAY,EAAC,QAAK,EAAA,KAAKjB,GACT,UAAA,gBAAAkB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAKC,EAAO,wBAAwB,GAAGA,EAAO,2BAA2BzB,CAAI,EAAE,GAAG;AAAA,QAC3F,CAACyB,EAAO,2BAA2B1B,CAAO,EAAE,CAAC,GAAGA;AAAA,QAChD,CAAC0B,EAAO,8BAA8B,CAAC,GAAGtB;AAAA,MAAA,CAC3C;AAAA,MACD,MAAK;AAAA,MACL,SAASQ;AAAA,MACT,WAAWK;AAAA,MACX,iBAAeP;AAAA,MACf,iBAAc;AAAA,MACd,cAAY,GAAGC,EAAc,KAAK;AAAA,MAClC,UAAAN;AAAA,MACA,iBAAeI;AAAA,MACd,GAAIV,KAAO,EAAE,KAAAA,EAAS;AAAA,MAEvB,UAAA;AAAA,QAAA,gBAAAwB,EAAC,UAAK,WAAWG,EAAO,8BAA8B,GACnD,UAAAf,EAAcR,CAAoC,GACrD;AAAA,QAEA,gBAAAoB;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,WAAWF,EAAKC,EAAO,6BAA6B,GAAG;AAAA,cACrD,CAACA,EAAO,mCAAmC,CAAC,GAAGhB;AAAA,YAAA,CAChD;AAAA,YACD,MAAK;AAAA,YACL,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,MACR;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ,CAAC;"}
|
|
1
|
+
{"version":3,"file":"SelectButton.js","sources":["../../../../src/components/SelectListbox/components/SelectButton.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, forwardRef } from 'react';\n\nimport type { KeyboardEvent } from 'react';\nimport type { OptionValue, SelectValue } from 'components/SelectListbox/SelectProvider';\n\nimport styles from 'components/SelectListbox/SelectListbox.module.css';\nimport { Icon } from 'components/Icon';\nimport { useSelect } from 'components/SelectListbox/SelectProvider';\n\nexport interface SelectButtonProps {\n variant?: 'noborder' | 'pill' | 'pillLeft' | 'pillRight' | 'darkBorder';\n size?: 'small' | 'medium' | 'default';\n onChange?: (option: OptionValue) => void;\n buttonLabelProp?: string;\n buttonLabelBold?: boolean;\n disabled?: boolean;\n}\n\nexport const SelectButton = forwardRef<HTMLButtonElement, SelectButtonProps>((props, ref) => {\n const { variant, size = 'default', onChange, buttonLabelProp = 'label', buttonLabelBold, disabled = false } = props;\n const buttonWrapper = useRef<HTMLSpanElement>(null);\n const isFirstRender = useRef(true);\n const { listboxId, isOpen, selectedValue, toggleListbox, setIsOpen, setActiveIndex, options } = useSelect() || {};\n\n const onTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n switch (event.key) {\n case 'Enter':\n event.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n return;\n }\n break;\n case 'Escape':\n if (isOpen) {\n event.stopPropagation();\n setActiveIndex(options.findIndex((option) => option.value === selectedValue?.value));\n setIsOpen(false);\n }\n break;\n }\n };\n\n useEffect(() => {\n isOpen\n ? (buttonWrapper.current?.children[0] as HTMLButtonElement).blur()\n : !isFirstRender.current && (buttonWrapper.current?.children[0] as HTMLButtonElement).focus();\n }, [isOpen]);\n\n useEffect(() => {\n isFirstRender.current = false;\n\n return () => {\n isFirstRender.current = true;\n };\n }, []);\n\n useEffect(() => {\n if (onChange) onChange(selectedValue);\n }, [onChange, selectedValue]);\n\n return (\n <span ref={buttonWrapper}>\n <button\n className={clsx(styles['select-listbox-trigger'], styles[`select-listbox-trigger--${size}`], {\n [styles[`select-listbox-trigger--${variant}`]]: variant,\n [styles['select-listbox-trigger--bold']]: buttonLabelBold,\n })}\n type=\"button\"\n onClick={toggleListbox}\n onKeyDown={onTriggerKeyDown}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-label={`${selectedValue.label}`}\n disabled={disabled}\n aria-controls={listboxId}\n {...(ref && { ref: ref })}\n >\n <span className={styles['select-listbox-trigger-label']}>\n {selectedValue[buttonLabelProp as keyof SelectValue]}\n </span>\n\n <Icon\n className={clsx(styles['select-listbox-trigger-icon'], {\n [styles['select-listbox-trigger-icon--open']]: isOpen,\n })}\n name=\"CheveronDown\"\n size={16}\n />\n </button>\n </span>\n );\n});\n"],"names":["SelectButton","forwardRef","props","ref","variant","size","onChange","buttonLabelProp","buttonLabelBold","disabled","buttonWrapper","useRef","isFirstRender","listboxId","isOpen","selectedValue","toggleListbox","setIsOpen","setActiveIndex","options","useSelect","onTriggerKeyDown","event","option","useEffect","_a","_b","jsx","jsxs","clsx","styles","Icon"],"mappings":";;;;;;AAmBO,MAAMA,IAAeC,EAAiD,CAACC,GAAOC,MAAQ;AACrF,QAAA,EAAE,SAAAC,GAAS,MAAAC,IAAO,WAAW,UAAAC,GAAU,iBAAAC,IAAkB,SAAS,iBAAAC,GAAiB,UAAAC,IAAW,GAAU,IAAAP,GACxGQ,IAAgBC,EAAwB,IAAI,GAC5CC,IAAgBD,EAAO,EAAI,GAC3B,EAAE,WAAAE,GAAW,QAAAC,GAAQ,eAAAC,GAAe,eAAAC,GAAe,WAAAC,GAAW,gBAAAC,GAAgB,SAAAC,EAAQ,IAAIC,EAAU,KAAK,CAAC,GAE1GC,IAAmB,CAACC,MAA4C;AACpE,YAAQA,EAAM,KAAK;AAAA,MACjB,KAAK;AAEH,YADAA,EAAM,eAAe,GACjB,CAACR,GAAQ;AACX,UAAAG,EAAU,EAAI;AACd;AAAA,QAAA;AAEF;AAAA,MACF,KAAK;AACH,QAAIH,MACFQ,EAAM,gBAAgB,GACPJ,EAAAC,EAAQ,UAAU,CAACI,MAAWA,EAAO,WAAUR,KAAA,gBAAAA,EAAe,MAAK,CAAC,GACnFE,EAAU,EAAK;AAEjB;AAAA,IAAA;AAAA,EAEN;AAEA,SAAAO,EAAU,MAAM;;AACd,IAAAV,MACKW,IAAAf,EAAc,YAAd,gBAAAe,EAAuB,SAAS,IAAyB,KAAK,IAC/D,CAACb,EAAc,aAAYc,IAAAhB,EAAc,YAAd,gBAAAgB,EAAuB,SAAS,IAAyB,MAAM;AAAA,EAAA,GAC7F,CAACZ,CAAM,CAAC,GAEXU,EAAU,OACRZ,EAAc,UAAU,IAEjB,MAAM;AACX,IAAAA,EAAc,UAAU;AAAA,EAC1B,IACC,EAAE,GAELY,EAAU,MAAM;AACV,IAAAlB,OAAmBS,CAAa;AAAA,EAAA,GACnC,CAACT,GAAUS,CAAa,CAAC,GAG1B,gBAAAY,EAAC,QAAK,EAAA,KAAKjB,GACT,UAAA,gBAAAkB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAKC,EAAO,wBAAwB,GAAGA,EAAO,2BAA2BzB,CAAI,EAAE,GAAG;AAAA,QAC3F,CAACyB,EAAO,2BAA2B1B,CAAO,EAAE,CAAC,GAAGA;AAAA,QAChD,CAAC0B,EAAO,8BAA8B,CAAC,GAAGtB;AAAA,MAAA,CAC3C;AAAA,MACD,MAAK;AAAA,MACL,SAASQ;AAAA,MACT,WAAWK;AAAA,MACX,iBAAeP;AAAA,MACf,iBAAc;AAAA,MACd,cAAY,GAAGC,EAAc,KAAK;AAAA,MAClC,UAAAN;AAAA,MACA,iBAAeI;AAAA,MACd,GAAIV,KAAO,EAAE,KAAAA,EAAS;AAAA,MAEvB,UAAA;AAAA,QAAA,gBAAAwB,EAAC,UAAK,WAAWG,EAAO,8BAA8B,GACnD,UAAAf,EAAcR,CAAoC,GACrD;AAAA,QAEA,gBAAAoB;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,WAAWF,EAAKC,EAAO,6BAA6B,GAAG;AAAA,cACrD,CAACA,EAAO,mCAAmC,CAAC,GAAGhB;AAAA,YAAA,CAChD;AAAA,YACD,MAAK;AAAA,YACL,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,MACR;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ,CAAC;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as c } from "react/jsx-runtime";
|
|
2
2
|
import { useRef as i, useCallback as u, useEffect as l } from "react";
|
|
3
3
|
import { useSelect as m } from "../SelectProvider.js";
|
|
4
|
-
import { s as f } from "../../../SelectListbox.module-
|
|
4
|
+
import { s as f } from "../../../SelectListbox.module-D-jCitTr.js";
|
|
5
5
|
const E = ({ children: o }) => {
|
|
6
6
|
const { isOpen: r, setIsOpen: n } = m(), t = i(null), e = u(
|
|
7
7
|
({ target: s }) => {
|
|
@@ -2,7 +2,7 @@ import { jsx as d } from "react/jsx-runtime";
|
|
|
2
2
|
import { c as v } from "../../../clsx-OuTLNxxd.js";
|
|
3
3
|
import { useRef as D, useEffect as p } from "react";
|
|
4
4
|
import { useSelect as y } from "../SelectProvider.js";
|
|
5
|
-
import { s as b } from "../../../SelectListbox.module-
|
|
5
|
+
import { s as b } from "../../../SelectListbox.module-D-jCitTr.js";
|
|
6
6
|
const S = ({ option: t, index: l, children: m }) => {
|
|
7
7
|
const o = D(null), { isOpen: r, activeIndex: s, setActiveIndex: c, selectedValue: f, setSelectedValue: u, setIsOpen: i, options: a } = y(), w = (e) => {
|
|
8
8
|
u(a[e]), i(!1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as s } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as m, useRef as x } from "react";
|
|
3
|
-
import { s as i } from "../../../SelectListbox.module-
|
|
3
|
+
import { s as i } from "../../../SelectListbox.module-D-jCitTr.js";
|
|
4
4
|
import { useSelect as a } from "../SelectProvider.js";
|
|
5
5
|
const h = m((l, e) => {
|
|
6
6
|
const { style: t, children: o } = l, { listboxId: r, isOpen: c } = a(), n = x(null);
|
|
@@ -13,6 +13,7 @@ interface optionProps {
|
|
|
13
13
|
maxFixedHeight?: `${number}${'px' | 'rem'}`;
|
|
14
14
|
horizontalPosition?: 'left' | 'right';
|
|
15
15
|
mobileBreakpoint?: `${number}${'px' | 'rem'}`;
|
|
16
|
+
fullWidth: boolean;
|
|
16
17
|
}
|
|
17
18
|
export declare function usePositionedFloaters<T extends HTMLElement = HTMLElement>(positionedElement: T | null, referenceElement: T | null, options: optionProps): positionProps;
|
|
18
19
|
export {};
|
|
@@ -1,62 +1,64 @@
|
|
|
1
|
-
import { useState as L, useEffect as
|
|
2
|
-
import { useDebounce as
|
|
3
|
-
const a = 10,
|
|
1
|
+
import { useState as L, useEffect as p } from "react";
|
|
2
|
+
import { useDebounce as F } from "./useDebounce.js";
|
|
3
|
+
const a = 10, y = 45, r = 300, B = 0, k = 768, D = 2;
|
|
4
4
|
function S(d, e, n) {
|
|
5
|
-
const [m, H] = L(!1),
|
|
5
|
+
const [m, H] = L(!1), w = {
|
|
6
6
|
inset: "0 auto auto 0",
|
|
7
7
|
opacity: 0,
|
|
8
8
|
maxHeight: "100%",
|
|
9
9
|
maxWidth: "100%",
|
|
10
|
+
minWidth: r,
|
|
10
11
|
overflowX: "hidden",
|
|
11
12
|
overflowY: "auto",
|
|
12
13
|
margin: "0rem"
|
|
13
|
-
}, [
|
|
14
|
+
}, [h, v] = L(w), l = (t) => {
|
|
14
15
|
const o = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
15
16
|
return t.indexOf("rem") !== -1 ? parseFloat(t) * o : parseFloat(t);
|
|
16
17
|
}, b = (t, o) => {
|
|
17
18
|
if (!t) return 0;
|
|
18
19
|
const i = o === "bottom" ? window.innerHeight - t.bottom - n.offset - a : t.top - n.offset - a;
|
|
19
|
-
return !n.maxFixedHeight ||
|
|
20
|
-
},
|
|
20
|
+
return !n.maxFixedHeight || l(n.maxFixedHeight) > i ? i : l(n.maxFixedHeight);
|
|
21
|
+
}, W = (t, o) => {
|
|
21
22
|
if (!t) return 0;
|
|
22
23
|
const i = o === "left" ? window.innerWidth - t.left - a : t.right - a;
|
|
23
|
-
return i <=
|
|
24
|
+
return i <= r ? r : i;
|
|
24
25
|
}, P = (t, o, i) => i ? `${t.left - Math.abs(o.width - t.width) / D}px` : `${t.left}px`, x = () => {
|
|
25
26
|
const t = d == null ? void 0 : d.getBoundingClientRect(), o = e == null ? void 0 : e.getBoundingClientRect();
|
|
26
27
|
let i = "bottom", u = "left";
|
|
27
28
|
const f = window.matchMedia(
|
|
28
|
-
`(max-width: ${n.mobileBreakpoint ?
|
|
29
|
+
`(max-width: ${n.mobileBreakpoint ? l(n.mobileBreakpoint) : k}px)`
|
|
29
30
|
).matches;
|
|
30
|
-
return !o || !t ?
|
|
31
|
+
return !o || !t ? w : (window.innerHeight - o.bottom - a < y && (i = "top"), (window.innerWidth - o.left - a < r || n.horizontalPosition === "right") && !f && (u = "right"), {
|
|
31
32
|
inset: `${i === "bottom" ? o[i] + "px" : "auto"}
|
|
32
33
|
${u === "right" ? window.innerWidth - o[u] + "px" : "auto"}
|
|
33
34
|
${i === "top" ? window.innerHeight - o[i] + "px" : "auto"}
|
|
34
35
|
${u === "left" ? P(o, t, f) : "auto"}`,
|
|
35
36
|
maxHeight: `${b(o, i)}px`,
|
|
36
|
-
maxWidth: `${
|
|
37
|
+
maxWidth: `${W(o, u)}px`,
|
|
38
|
+
minWidth: n.fullWidth ? o.width : r,
|
|
37
39
|
overflowX: "hidden",
|
|
38
40
|
overflowY: "auto",
|
|
39
41
|
opacity: 1,
|
|
40
42
|
margin: `${n.offset}px 0`
|
|
41
43
|
});
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
...
|
|
44
|
+
}, c = () => {
|
|
45
|
+
v({
|
|
46
|
+
...h,
|
|
45
47
|
...x()
|
|
46
48
|
}), H(!0);
|
|
47
49
|
}, $ = () => {
|
|
48
|
-
m &&
|
|
49
|
-
...
|
|
50
|
+
m && v({
|
|
51
|
+
...h,
|
|
50
52
|
...x()
|
|
51
53
|
});
|
|
52
54
|
}, s = (t) => {
|
|
53
55
|
!e || e.contains(t.target) || !d || d.contains(t.target);
|
|
54
|
-
}, g =
|
|
55
|
-
return
|
|
56
|
-
e !== null && (n.mouseEvent === "click" ? e.removeEventListener("click",
|
|
56
|
+
}, g = F($, B);
|
|
57
|
+
return p(() => (e !== null && (n.mouseEvent === "click" ? e.addEventListener("click", c) : (e.addEventListener("mouseenter", c), e.addEventListener("mouseleave", s)), document.addEventListener("mousedown", s), document.addEventListener("touchstart", s), window.addEventListener("resize", g)), () => {
|
|
58
|
+
e !== null && (n.mouseEvent === "click" ? e.removeEventListener("click", c) : (e.removeEventListener("mouseenter", c), e.removeEventListener("mouseleave", s)), document.removeEventListener("mousedown", s), document.removeEventListener("touchstart", s), window.removeEventListener("resize", g));
|
|
57
59
|
})), {
|
|
58
60
|
style: {
|
|
59
|
-
style:
|
|
61
|
+
style: h
|
|
60
62
|
},
|
|
61
63
|
status: m
|
|
62
64
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePositionedFloaters.js","sources":["../../../src/components/hooks/usePositionedFloaters.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useDebounce } from './useDebounce';\n\ninterface positionProps {\n style: {\n style: {\n inset: string;\n };\n };\n status: boolean;\n}\n\ninterface optionProps {\n mouseEvent: 'click' | 'hover';\n position: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';\n offset: number;\n maxFixedHeight?: `${number}${'px' | 'rem'}`;\n horizontalPosition?: 'left' | 'right';\n mobileBreakpoint?: `${number}${'px' | 'rem'}`;\n}\n\nconst BODY_PADDING = 10;\nconst MIN_HEIGHT = 45;\nconst MIN_WIDTH = 300;\nconst DEBOUNCE_DELAY = 0;\nconst MOBILE_BREAKPOINT = 768;\nconst HALF = 2;\n\nexport function usePositionedFloaters<T extends HTMLElement = HTMLElement>(\n positionedElement: T | null,\n referenceElement: T | null,\n options: optionProps\n): positionProps {\n const [status, setStatus] = useState(false);\n const defaultStyle = {\n inset: '0 auto auto 0',\n opacity: 0,\n maxHeight: '100%',\n maxWidth: '100%',\n overflowX: 'hidden',\n overflowY: 'auto',\n margin: '0rem',\n };\n\n const [style, setStyle] = useState(defaultStyle);\n\n const sizeToPx = (size: `${number}${'px' | 'rem'}`): number => {\n const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return size.indexOf('rem') !== -1 ? parseFloat(size) * rootFontSize : parseFloat(size);\n };\n\n const setHeight = (refRect: DOMRect, pos: string): number => {\n if (!refRect) return 0;\n\n const _maxHeight =\n pos === 'bottom'\n ? window.innerHeight - refRect.bottom - options.offset - BODY_PADDING\n : refRect.top - options.offset - BODY_PADDING;\n\n return !options.maxFixedHeight || sizeToPx(options.maxFixedHeight) > _maxHeight\n ? _maxHeight\n : sizeToPx(options.maxFixedHeight);\n };\n\n const setWidth = (refRect: DOMRect, pos: string): number => {\n if (!refRect) return 0;\n\n const _availableWidth =\n pos === 'left' ? window.innerWidth - refRect.left - BODY_PADDING : refRect.right - BODY_PADDING;\n\n return _availableWidth <= MIN_WIDTH ? MIN_WIDTH : _availableWidth;\n };\n\n const setLeft = (refRect: DOMRect, posRect: DOMRect, isMobile: boolean) => {\n if (isMobile) {\n return `${refRect.left - Math.abs(posRect.width - refRect.width) / HALF}px`;\n } else {\n return `${refRect.left}px`;\n }\n };\n\n const calcPosition = (): typeof defaultStyle => {\n const positionedRect = (positionedElement as HTMLElement | null)?.getBoundingClientRect();\n const referenceRect = (referenceElement as HTMLElement | null)?.getBoundingClientRect();\n let yPos = 'bottom';\n let xPos = 'left';\n\n const isMobile = window.matchMedia(\n `(max-width: ${options.mobileBreakpoint ? sizeToPx(options.mobileBreakpoint) : MOBILE_BREAKPOINT}px)`\n ).matches;\n\n if (!referenceRect || !positionedRect) {\n return defaultStyle;\n }\n\n if (window.innerHeight - referenceRect.bottom - BODY_PADDING < MIN_HEIGHT) {\n yPos = 'top';\n }\n\n if (\n (window.innerWidth - referenceRect.left - BODY_PADDING < MIN_WIDTH || options.horizontalPosition === 'right') &&\n !isMobile\n ) {\n xPos = 'right';\n }\n\n return {\n inset: `${yPos === 'bottom' ? referenceRect[yPos] + 'px' : 'auto'}\n ${xPos === 'right' ? window.innerWidth - referenceRect[xPos] + 'px' : 'auto'}\n ${yPos === 'top' ? window.innerHeight - referenceRect[yPos] + 'px' : 'auto'}\n ${xPos === 'left' ? setLeft(referenceRect, positionedRect, isMobile) : 'auto'}`,\n maxHeight: `${setHeight(referenceRect, yPos)}px`,\n maxWidth: `${setWidth(referenceRect, xPos)}px`,\n overflowX: 'hidden',\n overflowY: 'auto',\n opacity: 1,\n margin: `${options.offset}px 0`,\n };\n };\n\n const handleMouseEvent = (): void => {\n setStyle({\n ...style,\n ...calcPosition(),\n });\n setStatus(true);\n };\n\n const updatePosition = (): void => {\n if (status) {\n setStyle({\n ...style,\n ...calcPosition(),\n });\n }\n };\n\n const handleClickOutside = (evt: Event): void => {\n if (\n !referenceElement ||\n (referenceElement as unknown as HTMLElement).contains(evt.target as Node) ||\n !positionedElement ||\n (positionedElement as unknown as HTMLElement).contains(evt.target as Node)\n ) {\n return;\n }\n };\n\n const debouncedUpdatePosition = useDebounce(updatePosition, DEBOUNCE_DELAY);\n\n useEffect(() => {\n if (referenceElement !== null) {\n if (options.mouseEvent === 'click') {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('click', handleMouseEvent);\n } else {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('mouseenter', handleMouseEvent);\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('mouseleave', handleClickOutside);\n }\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('touchstart', handleClickOutside);\n window.addEventListener('resize', debouncedUpdatePosition);\n }\n\n return () => {\n if (referenceElement !== null) {\n if (options.mouseEvent === 'click') {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('click', handleMouseEvent);\n } else {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('mouseenter', handleMouseEvent);\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('mouseleave', handleClickOutside);\n }\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('touchstart', handleClickOutside);\n window.removeEventListener('resize', debouncedUpdatePosition);\n }\n };\n });\n\n return {\n style: {\n style,\n },\n status,\n };\n}\n"],"names":["BODY_PADDING","MIN_HEIGHT","MIN_WIDTH","DEBOUNCE_DELAY","MOBILE_BREAKPOINT","HALF","usePositionedFloaters","positionedElement","referenceElement","options","status","setStatus","useState","defaultStyle","style","setStyle","sizeToPx","size","rootFontSize","setHeight","refRect","pos","_maxHeight","setWidth","_availableWidth","setLeft","posRect","isMobile","calcPosition","positionedRect","referenceRect","yPos","xPos","handleMouseEvent","updatePosition","handleClickOutside","evt","debouncedUpdatePosition","useDebounce","useEffect"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"usePositionedFloaters.js","sources":["../../../src/components/hooks/usePositionedFloaters.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useDebounce } from './useDebounce';\n\ninterface positionProps {\n style: {\n style: {\n inset: string;\n };\n };\n status: boolean;\n}\n\ninterface optionProps {\n mouseEvent: 'click' | 'hover';\n position: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';\n offset: number;\n maxFixedHeight?: `${number}${'px' | 'rem'}`;\n horizontalPosition?: 'left' | 'right';\n mobileBreakpoint?: `${number}${'px' | 'rem'}`;\n fullWidth: boolean;\n}\n\nconst BODY_PADDING = 10;\nconst MIN_HEIGHT = 45;\nconst MIN_WIDTH = 300;\nconst DEBOUNCE_DELAY = 0;\nconst MOBILE_BREAKPOINT = 768;\nconst HALF = 2;\n\nexport function usePositionedFloaters<T extends HTMLElement = HTMLElement>(\n positionedElement: T | null,\n referenceElement: T | null,\n options: optionProps\n): positionProps {\n const [status, setStatus] = useState(false);\n const defaultStyle = {\n inset: '0 auto auto 0',\n opacity: 0,\n maxHeight: '100%',\n maxWidth: '100%',\n minWidth: MIN_WIDTH,\n overflowX: 'hidden',\n overflowY: 'auto',\n margin: '0rem',\n };\n\n const [style, setStyle] = useState(defaultStyle);\n\n const sizeToPx = (size: `${number}${'px' | 'rem'}`): number => {\n const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return size.indexOf('rem') !== -1 ? parseFloat(size) * rootFontSize : parseFloat(size);\n };\n\n const setHeight = (refRect: DOMRect, pos: string): number => {\n if (!refRect) return 0;\n\n const _maxHeight =\n pos === 'bottom'\n ? window.innerHeight - refRect.bottom - options.offset - BODY_PADDING\n : refRect.top - options.offset - BODY_PADDING;\n\n return !options.maxFixedHeight || sizeToPx(options.maxFixedHeight) > _maxHeight\n ? _maxHeight\n : sizeToPx(options.maxFixedHeight);\n };\n\n const setWidth = (refRect: DOMRect, pos: string): number => {\n if (!refRect) return 0;\n\n const _availableWidth =\n pos === 'left' ? window.innerWidth - refRect.left - BODY_PADDING : refRect.right - BODY_PADDING;\n\n return _availableWidth <= MIN_WIDTH ? MIN_WIDTH : _availableWidth;\n };\n\n const setLeft = (refRect: DOMRect, posRect: DOMRect, isMobile: boolean) => {\n if (isMobile) {\n return `${refRect.left - Math.abs(posRect.width - refRect.width) / HALF}px`;\n } else {\n return `${refRect.left}px`;\n }\n };\n\n const calcPosition = (): typeof defaultStyle => {\n const positionedRect = (positionedElement as HTMLElement | null)?.getBoundingClientRect();\n const referenceRect = (referenceElement as HTMLElement | null)?.getBoundingClientRect();\n let yPos = 'bottom';\n let xPos = 'left';\n\n const isMobile = window.matchMedia(\n `(max-width: ${options.mobileBreakpoint ? sizeToPx(options.mobileBreakpoint) : MOBILE_BREAKPOINT}px)`\n ).matches;\n\n if (!referenceRect || !positionedRect) {\n return defaultStyle;\n }\n\n if (window.innerHeight - referenceRect.bottom - BODY_PADDING < MIN_HEIGHT) {\n yPos = 'top';\n }\n\n if (\n (window.innerWidth - referenceRect.left - BODY_PADDING < MIN_WIDTH || options.horizontalPosition === 'right') &&\n !isMobile\n ) {\n xPos = 'right';\n }\n\n return {\n inset: `${yPos === 'bottom' ? referenceRect[yPos] + 'px' : 'auto'}\n ${xPos === 'right' ? window.innerWidth - referenceRect[xPos] + 'px' : 'auto'}\n ${yPos === 'top' ? window.innerHeight - referenceRect[yPos] + 'px' : 'auto'}\n ${xPos === 'left' ? setLeft(referenceRect, positionedRect, isMobile) : 'auto'}`,\n maxHeight: `${setHeight(referenceRect, yPos)}px`,\n maxWidth: `${setWidth(referenceRect, xPos)}px`,\n minWidth: options.fullWidth ? referenceRect.width : MIN_WIDTH,\n overflowX: 'hidden',\n overflowY: 'auto',\n opacity: 1,\n margin: `${options.offset}px 0`,\n };\n };\n\n const handleMouseEvent = (): void => {\n setStyle({\n ...style,\n ...calcPosition(),\n });\n setStatus(true);\n };\n\n const updatePosition = (): void => {\n if (status) {\n setStyle({\n ...style,\n ...calcPosition(),\n });\n }\n };\n\n const handleClickOutside = (evt: Event): void => {\n if (\n !referenceElement ||\n (referenceElement as unknown as HTMLElement).contains(evt.target as Node) ||\n !positionedElement ||\n (positionedElement as unknown as HTMLElement).contains(evt.target as Node)\n ) {\n return;\n }\n };\n\n const debouncedUpdatePosition = useDebounce(updatePosition, DEBOUNCE_DELAY);\n\n useEffect(() => {\n if (referenceElement !== null) {\n if (options.mouseEvent === 'click') {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('click', handleMouseEvent);\n } else {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('mouseenter', handleMouseEvent);\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).addEventListener('mouseleave', handleClickOutside);\n }\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('touchstart', handleClickOutside);\n window.addEventListener('resize', debouncedUpdatePosition);\n }\n\n return () => {\n if (referenceElement !== null) {\n if (options.mouseEvent === 'click') {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('click', handleMouseEvent);\n } else {\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('mouseenter', handleMouseEvent);\n // eslint-disable-next-line no-extra-semi\n (referenceElement as unknown as HTMLElement).removeEventListener('mouseleave', handleClickOutside);\n }\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('touchstart', handleClickOutside);\n window.removeEventListener('resize', debouncedUpdatePosition);\n }\n };\n });\n\n return {\n style: {\n style,\n },\n status,\n };\n}\n"],"names":["BODY_PADDING","MIN_HEIGHT","MIN_WIDTH","DEBOUNCE_DELAY","MOBILE_BREAKPOINT","HALF","usePositionedFloaters","positionedElement","referenceElement","options","status","setStatus","useState","defaultStyle","style","setStyle","sizeToPx","size","rootFontSize","setHeight","refRect","pos","_maxHeight","setWidth","_availableWidth","setLeft","posRect","isMobile","calcPosition","positionedRect","referenceRect","yPos","xPos","handleMouseEvent","updatePosition","handleClickOutside","evt","debouncedUpdatePosition","useDebounce","useEffect"],"mappings":"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"}
|
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": "2.
|
|
5
|
+
"version": "2.1.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@react-aria/overlays": "^3.24.0",
|
|
48
48
|
"@react-types/dialog": "^3.5.14",
|
|
49
49
|
"@semantic-release/git": "^10.0.1",
|
|
50
|
-
"@semantic-release/gitlab": "^13.2.
|
|
50
|
+
"@semantic-release/gitlab": "^13.2.3",
|
|
51
51
|
"@semantic-release/npm": "^12.0.1",
|
|
52
52
|
"@storybook/addon-a11y": "^8.4.6",
|
|
53
53
|
"@storybook/addon-essentials": "^8.4.6",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@storybook/test": "^8.4.6",
|
|
61
61
|
"@types/node": "^22.10.1",
|
|
62
62
|
"@types/react-dom": "^18.3.1",
|
|
63
|
-
"@types/react": "^18.3.
|
|
63
|
+
"@types/react": "^18.3.13",
|
|
64
64
|
"@uva-glass/eslint-config": "^1.3.1",
|
|
65
65
|
"@uva-glass/stylelint-config": "^1.1.0",
|
|
66
66
|
"@vitejs/plugin-react": "^4.3.4",
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import './assets/SelectListbox.css';const l = {
|
|
2
|
-
"select-listbox-container": "_select-listbox-container_x5lzf_1",
|
|
3
|
-
"select-listbox__wrapper": "_select-listbox__wrapper_x5lzf_5",
|
|
4
|
-
"select-listbox-trigger": "_select-listbox-trigger_x5lzf_15",
|
|
5
|
-
"select-listbox-trigger--default": "_select-listbox-trigger--default_x5lzf_30",
|
|
6
|
-
"select-listbox-trigger--small": "_select-listbox-trigger--small_x5lzf_34",
|
|
7
|
-
"select-listbox-trigger-label": "_select-listbox-trigger-label_x5lzf_38",
|
|
8
|
-
"select-listbox__wrapper--align-right": "_select-listbox__wrapper--align-right_x5lzf_46",
|
|
9
|
-
"select-listbox-trigger--bold": "_select-listbox-trigger--bold_x5lzf_50",
|
|
10
|
-
"select-listbox-trigger--pill": "_select-listbox-trigger--pill_x5lzf_54",
|
|
11
|
-
"select-listbox-trigger--pillLeft": "_select-listbox-trigger--pillLeft_x5lzf_59",
|
|
12
|
-
"select-listbox-trigger--pillRight": "_select-listbox-trigger--pillRight_x5lzf_64",
|
|
13
|
-
"select-listbox-trigger--noborder": "_select-listbox-trigger--noborder_x5lzf_79",
|
|
14
|
-
"select-listbox-trigger-icon": "_select-listbox-trigger-icon_x5lzf_91",
|
|
15
|
-
"select-listbox-trigger-icon--open": "_select-listbox-trigger-icon--open_x5lzf_96",
|
|
16
|
-
"select-listbox": "_select-listbox_x5lzf_1",
|
|
17
|
-
"select-listbox-option": "_select-listbox-option_x5lzf_110",
|
|
18
|
-
"select-listbox-option--active": "_select-listbox-option--active_x5lzf_122"
|
|
19
|
-
};
|
|
20
|
-
export {
|
|
21
|
-
l as s
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=SelectListbox.module-CdK9mQmJ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SelectListbox.module-CdK9mQmJ.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
|