ember-primitives 0.48.2 → 0.50.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/bin/index.mjs +271 -0
- package/declarations/components/portal.d.ts.map +1 -1
- package/declarations/components/rating/public-types.d.ts +0 -4
- package/declarations/components/rating/public-types.d.ts.map +1 -1
- package/declarations/components/rating/rating.d.ts +9 -1
- package/declarations/components/rating/rating.d.ts.map +1 -1
- package/declarations/components/rating/stars.d.ts.map +1 -1
- package/declarations/components/rating/state.d.ts +4 -0
- package/declarations/components/rating/state.d.ts.map +1 -1
- package/declarations/components/rating/utils.d.ts +0 -1
- package/declarations/components/rating/utils.d.ts.map +1 -1
- package/declarations/tabster.d.ts.map +1 -1
- package/declarations/utils.d.ts.map +1 -1
- package/declarations/viewport/in-viewport.d.ts +70 -0
- package/declarations/viewport/in-viewport.d.ts.map +1 -0
- package/declarations/viewport/viewport.d.ts +59 -0
- package/declarations/viewport/viewport.d.ts.map +1 -0
- package/declarations/viewport.d.ts +3 -0
- package/declarations/viewport.d.ts.map +1 -0
- package/dist/-private.js +0 -1
- package/dist/-private.js.map +1 -1
- package/dist/color-scheme.js +0 -1
- package/dist/color-scheme.js.map +1 -1
- package/dist/{component-Bs3N-G9z.js → component-BXy_iafw.js} +2 -3
- package/dist/component-BXy_iafw.js.map +1 -0
- package/dist/components/accordion.js +5 -6
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/avatar.js +3 -4
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/dialog.js +2 -3
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/external-link.js +1 -2
- package/dist/components/external-link.js.map +1 -1
- package/dist/components/form.js +1 -2
- package/dist/components/form.js.map +1 -1
- package/dist/components/heading.js +1 -2
- package/dist/components/heading.js.map +1 -1
- package/dist/components/keys.js +2 -3
- package/dist/components/keys.js.map +1 -1
- package/dist/components/layout/hero.js +1 -1
- package/dist/components/layout/sticky-footer.js +1 -1
- package/dist/components/link.js +1 -2
- package/dist/components/link.js.map +1 -1
- package/dist/components/menu.js +6 -8
- package/dist/components/menu.js.map +1 -1
- package/dist/components/one-time-password.js +1 -2
- package/dist/components/popover.js +3 -4
- package/dist/components/popover.js.map +1 -1
- package/dist/components/portal-targets.js +2 -3
- package/dist/components/portal-targets.js.map +1 -1
- package/dist/components/portal.js +3 -7
- package/dist/components/portal.js.map +1 -1
- package/dist/components/progress.js +2 -3
- package/dist/components/progress.js.map +1 -1
- package/dist/components/rating.js +1 -2
- package/dist/components/scroller.js +1 -2
- package/dist/components/scroller.js.map +1 -1
- package/dist/components/shadowed.js +2 -3
- package/dist/components/shadowed.js.map +1 -1
- package/dist/components/switch.js +5 -6
- package/dist/components/switch.js.map +1 -1
- package/dist/components/tabs.js +6 -7
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/toggle-group.js +3 -4
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js +2 -3
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/visually-hidden.js +1 -2
- package/dist/components/visually-hidden.js.map +1 -1
- package/dist/components/zoetrope.js +1 -2
- package/dist/dom-context.js +2 -3
- package/dist/dom-context.js.map +1 -1
- package/dist/floating-ui.js +1 -2
- package/dist/head.js +1 -2
- package/dist/head.js.map +1 -1
- package/dist/helpers/body-class.js +0 -1
- package/dist/helpers/body-class.js.map +1 -1
- package/dist/helpers/link.js +0 -1
- package/dist/helpers/link.js.map +1 -1
- package/dist/helpers/service.js +0 -1
- package/dist/helpers/service.js.map +1 -1
- package/dist/helpers.js +0 -1
- package/dist/helpers.js.map +1 -1
- package/dist/iframe.js +0 -1
- package/dist/iframe.js.map +1 -1
- package/dist/{index-DKE67I8L.js → index-gRO4Cvlf.js} +2 -2
- package/dist/index-gRO4Cvlf.js.map +1 -0
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/load.js +0 -1
- package/dist/load.js.map +1 -1
- package/dist/narrowing.js +0 -1
- package/dist/narrowing.js.map +1 -1
- package/dist/on-resize.js +0 -1
- package/dist/on-resize.js.map +1 -1
- package/dist/{otp-C6hCCXKx.js → otp-7rz1PWP0.js} +6 -7
- package/dist/otp-7rz1PWP0.js.map +1 -0
- package/dist/proper-links.js +0 -1
- package/dist/proper-links.js.map +1 -1
- package/dist/qp.js +0 -1
- package/dist/qp.js.map +1 -1
- package/dist/rating-BrIiwDLw.js +152 -0
- package/dist/rating-BrIiwDLw.js.map +1 -0
- package/dist/resize-observer.js +0 -1
- package/dist/resize-observer.js.map +1 -1
- package/dist/service.js +0 -1
- package/dist/service.js.map +1 -1
- package/dist/store.js +0 -1
- package/dist/store.js.map +1 -1
- package/dist/styles.css.js +0 -1
- package/dist/tabster.js +0 -1
- package/dist/tabster.js.map +1 -1
- package/dist/test-support.js +0 -1
- package/dist/test-support.js.map +1 -1
- package/dist/{utils-C5796IKA.js → utils-D0v9WKmV.js} +1 -2
- package/dist/utils-D0v9WKmV.js.map +1 -0
- package/dist/utils.js +4 -1
- package/dist/utils.js.map +1 -1
- package/dist/viewport/in-viewport.js +82 -0
- package/dist/viewport/in-viewport.js.map +1 -0
- package/dist/viewport/viewport.js +92 -0
- package/dist/viewport/viewport.js.map +1 -0
- package/dist/viewport.js +3 -0
- package/dist/viewport.js.map +1 -0
- package/package.json +24 -20
- package/src/-private.ts +4 -0
- package/src/color-scheme.ts +165 -0
- package/src/components/-private/typed-elements.gts +13 -0
- package/src/components/-private/utils.ts +16 -0
- package/src/components/accordion/content.gts +34 -0
- package/src/components/accordion/header.gts +36 -0
- package/src/components/accordion/item.gts +55 -0
- package/src/components/accordion/public.ts +64 -0
- package/src/components/accordion/trigger.gts +32 -0
- package/src/components/accordion.gts +195 -0
- package/src/components/avatar.gts +108 -0
- package/src/components/dialog.gts +234 -0
- package/src/components/external-link.gts +14 -0
- package/src/components/form.gts +75 -0
- package/src/components/heading.gts +36 -0
- package/src/components/keys.gts +53 -0
- package/src/components/layout/hero.css +5 -0
- package/src/components/layout/hero.gts +17 -0
- package/src/components/layout/sticky-footer.css +9 -0
- package/src/components/layout/sticky-footer.gts +40 -0
- package/src/components/link.gts +172 -0
- package/src/components/menu.gts +373 -0
- package/src/components/one-time-password/buttons.gts +31 -0
- package/src/components/one-time-password/input.gts +198 -0
- package/src/components/one-time-password/otp.gts +130 -0
- package/src/components/one-time-password/utils.ts +201 -0
- package/src/components/one-time-password.gts +2 -0
- package/src/components/popover.gts +248 -0
- package/src/components/portal-targets.gts +136 -0
- package/src/components/portal.gts +194 -0
- package/src/components/progress.gts +154 -0
- package/src/components/rating/public-types.ts +44 -0
- package/src/components/rating/range.gts +22 -0
- package/src/components/rating/rating.gts +228 -0
- package/src/components/rating/stars.gts +60 -0
- package/src/components/rating/state.gts +144 -0
- package/src/components/rating/utils.ts +7 -0
- package/src/components/rating.gts +5 -0
- package/src/components/scroller.gts +179 -0
- package/src/components/shadowed.gts +110 -0
- package/src/components/switch.gts +103 -0
- package/src/components/tabs.gts +519 -0
- package/src/components/toggle-group.gts +265 -0
- package/src/components/toggle.gts +81 -0
- package/src/components/violations.css +105 -0
- package/src/components/violations.css.ts +1 -0
- package/src/components/visually-hidden.css +14 -0
- package/src/components/visually-hidden.gts +15 -0
- package/src/components/zoetrope/index.gts +358 -0
- package/src/components/zoetrope/styles.css +40 -0
- package/src/components/zoetrope/types.ts +65 -0
- package/src/components/zoetrope.ts +3 -0
- package/src/dom-context.gts +245 -0
- package/src/floating-ui/component.gts +186 -0
- package/src/floating-ui/middleware.ts +13 -0
- package/src/floating-ui/modifier.ts +183 -0
- package/src/floating-ui.ts +2 -0
- package/src/head.gts +37 -0
- package/src/helpers/body-class.ts +94 -0
- package/src/helpers/link.ts +125 -0
- package/src/helpers/service.ts +25 -0
- package/src/helpers.ts +2 -0
- package/src/iframe.ts +31 -0
- package/src/index.ts +43 -0
- package/src/load.gts +77 -0
- package/src/narrowing.ts +7 -0
- package/src/on-resize.ts +64 -0
- package/src/proper-links.ts +140 -0
- package/src/qp.ts +107 -0
- package/src/resize-observer.ts +132 -0
- package/src/service.ts +103 -0
- package/src/store.ts +72 -0
- package/src/styles.css.ts +5 -0
- package/src/tabster.ts +54 -0
- package/src/template-registry.ts +44 -0
- package/src/test-support/a11y.ts +50 -0
- package/src/test-support/dom.ts +112 -0
- package/src/test-support/otp.ts +64 -0
- package/src/test-support/rating.ts +144 -0
- package/src/test-support/routing.ts +62 -0
- package/src/test-support/zoetrope.ts +51 -0
- package/src/test-support.gts +6 -0
- package/src/type-utils.ts +1 -0
- package/src/utils.ts +75 -0
- package/src/viewport/in-viewport.gts +128 -0
- package/src/viewport/viewport.ts +122 -0
- package/src/viewport.ts +2 -0
- package/dist/component-Bs3N-G9z.js.map +0 -1
- package/dist/index-DKE67I8L.js.map +0 -1
- package/dist/otp-C6hCCXKx.js.map +0 -1
- package/dist/rating-D052JWRa.js +0 -149
- package/dist/rating-D052JWRa.js.map +0 -1
- package/dist/utils-C5796IKA.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Component from "@glimmer/component";
|
|
2
|
+
|
|
3
|
+
import { getDataState } from "./item.gts";
|
|
4
|
+
|
|
5
|
+
import type { AccordionContentExternalSignature } from "./public.ts";
|
|
6
|
+
|
|
7
|
+
interface Signature extends AccordionContentExternalSignature {
|
|
8
|
+
Args: {
|
|
9
|
+
isExpanded: boolean;
|
|
10
|
+
value: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class AccordionContent extends Component<Signature> {
|
|
16
|
+
<template>
|
|
17
|
+
<div
|
|
18
|
+
role="region"
|
|
19
|
+
id={{@value}}
|
|
20
|
+
data-state={{getDataState @isExpanded}}
|
|
21
|
+
hidden={{this.isHidden}}
|
|
22
|
+
data-disabled={{@disabled}}
|
|
23
|
+
...attributes
|
|
24
|
+
>
|
|
25
|
+
{{yield}}
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
get isHidden() {
|
|
30
|
+
return !this.args.isExpanded;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default AccordionContent;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { hash } from "@ember/helper";
|
|
2
|
+
|
|
3
|
+
import { getDataState } from "./item.gts";
|
|
4
|
+
import Trigger from "./trigger.gts";
|
|
5
|
+
|
|
6
|
+
import type { AccordionHeaderExternalSignature } from "./public.ts";
|
|
7
|
+
import type { TOC } from "@ember/component/template-only";
|
|
8
|
+
|
|
9
|
+
interface Signature extends AccordionHeaderExternalSignature {
|
|
10
|
+
Args: {
|
|
11
|
+
value: string;
|
|
12
|
+
isExpanded: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
toggleItem: () => void;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const AccordionHeader: TOC<Signature> = <template>
|
|
19
|
+
<div
|
|
20
|
+
role="heading"
|
|
21
|
+
aria-level="3"
|
|
22
|
+
data-state={{getDataState @isExpanded}}
|
|
23
|
+
data-disabled={{@disabled}}
|
|
24
|
+
...attributes
|
|
25
|
+
>
|
|
26
|
+
{{yield
|
|
27
|
+
(hash
|
|
28
|
+
Trigger=(component
|
|
29
|
+
Trigger value=@value isExpanded=@isExpanded disabled=@disabled toggleItem=@toggleItem
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
}}
|
|
33
|
+
</div>
|
|
34
|
+
</template>;
|
|
35
|
+
|
|
36
|
+
export default AccordionHeader;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import Component from "@glimmer/component";
|
|
2
|
+
import { hash } from "@ember/helper";
|
|
3
|
+
|
|
4
|
+
import Content from "./content.gts";
|
|
5
|
+
import Header from "./header.gts";
|
|
6
|
+
|
|
7
|
+
import type { AccordionItemExternalSignature } from "./public.ts";
|
|
8
|
+
|
|
9
|
+
export function getDataState(isExpanded: boolean): string {
|
|
10
|
+
return isExpanded ? "open" : "closed";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface Signature extends AccordionItemExternalSignature {
|
|
14
|
+
Args: AccordionItemExternalSignature["Args"] & {
|
|
15
|
+
selectedValue?: string | string[];
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
toggleItem: (value: string) => void;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class AccordionItem extends Component<Signature> {
|
|
22
|
+
<template>
|
|
23
|
+
<div data-state={{getDataState this.isExpanded}} data-disabled={{@disabled}} ...attributes>
|
|
24
|
+
{{yield
|
|
25
|
+
(hash
|
|
26
|
+
isExpanded=this.isExpanded
|
|
27
|
+
Header=(component
|
|
28
|
+
Header
|
|
29
|
+
value=@value
|
|
30
|
+
isExpanded=this.isExpanded
|
|
31
|
+
disabled=@disabled
|
|
32
|
+
toggleItem=this.toggleItem
|
|
33
|
+
)
|
|
34
|
+
Content=(component Content value=@value isExpanded=this.isExpanded disabled=@disabled)
|
|
35
|
+
)
|
|
36
|
+
}}
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
get isExpanded(): boolean {
|
|
41
|
+
if (Array.isArray(this.args.selectedValue)) {
|
|
42
|
+
return this.args.selectedValue.includes(this.args.value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return this.args.selectedValue === this.args.value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
toggleItem = (): void => {
|
|
49
|
+
if (this.args.disabled) return;
|
|
50
|
+
|
|
51
|
+
this.args.toggleItem(this.args.value);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default AccordionItem;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type Content from './content.gts';
|
|
2
|
+
import type Header from './header.gts';
|
|
3
|
+
import type Trigger from './trigger.gts';
|
|
4
|
+
import type { WithBoundArgs } from '@glint/template';
|
|
5
|
+
|
|
6
|
+
export interface AccordionTriggerExternalSignature {
|
|
7
|
+
Element: HTMLButtonElement;
|
|
8
|
+
Blocks: {
|
|
9
|
+
default: [];
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AccordionContentExternalSignature {
|
|
14
|
+
Element: HTMLDivElement;
|
|
15
|
+
Blocks: {
|
|
16
|
+
default: [];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AccordionHeaderExternalSignature {
|
|
21
|
+
/**
|
|
22
|
+
* Add aria-level according to the heading level where the accordion is used (default: 3).
|
|
23
|
+
* See https://www.w3.org/WAI/ARIA/apg/patterns/accordion/ for more information.
|
|
24
|
+
*/
|
|
25
|
+
Element: HTMLDivElement;
|
|
26
|
+
Blocks: {
|
|
27
|
+
default: [
|
|
28
|
+
{
|
|
29
|
+
/**
|
|
30
|
+
* The AccordionTrigger component.
|
|
31
|
+
*/
|
|
32
|
+
Trigger: WithBoundArgs<typeof Trigger, 'value' | 'isExpanded' | 'disabled' | 'toggleItem'>;
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface AccordionItemExternalSignature {
|
|
39
|
+
Element: HTMLDivElement;
|
|
40
|
+
Blocks: {
|
|
41
|
+
default: [
|
|
42
|
+
{
|
|
43
|
+
/**
|
|
44
|
+
* Whether the accordion item is expanded.
|
|
45
|
+
*/
|
|
46
|
+
isExpanded: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The AccordionHeader component.
|
|
49
|
+
*/
|
|
50
|
+
Header: WithBoundArgs<typeof Header, 'value' | 'isExpanded' | 'disabled' | 'toggleItem'>;
|
|
51
|
+
/**
|
|
52
|
+
* The AccordionContent component.
|
|
53
|
+
*/
|
|
54
|
+
Content: WithBoundArgs<typeof Content, 'value' | 'isExpanded' | 'disabled'>;
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
};
|
|
58
|
+
Args: {
|
|
59
|
+
/**
|
|
60
|
+
* The value of the accordion item.
|
|
61
|
+
*/
|
|
62
|
+
value: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { on } from "@ember/modifier";
|
|
2
|
+
|
|
3
|
+
import { getDataState } from "./item.gts";
|
|
4
|
+
|
|
5
|
+
import type { AccordionTriggerExternalSignature } from "./public.ts";
|
|
6
|
+
import type { TOC } from "@ember/component/template-only";
|
|
7
|
+
|
|
8
|
+
interface Signature extends AccordionTriggerExternalSignature {
|
|
9
|
+
Args: {
|
|
10
|
+
isExpanded: boolean;
|
|
11
|
+
value: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
toggleItem: () => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const AccordionTrigger: TOC<Signature> = <template>
|
|
18
|
+
<button
|
|
19
|
+
type="button"
|
|
20
|
+
aria-controls={{@value}}
|
|
21
|
+
aria-expanded={{@isExpanded}}
|
|
22
|
+
data-state={{getDataState @isExpanded}}
|
|
23
|
+
data-disabled={{@disabled}}
|
|
24
|
+
aria-disabled={{if @disabled "true" "false"}}
|
|
25
|
+
{{on "click" @toggleItem}}
|
|
26
|
+
...attributes
|
|
27
|
+
>
|
|
28
|
+
{{yield}}
|
|
29
|
+
</button>
|
|
30
|
+
</template>;
|
|
31
|
+
|
|
32
|
+
export default AccordionTrigger;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import Component from "@glimmer/component";
|
|
2
|
+
import { assert } from "@ember/debug";
|
|
3
|
+
import { hash } from "@ember/helper";
|
|
4
|
+
|
|
5
|
+
// temp
|
|
6
|
+
// https://github.com/tracked-tools/tracked-toolbox/issues/38
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import { localCopy } from "tracked-toolbox";
|
|
10
|
+
|
|
11
|
+
import AccordionItem from "./accordion/item.gts";
|
|
12
|
+
|
|
13
|
+
import type { WithBoundArgs } from "@glint/template";
|
|
14
|
+
|
|
15
|
+
type AccordionSingleArgs = {
|
|
16
|
+
/**
|
|
17
|
+
* The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.
|
|
18
|
+
*/
|
|
19
|
+
type: "single";
|
|
20
|
+
/**
|
|
21
|
+
* Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.
|
|
22
|
+
*/
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* When type is `single`, whether the accordion is collapsible. When `true`, the selected item can be collapsed by clicking its trigger.
|
|
26
|
+
*/
|
|
27
|
+
collapsible?: boolean;
|
|
28
|
+
} & (
|
|
29
|
+
| {
|
|
30
|
+
/**
|
|
31
|
+
* The currently selected value. To be used in a controlled fashion in conjunction with `onValueChange`.
|
|
32
|
+
*/
|
|
33
|
+
value: string;
|
|
34
|
+
/**
|
|
35
|
+
* A callback that is called when the selected value changes. To be used in a controlled fashion in conjunction with `value`.
|
|
36
|
+
*/
|
|
37
|
+
onValueChange: (value: string | undefined) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Not available in a controlled fashion.
|
|
40
|
+
*/
|
|
41
|
+
defaultValue?: never;
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
/**
|
|
45
|
+
* Not available in an uncontrolled fashion.
|
|
46
|
+
*/
|
|
47
|
+
value?: never;
|
|
48
|
+
/**
|
|
49
|
+
* Not available in an uncontrolled fashion.
|
|
50
|
+
*/
|
|
51
|
+
onValueChange?: never;
|
|
52
|
+
/**
|
|
53
|
+
* The default value of the accordion. To be used in an uncontrolled fashion.
|
|
54
|
+
*/
|
|
55
|
+
defaultValue?: string;
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
type AccordionMultipleArgs = {
|
|
60
|
+
/**
|
|
61
|
+
* The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.
|
|
62
|
+
*/
|
|
63
|
+
type: "multiple";
|
|
64
|
+
/**
|
|
65
|
+
* Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.
|
|
66
|
+
*/
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
} & (
|
|
69
|
+
| {
|
|
70
|
+
/**
|
|
71
|
+
* The currently selected values. To be used in a controlled fashion in conjunction with `onValueChange`.
|
|
72
|
+
*/
|
|
73
|
+
value: string[];
|
|
74
|
+
/**
|
|
75
|
+
* A callback that is called when the selected values change. To be used in a controlled fashion in conjunction with `value`.
|
|
76
|
+
*/
|
|
77
|
+
onValueChange: (value?: string[]) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Not available in a controlled fashion.
|
|
80
|
+
*/
|
|
81
|
+
defaultValue?: never;
|
|
82
|
+
}
|
|
83
|
+
| {
|
|
84
|
+
/**
|
|
85
|
+
* Not available in an uncontrolled fashion.
|
|
86
|
+
*/
|
|
87
|
+
value?: never;
|
|
88
|
+
/**
|
|
89
|
+
* Not available in an uncontrolled fashion.
|
|
90
|
+
*/
|
|
91
|
+
onValueChange?: never;
|
|
92
|
+
/**
|
|
93
|
+
* The default values of the accordion. To be used in an uncontrolled fashion.
|
|
94
|
+
*/
|
|
95
|
+
defaultValue?: string[];
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
export class Accordion extends Component<{
|
|
100
|
+
Element: HTMLDivElement;
|
|
101
|
+
Args: AccordionSingleArgs | AccordionMultipleArgs;
|
|
102
|
+
Blocks: {
|
|
103
|
+
default: [
|
|
104
|
+
{
|
|
105
|
+
/**
|
|
106
|
+
* The AccordionItem component.
|
|
107
|
+
*/
|
|
108
|
+
Item: WithBoundArgs<typeof AccordionItem, "selectedValue" | "toggleItem" | "disabled">;
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
};
|
|
112
|
+
}> {
|
|
113
|
+
<template>
|
|
114
|
+
<div data-disabled={{@disabled}} ...attributes>
|
|
115
|
+
{{yield
|
|
116
|
+
(hash
|
|
117
|
+
Item=(component
|
|
118
|
+
AccordionItem
|
|
119
|
+
selectedValue=this.selectedValue
|
|
120
|
+
toggleItem=this.toggleItem
|
|
121
|
+
disabled=@disabled
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
}}
|
|
125
|
+
</div>
|
|
126
|
+
</template>
|
|
127
|
+
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
129
|
+
@localCopy("args.defaultValue") declare _internallyManagedValue?: string | string[];
|
|
130
|
+
|
|
131
|
+
get selectedValue() {
|
|
132
|
+
return this.args.value ?? this._internallyManagedValue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
toggleItem = (value: string) => {
|
|
136
|
+
if (this.args.disabled) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (this.args.type === "single") {
|
|
141
|
+
this.toggleItemSingle(value);
|
|
142
|
+
} else if (this.args.type === "multiple") {
|
|
143
|
+
this.toggleItemMultiple(value);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
toggleItemSingle = (value: string) => {
|
|
148
|
+
assert("Cannot call `toggleItemSingle` when `disabled` is true.", !this.args.disabled);
|
|
149
|
+
assert(
|
|
150
|
+
"Cannot call `toggleItemSingle` when `type` is not `single`.",
|
|
151
|
+
this.args.type === "single",
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
if (value === this.selectedValue && !this.args.collapsible) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const newValue = value === this.selectedValue ? undefined : value;
|
|
159
|
+
|
|
160
|
+
if (this.args.onValueChange) {
|
|
161
|
+
this.args.onValueChange(newValue);
|
|
162
|
+
} else {
|
|
163
|
+
this._internallyManagedValue = newValue;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
toggleItemMultiple = (value: string) => {
|
|
168
|
+
assert("Cannot call `toggleItemMultiple` when `disabled` is true.", !this.args.disabled);
|
|
169
|
+
assert(
|
|
170
|
+
"Cannot call `toggleItemMultiple` when `type` is not `multiple`.",
|
|
171
|
+
this.args.type === "multiple",
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const currentValues = (this.selectedValue as string[] | undefined) ?? [];
|
|
175
|
+
const indexOfValue = currentValues.indexOf(value);
|
|
176
|
+
let newValue: string[];
|
|
177
|
+
|
|
178
|
+
if (indexOfValue === -1) {
|
|
179
|
+
newValue = [...currentValues, value];
|
|
180
|
+
} else {
|
|
181
|
+
newValue = [
|
|
182
|
+
...currentValues.slice(0, indexOfValue),
|
|
183
|
+
...currentValues.slice(indexOfValue + 1),
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (this.args.onValueChange) {
|
|
188
|
+
this.args.onValueChange(newValue);
|
|
189
|
+
} else {
|
|
190
|
+
this._internallyManagedValue = newValue;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export default Accordion;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { hash } from "@ember/helper";
|
|
2
|
+
|
|
3
|
+
import { ReactiveImage } from "reactiveweb/image";
|
|
4
|
+
import { WaitUntil } from "reactiveweb/wait-until";
|
|
5
|
+
|
|
6
|
+
import type { TOC } from "@ember/component/template-only";
|
|
7
|
+
import type { WithBoundArgs } from "@glint/template";
|
|
8
|
+
|
|
9
|
+
const Fallback: TOC<{
|
|
10
|
+
Blocks: { default: [] };
|
|
11
|
+
Args: {
|
|
12
|
+
/**
|
|
13
|
+
* The number of milliseconds to wait for the image to load
|
|
14
|
+
* before displaying the fallback
|
|
15
|
+
*/
|
|
16
|
+
delayMs?: number;
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
* Bound internally by ember-primitives
|
|
20
|
+
*/
|
|
21
|
+
isLoaded: boolean;
|
|
22
|
+
};
|
|
23
|
+
}> = <template>
|
|
24
|
+
{{#unless @isLoaded}}
|
|
25
|
+
{{#let (WaitUntil @delayMs) as |delayFinished|}}
|
|
26
|
+
{{#if delayFinished}}
|
|
27
|
+
{{yield}}
|
|
28
|
+
{{/if}}
|
|
29
|
+
{{/let}}
|
|
30
|
+
{{/unless}}
|
|
31
|
+
</template>;
|
|
32
|
+
|
|
33
|
+
const Image: TOC<{
|
|
34
|
+
Element: HTMLImageElement;
|
|
35
|
+
Args: {
|
|
36
|
+
/**
|
|
37
|
+
* @private
|
|
38
|
+
* The `src` value for the image.
|
|
39
|
+
*
|
|
40
|
+
* Bound internally by ember-primitives
|
|
41
|
+
*/
|
|
42
|
+
src: string;
|
|
43
|
+
/**
|
|
44
|
+
* @private
|
|
45
|
+
* Bound internally by ember-primitives
|
|
46
|
+
*/
|
|
47
|
+
isLoaded: boolean;
|
|
48
|
+
};
|
|
49
|
+
}> = <template>
|
|
50
|
+
{{#if @isLoaded}}
|
|
51
|
+
<img alt="__missing__" ...attributes src={{@src}} />
|
|
52
|
+
{{/if}}
|
|
53
|
+
</template>;
|
|
54
|
+
|
|
55
|
+
export const Avatar: TOC<{
|
|
56
|
+
Element: HTMLSpanElement;
|
|
57
|
+
Args: {
|
|
58
|
+
/**
|
|
59
|
+
* The `src` value for the image.
|
|
60
|
+
*/
|
|
61
|
+
src: string;
|
|
62
|
+
};
|
|
63
|
+
Blocks: {
|
|
64
|
+
default: [
|
|
65
|
+
avatar: {
|
|
66
|
+
/**
|
|
67
|
+
* The image to render. It will only render when it has loaded.
|
|
68
|
+
*/
|
|
69
|
+
Image: WithBoundArgs<typeof Image, "src" | "isLoaded">;
|
|
70
|
+
/**
|
|
71
|
+
* An element that renders when the image hasn't loaded.
|
|
72
|
+
* This means whilst it's loading, or if there was an error.
|
|
73
|
+
* If you notice a flash during loading,
|
|
74
|
+
* you can provide a delayMs prop to delay its rendering so it only renders for those with slower connections.
|
|
75
|
+
*/
|
|
76
|
+
Fallback: WithBoundArgs<typeof Fallback, "isLoaded">;
|
|
77
|
+
/**
|
|
78
|
+
* true while the image is loading
|
|
79
|
+
*/
|
|
80
|
+
isLoading: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* If the image fails to load, this will be `true`
|
|
83
|
+
*/
|
|
84
|
+
isError: boolean;
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
};
|
|
88
|
+
}> = <template>
|
|
89
|
+
{{#let (ReactiveImage @src) as |imgState|}}
|
|
90
|
+
<span
|
|
91
|
+
data-prim-avatar
|
|
92
|
+
...attributes
|
|
93
|
+
data-loading={{imgState.isLoading}}
|
|
94
|
+
data-error={{imgState.isError}}
|
|
95
|
+
>
|
|
96
|
+
{{yield
|
|
97
|
+
(hash
|
|
98
|
+
Image=(component Image src=@src isLoaded=imgState.isResolved)
|
|
99
|
+
Fallback=(component Fallback isLoaded=imgState.isResolved)
|
|
100
|
+
isLoading=imgState.isLoading
|
|
101
|
+
isError=imgState.isError
|
|
102
|
+
)
|
|
103
|
+
}}
|
|
104
|
+
</span>
|
|
105
|
+
{{/let}}
|
|
106
|
+
</template>;
|
|
107
|
+
|
|
108
|
+
export default Avatar;
|