ember-primitives 0.27.2 → 0.28.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/declarations/color-scheme.d.ts.map +1 -1
- package/declarations/components/-private/typed-elements.d.ts +1 -1
- package/declarations/components/accordion/content.d.ts +2 -2
- package/declarations/components/accordion/header.d.ts +2 -2
- package/declarations/components/accordion/item.d.ts +3 -3
- package/declarations/components/accordion/public.d.ts +3 -3
- package/declarations/components/accordion/trigger.d.ts +2 -2
- package/declarations/components/accordion.d.ts +7 -7
- package/declarations/components/accordion.d.ts.map +1 -1
- package/declarations/components/avatar.d.ts +4 -4
- package/declarations/components/dialog.d.ts +4 -4
- package/declarations/components/dialog.d.ts.map +1 -1
- package/declarations/components/external-link.d.ts +1 -1
- package/declarations/components/form.d.ts +3 -3
- package/declarations/components/keys.d.ts +17 -0
- package/declarations/components/keys.d.ts.map +1 -0
- package/declarations/components/layout/hero.d.ts +2 -2
- package/declarations/components/layout/sticky-footer.d.ts +2 -2
- package/declarations/components/menu.d.ts +19 -19
- package/declarations/components/menu.d.ts.map +1 -1
- package/declarations/components/one-time-password/buttons.d.ts +1 -1
- package/declarations/components/one-time-password/index.d.ts +2 -2
- package/declarations/components/one-time-password/input.d.ts +5 -5
- package/declarations/components/one-time-password/input.d.ts.map +1 -1
- package/declarations/components/one-time-password/otp.d.ts +5 -5
- package/declarations/components/one-time-password/otp.d.ts.map +1 -1
- package/declarations/components/one-time-password/utils.d.ts.map +1 -1
- package/declarations/components/popover.d.ts +17 -26
- package/declarations/components/popover.d.ts.map +1 -1
- package/declarations/components/portal-targets.d.ts +1 -1
- package/declarations/components/portal.d.ts +4 -3
- package/declarations/components/portal.d.ts.map +1 -1
- package/declarations/components/progress.d.ts +4 -4
- package/declarations/components/scroller.d.ts +1 -1
- package/declarations/components/shadowed.d.ts +1 -1
- package/declarations/components/switch.d.ts +5 -5
- package/declarations/components/toggle-group.d.ts +4 -4
- package/declarations/components/toggle.d.ts +2 -2
- package/declarations/components/toggle.d.ts.map +1 -1
- package/declarations/components/zoetrope/index.d.ts +3 -3
- package/declarations/components/zoetrope.d.ts +2 -2
- package/declarations/floating-ui/component.d.ts +19 -16
- package/declarations/floating-ui/component.d.ts.map +1 -1
- package/declarations/floating-ui/modifier.d.ts.map +1 -1
- package/declarations/floating-ui.d.ts +1 -1
- package/declarations/helpers/link.d.ts.map +1 -1
- package/declarations/index.d.ts +20 -19
- package/declarations/index.d.ts.map +1 -1
- package/declarations/proper-links.d.ts.map +1 -1
- package/declarations/test-support/routing.d.ts.map +1 -1
- package/declarations/utils.d.ts.map +1 -1
- package/dist/color-scheme.js +5 -5
- package/dist/color-scheme.js.map +1 -1
- package/dist/components/-private/typed-elements.js.map +1 -1
- package/dist/components/-private/utils.js +1 -3
- package/dist/components/-private/utils.js.map +1 -1
- package/dist/components/accordion/content.js +1 -1
- package/dist/components/accordion/header.js +1 -1
- package/dist/components/accordion/item.js +1 -1
- package/dist/components/accordion/trigger.js +1 -1
- package/dist/components/accordion.js +26 -25
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/dialog.js +15 -14
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/external-link.js.map +1 -1
- package/dist/components/form.js +6 -6
- package/dist/components/form.js.map +1 -1
- package/dist/components/keys.js +33 -0
- package/dist/components/keys.js.map +1 -0
- package/dist/components/layout/hero.js.map +1 -1
- package/dist/components/layout/sticky-footer.js.map +1 -1
- package/dist/components/link.js.map +1 -1
- package/dist/components/menu.js +47 -46
- package/dist/components/menu.js.map +1 -1
- package/dist/components/one-time-password/buttons.js +5 -5
- package/dist/components/one-time-password/buttons.js.map +1 -1
- package/dist/components/one-time-password/input.js +14 -14
- package/dist/components/one-time-password/input.js.map +1 -1
- package/dist/components/one-time-password/otp.js +26 -25
- package/dist/components/one-time-password/otp.js.map +1 -1
- package/dist/components/one-time-password/utils.js +18 -18
- package/dist/components/one-time-password/utils.js.map +1 -1
- package/dist/components/popover.js +44 -44
- package/dist/components/popover.js.map +1 -1
- package/dist/components/portal-targets.js +16 -16
- package/dist/components/portal-targets.js.map +1 -1
- package/dist/components/portal.js +5 -3
- package/dist/components/portal.js.map +1 -1
- package/dist/components/progress.js +16 -16
- package/dist/components/progress.js.map +1 -1
- package/dist/components/scroller.js +6 -6
- package/dist/components/scroller.js.map +1 -1
- package/dist/components/shadowed.js +9 -9
- package/dist/components/shadowed.js.map +1 -1
- package/dist/components/switch.js.map +1 -1
- package/dist/components/toggle-group.js +24 -24
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js +4 -4
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/violations.css +8 -8
- package/dist/components/zoetrope/index.js +102 -102
- package/dist/components/zoetrope/index.js.map +1 -1
- package/dist/floating-ui/component.js +6 -6
- package/dist/floating-ui/component.js.map +1 -1
- package/dist/floating-ui/modifier.js +10 -6
- package/dist/floating-ui/modifier.js.map +1 -1
- package/dist/helpers/link.js +11 -7
- package/dist/helpers/link.js.map +1 -1
- package/dist/helpers/service.js +1 -1
- package/dist/helpers/service.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/{item-DmpElnSZ.js → item-D6pwWzMs.js} +3 -3
- package/dist/item-D6pwWzMs.js.map +1 -0
- package/dist/proper-links.js +10 -10
- package/dist/proper-links.js.map +1 -1
- package/dist/tabster.js +2 -2
- package/dist/tabster.js.map +1 -1
- package/dist/test-support/a11y.js +4 -4
- package/dist/test-support/a11y.js.map +1 -1
- package/dist/test-support/otp.js +6 -6
- package/dist/test-support/otp.js.map +1 -1
- package/dist/test-support/routing.js +3 -2
- package/dist/test-support/routing.js.map +1 -1
- package/dist/test-support/zoetrope.js.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- package/package.json +20 -30
- package/dist/item-DmpElnSZ.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"switch.js","sources":["../../src/components/switch.gts"],"sourcesContent":["import { fn, hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { uniqueId } from \"../utils.ts\";\nimport { Label } from \"./-private/typed-elements.gts\";\nimport { toggleWithFallback } from \"./-private/utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Element: HTMLInputElement;\n Args: {\n /**\n * The initial checked value of the Switch.\n * This value is reactive, so if the value that\n * `@checked` is set to updates, the state of the Switch will also update.\n */\n checked?: boolean;\n /**\n * Callback when the Switch state is toggled\n */\n onChange?: (checked: boolean, event: Event) => void;\n };\n Blocks: {\n default?: [\n {\n /**\n * The Switch Element.\n * It has a pre-wired `id` so that the relevant Label is\n * appropriately associated via the `for` property of the Label.\n *\n * ```gjs\n * import { Switch } from 'ember-primitives';\n *\n * <template>\n * <Switch as |s|>\n * <s.Control />\n * </Switch>\n * </template>\n * ```\n */\n Control: WithBoundArgs<typeof Checkbox, \"checked\" | \"id\" | \"onChange\">;\n /**\n * The Switch element requires a label, and this label already has\n * the association to the Control by setting the `for` attribute to the `id` of the Control\n *\n * ```gjs\n * import { Switch } from 'ember-primitives';\n *\n * <template>\n * <Switch as |s|>\n * <s.Label />\n * </Switch>\n * </template>\n * ```\n */\n Label: WithBoundArgs<typeof Label, \"for\">;\n },\n ];\n };\n}\n\ninterface ControlSignature {\n Element: HTMLInputElement;\n Args: { id: string; checked?: boolean; onChange: () => void };\n}\n\nconst Checkbox: TOC<ControlSignature> = <template>\n {{#let (cell @checked) as |checked|}}\n <input\n id={{@id}}\n type=\"checkbox\"\n role=\"switch\"\n checked={{checked.current}}\n aria-checked={{checked.current}}\n data-state={{if checked.current \"on\" \"off\"}}\n {{on \"click\" (fn toggleWithFallback checked.toggle @onChange)}}\n ...attributes\n />\n {{/let}}\n</template>;\n\n/**\n * @public\n */\nexport const Switch: TOC<Signature> = <template>\n <div ...attributes data-prim-switch>\n {{! @glint-nocheck }}\n {{#let (uniqueId) as |id|}}\n {{yield\n (hash\n Control=(component Checkbox checked=@checked id=id onChange=@onChange)\n Label=(component Label for=id)\n )\n }}\n {{/let}}\n </div>\n</template>;\n\nexport default Switch;\n"],"names":["Checkbox","setComponentTemplate","precompileTemplate","strictMode","scope","cell","on","fn","toggleWithFallback","templateOnly","Switch","uniqueId","hash","Label"],"mappings":";;;;;;;;;;AAsEA,MAAMA,QAAkC,GAAAC,oBAAA,CAAAC,kBAAA,CAaxC,mTAAA,EAAA;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;IAAAC,EAAA;IAAAC,EAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;AAEV;;AAEC;MACYC,MAAY,GAAAT,oBAAA,CAAaC,kBAAA,CAYtC,kQAAA,EAAA;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAO,QAAA;IAAAC,IAAA;IAAAZ,QAAA;AAAAa,IAAAA;AAAA,GAAA;AAAU,CAAE,CAAA,EAAAJ,YAAA,EAAA;;;;"}
|
|
@@ -15,8 +15,8 @@ const TABSTER_CONFIG = getTabsterAttribute({
|
|
|
15
15
|
cyclic: true
|
|
16
16
|
}
|
|
17
17
|
}, true);
|
|
18
|
-
function isMulti(
|
|
19
|
-
return
|
|
18
|
+
function isMulti(x) {
|
|
19
|
+
return x === "multi";
|
|
20
20
|
}
|
|
21
21
|
class ToggleGroup extends Component {
|
|
22
22
|
// See: https://github.com/typed-ember/glint/issues/715
|
|
@@ -31,20 +31,20 @@ class ToggleGroup extends Component {
|
|
|
31
31
|
}), this);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
class SingleToggleGroup extends Component {
|
|
35
35
|
static {
|
|
36
|
-
g(this.prototype, "activePressed", [localCopy(
|
|
36
|
+
g(this.prototype, "activePressed", [localCopy("args.value")]);
|
|
37
37
|
}
|
|
38
|
-
#activePressed = (i(this, "activePressed"), void 0);
|
|
39
|
-
handleToggle =
|
|
40
|
-
if (this.activePressed ===
|
|
38
|
+
#activePressed = (i(this, "activePressed"), void 0); // eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
39
|
+
handleToggle = value => {
|
|
40
|
+
if (this.activePressed === value) {
|
|
41
41
|
this.activePressed = undefined;
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
this.activePressed =
|
|
44
|
+
this.activePressed = value;
|
|
45
45
|
this.args.onChange?.(this.activePressed);
|
|
46
46
|
};
|
|
47
|
-
isPressed =
|
|
47
|
+
isPressed = value => value === this.activePressed;
|
|
48
48
|
static {
|
|
49
49
|
setComponentTemplate(precompileTemplate("\n <div data-tabster={{TABSTER_CONFIG}} ...attributes>\n {{yield (hash Item=(component Toggle onChange=this.handleToggle isPressed=this.isPressed))}}\n </div>\n ", {
|
|
50
50
|
strictMode: true,
|
|
@@ -55,38 +55,38 @@ let SingleToggleGroup = class SingleToggleGroup extends Component {
|
|
|
55
55
|
})
|
|
56
56
|
}), this);
|
|
57
57
|
}
|
|
58
|
-
}
|
|
59
|
-
|
|
58
|
+
}
|
|
59
|
+
class MultiToggleGroup extends Component {
|
|
60
60
|
/**
|
|
61
61
|
* Normalizes @value to a Set
|
|
62
62
|
* and makes sure that even if the input Set is reactive,
|
|
63
63
|
* we don't mistakenly dirty it.
|
|
64
64
|
*/
|
|
65
65
|
get activePressed() {
|
|
66
|
-
|
|
67
|
-
if (!
|
|
66
|
+
const value = this.args.value;
|
|
67
|
+
if (!value) {
|
|
68
68
|
return new TrackedSet();
|
|
69
69
|
}
|
|
70
|
-
if (Array.isArray(
|
|
71
|
-
return new TrackedSet(
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
return new TrackedSet(value);
|
|
72
72
|
}
|
|
73
|
-
if (
|
|
74
|
-
return new TrackedSet(
|
|
73
|
+
if (value instanceof Set) {
|
|
74
|
+
return new TrackedSet(value);
|
|
75
75
|
}
|
|
76
|
-
return new TrackedSet([
|
|
76
|
+
return new TrackedSet([value]);
|
|
77
77
|
}
|
|
78
78
|
static {
|
|
79
79
|
n(this.prototype, "activePressed", [cached]);
|
|
80
80
|
}
|
|
81
|
-
handleToggle =
|
|
82
|
-
if (this.activePressed.has(
|
|
83
|
-
this.activePressed.delete(
|
|
81
|
+
handleToggle = value => {
|
|
82
|
+
if (this.activePressed.has(value)) {
|
|
83
|
+
this.activePressed.delete(value);
|
|
84
84
|
} else {
|
|
85
|
-
this.activePressed.add(
|
|
85
|
+
this.activePressed.add(value);
|
|
86
86
|
}
|
|
87
87
|
this.args.onChange?.(new Set(this.activePressed.values()));
|
|
88
88
|
};
|
|
89
|
-
isPressed =
|
|
89
|
+
isPressed = value => this.activePressed.has(value);
|
|
90
90
|
static {
|
|
91
91
|
setComponentTemplate(precompileTemplate("\n <div data-tabster={{TABSTER_CONFIG}} ...attributes>\n {{yield (hash Item=(component Toggle onChange=this.handleToggle isPressed=this.isPressed))}}\n </div>\n ", {
|
|
92
92
|
strictMode: true,
|
|
@@ -97,7 +97,7 @@ let MultiToggleGroup = class MultiToggleGroup extends Component {
|
|
|
97
97
|
})
|
|
98
98
|
}), this);
|
|
99
99
|
}
|
|
100
|
-
}
|
|
100
|
+
}
|
|
101
101
|
|
|
102
102
|
export { ToggleGroup };
|
|
103
103
|
//# sourceMappingURL=toggle-group.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-group.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toggle-group.js","sources":["../../src/components/toggle-group.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { cached } from \"@glimmer/tracking\";\nimport { hash } from \"@ember/helper\";\n\nimport { getTabsterAttribute, MoverDirections } from \"tabster\";\nimport { TrackedSet } from \"tracked-built-ins\";\n// The consumer will need to provide types for tracked-toolbox.\n// Or.. better yet, we PR to trakcked-toolbox to provide them\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport { localCopy } from \"tracked-toolbox\";\n\nimport { Toggle } from \"./toggle.gts\";\n\nimport type { ComponentLike } from \"@glint/template\";\n\nconst TABSTER_CONFIG = getTabsterAttribute(\n {\n mover: {\n direction: MoverDirections.Both,\n cyclic: true,\n },\n },\n true,\n);\n\nexport interface ItemSignature<Value = any> {\n /**\n * The button element will have aria-pressed=\"true\" on it when the button is in the pressed state.\n */\n Element: HTMLButtonElement;\n Args: {\n /**\n * When used in a group of Toggles, this option will be helpful to\n * know which toggle was pressed if you're using the same @onChange\n * handler for multiple toggles.\n */\n value?: Value;\n };\n Blocks: {\n default: [\n /**\n * the current pressed state of the toggle button\n *\n * Useful when using the toggle button as an uncontrolled component\n */\n pressed: boolean,\n ];\n };\n}\n\nexport type Item<Value = any> = ComponentLike<ItemSignature<Value>>;\n\nexport interface SingleSignature<Value> {\n Element: HTMLDivElement;\n Args: {\n /**\n * Optionally set the initial toggle state\n */\n value?: Value;\n /**\n * Callback for when the toggle-group's state is changed.\n *\n * Can be used to control the state of the component.\n *\n *\n * When none of the toggles are selected, undefined will be passed.\n */\n onChange?: (value: Value | undefined) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * The Toggle Switch\n */\n Item: Item;\n },\n ];\n };\n}\n\nexport interface MultiSignature<Value = any> {\n Element: HTMLDivElement;\n Args: {\n /**\n * Optionally set the initial toggle state\n */\n value?: Value[] | Set<Value> | Value;\n /**\n * Callback for when the toggle-group's state is changed.\n *\n * Can be used to control the state of the component.\n *\n *\n * When none of the toggles are selected, undefined will be passed.\n */\n onChange?: (value: Set<Value>) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * The Toggle Switch\n */\n Item: Item;\n },\n ];\n };\n}\n\ninterface PrivateSingleSignature<Value = any> {\n Element: HTMLDivElement;\n Args: {\n type?: \"single\";\n\n /**\n * Optionally set the initial toggle state\n */\n value?: Value;\n /**\n * Callback for when the toggle-group's state is changed.\n *\n * Can be used to control the state of the component.\n *\n *\n * When none of the toggles are selected, undefined will be passed.\n */\n onChange?: (value: Value | undefined) => void;\n };\n Blocks: {\n default: [\n {\n Item: Item;\n },\n ];\n };\n}\n\ninterface PrivateMultiSignature<Value = any> {\n Element: HTMLDivElement;\n Args: {\n type: \"multi\";\n /**\n * Optionally set the initial toggle state\n */\n value?: Value[] | Set<Value> | Value;\n /**\n * Callback for when the toggle-group's state is changed.\n *\n * Can be used to control the state of the component.\n *\n *\n * When none of the toggles are selected, undefined will be passed.\n */\n onChange?: (value: Set<Value>) => void;\n };\n Blocks: {\n default: [\n {\n Item: Item;\n },\n ];\n };\n}\n\nfunction isMulti(x: \"single\" | \"multi\" | undefined): x is \"multi\" {\n return x === \"multi\";\n}\n\nexport class ToggleGroup<Value = any> extends Component<\n PrivateSingleSignature<Value> | PrivateMultiSignature<Value>\n> {\n // See: https://github.com/typed-ember/glint/issues/715\n <template>\n {{#if (isMulti this.args.type)}}\n <MultiToggleGroup\n @value={{this.args.value}}\n @onChange={{this.args.onChange}}\n ...attributes\n as |x|\n >\n {{yield x}}\n </MultiToggleGroup>\n {{else}}\n <SingleToggleGroup\n @value={{this.args.value}}\n @onChange={{this.args.onChange}}\n ...attributes\n as |x|\n >\n {{yield x}}\n </SingleToggleGroup>\n {{/if}}\n </template>\n}\n\nclass SingleToggleGroup<Value = any> extends Component<SingleSignature<Value>> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.value\") activePressed?: Value;\n\n handleToggle = (value: Value) => {\n if (this.activePressed === value) {\n this.activePressed = undefined;\n\n return;\n }\n\n this.activePressed = value;\n\n this.args.onChange?.(this.activePressed);\n };\n\n isPressed = (value: Value | undefined) => value === this.activePressed;\n\n <template>\n <div data-tabster={{TABSTER_CONFIG}} ...attributes>\n {{yield (hash Item=(component Toggle onChange=this.handleToggle isPressed=this.isPressed))}}\n </div>\n </template>\n}\n\nclass MultiToggleGroup<Value = any> extends Component<MultiSignature<Value>> {\n /**\n * Normalizes @value to a Set\n * and makes sure that even if the input Set is reactive,\n * we don't mistakenly dirty it.\n */\n @cached\n get activePressed(): TrackedSet<Value> {\n const value = this.args.value;\n\n if (!value) {\n return new TrackedSet();\n }\n\n if (Array.isArray(value)) {\n return new TrackedSet(value);\n }\n\n if (value instanceof Set) {\n return new TrackedSet(value);\n }\n\n return new TrackedSet([value]);\n }\n\n handleToggle = (value: Value) => {\n if (this.activePressed.has(value)) {\n this.activePressed.delete(value);\n } else {\n this.activePressed.add(value);\n }\n\n this.args.onChange?.(new Set<Value>(this.activePressed.values()));\n };\n\n isPressed = (value: Value) => this.activePressed.has(value);\n\n <template>\n <div data-tabster={{TABSTER_CONFIG}} ...attributes>\n {{yield (hash Item=(component Toggle onChange=this.handleToggle isPressed=this.isPressed))}}\n </div>\n </template>\n}\n"],"names":["TABSTER_CONFIG","getTabsterAttribute","mover","direction","MoverDirections","Both","cyclic","isMulti","x","ToggleGroup","Component","setComponentTemplate","precompileTemplate","strictMode","scope","MultiToggleGroup","SingleToggleGroup","g","prototype","localCopy","i","void 0","handleToggle","value","activePressed","undefined","args","onChange","isPressed","hash","Toggle","TrackedSet","Array","isArray","Set","n","cached","has","delete","add","values"],"mappings":"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"}
|
|
@@ -8,10 +8,10 @@ import templateOnly from '@ember/component/template-only';
|
|
|
8
8
|
|
|
9
9
|
// import Component from '@glimmer/component';
|
|
10
10
|
|
|
11
|
-
function isPressed(
|
|
12
|
-
if (!
|
|
13
|
-
if (!
|
|
14
|
-
return
|
|
11
|
+
function isPressed(pressed, value, isPressed) {
|
|
12
|
+
if (!value) return Boolean(pressed);
|
|
13
|
+
if (!isPressed) return Boolean(pressed);
|
|
14
|
+
return isPressed(value);
|
|
15
15
|
}
|
|
16
16
|
const Toggle = setComponentTemplate(precompileTemplate("\n {{#let (cell (isPressed @pressed @value @isPressed)) as |pressed|}}\n <button type=\"button\" aria-pressed=\"{{pressed.current}}\" {{on \"click\" (fn toggleWithFallback pressed.toggle @onChange @value)}} ...attributes>\n {{yield pressed.current}}\n </button>\n {{/let}}\n", {
|
|
17
17
|
strictMode: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toggle.js","sources":["../../src/components/toggle.gts"],"sourcesContent":["// import Component from '@glimmer/component';\nimport { fn } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { toggleWithFallback } from \"./-private/utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport interface Signature<Value = any> {\n Element: HTMLButtonElement;\n Args: {\n /**\n * The pressed-state of the toggle.\n *\n * Can be used to control the state of the component.\n */\n pressed?: boolean;\n /**\n * Callback for when the toggle's state is changed.\n *\n * Can be used to control the state of the component.\n *\n * if a `@value` is passed to this `<Toggle>`, that @value will\n * be passed to the `@onChange` handler.\n *\n * This can be useful when using the same function for the `@onChange`\n * handler with multiple `<Toggle>` components.\n */\n onChange?: (value: Value | undefined, pressed: boolean) => void;\n\n /**\n * When used in a group of Toggles, this option will be helpful to\n * know which toggle was pressed if you're using the same @onChange\n * handler for multiple toggles.\n */\n value?: Value;\n\n /**\n * When controlling state in a wrapping component, this function can be used in conjunction with `@value` to determine if this `<Toggle>` should appear pressed.\n */\n isPressed?: (value?: Value) => boolean;\n };\n Blocks: {\n default: [\n /**\n * the current pressed state of the toggle button\n *\n * Useful when using the toggle button as an uncontrolled component\n */\n pressed: boolean,\n ];\n };\n}\n\nfunction isPressed(\n pressed?: boolean,\n value?: unknown,\n isPressed?: (value?: unknown) => boolean,\n): boolean {\n if (!value) return Boolean(pressed);\n if (!isPressed) return Boolean(pressed);\n\n return isPressed(value);\n}\n\nexport const Toggle: TOC<Signature> = <template>\n {{#let (cell (isPressed @pressed @value @isPressed)) as |pressed|}}\n <button\n type=\"button\"\n aria-pressed=\"{{pressed.current}}\"\n {{on \"click\" (fn toggleWithFallback pressed.toggle @onChange @value)}}\n ...attributes\n >\n {{yield pressed.current}}\n </button>\n {{/let}}\n</template>;\n\nexport default Toggle;\n"],"names":["isPressed","pressed","value","Boolean","Toggle","setComponentTemplate","precompileTemplate","strictMode","scope","cell","on","fn","toggleWithFallback","templateOnly"],"mappings":";;;;;;;;AAAA;;AAwDA,SAASA,SACPA,CAAAC,OAAiB,EACjBC,KAAe,EACfF,SAAwC,EAChC;AACR,EAAA,IAAI,CAACE,KAAO,EAAA,OAAOC,OAAQ,CAAAF,OAAA,CAAA;AAC3B,EAAA,IAAI,CAACD,SAAW,EAAA,OAAOG,OAAQ,CAAAF,OAAA,CAAA;EAE/B,OAAOD,SAAU,CAAAE,KAAA,CAAA;AACnB;MAEaE,MAAY,GAAAC,oBAAA,CAAaC,kBAAA,CAWtC,iSAAA,EAAA;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;IAAAT,SAAA;IAAAU,EAAA;IAAAC,EAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAE,CAAA,EAAAC,YAAA,EAAA;;;;"}
|
|
@@ -68,10 +68,10 @@ div[data-prim-switch]:not(:has(label)):has(input[role="switch"]) input[role="swi
|
|
|
68
68
|
|
|
69
69
|
@media (prefers-color-scheme: light) {
|
|
70
70
|
:is(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
a[href="##missing##"],
|
|
72
|
+
span[data-prim-avatar]:has(img[alt="__missing__"]),
|
|
73
|
+
div[data-prim-switch]:has(input[role="switch"]):not(:has(label)) input[role="switch"]
|
|
74
|
+
) {
|
|
75
75
|
border-color: black;
|
|
76
76
|
}
|
|
77
77
|
:is(
|
|
@@ -87,10 +87,10 @@ div[data-prim-switch]:not(:has(label)):has(input[role="switch"]) input[role="swi
|
|
|
87
87
|
|
|
88
88
|
@media (prefers-color-scheme: dark) {
|
|
89
89
|
:is(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
a[href="##missing##"],
|
|
91
|
+
span[data-prim-avatar]:has(img[alt="__missing__"]),
|
|
92
|
+
div[data-prim-switch]:has(input[role="switch"]):not(:has(label)) input[role="switch"]
|
|
93
|
+
) {
|
|
94
94
|
border-color: red;
|
|
95
95
|
}
|
|
96
96
|
:is(
|
|
@@ -10,7 +10,7 @@ import { precompileTemplate } from '@ember/template-compilation';
|
|
|
10
10
|
import { setComponentTemplate } from '@ember/component';
|
|
11
11
|
import { g, i } from 'decorator-transforms/runtime';
|
|
12
12
|
|
|
13
|
-
const testWaiter = buildWaiter(
|
|
13
|
+
const testWaiter = buildWaiter("ember-primitive:zoetrope-waiter");
|
|
14
14
|
const DEFAULT_GAP = 8;
|
|
15
15
|
const DEFAULT_OFFSET = 0;
|
|
16
16
|
class Zoetrope extends Component {
|
|
@@ -38,71 +38,71 @@ class Zoetrope extends Component {
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
#offsetWidth = (i(this, "offsetWidth"), void 0);
|
|
41
|
-
setCSSVariables = modifier((
|
|
42
|
-
gap
|
|
43
|
-
offset
|
|
41
|
+
setCSSVariables = modifier((element, _, {
|
|
42
|
+
gap,
|
|
43
|
+
offset
|
|
44
44
|
}) => {
|
|
45
|
-
if (
|
|
46
|
-
if (
|
|
45
|
+
if (gap) element.style.setProperty("--zoetrope-gap", `${gap}px`);
|
|
46
|
+
if (offset) element.style.setProperty("--zoetrope-offset", `${offset}px`);
|
|
47
47
|
});
|
|
48
48
|
scrollerWaiter = testWaiter.beginAsync();
|
|
49
49
|
noScrollWaiter = () => {
|
|
50
50
|
testWaiter.endAsync(this.scrollerWaiter);
|
|
51
51
|
};
|
|
52
|
-
configureScroller = modifier(
|
|
53
|
-
this.scrollerElement =
|
|
54
|
-
this.currentlyScrolled =
|
|
55
|
-
const
|
|
56
|
-
this.scrollWidth =
|
|
57
|
-
this.offsetWidth =
|
|
52
|
+
configureScroller = modifier(element => {
|
|
53
|
+
this.scrollerElement = element;
|
|
54
|
+
this.currentlyScrolled = element.scrollLeft;
|
|
55
|
+
const zoetropeResizeObserver = new ResizeObserver(() => {
|
|
56
|
+
this.scrollWidth = element.scrollWidth;
|
|
57
|
+
this.offsetWidth = element.offsetWidth;
|
|
58
58
|
});
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
zoetropeResizeObserver.observe(element);
|
|
60
|
+
element.addEventListener("scroll", this.scrollListener, {
|
|
61
61
|
passive: true
|
|
62
62
|
});
|
|
63
|
-
|
|
63
|
+
element.addEventListener("keydown", this.tabListener);
|
|
64
64
|
requestAnimationFrame(() => {
|
|
65
65
|
testWaiter.endAsync(this.scrollerWaiter);
|
|
66
66
|
});
|
|
67
67
|
return () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
element.removeEventListener("scroll", this.scrollListener);
|
|
69
|
+
element.removeEventListener("keydown", this.tabListener);
|
|
70
|
+
zoetropeResizeObserver.unobserve(element);
|
|
71
71
|
};
|
|
72
72
|
});
|
|
73
|
-
tabListener =
|
|
74
|
-
const
|
|
73
|
+
tabListener = event => {
|
|
74
|
+
const target = event.target;
|
|
75
75
|
const {
|
|
76
|
-
key
|
|
77
|
-
shiftKey
|
|
78
|
-
} =
|
|
79
|
-
if (!this.scrollerElement || this.scrollerElement ===
|
|
76
|
+
key,
|
|
77
|
+
shiftKey
|
|
78
|
+
} = event;
|
|
79
|
+
if (!this.scrollerElement || this.scrollerElement === target) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
82
|
+
if (key !== "Tab") {
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
if (!
|
|
85
|
+
const nextElement = target.nextElementSibling;
|
|
86
|
+
const previousElement = target.previousElementSibling;
|
|
87
|
+
if (!shiftKey && !nextElement || shiftKey && !previousElement) {
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
let
|
|
92
|
-
if (
|
|
93
|
-
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
let newTarget = null;
|
|
92
|
+
if (shiftKey) {
|
|
93
|
+
newTarget = previousElement;
|
|
94
94
|
} else {
|
|
95
|
-
|
|
95
|
+
newTarget = nextElement;
|
|
96
96
|
}
|
|
97
|
-
if (!
|
|
97
|
+
if (!newTarget) {
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
newTarget?.focus({
|
|
101
101
|
preventScroll: true
|
|
102
102
|
});
|
|
103
|
-
const
|
|
103
|
+
const rect = getRelativeBoundingClientRect(newTarget, this.scrollerElement);
|
|
104
104
|
this.scrollerElement?.scrollBy({
|
|
105
|
-
left:
|
|
105
|
+
left: rect.left,
|
|
106
106
|
behavior: this.scrollBehavior
|
|
107
107
|
});
|
|
108
108
|
};
|
|
@@ -126,107 +126,107 @@ class Zoetrope extends Component {
|
|
|
126
126
|
}
|
|
127
127
|
get scrollBehavior() {
|
|
128
128
|
if (macroCondition(isTesting())) {
|
|
129
|
-
return
|
|
129
|
+
return "instant";
|
|
130
130
|
}
|
|
131
|
-
return this.args.scrollBehavior ||
|
|
131
|
+
return this.args.scrollBehavior || "smooth";
|
|
132
132
|
}
|
|
133
133
|
scrollLeft = () => {
|
|
134
134
|
if (!(this.scrollerElement instanceof HTMLElement)) {
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
const {
|
|
138
|
-
firstChild
|
|
138
|
+
firstChild
|
|
139
139
|
} = this.findOverflowingElement();
|
|
140
|
-
if (!
|
|
140
|
+
if (!firstChild) {
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
let
|
|
146
|
-
let
|
|
147
|
-
for (let
|
|
148
|
-
const
|
|
149
|
-
if (!(
|
|
143
|
+
const children = [...this.scrollerElement.children];
|
|
144
|
+
const firstChildIndex = children.indexOf(firstChild);
|
|
145
|
+
let targetElement = firstChild;
|
|
146
|
+
let accumalatedWidth = 0;
|
|
147
|
+
for (let i = firstChildIndex; i >= 0; i--) {
|
|
148
|
+
const child = children[i];
|
|
149
|
+
if (!(child instanceof HTMLElement)) {
|
|
150
150
|
continue;
|
|
151
151
|
}
|
|
152
|
-
|
|
153
|
-
if (
|
|
152
|
+
accumalatedWidth += child.offsetWidth + this.gap;
|
|
153
|
+
if (accumalatedWidth >= this.offsetWidth) {
|
|
154
154
|
break;
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
targetElement = child;
|
|
157
157
|
}
|
|
158
|
-
const
|
|
158
|
+
const rect = getRelativeBoundingClientRect(targetElement, this.scrollerElement);
|
|
159
159
|
this.scrollerElement.scrollBy({
|
|
160
|
-
left:
|
|
160
|
+
left: rect.left,
|
|
161
161
|
behavior: this.scrollBehavior
|
|
162
162
|
});
|
|
163
|
-
waitForPromise(new Promise(requestAnimationFrame));
|
|
163
|
+
void waitForPromise(new Promise(requestAnimationFrame));
|
|
164
164
|
};
|
|
165
165
|
scrollRight = () => {
|
|
166
166
|
if (!(this.scrollerElement instanceof HTMLElement)) {
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
169
|
const {
|
|
170
|
-
activeSlide
|
|
171
|
-
lastChild
|
|
170
|
+
activeSlide,
|
|
171
|
+
lastChild
|
|
172
172
|
} = this.findOverflowingElement();
|
|
173
|
-
if (!
|
|
173
|
+
if (!lastChild) {
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
|
-
let
|
|
176
|
+
let rect = getRelativeBoundingClientRect(lastChild, this.scrollerElement);
|
|
177
177
|
// If the card is larger than the container then skip to the next card
|
|
178
|
-
if (
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
if (!
|
|
178
|
+
if (rect.width > this.offsetWidth && activeSlide === lastChild) {
|
|
179
|
+
const children = [...this.scrollerElement.children];
|
|
180
|
+
const lastChildIndex = children.indexOf(lastChild);
|
|
181
|
+
const targetElement = children[lastChildIndex + 1];
|
|
182
|
+
if (!targetElement) {
|
|
183
183
|
return;
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
rect = getRelativeBoundingClientRect(targetElement, this.scrollerElement);
|
|
186
186
|
}
|
|
187
187
|
this.scrollerElement?.scrollBy({
|
|
188
|
-
left:
|
|
188
|
+
left: rect.left,
|
|
189
189
|
behavior: this.scrollBehavior
|
|
190
190
|
});
|
|
191
|
-
waitForPromise(new Promise(requestAnimationFrame));
|
|
191
|
+
void waitForPromise(new Promise(requestAnimationFrame));
|
|
192
192
|
};
|
|
193
193
|
findOverflowingElement() {
|
|
194
|
-
const
|
|
194
|
+
const returnObj = {
|
|
195
195
|
firstChild: undefined,
|
|
196
196
|
lastChild: undefined,
|
|
197
197
|
activeSlide: undefined
|
|
198
198
|
};
|
|
199
199
|
if (!this.scrollerElement) {
|
|
200
|
-
return
|
|
200
|
+
return returnObj;
|
|
201
201
|
}
|
|
202
|
-
const
|
|
203
|
-
if (!
|
|
204
|
-
return
|
|
202
|
+
const parentElement = this.scrollerElement.parentElement;
|
|
203
|
+
if (!parentElement) {
|
|
204
|
+
return returnObj;
|
|
205
205
|
}
|
|
206
|
-
const
|
|
207
|
-
const
|
|
206
|
+
const containerRect = getRelativeBoundingClientRect(this.scrollerElement, parentElement);
|
|
207
|
+
const children = [...this.scrollerElement.children];
|
|
208
208
|
// Find the first child that is overflowing the left edge of the container
|
|
209
209
|
// and the last child that is overflowing the right edge of the container
|
|
210
|
-
for (const
|
|
211
|
-
const
|
|
212
|
-
if (
|
|
213
|
-
|
|
210
|
+
for (const child of children) {
|
|
211
|
+
const rect = getRelativeBoundingClientRect(child, this.scrollerElement);
|
|
212
|
+
if (rect.right + this.gap >= containerRect.left && !returnObj.firstChild) {
|
|
213
|
+
returnObj.firstChild = child;
|
|
214
214
|
}
|
|
215
|
-
if (
|
|
216
|
-
|
|
215
|
+
if (rect.left >= this.offset && !returnObj.activeSlide) {
|
|
216
|
+
returnObj.activeSlide = child;
|
|
217
217
|
}
|
|
218
|
-
if (
|
|
219
|
-
|
|
218
|
+
if (rect.right >= containerRect.width && !returnObj.lastChild) {
|
|
219
|
+
returnObj.lastChild = child;
|
|
220
220
|
break;
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
-
if (!
|
|
224
|
-
|
|
223
|
+
if (!returnObj.firstChild) {
|
|
224
|
+
returnObj.firstChild = children[0];
|
|
225
225
|
}
|
|
226
|
-
if (!
|
|
227
|
-
|
|
226
|
+
if (!returnObj.lastChild) {
|
|
227
|
+
returnObj.lastChild = children[children.length - 1];
|
|
228
228
|
}
|
|
229
|
-
return
|
|
229
|
+
return returnObj;
|
|
230
230
|
}
|
|
231
231
|
static {
|
|
232
232
|
setComponentTemplate(precompileTemplate("\n <section class=\"ember-primitives__zoetrope\" {{this.setCSSVariables gap=this.gap offset=this.offset}} ...attributes>\n {{#if (has-block \"header\")}}\n <div class=\"ember-primitives__zoetrope__header\">\n {{yield to=\"header\"}}\n </div>\n {{/if}}\n\n {{#if (has-block \"controls\")}}\n {{yield (hash cannotScrollLeft=this.cannotScrollLeft cannotScrollRight=this.cannotScrollRight canScroll=this.canScroll scrollLeft=this.scrollLeft scrollRight=this.scrollRight) to=\"controls\"}}\n {{else}}\n {{#if this.canScroll}}\n <div class=\"ember-primitives__zoetrope__controls\">\n <button type=\"button\" {{on \"click\" this.scrollLeft}} disabled={{this.cannotScrollLeft}}>Left</button>\n\n <button type=\"button\" {{on \"click\" this.scrollRight}} disabled={{this.cannotScrollRight}}>Right</button>\n </div>\n {{/if}}\n {{/if}}\n {{#if (has-block \"content\")}}\n <div class=\"ember-primitives__zoetrope__scroller\" {{this.configureScroller}}>\n {{yield to=\"content\"}}\n </div>\n {{else}}\n {{(this.noScrollWaiter)}}\n {{/if}}\n </section>\n ", {
|
|
@@ -238,28 +238,28 @@ class Zoetrope extends Component {
|
|
|
238
238
|
}), this);
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
function getRelativeBoundingClientRect(
|
|
242
|
-
if (!
|
|
243
|
-
throw new Error(
|
|
241
|
+
function getRelativeBoundingClientRect(childElement, parentElement) {
|
|
242
|
+
if (!childElement || !parentElement) {
|
|
243
|
+
throw new Error("Both childElement and parentElement must be provided");
|
|
244
244
|
}
|
|
245
245
|
// Get the bounding rect of the child and parent elements
|
|
246
|
-
const
|
|
247
|
-
const
|
|
246
|
+
const childRect = childElement.getBoundingClientRect();
|
|
247
|
+
const parentRect = parentElement.getBoundingClientRect();
|
|
248
248
|
// Get computed styles of the parent element
|
|
249
|
-
const
|
|
249
|
+
const parentStyles = window.getComputedStyle(parentElement);
|
|
250
250
|
// Extract and parse parent's padding, and border, for all sides
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
const
|
|
251
|
+
const parentPaddingTop = parseFloat(parentStyles.paddingTop);
|
|
252
|
+
const parentPaddingLeft = parseFloat(parentStyles.paddingLeft);
|
|
253
|
+
const parentBorderTopWidth = parseFloat(parentStyles.borderTopWidth);
|
|
254
|
+
const parentBorderLeftWidth = parseFloat(parentStyles.borderLeftWidth);
|
|
255
255
|
// Calculate child's position relative to parent's content area (including padding and borders)
|
|
256
256
|
return {
|
|
257
|
-
width:
|
|
258
|
-
height:
|
|
259
|
-
top:
|
|
260
|
-
left:
|
|
261
|
-
bottom:
|
|
262
|
-
right:
|
|
257
|
+
width: childRect.width,
|
|
258
|
+
height: childRect.height,
|
|
259
|
+
top: childRect.top - parentRect.top - parentBorderTopWidth - parentPaddingTop,
|
|
260
|
+
left: childRect.left - parentRect.left - parentBorderLeftWidth - parentPaddingLeft,
|
|
261
|
+
bottom: childRect.top - parentRect.top - parentBorderTopWidth - parentPaddingTop + childRect.height,
|
|
262
|
+
right: childRect.left - parentRect.left - parentBorderLeftWidth - parentPaddingLeft + childRect.width
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
265
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/zoetrope/index.gts"],"sourcesContent":["import \"./styles.css\";\n\nimport Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport { buildWaiter, waitForPromise } from \"@ember/test-waiters\";\nimport { isTesting, macroCondition } from \"@embroider/macros\";\n\nimport { modifier } from \"ember-modifier\";\n\nimport type { ScrollBehavior, Signature } from \"./types.ts\";\n\nconst testWaiter = buildWaiter(\"ember-primitive:zoetrope-waiter\");\nconst DEFAULT_GAP = 8;\nconst DEFAULT_OFFSET = 0;\n\nexport class Zoetrope extends Component<Signature> {\n @tracked scrollerElement: HTMLElement | null = null;\n @tracked currentlyScrolled = 0;\n @tracked scrollWidth = 0;\n @tracked offsetWidth = 0;\n\n private setCSSVariables = modifier(\n (element: HTMLElement, _: unknown, { gap, offset }: { gap: number; offset: number }) => {\n if (gap) element.style.setProperty(\"--zoetrope-gap\", `${gap}px`);\n if (offset) element.style.setProperty(\"--zoetrope-offset\", `${offset}px`);\n },\n );\n\n scrollerWaiter = testWaiter.beginAsync();\n noScrollWaiter = () => {\n testWaiter.endAsync(this.scrollerWaiter);\n };\n\n private configureScroller = modifier((element: HTMLElement) => {\n this.scrollerElement = element;\n this.currentlyScrolled = element.scrollLeft;\n\n const zoetropeResizeObserver = new ResizeObserver(() => {\n this.scrollWidth = element.scrollWidth;\n this.offsetWidth = element.offsetWidth;\n });\n\n zoetropeResizeObserver.observe(element);\n\n element.addEventListener(\"scroll\", this.scrollListener, { passive: true });\n element.addEventListener(\"keydown\", this.tabListener);\n\n requestAnimationFrame(() => {\n testWaiter.endAsync(this.scrollerWaiter);\n });\n\n return () => {\n element.removeEventListener(\"scroll\", this.scrollListener);\n element.removeEventListener(\"keydown\", this.tabListener);\n\n zoetropeResizeObserver.unobserve(element);\n };\n });\n\n private tabListener = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n const { key, shiftKey } = event;\n\n if (!this.scrollerElement || this.scrollerElement === target) {\n return;\n }\n\n if (key !== \"Tab\") {\n return;\n }\n\n const nextElement = target.nextElementSibling;\n const previousElement = target.previousElementSibling;\n\n if ((!shiftKey && !nextElement) || (shiftKey && !previousElement)) {\n return;\n }\n\n event.preventDefault();\n\n let newTarget: HTMLElement | null = null;\n\n if (shiftKey) {\n newTarget = previousElement as HTMLElement;\n } else {\n newTarget = nextElement as HTMLElement;\n }\n\n if (!newTarget) {\n return;\n }\n\n newTarget?.focus({ preventScroll: true });\n\n const rect = getRelativeBoundingClientRect(newTarget, this.scrollerElement);\n\n this.scrollerElement?.scrollBy({\n left: rect.left,\n behavior: this.scrollBehavior,\n });\n };\n\n private scrollListener = () => {\n this.currentlyScrolled = this.scrollerElement?.scrollLeft || 0;\n };\n\n get offset() {\n return this.args.offset ?? DEFAULT_OFFSET;\n }\n\n get gap() {\n return this.args.gap ?? DEFAULT_GAP;\n }\n\n get canScroll() {\n return this.scrollWidth > this.offsetWidth + this.offset;\n }\n\n get cannotScrollLeft() {\n return this.currentlyScrolled <= this.offset;\n }\n\n get cannotScrollRight() {\n return this.scrollWidth - this.offsetWidth - this.offset < this.currentlyScrolled;\n }\n\n get scrollBehavior(): ScrollBehavior {\n if (macroCondition(isTesting())) {\n return \"instant\";\n }\n\n return this.args.scrollBehavior || \"smooth\";\n }\n\n scrollLeft = () => {\n if (!(this.scrollerElement instanceof HTMLElement)) {\n return;\n }\n\n const { firstChild } = this.findOverflowingElement();\n\n if (!firstChild) {\n return;\n }\n\n const children = [...this.scrollerElement.children];\n\n const firstChildIndex = children.indexOf(firstChild);\n\n let targetElement = firstChild;\n let accumalatedWidth = 0;\n\n for (let i = firstChildIndex; i >= 0; i--) {\n const child = children[i];\n\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n\n accumalatedWidth += child.offsetWidth + this.gap;\n\n if (accumalatedWidth >= this.offsetWidth) {\n break;\n }\n\n targetElement = child;\n }\n\n const rect = getRelativeBoundingClientRect(targetElement, this.scrollerElement);\n\n this.scrollerElement.scrollBy({\n left: rect.left,\n behavior: this.scrollBehavior,\n });\n\n void waitForPromise(new Promise(requestAnimationFrame));\n };\n\n scrollRight = () => {\n if (!(this.scrollerElement instanceof HTMLElement)) {\n return;\n }\n\n const { activeSlide, lastChild } = this.findOverflowingElement();\n\n if (!lastChild) {\n return;\n }\n\n let rect = getRelativeBoundingClientRect(lastChild, this.scrollerElement);\n\n // If the card is larger than the container then skip to the next card\n if (rect.width > this.offsetWidth && activeSlide === lastChild) {\n const children = [...this.scrollerElement.children];\n const lastChildIndex = children.indexOf(lastChild);\n const targetElement = children[lastChildIndex + 1];\n\n if (!targetElement) {\n return;\n }\n\n rect = getRelativeBoundingClientRect(targetElement, this.scrollerElement);\n }\n\n this.scrollerElement?.scrollBy({\n left: rect.left,\n behavior: this.scrollBehavior,\n });\n\n void waitForPromise(new Promise(requestAnimationFrame));\n };\n\n private findOverflowingElement() {\n const returnObj: {\n activeSlide?: Element;\n firstChild?: Element;\n lastChild?: Element;\n } = {\n firstChild: undefined,\n lastChild: undefined,\n activeSlide: undefined,\n };\n\n if (!this.scrollerElement) {\n return returnObj;\n }\n\n const parentElement = this.scrollerElement.parentElement;\n\n if (!parentElement) {\n return returnObj;\n }\n\n const containerRect = getRelativeBoundingClientRect(this.scrollerElement, parentElement);\n\n const children = [...this.scrollerElement.children];\n\n // Find the first child that is overflowing the left edge of the container\n // and the last child that is overflowing the right edge of the container\n for (const child of children) {\n const rect = getRelativeBoundingClientRect(child, this.scrollerElement);\n\n if (rect.right + this.gap >= containerRect.left && !returnObj.firstChild) {\n returnObj.firstChild = child;\n }\n\n if (rect.left >= this.offset && !returnObj.activeSlide) {\n returnObj.activeSlide = child;\n }\n\n if (rect.right >= containerRect.width && !returnObj.lastChild) {\n returnObj.lastChild = child;\n\n break;\n }\n }\n\n if (!returnObj.firstChild) {\n returnObj.firstChild = children[0];\n }\n\n if (!returnObj.lastChild) {\n returnObj.lastChild = children[children.length - 1];\n }\n\n return returnObj;\n }\n\n <template>\n <section\n class=\"ember-primitives__zoetrope\"\n {{this.setCSSVariables gap=this.gap offset=this.offset}}\n ...attributes\n >\n {{#if (has-block \"header\")}}\n <div class=\"ember-primitives__zoetrope__header\">\n {{yield to=\"header\"}}\n </div>\n {{/if}}\n\n {{#if (has-block \"controls\")}}\n {{yield\n (hash\n cannotScrollLeft=this.cannotScrollLeft\n cannotScrollRight=this.cannotScrollRight\n canScroll=this.canScroll\n scrollLeft=this.scrollLeft\n scrollRight=this.scrollRight\n )\n to=\"controls\"\n }}\n {{else}}\n {{#if this.canScroll}}\n <div class=\"ember-primitives__zoetrope__controls\">\n <button\n type=\"button\"\n {{on \"click\" this.scrollLeft}}\n disabled={{this.cannotScrollLeft}}\n >Left</button>\n\n <button\n type=\"button\"\n {{on \"click\" this.scrollRight}}\n disabled={{this.cannotScrollRight}}\n >Right</button>\n </div>\n {{/if}}\n {{/if}}\n {{#if (has-block \"content\")}}\n <div class=\"ember-primitives__zoetrope__scroller\" {{this.configureScroller}}>\n {{yield to=\"content\"}}\n </div>\n {{else}}\n {{(this.noScrollWaiter)}}\n {{/if}}\n </section>\n </template>\n}\n\nexport default Zoetrope;\n\nfunction getRelativeBoundingClientRect(childElement: Element, parentElement: Element) {\n if (!childElement || !parentElement) {\n throw new Error(\"Both childElement and parentElement must be provided\");\n }\n\n // Get the bounding rect of the child and parent elements\n const childRect = childElement.getBoundingClientRect();\n const parentRect = parentElement.getBoundingClientRect();\n\n // Get computed styles of the parent element\n const parentStyles = window.getComputedStyle(parentElement);\n\n // Extract and parse parent's padding, and border, for all sides\n const parentPaddingTop = parseFloat(parentStyles.paddingTop);\n const parentPaddingLeft = parseFloat(parentStyles.paddingLeft);\n\n const parentBorderTopWidth = parseFloat(parentStyles.borderTopWidth);\n const parentBorderLeftWidth = parseFloat(parentStyles.borderLeftWidth);\n\n // Calculate child's position relative to parent's content area (including padding and borders)\n return {\n width: childRect.width,\n height: childRect.height,\n top: childRect.top - parentRect.top - parentBorderTopWidth - parentPaddingTop,\n left: childRect.left - parentRect.left - parentBorderLeftWidth - parentPaddingLeft,\n bottom:\n childRect.top - parentRect.top - parentBorderTopWidth - parentPaddingTop + childRect.height,\n right:\n childRect.left -\n parentRect.left -\n parentBorderLeftWidth -\n parentPaddingLeft +\n childRect.width,\n };\n}\n"],"names":["testWaiter","buildWaiter","DEFAULT_GAP","DEFAULT_OFFSET","Zoetrope","Component","g","prototype","tracked","i","void 0","setCSSVariables","modifier","element","_","gap","offset","style","setProperty","scrollerWaiter","beginAsync","noScrollWaiter","endAsync","configureScroller","scrollerElement","currentlyScrolled","scrollLeft","zoetropeResizeObserver","ResizeObserver","scrollWidth","offsetWidth","observe","addEventListener","scrollListener","passive","tabListener","requestAnimationFrame","removeEventListener","unobserve","event","target","key","shiftKey","nextElement","nextElementSibling","previousElement","previousElementSibling","preventDefault","newTarget","focus","preventScroll","rect","getRelativeBoundingClientRect","scrollBy","left","behavior","scrollBehavior","args","canScroll","cannotScrollLeft","cannotScrollRight","macroCondition","isTesting","HTMLElement","firstChild","findOverflowingElement","children","firstChildIndex","indexOf","targetElement","accumalatedWidth","child","waitForPromise","Promise","scrollRight","activeSlide","lastChild","width","lastChildIndex","returnObj","undefined","parentElement","containerRect","right","length","setComponentTemplate","precompileTemplate","strictMode","scope","hash","on","childElement","Error","childRect","getBoundingClientRect","parentRect","parentStyles","window","getComputedStyle","parentPaddingTop","parseFloat","paddingTop","parentPaddingLeft","paddingLeft","parentBorderTopWidth","borderTopWidth","parentBorderLeftWidth","borderLeftWidth","height","top","bottom"],"mappings":"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"}
|
|
@@ -7,9 +7,9 @@ import { precompileTemplate } from '@ember/template-compilation';
|
|
|
7
7
|
import { setComponentTemplate } from '@ember/component';
|
|
8
8
|
import { g, i } from 'decorator-transforms/runtime';
|
|
9
9
|
|
|
10
|
-
const ref = modifier((
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const ref = modifier((element, positional) => {
|
|
11
|
+
const fn = positional[0];
|
|
12
|
+
fn(element);
|
|
13
13
|
});
|
|
14
14
|
/**
|
|
15
15
|
* A component that provides no DOM and yields two modifiers for creating
|
|
@@ -42,9 +42,9 @@ class FloatingUI extends Component {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
#data = (i(this, "data"), void 0);
|
|
45
|
-
setData =
|
|
46
|
-
setReference =
|
|
47
|
-
this.reference =
|
|
45
|
+
setData = data => this.data = data;
|
|
46
|
+
setReference = element => {
|
|
47
|
+
this.reference = element;
|
|
48
48
|
};
|
|
49
49
|
static {
|
|
50
50
|
setComponentTemplate(precompileTemplate("\n {{#let (modifier anchorTo flipOptions=@flipOptions hideOptions=@hideOptions middleware=@middleware offsetOptions=@offsetOptions placement=@placement shiftOptions=@shiftOptions strategy=@strategy setData=this.setData) as |prewiredAnchorTo|}}\n {{#let (if this.reference (modifier prewiredAnchorTo this.reference)) as |floating|}}\n {{!-- @glint-nocheck -- Excessively deep, possibly infinite --}}\n {{yield (modifier ref this.setReference) floating (hash setReference=this.setReference data=this.data)}}\n {{/let}}\n {{/let}}\n ", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"component.js","sources":["../../src/floating-ui/component.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { hash } from \"@ember/helper\";\n\nimport { modifier as eModifier } from \"ember-modifier\";\n\nimport { anchorTo } from \"./modifier.ts\";\n\nimport type { Signature as ModifierSignature } from \"./modifier.ts\";\nimport type { MiddlewareState } from \"@floating-ui/dom\";\nimport type { ModifierLike } from \"@glint/template\";\n\ntype ModifierArgs = ModifierSignature[\"Args\"][\"Named\"];\n\ninterface ReferenceSignature {\n Element: HTMLElement | SVGElement;\n}\n\nexport interface Signature {\n Args: {\n /**\n * Additional middleware to pass to FloatingUI.\n *\n * See: [The middleware docs](https://floating-ui.com/docs/middleware)\n */\n middleware?: ModifierArgs[\"middleware\"];\n /**\n * Where to place the floating element relative to its reference element.\n * The default is 'bottom'.\n *\n * See: [The placement docs](https://floating-ui.com/docs/computePosition#placement)\n */\n placement?: ModifierArgs[\"placement\"];\n /**\n * This is the type of CSS position property to use.\n * By default this is 'fixed', but can also be 'absolute'.\n *\n * See: [The strategy docs](https://floating-ui.com/docs/computePosition#strategy)\n */\n strategy?: ModifierArgs[\"strategy\"];\n /**\n * Options to pass to the [flip middleware](https://floating-ui.com/docs/flip)\n */\n flipOptions?: ModifierArgs[\"flipOptions\"];\n /**\n * Options to pass to the [hide middleware](https://floating-ui.com/docs/hide)\n */\n hideOptions?: ModifierArgs[\"hideOptions\"];\n /**\n * Options to pass to the [shift middleware](https://floating-ui.com/docs/shift)\n */\n shiftOptions?: ModifierArgs[\"shiftOptions\"];\n /**\n * Options to pass to the [offset middleware](https://floating-ui.com/docs/offset)\n */\n offsetOptions?: ModifierArgs[\"offsetOptions\"];\n };\n Blocks: {\n default: [\n /**\n * A modifier to apply to the _reference_ element.\n * This is what the floating element will use to anchor to.\n *\n * Example\n * ```gjs\n * import { FloatingUI } from 'ember-primitives/floating-ui';\n *\n * <template>\n * <FloatingUI as |reference floating|>\n * <button {{reference}}> ... </button>\n * ...\n * </FloatingUI>\n * </template>\n * ```\n */\n reference: ModifierLike<ReferenceSignature>,\n /**\n * A modifier to apply to the _floating_ element.\n * This is what will anchor to the reference element.\n *\n * Example\n * ```gjs\n * import { FloatingUI } from 'ember-primitives/floating-ui';\n *\n * <template>\n * <FloatingUI as |reference floating|>\n * <button {{reference}}> ... </button>\n * <menu {{floating}}> ... </menu>\n * </FloatingUI>\n * </template>\n * ```\n */\n floating:\n | undefined\n | ModifierLike<{\n Element: HTMLElement;\n Args: {\n Named: ModifierArgs;\n };\n }>,\n /**\n * Special utilities for advanced usage\n */\n util: {\n /**\n * If you want to have a single modifier with custom behavior\n * on your reference element, you may use this `setReference`\n * function to set the reference, rather than having multiple modifiers\n * on that element.\n */\n setReference: (element: HTMLElement | SVGElement) => void;\n /**\n * Metadata exposed from floating-ui.\n * Gives you x, y position, among other things.\n */\n data?: MiddlewareState;\n },\n ];\n };\n}\n\nconst ref = eModifier<{\n Element: HTMLElement | SVGElement;\n Args: {\n Positional: [setRef: (element: HTMLElement | SVGElement) => void];\n };\n}>((element: HTMLElement | SVGElement, positional) => {\n const fn = positional[0];\n\n fn(element);\n});\n\n/**\n * A component that provides no DOM and yields two modifiers for creating\n * creating floating uis, such as menus, popovers, tooltips, etc.\n * This component currently uses [Floating UI](https://floating-ui.com/)\n * but will be switching to [CSS Anchor Positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning) when that lands.\n *\n * Example usage:\n * ```gjs\n * import { FloatingUI } from 'ember-primitives/floating-ui';\n *\n * <template>\n * <FloatingUI as |reference floating|>\n * <button {{reference}}> ... </button>\n * <menu {{floating}}> ... </menu>\n * </FloatingUI>\n * </template>\n * ```\n */\nexport class FloatingUI extends Component<Signature> {\n @tracked reference?: HTMLElement | SVGElement = undefined;\n @tracked data?: MiddlewareState = undefined;\n\n setData: ModifierArgs[\"setData\"] = (data) => (this.data = data);\n\n setReference = (element: HTMLElement | SVGElement) => {\n this.reference = element;\n };\n\n <template>\n {{#let\n (modifier\n anchorTo\n flipOptions=@flipOptions\n hideOptions=@hideOptions\n middleware=@middleware\n offsetOptions=@offsetOptions\n placement=@placement\n shiftOptions=@shiftOptions\n strategy=@strategy\n setData=this.setData\n )\n as |prewiredAnchorTo|\n }}\n {{#let (if this.reference (modifier prewiredAnchorTo this.reference)) as |floating|}}\n {{! @glint-nocheck -- Excessively deep, possibly infinite }}\n {{yield\n (modifier ref this.setReference)\n floating\n (hash setReference=this.setReference data=this.data)\n }}\n {{/let}}\n {{/let}}\n </template>\n}\n"],"names":["ref","eModifier","element","positional","fn","FloatingUI","Component","g","prototype","tracked","undefined","i","void 0","setData","data","setReference","reference","setComponentTemplate","precompileTemplate","strictMode","scope","anchorTo","hash"],"mappings":";;;;;;;;;AAyHA,MAAMA,GAAM,GAAAC,QAAA,CAKT,CAACC,OAAmC,EAAAC,UAAA,KAAA;AACrC,EAAA,MAAMC,EAAA,GAAKD,UAAU,CAAC,CAAE,CAAA;EAExBC,EAAG,CAAAF,OAAA,CAAA;AACL,CAAA,CAAA;AAEA;;;;;;;;;;;;;;;;;;AAkBO,MAAMG,UAAA,SAAmBC,SAAU,CAAA;AAAA,EAAA;IAAAC,CAAA,CAAA,IAAA,CAAAC,SAAA,EAAA,WAAA,EAAA,CACvCC,OAAA,CAAA,EAAA,YAAA;AAAA,MAAA,OAA+CC,SAAU;AAAA,KAAA,CAAA;AAAA;AAAA,EAAA,UAAA,IAAAC,CAAA,CAAA,IAAA,EAAA,WAAA,CAAA,EAAAC,MAAA;AAAA,EAAA;IAAAL,CAAA,CAAA,IAAA,CAAAC,SAAA,EAAA,MAAA,EAAA,CACzDC,OAAA,CAAA,EAAA,YAAA;AAAA,MAAA,OAAiCC,SAAU;AAAA,KAAA,CAAA;AAAA;AAAA,EAAA,KAAA,IAAAC,CAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAAC,MAAA;AAE5CC,EAAAA,OAAS,GAA2BC,IAAS,IAAC,IAAI,CAACA,IAAI,GAAGA,IAAM;EAEhEC,YAAe,GAACb,OAAuB,IAAA;IACrC,IAAI,CAACc,SAAS,GAAGd,OAAA;GACjB;AAEF,EAAA;IAAAe,oBAAA,CAAAC,kBAAA,CAwBA,mjBAAA,EAAA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;QAAAC,QAAA;QAAArB,GAAA;AAAAsB,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}
|