kitunga-web 0.1.98 → 0.1.99
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/features/data-display/components/Badges/CheckBadge/CheckBadge.d.ts +16 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.d.ts.map +1 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.js +14 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.js.map +1 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.module.css +29 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.d.ts +19 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.d.ts.map +1 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.js +33 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.js.map +1 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.module.css +64 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.d.ts +25 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.d.ts.map +1 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.js +35 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.js.map +1 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.module.css +85 -0
- package/dist/features/inputs/components/Inputs/Checkbox.d.ts +17 -0
- package/dist/features/inputs/components/Inputs/Checkbox.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/Checkbox.js +16 -0
- package/dist/features/inputs/components/Inputs/Checkbox.js.map +1 -0
- package/dist/features/inputs/components/Inputs/Checkbox.module.css +68 -0
- package/dist/features/inputs/components/Inputs/FormLabel.d.ts +12 -0
- package/dist/features/inputs/components/Inputs/FormLabel.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/FormLabel.js +10 -0
- package/dist/features/inputs/components/Inputs/FormLabel.js.map +1 -0
- package/dist/features/inputs/components/Inputs/FormLabel.module.css +23 -0
- package/dist/features/inputs/components/Inputs/RadioButton.d.ts +13 -0
- package/dist/features/inputs/components/Inputs/RadioButton.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/RadioButton.js +9 -0
- package/dist/features/inputs/components/Inputs/RadioButton.js.map +1 -0
- package/dist/features/inputs/components/Inputs/RadioButton.module.css +66 -0
- package/dist/features/inputs/components/Inputs/Toggle.d.ts +12 -0
- package/dist/features/inputs/components/Inputs/Toggle.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/Toggle.js +8 -0
- package/dist/features/inputs/components/Inputs/Toggle.js.map +1 -0
- package/dist/features/inputs/components/Inputs/Toggle.module.css +62 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.d.ts +94 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.d.ts.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.js +137 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.js.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.module.css +228 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.d.ts +51 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.d.ts.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.js +65 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.js.map +1 -0
- package/dist/features/selects/components/{Selects → PickerSelect}/pickerOptions.d.ts +18 -3
- package/dist/features/selects/components/PickerSelect/pickerOptions.d.ts.map +1 -0
- package/dist/features/selects/components/{Selects → PickerSelect}/pickerOptions.js +4 -4
- package/dist/features/selects/components/PickerSelect/pickerOptions.js.map +1 -0
- package/dist/features/selects/components/Selects/CustomSelect.d.ts +1 -51
- package/dist/features/selects/components/Selects/CustomSelect.d.ts.map +1 -1
- package/dist/features/selects/components/Selects/CustomSelect.js +34 -140
- package/dist/features/selects/components/Selects/CustomSelect.js.map +1 -1
- package/dist/features/selects/components/Selects/CustomSelect.module.css +0 -127
- package/dist/shared/styles/tokens.css +11 -0
- package/dist/ui.d.ts +20 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +10 -0
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/dist/features/selects/components/Selects/pickerOptions.d.ts.map +0 -1
- package/dist/features/selects/components/Selects/pickerOptions.js.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export interface ToggleProps {
|
|
3
|
+
checked: boolean;
|
|
4
|
+
onChange: (checked: boolean) => void;
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
id?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function Toggle({ checked, onChange, label, disabled, id, name, className, }: ToggleProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=Toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/Toggle.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,EAAE,EACF,IAAI,EACJ,SAAc,GACf,EAAE,WAAW,2CAkBb"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import styles from './Toggle.module.css';
|
|
4
|
+
// Switch partilhado — a pill 40×22 com o thumb a deslizar.
|
|
5
|
+
export function Toggle({ checked, onChange, label, disabled = false, id, name, className = '', }) {
|
|
6
|
+
return (_jsxs("label", { className: `${styles.wrapper} ${disabled ? styles.disabled : ''} ${className}`, children: [_jsxs("span", { className: styles.track, children: [_jsx("input", { type: "checkbox", id: id, name: name, checked: checked, disabled: disabled, onChange: (e) => onChange(e.target.checked), className: styles.input }), _jsx("span", { className: styles.thumb })] }), label && _jsx("span", { className: styles.label, children: label })] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=Toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/Toggle.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,MAAM,MAAM,qBAAqB,CAAC;AAYzC,2DAA2D;AAC3D,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,EAAE,EACF,IAAI,EACJ,SAAS,GAAG,EAAE,GACF;IACZ,OAAO,CACL,iBAAO,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,aACnF,gBAAM,SAAS,EAAE,MAAM,CAAC,KAAK,aAC3B,gBACE,IAAI,EAAC,UAAU,EACf,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAC3C,SAAS,EAAE,MAAM,CAAC,KAAK,GACvB,EACF,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,GAAI,IAC5B,EACN,KAAK,IAAI,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAQ,IACjD,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 8px;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
user-select: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wrapper.disabled {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
opacity: 0.5;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.track {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: 40px;
|
|
17
|
+
height: 22px;
|
|
18
|
+
border-radius: 999px;
|
|
19
|
+
background: var(--bg-hover-normal);
|
|
20
|
+
border: 1.5px solid var(--border-divider);
|
|
21
|
+
transition: background 0.15s ease, border-color 0.15s ease;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.input {
|
|
26
|
+
position: absolute;
|
|
27
|
+
inset: 0;
|
|
28
|
+
margin: 0;
|
|
29
|
+
opacity: 0;
|
|
30
|
+
cursor: inherit;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.thumb {
|
|
34
|
+
position: absolute;
|
|
35
|
+
top: 2px;
|
|
36
|
+
left: 2px;
|
|
37
|
+
width: 16px;
|
|
38
|
+
height: 16px;
|
|
39
|
+
border-radius: 50%;
|
|
40
|
+
background: var(--color-white);
|
|
41
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
|
42
|
+
transition: transform 0.15s ease;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.input:checked ~ .thumb {
|
|
46
|
+
transform: translateX(18px);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.track:has(.input:checked) {
|
|
50
|
+
background: var(--bg-interactive);
|
|
51
|
+
border-color: var(--bg-interactive);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.input:focus-visible ~ .thumb {
|
|
55
|
+
outline: 2px solid var(--bg-interactive);
|
|
56
|
+
outline-offset: 2px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.label {
|
|
60
|
+
font-size: 0.875rem;
|
|
61
|
+
color: var(--text-primary);
|
|
62
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type PickerSheetClassNames } from './PickerSheet';
|
|
3
|
+
import { type PickerOption } from './pickerOptions';
|
|
4
|
+
export interface PickerSelectClassNames extends PickerSheetClassNames {
|
|
5
|
+
/** Applied on the wrapper around the CustomSelect trigger. */
|
|
6
|
+
trigger?: string;
|
|
7
|
+
overlay?: string;
|
|
8
|
+
panel?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PickerSelectProps {
|
|
11
|
+
id?: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
value: string;
|
|
15
|
+
onChange: (value: string) => void;
|
|
16
|
+
/** Explicit options — always wins over `kind`. */
|
|
17
|
+
options?: PickerOption[];
|
|
18
|
+
/** Convenience builders:
|
|
19
|
+
* 'country' → every libphonenumber territory + Intl.DisplayNames
|
|
20
|
+
* + flags from flagBaseUrl;
|
|
21
|
+
* 'language' → `locales` + `getLanguageLabel` + Globe glyph. */
|
|
22
|
+
kind?: 'country' | 'language';
|
|
23
|
+
/** Locale for Intl.DisplayNames + sort order (consumer's active
|
|
24
|
+
* language; default 'en'). */
|
|
25
|
+
displayLocale?: string;
|
|
26
|
+
/** Base URL of the consumer's flag SVG assets (default '/flags/4x3'). */
|
|
27
|
+
flagBaseUrl?: string;
|
|
28
|
+
/** Priority country codes — product order, land in the
|
|
29
|
+
* `suggestedLabel` group (kind='country'). */
|
|
30
|
+
priorityCodes?: readonly string[];
|
|
31
|
+
/** Header text for the priority group (kind='country'). */
|
|
32
|
+
suggestedLabel?: string;
|
|
33
|
+
/** Whitelist of locales for kind='language'. */
|
|
34
|
+
locales?: readonly string[];
|
|
35
|
+
/** Language name resolver — consumer's i18n. */
|
|
36
|
+
getLanguageLabel?: (locale: string) => string;
|
|
37
|
+
/** Per-row icon for kind='language' (default: Globe glyph). */
|
|
38
|
+
languageIcon?: React.ReactNode;
|
|
39
|
+
/** Texto do topo do sheet. */
|
|
40
|
+
title?: string;
|
|
41
|
+
/** Ícone do botão esquerdo do header (default ArrowLeft — no Masolo
|
|
42
|
+
* só aparece no takeover ≤600px, via --picker-back-display). */
|
|
43
|
+
backIcon?: React.ReactNode;
|
|
44
|
+
/** Acção do botão esquerdo (default: fecha o sheet). */
|
|
45
|
+
onBack?: () => void;
|
|
46
|
+
/** aria-label do botão esquerdo. */
|
|
47
|
+
backAriaLabel?: string;
|
|
48
|
+
/** Ícone do botão de fecho à direita (default X). */
|
|
49
|
+
closeIcon?: React.ReactNode;
|
|
50
|
+
/** aria-label do botão de fecho. */
|
|
51
|
+
closeAriaLabel?: string;
|
|
52
|
+
/** Show the pinned SearchInput (default true). */
|
|
53
|
+
searchable?: boolean;
|
|
54
|
+
searchPlaceholder?: string;
|
|
55
|
+
searchSize?: 'sm' | 'md' | 'lg';
|
|
56
|
+
/** Autofocus search on open (default false — mobile pops keyboard). */
|
|
57
|
+
searchAutoFocus?: boolean;
|
|
58
|
+
searchEmptyProps?: {
|
|
59
|
+
title?: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
actionLabel?: string;
|
|
62
|
+
};
|
|
63
|
+
placeholder?: string;
|
|
64
|
+
size?: 'sm' | 'md' | 'lg';
|
|
65
|
+
variant?: 'default' | 'flat';
|
|
66
|
+
valueBold?: boolean;
|
|
67
|
+
collapsible?: boolean;
|
|
68
|
+
leftIcon?: React.ReactNode;
|
|
69
|
+
hasError?: boolean;
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
className?: string;
|
|
72
|
+
/** Class slots for the consumer's skin — media queries / breakpoint
|
|
73
|
+
* rules always live in the consumer's CSS, never in kitunga. */
|
|
74
|
+
classNames?: PickerSelectClassNames;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* PickerSelect — a selection sheet (overlay + header + search + grouped
|
|
78
|
+
* list) that uses CustomSelect purely as its visual trigger.
|
|
79
|
+
*
|
|
80
|
+
* The wrapped CustomSelect never opens its own dropdown: click and
|
|
81
|
+
* Enter/Space are intercepted in the capture phase by the wrapper, so
|
|
82
|
+
* the inner select stays closed and unaware. All sheet state lives
|
|
83
|
+
* here — the two components don't know about each other's internals.
|
|
84
|
+
*
|
|
85
|
+
* For consumers with their own popup manager (Masolo's PopupContext /
|
|
86
|
+
* PopupManager), mount `PickerSheet` inside the system's `.modal` —
|
|
87
|
+
* the overlay/panel anatomy comes from the consumer.
|
|
88
|
+
*
|
|
89
|
+
* Responsiveness is entirely the consumer's: every dimension/visibility
|
|
90
|
+
* knob is a `--picker-*` CSS var or a `classNames` slot.
|
|
91
|
+
*/
|
|
92
|
+
declare const PickerSelect: React.FC<PickerSelectProps>;
|
|
93
|
+
export default PickerSelect;
|
|
94
|
+
//# sourceMappingURL=PickerSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickerSelect.d.ts","sourceRoot":"","sources":["../../../../../src/features/selects/components/PickerSelect/PickerSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kDAAkD;IAClD,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;;qEAGiE;IACjE,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B;mCAC+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;mDAC+C;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,+DAA+D;IAC/D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE/B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;qEACiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAChC,uEAAuE;IACvE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAGF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;qEACiE;IACjE,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4M7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
|
+
import CustomSelect from '../Selects/CustomSelect';
|
|
5
|
+
import PickerSheet from './PickerSheet';
|
|
6
|
+
import { buildCountryPickerOptions, buildLanguagePickerOptions, } from './pickerOptions';
|
|
7
|
+
import styles from './PickerSelect.module.css';
|
|
8
|
+
/**
|
|
9
|
+
* PickerSelect — a selection sheet (overlay + header + search + grouped
|
|
10
|
+
* list) that uses CustomSelect purely as its visual trigger.
|
|
11
|
+
*
|
|
12
|
+
* The wrapped CustomSelect never opens its own dropdown: click and
|
|
13
|
+
* Enter/Space are intercepted in the capture phase by the wrapper, so
|
|
14
|
+
* the inner select stays closed and unaware. All sheet state lives
|
|
15
|
+
* here — the two components don't know about each other's internals.
|
|
16
|
+
*
|
|
17
|
+
* For consumers with their own popup manager (Masolo's PopupContext /
|
|
18
|
+
* PopupManager), mount `PickerSheet` inside the system's `.modal` —
|
|
19
|
+
* the overlay/panel anatomy comes from the consumer.
|
|
20
|
+
*
|
|
21
|
+
* Responsiveness is entirely the consumer's: every dimension/visibility
|
|
22
|
+
* knob is a `--picker-*` CSS var or a `classNames` slot.
|
|
23
|
+
*/
|
|
24
|
+
const PickerSelect = ({ id, name, required = false, value, onChange, options, kind, displayLocale, flagBaseUrl, priorityCodes, suggestedLabel, locales, getLanguageLabel, languageIcon, title = 'Select', backIcon, onBack, backAriaLabel, closeIcon, closeAriaLabel, searchable = true, searchPlaceholder, searchSize = 'md', searchAutoFocus = false, searchEmptyProps, placeholder = 'Selecione uma opção', size = 'md', variant = 'default', valueBold = false, collapsible = false, leftIcon, hasError = false, disabled = false, className = '', classNames, }) => {
|
|
25
|
+
var _a, _b, _c, _d;
|
|
26
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
27
|
+
// Transient history entry — mobile back gesture/button pops it and
|
|
28
|
+
// closes the sheet (same model as Masolo's PopupContext, router-free).
|
|
29
|
+
const pushedRef = useRef(false);
|
|
30
|
+
const resolvedOptions = React.useMemo(() => {
|
|
31
|
+
if (options === null || options === void 0 ? void 0 : options.length)
|
|
32
|
+
return options;
|
|
33
|
+
if (kind === 'country') {
|
|
34
|
+
return buildCountryPickerOptions({
|
|
35
|
+
displayLocale,
|
|
36
|
+
flagBaseUrl,
|
|
37
|
+
priorityCodes,
|
|
38
|
+
suggestedLabel,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (kind === 'language') {
|
|
42
|
+
return buildLanguagePickerOptions({
|
|
43
|
+
locales: locales !== null && locales !== void 0 ? locales : [],
|
|
44
|
+
getLanguageLabel,
|
|
45
|
+
displayLocale,
|
|
46
|
+
languageIcon,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return options !== null && options !== void 0 ? options : [];
|
|
50
|
+
}, [
|
|
51
|
+
options,
|
|
52
|
+
kind,
|
|
53
|
+
displayLocale,
|
|
54
|
+
flagBaseUrl,
|
|
55
|
+
priorityCodes,
|
|
56
|
+
suggestedLabel,
|
|
57
|
+
locales,
|
|
58
|
+
getLanguageLabel,
|
|
59
|
+
languageIcon,
|
|
60
|
+
]);
|
|
61
|
+
// Close: if the history entry is ours, back() pops it and the
|
|
62
|
+
// popstate listener flips isOpen; otherwise just flip the state.
|
|
63
|
+
const closeSheet = useCallback(() => {
|
|
64
|
+
if (pushedRef.current) {
|
|
65
|
+
pushedRef.current = false;
|
|
66
|
+
window.history.back();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setIsOpen(false);
|
|
70
|
+
}, []);
|
|
71
|
+
const openSheet = useCallback(() => {
|
|
72
|
+
if (disabled || isOpen)
|
|
73
|
+
return;
|
|
74
|
+
setIsOpen(true);
|
|
75
|
+
if (typeof window !== 'undefined') {
|
|
76
|
+
pushedRef.current = true;
|
|
77
|
+
window.history.pushState({ __kitungaPickerSelect: true }, '');
|
|
78
|
+
}
|
|
79
|
+
}, [disabled, isOpen]);
|
|
80
|
+
// popstate — the OS/browser back popped our entry: close the sheet.
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!isOpen)
|
|
83
|
+
return;
|
|
84
|
+
const handlePopState = () => {
|
|
85
|
+
pushedRef.current = false;
|
|
86
|
+
setIsOpen(false);
|
|
87
|
+
};
|
|
88
|
+
window.addEventListener('popstate', handlePopState);
|
|
89
|
+
return () => window.removeEventListener('popstate', handlePopState);
|
|
90
|
+
}, [isOpen]);
|
|
91
|
+
// ESC + page scroll lock while the sheet is open.
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!isOpen)
|
|
94
|
+
return;
|
|
95
|
+
const handleKeyDown = (e) => {
|
|
96
|
+
if (e.key === 'Escape')
|
|
97
|
+
closeSheet();
|
|
98
|
+
};
|
|
99
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
100
|
+
document.body.style.overflow = 'hidden';
|
|
101
|
+
return () => {
|
|
102
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
103
|
+
document.body.style.overflow = 'unset';
|
|
104
|
+
};
|
|
105
|
+
}, [isOpen, closeSheet]);
|
|
106
|
+
const handleTriggerClick = (e) => {
|
|
107
|
+
if (disabled)
|
|
108
|
+
return;
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
if (isOpen)
|
|
112
|
+
closeSheet();
|
|
113
|
+
else
|
|
114
|
+
openSheet();
|
|
115
|
+
};
|
|
116
|
+
const handleTriggerKey = (e) => {
|
|
117
|
+
if (disabled)
|
|
118
|
+
return;
|
|
119
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
e.stopPropagation();
|
|
122
|
+
if (isOpen)
|
|
123
|
+
closeSheet();
|
|
124
|
+
else
|
|
125
|
+
openSheet();
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const handleSelect = (option) => {
|
|
129
|
+
if (option.disabled)
|
|
130
|
+
return;
|
|
131
|
+
onChange(option.value);
|
|
132
|
+
closeSheet();
|
|
133
|
+
};
|
|
134
|
+
return (_jsxs("div", { className: `${styles.pickerSelect} ${className}`, children: [_jsx("div", { className: `${styles.triggerWrap} ${(_a = classNames === null || classNames === void 0 ? void 0 : classNames.trigger) !== null && _a !== void 0 ? _a : ''}`, onClickCapture: handleTriggerClick, onKeyDownCapture: handleTriggerKey, children: _jsx(CustomSelect, { value: value, onChange: onChange, options: resolvedOptions, placeholder: placeholder, size: size, variant: variant, valueBold: valueBold, collapsible: collapsible, leftIcon: leftIcon, hasError: hasError, disabled: disabled, className: (_b = classNames === null || classNames === void 0 ? void 0 : classNames.trigger) !== null && _b !== void 0 ? _b : '' }) }), isOpen && (_jsx("div", { className: `${styles.overlay} ${(_c = classNames === null || classNames === void 0 ? void 0 : classNames.overlay) !== null && _c !== void 0 ? _c : ''}`, onClick: closeSheet, role: "dialog", "aria-modal": "true", "aria-label": title, children: _jsx("div", { className: `${styles.panel} ${(_d = classNames === null || classNames === void 0 ? void 0 : classNames.panel) !== null && _d !== void 0 ? _d : ''}`, onClick: (e) => e.stopPropagation(), children: _jsx(PickerSheet, { options: resolvedOptions, value: value, onSelect: handleSelect, onClose: closeSheet, title: title, backIcon: backIcon, onBack: onBack, backAriaLabel: backAriaLabel, closeIcon: closeIcon, closeAriaLabel: closeAriaLabel, searchable: searchable, searchPlaceholder: searchPlaceholder, searchSize: searchSize, searchAutoFocus: searchAutoFocus, searchEmptyProps: searchEmptyProps, classNames: classNames }) }) })), _jsx("input", { type: "hidden", id: id, name: name, value: value, required: required })] }));
|
|
135
|
+
};
|
|
136
|
+
export default PickerSelect;
|
|
137
|
+
//# sourceMappingURL=PickerSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickerSelect.js","sourceRoot":"","sources":["../../../../../src/features/selects/components/PickerSelect/PickerSelect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/* ===== PickerSelect — overlay-sheet with header, search and grouped
|
|
2
|
+
sections, for long lists with visual identity (countries, languages).
|
|
3
|
+
The trigger is a wrapped CustomSelect; the sheet lives entirely here.
|
|
4
|
+
ZERO breakpoints: the consumer's skin drives every responsive rule
|
|
5
|
+
through the --picker-* vars and the `classNames` slots — kitunga does
|
|
6
|
+
not know the Masolo 600px rule or any other product's (decision 75). */
|
|
7
|
+
|
|
8
|
+
.pickerSelect {
|
|
9
|
+
position: relative;
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Wrapper that hijacks click/keys on the wrapped CustomSelect so its
|
|
14
|
+
own dropdown never opens. */
|
|
15
|
+
.triggerWrap {
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.overlay {
|
|
20
|
+
position: fixed;
|
|
21
|
+
inset: 0;
|
|
22
|
+
z-index: var(--picker-overlay-z, 1300);
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
height: 100dvh;
|
|
27
|
+
padding: var(--picker-overlay-padding, var(--spacing-lg));
|
|
28
|
+
background: var(--picker-overlay-bg, rgba(0, 0, 0, 0.5));
|
|
29
|
+
animation: pickerFadeIn 0.15s ease-out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.panel {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
width: var(--picker-panel-width, 100%);
|
|
37
|
+
max-width: var(--picker-panel-max-width, 480px);
|
|
38
|
+
height: var(--picker-panel-height, 600px);
|
|
39
|
+
max-height: var(--picker-panel-max-height, 100%);
|
|
40
|
+
background: var(--picker-panel-bg, var(--bg-primary));
|
|
41
|
+
border-radius: var(--picker-panel-radius, var(--radius-sm));
|
|
42
|
+
box-shadow: var(--picker-panel-shadow, 0 10px 25px rgba(0, 0, 0, 0.2));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.header {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: var(--spacing-md);
|
|
49
|
+
padding: var(--spacing-md);
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.title {
|
|
54
|
+
flex: 1;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
margin: 0;
|
|
57
|
+
font-size: 18px;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
color: var(--text-primary);
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
text-overflow: ellipsis;
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.back,
|
|
66
|
+
.close {
|
|
67
|
+
align-items: center;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
width: 40px;
|
|
70
|
+
height: 40px;
|
|
71
|
+
padding: 0;
|
|
72
|
+
border: none;
|
|
73
|
+
border-radius: 50%;
|
|
74
|
+
background: var(--picker-button-bg, var(--bg-hover-normal));
|
|
75
|
+
color: var(--picker-button-color, var(--text-primary));
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
flex-shrink: 0;
|
|
78
|
+
transition: background-color var(--transition-fast);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.back:hover,
|
|
82
|
+
.close:hover {
|
|
83
|
+
background-color: var(--picker-button-hover, var(--color-gray-200));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Control visibility — always the consumer's CSS. In Masolo the X
|
|
87
|
+
dies and the ← appears in the ≤600px takeover, via
|
|
88
|
+
--picker-back-display / --picker-close-display in the app's own
|
|
89
|
+
media query. Both are "close": ← is back in form, close in function
|
|
90
|
+
(decision 30). */
|
|
91
|
+
.back {
|
|
92
|
+
display: var(--picker-back-display, none);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.close {
|
|
96
|
+
display: var(--picker-close-display, flex);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Espaço uniforme à volta da pesquisa — spacing-md em todos os
|
|
100
|
+
lados, como a anatomia da casa (o header acima já traz o seu
|
|
101
|
+
padding-md, pelo que o respiro X→input fica md+md). */
|
|
102
|
+
.searchRow {
|
|
103
|
+
padding: var(--picker-search-padding, var(--spacing-md));
|
|
104
|
+
border-bottom: 1px solid var(--picker-search-border, var(--border-divider));
|
|
105
|
+
flex-shrink: 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.list {
|
|
109
|
+
flex: 1;
|
|
110
|
+
min-height: 0;
|
|
111
|
+
overflow-y: auto;
|
|
112
|
+
/* The parent list breathes: spacing-md top/bottom, 8px on the
|
|
113
|
+
sides — items float inside the panel, never glued to the edges. */
|
|
114
|
+
padding: var(--picker-list-padding, var(--spacing-md) var(--spacing-sm));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Section header — just another list item: scrolls with the list,
|
|
118
|
+
never sticky/absolute. */
|
|
119
|
+
.groupHeader {
|
|
120
|
+
padding: var(--spacing-sm) var(--picker-group-padding-x, var(--spacing-sm));
|
|
121
|
+
font-size: var(--picker-group-size, 0.8rem);
|
|
122
|
+
font-weight: 600;
|
|
123
|
+
letter-spacing: 0.04em;
|
|
124
|
+
text-transform: uppercase;
|
|
125
|
+
color: var(--picker-group-color, var(--text-tertiary));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Picker rows — the reference list style (decision 75): no dividers
|
|
129
|
+
between rows, gray hover (EntityRow colors), light-blue selected
|
|
130
|
+
(--selection-bg) + CheckBadge on the right. Each item carries its
|
|
131
|
+
own 8px padding and radius-sm. */
|
|
132
|
+
.option {
|
|
133
|
+
min-height: var(--picker-option-height, 52px);
|
|
134
|
+
padding: var(--picker-option-padding, var(--spacing-sm));
|
|
135
|
+
border-radius: var(--picker-option-radius, var(--radius-sm));
|
|
136
|
+
cursor: pointer;
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
justify-content: space-between;
|
|
140
|
+
transition: all 0.12s ease;
|
|
141
|
+
color: var(--text-primary);
|
|
142
|
+
font-weight: 400;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.option span {
|
|
146
|
+
font-size: var(--picker-option-font-size, 1rem);
|
|
147
|
+
line-height: 1.3;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* O gap global entre itens (--entity-row-gap) — via `~` para que o
|
|
151
|
+
primeiro filho nunca leve espaço e as cores de hover/selecção
|
|
152
|
+
nunca se colem. */
|
|
153
|
+
.list > * ~ * {
|
|
154
|
+
margin-top: var(--picker-option-gap, var(--entity-row-gap, 2px));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.option:hover {
|
|
158
|
+
background-color: var(--bg-hover-normal);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.option.selected {
|
|
162
|
+
background-color: var(--picker-option-selected-bg, #f2f6fe);
|
|
163
|
+
color: var(--picker-option-selected-text, var(--selection-text));
|
|
164
|
+
font-weight: var(--picker-option-selected-weight, 700);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.option.disabledOption {
|
|
168
|
+
opacity: 0.45;
|
|
169
|
+
cursor: not-allowed;
|
|
170
|
+
color: var(--text-tertiary);
|
|
171
|
+
background-color: var(--bg-primary);
|
|
172
|
+
pointer-events: none;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.optionText {
|
|
176
|
+
display: inline-flex;
|
|
177
|
+
align-items: center;
|
|
178
|
+
min-width: 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Row icons in the picker list — the same circular 24px frame as the
|
|
182
|
+
CustomSelect trigger: img/svg children fill it and the circle crops
|
|
183
|
+
(flags always read round, trigger and list consistent). */
|
|
184
|
+
.optionIcon {
|
|
185
|
+
display: inline-flex;
|
|
186
|
+
align-items: center;
|
|
187
|
+
justify-content: center;
|
|
188
|
+
width: var(--picker-icon-size, 24px);
|
|
189
|
+
height: var(--picker-icon-size, 24px);
|
|
190
|
+
border-radius: var(--picker-icon-radius, 50%);
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
flex-shrink: 0;
|
|
193
|
+
font-size: 1rem;
|
|
194
|
+
margin-right: var(--spacing-md);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.optionIcon > img,
|
|
198
|
+
.optionIcon > svg {
|
|
199
|
+
width: 100%;
|
|
200
|
+
height: 100%;
|
|
201
|
+
object-fit: cover;
|
|
202
|
+
display: block;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.option:focus-visible {
|
|
206
|
+
outline: none;
|
|
207
|
+
background-color: var(--bg-tertiary);
|
|
208
|
+
color: var(--color-primary);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Flag fallback when the asset fails — ISO text inside the same
|
|
212
|
+
rectangular frame (a consumer with partial flagBaseUrl never shows
|
|
213
|
+
a broken image). */
|
|
214
|
+
.flagFallback {
|
|
215
|
+
font-size: 0.55rem;
|
|
216
|
+
font-weight: 700;
|
|
217
|
+
letter-spacing: 0.02em;
|
|
218
|
+
color: var(--text-tertiary);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@keyframes pickerFadeIn {
|
|
222
|
+
from {
|
|
223
|
+
opacity: 0;
|
|
224
|
+
}
|
|
225
|
+
to {
|
|
226
|
+
opacity: 1;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PickerOption } from './pickerOptions';
|
|
3
|
+
export interface PickerSheetClassNames {
|
|
4
|
+
header?: string;
|
|
5
|
+
backButton?: string;
|
|
6
|
+
closeButton?: string;
|
|
7
|
+
searchRow?: string;
|
|
8
|
+
list?: string;
|
|
9
|
+
groupHeader?: string;
|
|
10
|
+
option?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PickerSheetProps {
|
|
13
|
+
options: PickerOption[];
|
|
14
|
+
value: string;
|
|
15
|
+
onSelect: (option: PickerOption) => void;
|
|
16
|
+
/** Chamado pelos controlos de fecho/voltar do header e pelo ESC. */
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
/** Texto do topo do sheet. */
|
|
19
|
+
title?: string;
|
|
20
|
+
/** Ícone do botão esquerdo do header (default ArrowLeft — no Masolo
|
|
21
|
+
* só aparece no takeover ≤600px, via --picker-back-display). */
|
|
22
|
+
backIcon?: React.ReactNode;
|
|
23
|
+
/** Acção do botão esquerdo (default: onClose). */
|
|
24
|
+
onBack?: () => void;
|
|
25
|
+
/** aria-label do botão esquerdo. */
|
|
26
|
+
backAriaLabel?: string;
|
|
27
|
+
/** Ícone do botão de fecho à direita (default X). */
|
|
28
|
+
closeIcon?: React.ReactNode;
|
|
29
|
+
/** aria-label do botão de fecho. */
|
|
30
|
+
closeAriaLabel?: string;
|
|
31
|
+
searchable?: boolean;
|
|
32
|
+
searchPlaceholder?: string;
|
|
33
|
+
searchSize?: 'sm' | 'md' | 'lg';
|
|
34
|
+
searchAutoFocus?: boolean;
|
|
35
|
+
searchEmptyProps?: {
|
|
36
|
+
title?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
actionLabel?: string;
|
|
39
|
+
};
|
|
40
|
+
classNames?: PickerSheetClassNames;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* PickerSheet — o conteúdo da folha (header + pesquisa + lista
|
|
44
|
+
* agrupada), SEM overlay. É o que o PickerSelect renderiza dentro do
|
|
45
|
+
* seu próprio overlay — e o que um consumidor com popup manager
|
|
46
|
+
* próprio (ex.: o PopupManager do Masolo) monta dentro do seu `.modal`
|
|
47
|
+
* para obter a anatomia 500×600 / takeover / X→← do próprio sistema.
|
|
48
|
+
*/
|
|
49
|
+
declare const PickerSheet: React.FC<PickerSheetProps>;
|
|
50
|
+
export default PickerSheet;
|
|
51
|
+
//# sourceMappingURL=PickerSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickerSheet.d.ts","sourceRoot":"","sources":["../../../../../src/features/selects/components/PickerSelect/PickerSheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,oEAAoE;IACpE,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;qEACiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAQD;;;;;;GAMG;AACH,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiI3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
|