@visitwonders/assembly 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/declarations/form/combobox-field.d.ts +71 -0
- package/declarations/form/combobox-field.d.ts.map +1 -0
- package/declarations/form/combobox-shared.d.ts +36 -0
- package/declarations/form/combobox-shared.d.ts.map +1 -0
- package/declarations/form/combobox.d.ts +239 -0
- package/declarations/form/combobox.d.ts.map +1 -0
- package/declarations/form/index.d.ts +4 -0
- package/declarations/form/index.d.ts.map +1 -1
- package/declarations/form/multi-combobox-field.d.ts +72 -0
- package/declarations/form/multi-combobox-field.d.ts.map +1 -0
- package/declarations/form/multi-combobox.d.ts +202 -0
- package/declarations/form/multi-combobox.d.ts.map +1 -0
- package/declarations/layout/h-stack.d.ts.map +1 -1
- package/declarations/layout/stack.d.ts.map +1 -1
- package/declarations/layout/v-stack.d.ts.map +1 -1
- package/declarations/overlay/popover.d.ts +20 -1
- package/declarations/overlay/popover.d.ts.map +1 -1
- package/dist/_app_/form/combobox-field.js +1 -0
- package/dist/_app_/form/combobox-shared.js +1 -0
- package/dist/_app_/form/combobox.js +1 -0
- package/dist/_app_/form/multi-combobox-field.js +1 -0
- package/dist/_app_/form/multi-combobox.js +1 -0
- package/dist/data/{sortable-list-css-211fcfeedc08052ccbac7f51549ce0b1.css → sortable-list-css-03e5d237ea377f7d6056e76cc85b2aaa.css} +8 -4
- package/dist/data/sortable-list.js +1 -1
- package/dist/form/combobox-field.js +37 -0
- package/dist/form/combobox-field.js.map +1 -0
- package/dist/form/combobox-shared.js +76 -0
- package/dist/form/combobox-shared.js.map +1 -0
- package/dist/form/combobox.css +345 -0
- package/dist/form/combobox.js +612 -0
- package/dist/form/combobox.js.map +1 -0
- package/dist/form/{display-field-css-890d9be4b5da61613fd017071f330735.css → display-field-css-502236a2343d47e31e52bdb93a769ca1.css} +2 -2
- package/dist/form/display-field.js +1 -1
- package/dist/form/index.js +4 -0
- package/dist/form/index.js.map +1 -1
- package/dist/form/multi-combobox-field.js +36 -0
- package/dist/form/multi-combobox-field.js.map +1 -0
- package/dist/form/multi-combobox.css +422 -0
- package/dist/form/multi-combobox.js +626 -0
- package/dist/form/multi-combobox.js.map +1 -0
- package/dist/layout/h-stack.js.map +1 -1
- package/dist/layout/panel.css +10 -0
- package/dist/layout/v-stack.js.map +1 -1
- package/dist/overlay/popover.js +19 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -13,6 +13,89 @@
|
|
|
13
13
|
ember install @visitwonders/assembly
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
Overlay components (`Popover`, `Tooltip`, `Modal`, `Drawer`, `Blanket`,
|
|
19
|
+
`Toast`) render through `ember-primitives`' `<Portal>`. The consuming
|
|
20
|
+
app must mount `<PortalTargets />` once — typically in the application
|
|
21
|
+
template — so that Assembly overlays can find their portal
|
|
22
|
+
destinations:
|
|
23
|
+
|
|
24
|
+
```gts
|
|
25
|
+
import { PortalTargets } from '@visitwonders/assembly/overlay';
|
|
26
|
+
|
|
27
|
+
<template>
|
|
28
|
+
{{outlet}}
|
|
29
|
+
<PortalTargets />
|
|
30
|
+
</template>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`<PortalTargets />` renders three empty `<div>` elements as portal
|
|
34
|
+
destinations. Its position in the template is layout-neutral —
|
|
35
|
+
overlays use fixed/absolute positioning and don't affect document
|
|
36
|
+
flow.
|
|
37
|
+
|
|
38
|
+
Without this, the first overlay you open will throw an assertion:
|
|
39
|
+
`Could not find element by the given name: ember-primitives__portal-targets__popover`.
|
|
40
|
+
|
|
41
|
+
### Integration tests
|
|
42
|
+
|
|
43
|
+
`setupRenderingTest` does not render the application template, so
|
|
44
|
+
rendering tests that exercise any component containing an overlay
|
|
45
|
+
(directly or transitively — e.g. `SelectField`, `DatePickerField`,
|
|
46
|
+
`MultiSelect`, anything that uses a dropdown or a tooltip-on-label)
|
|
47
|
+
need portal destinations inside `#ember-testing`. The cleanest
|
|
48
|
+
pattern is to inject them in your shared `setupRenderingTest`
|
|
49
|
+
wrapper so every rendering test gets them automatically — no
|
|
50
|
+
per-test boilerplate, no wrapper around `render`:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// tests/helpers/index.ts
|
|
54
|
+
import { setupRenderingTest as upstreamSetupRenderingTest } from 'ember-qunit';
|
|
55
|
+
import type { SetupTestOptions } from 'ember-qunit';
|
|
56
|
+
|
|
57
|
+
const PORTAL_TARGET_NAMES = [
|
|
58
|
+
'ember-primitives__portal-targets__popover',
|
|
59
|
+
'ember-primitives__portal-targets__tooltip',
|
|
60
|
+
'ember-primitives__portal-targets__modal',
|
|
61
|
+
] as const;
|
|
62
|
+
|
|
63
|
+
export function setupRenderingTest(
|
|
64
|
+
hooks: NestedHooks,
|
|
65
|
+
options?: SetupTestOptions,
|
|
66
|
+
) {
|
|
67
|
+
upstreamSetupRenderingTest(hooks, options);
|
|
68
|
+
|
|
69
|
+
hooks.beforeEach(function () {
|
|
70
|
+
const root = document.getElementById('ember-testing');
|
|
71
|
+
if (!root) return;
|
|
72
|
+
for (const name of PORTAL_TARGET_NAMES) {
|
|
73
|
+
const target = document.createElement('div');
|
|
74
|
+
target.setAttribute('data-portal-name', name);
|
|
75
|
+
target.setAttribute('data-test-portal-target', '');
|
|
76
|
+
root.appendChild(target);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
hooks.afterEach(function () {
|
|
81
|
+
const root = document.getElementById('ember-testing');
|
|
82
|
+
if (!root) return;
|
|
83
|
+
for (const target of root.querySelectorAll('[data-test-portal-target]')) {
|
|
84
|
+
target.remove();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
This works because `@ember/test-helpers`' `setupRenderingContext`
|
|
91
|
+
appends (rather than replaces) the Ember outlet view inside
|
|
92
|
+
`#ember-testing`, so sibling elements injected here survive every
|
|
93
|
+
`render()` call and are still reachable by `Portal`'s
|
|
94
|
+
`findNearestTarget` walk. Tests can keep importing `render` from
|
|
95
|
+
`@ember/test-helpers` unchanged. Application tests
|
|
96
|
+
(`setupApplicationTest`) are unaffected — they pick up
|
|
97
|
+
`<PortalTargets />` from the application template automatically.
|
|
98
|
+
|
|
16
99
|
## Usage
|
|
17
100
|
|
|
18
101
|
[Longer description of how to use the addon in apps.]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import type { ComboBoxItems, ComboBoxOption } from './combobox-shared.ts';
|
|
3
|
+
export type LabelVisibility = 'visible' | 'hidden';
|
|
4
|
+
export interface ComboBoxFieldSignature {
|
|
5
|
+
Element: HTMLDivElement;
|
|
6
|
+
Args: {
|
|
7
|
+
/** Label text (required). */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Available options. Flat or pre-grouped. */
|
|
10
|
+
items: ComboBoxItems;
|
|
11
|
+
/** Current selected value (controlled). */
|
|
12
|
+
value?: string | null;
|
|
13
|
+
/** Fires when the selection changes. */
|
|
14
|
+
onChange?: (value: string | null, option: ComboBoxOption | null) => void;
|
|
15
|
+
/** Async search (passed through to ComboBox). */
|
|
16
|
+
onSearch?: (query: string) => Promise<ComboBoxItems>;
|
|
17
|
+
/** Debounce for `onSearch` in ms. */
|
|
18
|
+
searchDebounceMs?: number;
|
|
19
|
+
/** Force the loading state. */
|
|
20
|
+
isLoading?: boolean;
|
|
21
|
+
/** Called when an `onSearch` promise rejects. */
|
|
22
|
+
onSearchError?: (error: unknown) => void;
|
|
23
|
+
/** Loading row text. */
|
|
24
|
+
loadingText?: string;
|
|
25
|
+
/** Input placeholder. */
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
/** Empty state text. */
|
|
28
|
+
noResultsText?: string;
|
|
29
|
+
/** Allow creating new options from a non-matching query. */
|
|
30
|
+
isCreatable?: boolean;
|
|
31
|
+
/** Fires when the user activates the create row. */
|
|
32
|
+
onCreate?: (query: string) => void;
|
|
33
|
+
/** Build the create-row label. */
|
|
34
|
+
createLabel?: (query: string) => string;
|
|
35
|
+
/** Help text displayed below the control. */
|
|
36
|
+
helpText?: string;
|
|
37
|
+
/** Error message (also sets invalid state). */
|
|
38
|
+
error?: string;
|
|
39
|
+
/** Field is required. */
|
|
40
|
+
isRequired?: boolean;
|
|
41
|
+
/** Field is disabled. */
|
|
42
|
+
isDisabled?: boolean;
|
|
43
|
+
/** Show the clear button when a value is set. */
|
|
44
|
+
isClearable?: boolean;
|
|
45
|
+
/** Info tooltip text shown next to the label. */
|
|
46
|
+
labelInfo?: string;
|
|
47
|
+
/** Label visibility. */
|
|
48
|
+
labelVisibility?: LabelVisibility;
|
|
49
|
+
/** Input name for forms. */
|
|
50
|
+
name?: string;
|
|
51
|
+
/** Blur event handler. */
|
|
52
|
+
onBlur?: (event: FocusEvent) => void;
|
|
53
|
+
/** Focus event handler. */
|
|
54
|
+
onFocus?: (event: FocusEvent) => void;
|
|
55
|
+
/** Fires when the dropdown opens. */
|
|
56
|
+
onOpen?: () => void;
|
|
57
|
+
/** Fires when the dropdown closes. */
|
|
58
|
+
onClose?: () => void;
|
|
59
|
+
};
|
|
60
|
+
Blocks: {
|
|
61
|
+
/** Rich tooltip content shown next to the label. */
|
|
62
|
+
info: [];
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export default class ComboBoxField extends Component<ComboBoxFieldSignature> {
|
|
66
|
+
get isInvalid(): boolean;
|
|
67
|
+
get isLabelHidden(): boolean;
|
|
68
|
+
/** Build aria-describedby from the control's help text and error IDs. */
|
|
69
|
+
getAriaDescribedBy: (controlId: string) => string | undefined;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=combobox-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox-field.d.ts","sourceRoot":"","sources":["../../src/form/combobox-field.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAI3C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE;QACJ,6BAA6B;QAC7B,KAAK,EAAE,MAAM,CAAC;QAEd,8CAA8C;QAC9C,KAAK,EAAE,aAAa,CAAC;QAErB,2CAA2C;QAC3C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAEtB,wCAAwC;QACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;QAEzE,iDAAiD;QACjD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;QAErD,qCAAqC;QACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAE1B,+BAA+B;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;QAEpB,iDAAiD;QACjD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAEzC,wBAAwB;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,yBAAyB;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,wBAAwB;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QAEvB,4DAA4D;QAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB,oDAAoD;QACpD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAEnC,kCAAkC;QAClC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAExC,6CAA6C;QAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAElB,+CAA+C;QAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf,yBAAyB;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QAErB,yBAAyB;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QAErB,iDAAiD;QACjD,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAC;QAEnB,wBAAwB;QACxB,eAAe,CAAC,EAAE,eAAe,CAAC;QAElC,4BAA4B;QAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;QAEd,0BAA0B;QAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;QAErC,2BAA2B;QAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;QAEtC,qCAAqC;QACrC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;QAEpB,sCAAsC;QACtC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,oDAAoD;QACpD,IAAI,EAAE,EAAE,CAAC;KACV,CAAC;CACH;AAED,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,SAAS,CAAC,sBAAsB,CAAC;IAC1E,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,yEAAyE;IACzE,kBAAkB,cAAe,MAAM,KAAG,MAAM,GAAG,SAAS,CAS1D;CAkEH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
declare const _default: {};
|
|
2
|
+
export default _default;
|
|
3
|
+
export interface ComboBoxOption {
|
|
4
|
+
/** Stable identity — what value / onChange refer to. */
|
|
5
|
+
value: string;
|
|
6
|
+
/** What the user sees in the trigger + option list. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Optional secondary line shown under the label in the option list. */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** Disabled options render but are not selectable. */
|
|
11
|
+
isDisabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ComboBoxOptionGroup {
|
|
14
|
+
/** Heading text shown above the group (non-selectable). */
|
|
15
|
+
label: string;
|
|
16
|
+
options: ComboBoxOption[];
|
|
17
|
+
}
|
|
18
|
+
export type ComboBoxItems = ComboBoxOption[] | ComboBoxOptionGroup[];
|
|
19
|
+
export interface MatchSegment {
|
|
20
|
+
text: string;
|
|
21
|
+
isMatch: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Splits `label` into alternating match / non-match segments based on a
|
|
25
|
+
* case-insensitive substring search for `query`. Used in templates to
|
|
26
|
+
* render matched substrings in <mark>-style spans.
|
|
27
|
+
*/
|
|
28
|
+
export declare function splitOnMatch(label: string, query: string): MatchSegment[];
|
|
29
|
+
/** Discriminator for flat option vs grouped option shape. */
|
|
30
|
+
export declare function isOptionGroup(item: ComboBoxOption | ComboBoxOptionGroup): item is ComboBoxOptionGroup;
|
|
31
|
+
/** Flatten `ComboBoxItems` to a single array of options regardless of whether
|
|
32
|
+
* the source was grouped. Used for lookups across the whole option universe
|
|
33
|
+
* (e.g., resolving a selected value to its label, duplicate-by-label checks
|
|
34
|
+
* for the create row). */
|
|
35
|
+
export declare function flattenOptions(items: ComboBoxItems): ComboBoxOption[];
|
|
36
|
+
//# sourceMappingURL=combobox-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox-shared.d.ts","sourceRoot":"","sources":["../../src/form/combobox-shared.ts"],"names":[],"mappings":";AAQA,wBAAkB;AAElB,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,EAAE,GAAG,mBAAmB,EAAE,CAAC;AAMrE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CA0BzE;AAMD,6DAA6D;AAC7D,wBAAgB,aAAa,CAC3B,IAAI,EAAE,cAAc,GAAG,mBAAmB,GACzC,IAAI,IAAI,mBAAmB,CAE7B;AAED;;;2BAG2B;AAC3B,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,EAAE,CAMrE"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { type ComboBoxItems, type ComboBoxOption, type ComboBoxOptionGroup } from './combobox-shared.ts';
|
|
3
|
+
export type { ComboBoxItems, ComboBoxOption, ComboBoxOptionGroup };
|
|
4
|
+
export interface ComboBoxSignature {
|
|
5
|
+
Element: HTMLDivElement;
|
|
6
|
+
Args: {
|
|
7
|
+
/** Available options. Either a flat array or pre-grouped. */
|
|
8
|
+
items: ComboBoxItems;
|
|
9
|
+
/** Current selected value (controlled). */
|
|
10
|
+
value?: string | null;
|
|
11
|
+
/** Fires when the selection changes. */
|
|
12
|
+
onChange?: (value: string | null, option: ComboBoxOption | null) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Async search. When provided, replaces the local filter — the component
|
|
15
|
+
* calls this with the debounced query and renders whatever it returns.
|
|
16
|
+
*/
|
|
17
|
+
onSearch?: (query: string) => Promise<ComboBoxItems>;
|
|
18
|
+
/** Debounce window for `onSearch` calls in ms. Defaults to 200. */
|
|
19
|
+
searchDebounceMs?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Force the loading state. Useful when the consumer drives loading
|
|
22
|
+
* itself (e.g., a separate cache lookup); otherwise the component
|
|
23
|
+
* tracks loading internally for `onSearch` calls.
|
|
24
|
+
*/
|
|
25
|
+
isLoading?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Fires when an `onSearch` promise rejects. The component clears
|
|
28
|
+
* its own loading state either way; this hook lets the consumer
|
|
29
|
+
* surface an error in the UI (banner, retry, log). If omitted,
|
|
30
|
+
* the rejection surfaces as an unhandled promise rejection and
|
|
31
|
+
* the stale items from the previous resolved call remain visible.
|
|
32
|
+
*/
|
|
33
|
+
onSearchError?: (error: unknown) => void;
|
|
34
|
+
/** Text shown in the loading row. Defaults to "Loading…". */
|
|
35
|
+
loadingText?: string;
|
|
36
|
+
/** Placeholder shown in the input when no value is selected. */
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
/** Text shown when filter yields no matches. */
|
|
39
|
+
noResultsText?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Allow users to "create" a new option from a non-matching query.
|
|
42
|
+
* When true and the query is non-empty + has no exact label match, a
|
|
43
|
+
* "Create '<query>'" row appears at the bottom of the listbox.
|
|
44
|
+
* Pressing Enter on it (or clicking it) fires `onCreate(query)`.
|
|
45
|
+
*/
|
|
46
|
+
isCreatable?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Called when the user activates the create row. The consumer is
|
|
49
|
+
* responsible for folding the new option into `items` and `value`.
|
|
50
|
+
*/
|
|
51
|
+
onCreate?: (query: string) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Build the create-row label. Defaults to `Create "<query>"`.
|
|
54
|
+
*/
|
|
55
|
+
createLabel?: (query: string) => string;
|
|
56
|
+
/** Disable the control entirely. */
|
|
57
|
+
isDisabled?: boolean;
|
|
58
|
+
/** Render in invalid (error) state. */
|
|
59
|
+
isInvalid?: boolean;
|
|
60
|
+
/** Mark the control as required. */
|
|
61
|
+
isRequired?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Show the clear button when a value is selected.
|
|
64
|
+
* Also enables Escape-to-clear when the input is focused and the
|
|
65
|
+
* dropdown is closed. Defaults to `true`.
|
|
66
|
+
*/
|
|
67
|
+
isClearable?: boolean;
|
|
68
|
+
/** Form-association name for the hidden input. */
|
|
69
|
+
name?: string;
|
|
70
|
+
/** ID for the input element (typically provided by Control). */
|
|
71
|
+
id?: string;
|
|
72
|
+
/** aria-describedby for accessibility (typically provided by Control). */
|
|
73
|
+
'aria-describedby'?: string;
|
|
74
|
+
/** Fires on input blur. */
|
|
75
|
+
onBlur?: (event: FocusEvent) => void;
|
|
76
|
+
/** Fires on input focus. */
|
|
77
|
+
onFocus?: (event: FocusEvent) => void;
|
|
78
|
+
/** Fires when the dropdown opens. Useful for analytics or lazy-loading. */
|
|
79
|
+
onOpen?: () => void;
|
|
80
|
+
/** Fires when the dropdown closes. */
|
|
81
|
+
onClose?: () => void;
|
|
82
|
+
};
|
|
83
|
+
Blocks: {
|
|
84
|
+
default: [];
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
interface NormalizedGroup {
|
|
88
|
+
label: string | null;
|
|
89
|
+
headingId: string | null;
|
|
90
|
+
options: ComboBoxOption[];
|
|
91
|
+
}
|
|
92
|
+
interface OptionRow {
|
|
93
|
+
kind: 'option';
|
|
94
|
+
option: ComboBoxOption;
|
|
95
|
+
optionId: string;
|
|
96
|
+
isActive: boolean;
|
|
97
|
+
isSelected: boolean;
|
|
98
|
+
}
|
|
99
|
+
interface CreateRow {
|
|
100
|
+
kind: 'create';
|
|
101
|
+
optionId: string;
|
|
102
|
+
isActive: boolean;
|
|
103
|
+
query: string;
|
|
104
|
+
label: string;
|
|
105
|
+
}
|
|
106
|
+
type Row = OptionRow | CreateRow;
|
|
107
|
+
interface RenderedGroup {
|
|
108
|
+
/** Stable key for {{#each}} — either the headingId for labelled groups
|
|
109
|
+
* or a fixed sentinel for the implicit ungrouped bucket. Without this
|
|
110
|
+
* Glimmer tears down + recreates the option DOM whenever activeId
|
|
111
|
+
* changes, breaking any captured DOM references in tests. */
|
|
112
|
+
key: string;
|
|
113
|
+
label: string | null;
|
|
114
|
+
headingId: string | null;
|
|
115
|
+
rows: OptionRow[];
|
|
116
|
+
}
|
|
117
|
+
export default class ComboBox extends Component<ComboBoxSignature> {
|
|
118
|
+
isOpen: boolean;
|
|
119
|
+
query: string;
|
|
120
|
+
activeId: string | null;
|
|
121
|
+
private remoteItems;
|
|
122
|
+
private isLoadingInternal;
|
|
123
|
+
private searchSeq;
|
|
124
|
+
private searchTimer;
|
|
125
|
+
inputElement: HTMLInputElement | null;
|
|
126
|
+
listboxElement: HTMLDivElement | null;
|
|
127
|
+
componentId: string;
|
|
128
|
+
listboxId: string;
|
|
129
|
+
createOptionId: string;
|
|
130
|
+
willDestroy(): void;
|
|
131
|
+
get isAsync(): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Source of truth for what's available to render. In async mode, we use
|
|
134
|
+
* the latest remote payload once it's resolved; before that, we fall
|
|
135
|
+
* back to `@items` so the dropdown isn't empty on first open.
|
|
136
|
+
*/
|
|
137
|
+
get effectiveItems(): ComboBoxItems;
|
|
138
|
+
get normalizedGroups(): NormalizedGroup[];
|
|
139
|
+
/**
|
|
140
|
+
* Per-group filtered output for rendering. In async mode we trust the
|
|
141
|
+
* server response and skip the local substring filter; otherwise we
|
|
142
|
+
* apply case-insensitive substring on `label` + `description`.
|
|
143
|
+
* Empty groups (no matches) are dropped so we don't render bare
|
|
144
|
+
* headings.
|
|
145
|
+
*/
|
|
146
|
+
get renderedGroups(): RenderedGroup[];
|
|
147
|
+
/**
|
|
148
|
+
* Flat list of option rows used for keyboard navigation. Excludes
|
|
149
|
+
* disabled options and group headings (headings aren't selectable).
|
|
150
|
+
* The create row, if visible, is appended at the end.
|
|
151
|
+
*/
|
|
152
|
+
get navigableRows(): Row[];
|
|
153
|
+
get hasOptionResults(): boolean;
|
|
154
|
+
get isCreateVisible(): boolean;
|
|
155
|
+
get createRow(): CreateRow | null;
|
|
156
|
+
get isLoading(): boolean;
|
|
157
|
+
get loadingText(): string;
|
|
158
|
+
get searchDebounceMs(): number;
|
|
159
|
+
scheduleAsyncSearch(query: string): void;
|
|
160
|
+
runAsyncSearch(query: string): Promise<void>;
|
|
161
|
+
get selectedOption(): ComboBoxOption | null;
|
|
162
|
+
/**
|
|
163
|
+
* What the input renders as its `value` attribute.
|
|
164
|
+
*
|
|
165
|
+
* - When the dropdown is open, we surface the user's typed query so
|
|
166
|
+
* typing feels like editing a normal text field and the filter
|
|
167
|
+
* reflects what they see.
|
|
168
|
+
* - When closed, we surface the selected option's label (or empty
|
|
169
|
+
* string if nothing's selected) so the input acts as a read-only
|
|
170
|
+
* display of the current value.
|
|
171
|
+
*
|
|
172
|
+
* The placeholder argument shows when this is empty.
|
|
173
|
+
*/
|
|
174
|
+
get displayValue(): string;
|
|
175
|
+
get hasValue(): boolean;
|
|
176
|
+
get isClearable(): boolean;
|
|
177
|
+
get showClearButton(): boolean;
|
|
178
|
+
get noResultsText(): string;
|
|
179
|
+
/**
|
|
180
|
+
* Text for the visually-hidden aria-live region. Screen-reader users
|
|
181
|
+
* need feedback on how their typing is shaping the result set — this
|
|
182
|
+
* announces counts and empty-state without showing anything visible.
|
|
183
|
+
*
|
|
184
|
+
* The region renders only when the dropdown is open so we don't
|
|
185
|
+
* announce stale counts after the user closes it.
|
|
186
|
+
*/
|
|
187
|
+
get announcement(): string;
|
|
188
|
+
get showEmptyState(): boolean;
|
|
189
|
+
get ariaExpanded(): 'true' | 'false';
|
|
190
|
+
get ariaRequired(): 'true' | undefined;
|
|
191
|
+
get ariaInvalid(): 'true' | undefined;
|
|
192
|
+
setupInput: import("ember-modifier").FunctionBasedModifier<{
|
|
193
|
+
Args: {
|
|
194
|
+
Positional: unknown[];
|
|
195
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
196
|
+
};
|
|
197
|
+
Element: HTMLInputElement;
|
|
198
|
+
}>;
|
|
199
|
+
setupListbox: import("ember-modifier").FunctionBasedModifier<{
|
|
200
|
+
Args: {
|
|
201
|
+
Positional: unknown[];
|
|
202
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
203
|
+
};
|
|
204
|
+
Element: HTMLDivElement;
|
|
205
|
+
}>;
|
|
206
|
+
handleInputFocus: (event: FocusEvent) => void;
|
|
207
|
+
handleInputBlur: (event: FocusEvent) => void;
|
|
208
|
+
handleInputClick: () => void;
|
|
209
|
+
handleInput: (event: Event) => void;
|
|
210
|
+
handleInputKeyDown: (event: KeyboardEvent) => void;
|
|
211
|
+
handleChevronMouseDown: (event: MouseEvent) => void;
|
|
212
|
+
handleChevronClick: (event: MouseEvent) => void;
|
|
213
|
+
openDropdown: (opts?: {
|
|
214
|
+
resetActive?: boolean;
|
|
215
|
+
}) => void;
|
|
216
|
+
closeDropdown: () => void;
|
|
217
|
+
handleOpenChange: (open: boolean) => void;
|
|
218
|
+
resetActiveToInitial(): void;
|
|
219
|
+
resetActiveToFirstNavigable(): void;
|
|
220
|
+
setActiveToFirst(): void;
|
|
221
|
+
setActiveToLast(): void;
|
|
222
|
+
moveActive(direction: 1 | -1): void;
|
|
223
|
+
/**
|
|
224
|
+
* Move the active row by `PAGE_STEP` items. Unlike `moveActive`,
|
|
225
|
+
* PageUp/PageDown don't wrap — they clamp to the first/last row so
|
|
226
|
+
* the user always lands on a valid entry at the ends.
|
|
227
|
+
*/
|
|
228
|
+
movePage(direction: 1 | -1): void;
|
|
229
|
+
scrollActiveIntoView(): void;
|
|
230
|
+
activateActive(): void;
|
|
231
|
+
selectOption: (option: ComboBoxOption) => void;
|
|
232
|
+
fireCreate: () => void;
|
|
233
|
+
handleOptionMouseDown: (event: MouseEvent) => void;
|
|
234
|
+
handleOptionMouseEnter: (optionId: string) => void;
|
|
235
|
+
handleClearMouseDown: (event: MouseEvent) => void;
|
|
236
|
+
handleClearClick: (event: MouseEvent) => void;
|
|
237
|
+
clearSelection(): void;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=combobox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/form/combobox.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { default as Calendar } from './calendar';
|
|
2
2
|
export { default as Checkbox } from './checkbox';
|
|
3
3
|
export { default as CheckboxGroup } from './checkbox-group';
|
|
4
|
+
export { default as ComboBox } from './combobox';
|
|
5
|
+
export { default as ComboBoxField } from './combobox-field';
|
|
6
|
+
export { default as MultiComboBox } from './multi-combobox';
|
|
7
|
+
export { default as MultiComboBoxField } from './multi-combobox-field';
|
|
4
8
|
export { default as Control } from './control';
|
|
5
9
|
export { default as CountrySelect } from './country-select';
|
|
6
10
|
export { default as CountrySelectField } from './country-select-field';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/form/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/form/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import type { ComboBoxItems, ComboBoxOption } from './combobox-shared.ts';
|
|
3
|
+
export type LabelVisibility = 'visible' | 'hidden';
|
|
4
|
+
export interface MultiComboBoxFieldSignature {
|
|
5
|
+
Element: HTMLDivElement;
|
|
6
|
+
Args: {
|
|
7
|
+
/** Label text (required). */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Available options. Flat or pre-grouped. */
|
|
10
|
+
items: ComboBoxItems;
|
|
11
|
+
/** Current selected values (controlled). */
|
|
12
|
+
values?: string[];
|
|
13
|
+
/** Fires when the selection changes. */
|
|
14
|
+
onChange?: (values: string[], options: ComboBoxOption[]) => void;
|
|
15
|
+
/** Async search. */
|
|
16
|
+
onSearch?: (query: string) => Promise<ComboBoxItems>;
|
|
17
|
+
/** Debounce for `onSearch` in ms. */
|
|
18
|
+
searchDebounceMs?: number;
|
|
19
|
+
/** Force the loading state. */
|
|
20
|
+
isLoading?: boolean;
|
|
21
|
+
/** Called when an `onSearch` promise rejects. */
|
|
22
|
+
onSearchError?: (error: unknown) => void;
|
|
23
|
+
/** Loading row text. */
|
|
24
|
+
loadingText?: string;
|
|
25
|
+
/** Input placeholder when no values selected. */
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
/** Empty state text. */
|
|
28
|
+
noResultsText?: string;
|
|
29
|
+
/** Allow creating new options from a non-matching query. */
|
|
30
|
+
isCreatable?: boolean;
|
|
31
|
+
/** Fires when the user activates the create row. */
|
|
32
|
+
onCreate?: (query: string) => void;
|
|
33
|
+
/** Build the create-row label. */
|
|
34
|
+
createLabel?: (query: string) => string;
|
|
35
|
+
/** Chips shown before collapsing to "+N more". */
|
|
36
|
+
maxVisibleChips?: number;
|
|
37
|
+
/** Help text displayed below the control. */
|
|
38
|
+
helpText?: string;
|
|
39
|
+
/** Error message (also sets invalid state). */
|
|
40
|
+
error?: string;
|
|
41
|
+
/** Field is required. */
|
|
42
|
+
isRequired?: boolean;
|
|
43
|
+
/** Field is disabled. */
|
|
44
|
+
isDisabled?: boolean;
|
|
45
|
+
/** Show the clear-all button when values are set. */
|
|
46
|
+
isClearable?: boolean;
|
|
47
|
+
/** Info tooltip text shown next to the label. */
|
|
48
|
+
labelInfo?: string;
|
|
49
|
+
/** Label visibility. */
|
|
50
|
+
labelVisibility?: LabelVisibility;
|
|
51
|
+
/** Input name — one hidden input is rendered per selected value. */
|
|
52
|
+
name?: string;
|
|
53
|
+
/** Blur event handler. */
|
|
54
|
+
onBlur?: (event: FocusEvent) => void;
|
|
55
|
+
/** Focus event handler. */
|
|
56
|
+
onFocus?: (event: FocusEvent) => void;
|
|
57
|
+
/** Fires when the dropdown opens. */
|
|
58
|
+
onOpen?: () => void;
|
|
59
|
+
/** Fires when the dropdown closes. */
|
|
60
|
+
onClose?: () => void;
|
|
61
|
+
};
|
|
62
|
+
Blocks: {
|
|
63
|
+
/** Rich tooltip content shown next to the label. */
|
|
64
|
+
info: [];
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export default class MultiComboBoxField extends Component<MultiComboBoxFieldSignature> {
|
|
68
|
+
get isInvalid(): boolean;
|
|
69
|
+
get isLabelHidden(): boolean;
|
|
70
|
+
getAriaDescribedBy: (controlId: string) => string | undefined;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=multi-combobox-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-combobox-field.d.ts","sourceRoot":"","sources":["../../src/form/multi-combobox-field.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAI3C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE;QACJ,6BAA6B;QAC7B,KAAK,EAAE,MAAM,CAAC;QAEd,8CAA8C;QAC9C,KAAK,EAAE,aAAa,CAAC;QAErB,4CAA4C;QAC5C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAElB,wCAAwC;QACxC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;QAEjE,oBAAoB;QACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;QAErD,qCAAqC;QACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAE1B,+BAA+B;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;QAEpB,iDAAiD;QACjD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAEzC,wBAAwB;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,iDAAiD;QACjD,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,wBAAwB;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QAEvB,4DAA4D;QAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB,oDAAoD;QACpD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAEnC,kCAAkC;QAClC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAExC,kDAAkD;QAClD,eAAe,CAAC,EAAE,MAAM,CAAC;QAEzB,6CAA6C;QAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAElB,+CAA+C;QAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf,yBAAyB;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QAErB,yBAAyB;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QAErB,qDAAqD;QACrD,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAC;QAEnB,wBAAwB;QACxB,eAAe,CAAC,EAAE,eAAe,CAAC;QAElC,oEAAoE;QACpE,IAAI,CAAC,EAAE,MAAM,CAAC;QAEd,0BAA0B;QAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;QAErC,2BAA2B;QAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;QAEtC,qCAAqC;QACrC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;QAEpB,sCAAsC;QACtC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,oDAAoD;QACpD,IAAI,EAAE,EAAE,CAAC;KACV,CAAC;CACH;AAED,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,SAAS,CAAC,2BAA2B,CAAC;IACpF,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,kBAAkB,cAAe,MAAM,KAAG,MAAM,GAAG,SAAS,CAS1D;CAkEH"}
|