ember-primitives 0.49.0 → 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.
Files changed (103) hide show
  1. package/bin/index.mjs +271 -0
  2. package/declarations/components/rating/public-types.d.ts +0 -4
  3. package/declarations/components/rating/public-types.d.ts.map +1 -1
  4. package/declarations/components/rating/rating.d.ts +9 -1
  5. package/declarations/components/rating/rating.d.ts.map +1 -1
  6. package/declarations/components/rating/stars.d.ts.map +1 -1
  7. package/declarations/components/rating/state.d.ts +4 -0
  8. package/declarations/components/rating/state.d.ts.map +1 -1
  9. package/declarations/components/rating/utils.d.ts +0 -1
  10. package/declarations/components/rating/utils.d.ts.map +1 -1
  11. package/dist/components/rating.js +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/{rating-CjBVsX6q.js → rating-BrIiwDLw.js} +21 -17
  14. package/dist/rating-BrIiwDLw.js.map +1 -0
  15. package/package.json +6 -2
  16. package/src/-private.ts +4 -0
  17. package/src/color-scheme.ts +165 -0
  18. package/src/components/-private/typed-elements.gts +13 -0
  19. package/src/components/-private/utils.ts +16 -0
  20. package/src/components/accordion/content.gts +34 -0
  21. package/src/components/accordion/header.gts +36 -0
  22. package/src/components/accordion/item.gts +55 -0
  23. package/src/components/accordion/public.ts +64 -0
  24. package/src/components/accordion/trigger.gts +32 -0
  25. package/src/components/accordion.gts +195 -0
  26. package/src/components/avatar.gts +108 -0
  27. package/src/components/dialog.gts +234 -0
  28. package/src/components/external-link.gts +14 -0
  29. package/src/components/form.gts +75 -0
  30. package/src/components/heading.gts +36 -0
  31. package/src/components/keys.gts +53 -0
  32. package/src/components/layout/hero.css +5 -0
  33. package/src/components/layout/hero.gts +17 -0
  34. package/src/components/layout/sticky-footer.css +9 -0
  35. package/src/components/layout/sticky-footer.gts +40 -0
  36. package/src/components/link.gts +172 -0
  37. package/src/components/menu.gts +373 -0
  38. package/src/components/one-time-password/buttons.gts +31 -0
  39. package/src/components/one-time-password/input.gts +198 -0
  40. package/src/components/one-time-password/otp.gts +130 -0
  41. package/src/components/one-time-password/utils.ts +201 -0
  42. package/src/components/one-time-password.gts +2 -0
  43. package/src/components/popover.gts +248 -0
  44. package/src/components/portal-targets.gts +136 -0
  45. package/src/components/portal.gts +194 -0
  46. package/src/components/progress.gts +154 -0
  47. package/src/components/rating/public-types.ts +44 -0
  48. package/src/components/rating/range.gts +22 -0
  49. package/src/components/rating/rating.gts +228 -0
  50. package/src/components/rating/stars.gts +60 -0
  51. package/src/components/rating/state.gts +144 -0
  52. package/src/components/rating/utils.ts +7 -0
  53. package/src/components/rating.gts +5 -0
  54. package/src/components/scroller.gts +179 -0
  55. package/src/components/shadowed.gts +110 -0
  56. package/src/components/switch.gts +103 -0
  57. package/src/components/tabs.gts +519 -0
  58. package/src/components/toggle-group.gts +265 -0
  59. package/src/components/toggle.gts +81 -0
  60. package/src/components/violations.css +105 -0
  61. package/src/components/violations.css.ts +1 -0
  62. package/src/components/visually-hidden.css +14 -0
  63. package/src/components/visually-hidden.gts +15 -0
  64. package/src/components/zoetrope/index.gts +358 -0
  65. package/src/components/zoetrope/styles.css +40 -0
  66. package/src/components/zoetrope/types.ts +65 -0
  67. package/src/components/zoetrope.ts +3 -0
  68. package/src/dom-context.gts +245 -0
  69. package/src/floating-ui/component.gts +186 -0
  70. package/src/floating-ui/middleware.ts +13 -0
  71. package/src/floating-ui/modifier.ts +183 -0
  72. package/src/floating-ui.ts +2 -0
  73. package/src/head.gts +37 -0
  74. package/src/helpers/body-class.ts +94 -0
  75. package/src/helpers/link.ts +125 -0
  76. package/src/helpers/service.ts +25 -0
  77. package/src/helpers.ts +2 -0
  78. package/src/iframe.ts +31 -0
  79. package/src/index.ts +43 -0
  80. package/src/load.gts +77 -0
  81. package/src/narrowing.ts +7 -0
  82. package/src/on-resize.ts +64 -0
  83. package/src/proper-links.ts +140 -0
  84. package/src/qp.ts +107 -0
  85. package/src/resize-observer.ts +132 -0
  86. package/src/service.ts +103 -0
  87. package/src/store.ts +72 -0
  88. package/src/styles.css.ts +5 -0
  89. package/src/tabster.ts +54 -0
  90. package/src/template-registry.ts +44 -0
  91. package/src/test-support/a11y.ts +50 -0
  92. package/src/test-support/dom.ts +112 -0
  93. package/src/test-support/otp.ts +64 -0
  94. package/src/test-support/rating.ts +144 -0
  95. package/src/test-support/routing.ts +62 -0
  96. package/src/test-support/zoetrope.ts +51 -0
  97. package/src/test-support.gts +6 -0
  98. package/src/type-utils.ts +1 -0
  99. package/src/utils.ts +75 -0
  100. package/src/viewport/in-viewport.gts +128 -0
  101. package/src/viewport/viewport.ts +122 -0
  102. package/src/viewport.ts +2 -0
  103. package/dist/rating-CjBVsX6q.js.map +0 -1
@@ -0,0 +1,179 @@
1
+ import Component from "@glimmer/component";
2
+ import { isDestroyed, isDestroying } from "@ember/destroyable";
3
+ import { hash } from "@ember/helper";
4
+
5
+ import { modifier } from "ember-modifier";
6
+
7
+ /**
8
+ * Utility component for helping with scrolling in any direction within
9
+ * any of the 4 directions: up, down, left, right.
10
+ *
11
+ * This can be used to auto-scroll content as new content is inserted into the scrollable area, or possibly to bring focus to something on the page.
12
+ */
13
+ export class Scroller extends Component<{
14
+ /**
15
+ * A containing element is required - in this case, a div.
16
+ * It must be scrollable for this component to work, but can be customized.
17
+ *
18
+ * By default, this element will have some styling applied:
19
+ * overflow: auto;
20
+ *
21
+ * By default, this element will have tabindex="0" to support keyboard usage.
22
+ *
23
+ * The scroll-behavior is "auto", which can be controlled via CSS
24
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
25
+ *
26
+ */
27
+ Element: HTMLDivElement;
28
+ Blocks: {
29
+ default: [
30
+ {
31
+ /**
32
+ * Scroll the content to the bottom
33
+ *
34
+ * ```gjs
35
+ * import { Scroller } from 'ember-primitives';
36
+ *
37
+ * <template>
38
+ * <Scroller as |s|>
39
+ * ...
40
+ *
41
+ * {{ (s.scrollToBottom) }}
42
+ * </Scroller>
43
+ * </template>
44
+ * ```
45
+ */
46
+ scrollToBottom: () => void;
47
+ /**
48
+ * Scroll the content to the top
49
+ *
50
+ * ```gjs
51
+ * import { Scroller } from 'ember-primitives';
52
+ *
53
+ * <template>
54
+ * <Scroller as |s|>
55
+ * ...
56
+ *
57
+ * {{ (s.scrollToTop) }}
58
+ * </Scroller>
59
+ * </template>
60
+ * ```
61
+ */
62
+ scrollToTop: () => void;
63
+ /**
64
+ * Scroll the content to the left
65
+ *
66
+ * ```gjs
67
+ * import { Scroller } from 'ember-primitives';
68
+ *
69
+ * <template>
70
+ * <Scroller as |s|>
71
+ * ...
72
+ *
73
+ * {{ (s.scrollToLeft) }}
74
+ * </Scroller>
75
+ * </template>
76
+ * ```
77
+ */
78
+ scrollToLeft: () => void;
79
+ /**
80
+ * Scroll the content to the right
81
+ *
82
+ * ```gjs
83
+ * import { Scroller } from 'ember-primitives';
84
+ *
85
+ * <template>
86
+ * <Scroller as |s|>
87
+ * ...
88
+ *
89
+ * {{ (s.scrollToRight) }}
90
+ * </Scroller>
91
+ * </template>
92
+ * ```
93
+ */
94
+ scrollToRight: () => void;
95
+ },
96
+ ];
97
+ };
98
+ }> {
99
+ declare withinElement: HTMLDivElement;
100
+
101
+ ref = modifier((el: HTMLDivElement) => {
102
+ this.withinElement = el;
103
+ });
104
+
105
+ #frame?: number;
106
+
107
+ scrollToBottom = () => {
108
+ if (this.#frame) {
109
+ cancelAnimationFrame(this.#frame);
110
+ }
111
+
112
+ this.#frame = requestAnimationFrame(() => {
113
+ if (isDestroyed(this) || isDestroying(this)) return;
114
+
115
+ this.withinElement.scrollTo({
116
+ top: this.withinElement.scrollHeight,
117
+ behavior: "auto",
118
+ });
119
+ });
120
+ };
121
+
122
+ scrollToTop = () => {
123
+ if (this.#frame) {
124
+ cancelAnimationFrame(this.#frame);
125
+ }
126
+
127
+ this.#frame = requestAnimationFrame(() => {
128
+ if (isDestroyed(this) || isDestroying(this)) return;
129
+
130
+ this.withinElement.scrollTo({
131
+ top: 0,
132
+ behavior: "auto",
133
+ });
134
+ });
135
+ };
136
+
137
+ scrollToLeft = () => {
138
+ if (this.#frame) {
139
+ cancelAnimationFrame(this.#frame);
140
+ }
141
+
142
+ this.#frame = requestAnimationFrame(() => {
143
+ if (isDestroyed(this) || isDestroying(this)) return;
144
+
145
+ this.withinElement.scrollTo({
146
+ left: 0,
147
+ behavior: "auto",
148
+ });
149
+ });
150
+ };
151
+
152
+ scrollToRight = () => {
153
+ if (this.#frame) {
154
+ cancelAnimationFrame(this.#frame);
155
+ }
156
+
157
+ this.#frame = requestAnimationFrame(() => {
158
+ if (isDestroyed(this) || isDestroying(this)) return;
159
+
160
+ this.withinElement.scrollTo({
161
+ left: this.withinElement.scrollWidth,
162
+ behavior: "auto",
163
+ });
164
+ });
165
+ };
166
+
167
+ <template>
168
+ <div tabindex="0" ...attributes {{this.ref}}>
169
+ {{yield
170
+ (hash
171
+ scrollToBottom=this.scrollToBottom
172
+ scrollToTop=this.scrollToTop
173
+ scrollToLeft=this.scrollToLeft
174
+ scrollToRight=this.scrollToRight
175
+ )
176
+ }}
177
+ </div>
178
+ </template>
179
+ }
@@ -0,0 +1,110 @@
1
+ import Component from "@glimmer/component";
2
+
3
+ import type Owner from "@ember/owner";
4
+
5
+ // index.html has the production-fingerprinted references to these links
6
+ // Ideally, we'd have some pre-processor scan everything for references to
7
+ // assets in public, but idk how to set that up
8
+ const getStyles = () => [...document.querySelectorAll("link")].map((link) => link.href);
9
+
10
+ /**
11
+ * style + native @import
12
+ * is the only robust way to load styles in a shadowroot.
13
+ *
14
+ * link is only valid in the head element.
15
+ */
16
+ const Styles = <template>
17
+ <style>
18
+ {{#each (getStyles) as |styleHref|}}
19
+
20
+ @import "{{styleHref}}";
21
+
22
+ {{/each}}
23
+ </style>
24
+ </template>;
25
+
26
+ /**
27
+ * Render content in a shadow dom, attached to a div.
28
+ *
29
+ * Uses the [shadow DOM][mdn-shadow-dom] API.
30
+ *
31
+ * [mdn-shadow-dom]: https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM
32
+ *
33
+ * This is useful when you want to render content that escapes your app's styles.
34
+ */
35
+ export class Shadowed extends Component<{
36
+ /**
37
+ * The shadow dom attaches to a div element.
38
+ * You may specify any attribute, and it'll be applied to this host element.
39
+ */
40
+ Element: HTMLDivElement;
41
+ Args: {
42
+ /**
43
+ * @public
44
+ *
45
+ * By default, shadow-dom does not include any styles.
46
+ * Setting this to true will include all the `<style>` tags
47
+ * that are present in the `<head>` element.
48
+ */
49
+ includeStyles?: boolean;
50
+ };
51
+ Blocks: {
52
+ /**
53
+ * Content to be placed within the ShadowDOM
54
+ */
55
+ default: [];
56
+ };
57
+ }> {
58
+ shadow: HTMLDivElement;
59
+ host: HTMLDivElement;
60
+ /**
61
+ * ember-source 5.6 broke the ability to in-element
62
+ * natively into a shadowroot.
63
+ *
64
+ * We have two or three more dives than we should have here.
65
+ *
66
+ *
67
+ * See these ember-source bugs:
68
+ * - https://github.com/emberjs/ember.js/issues/20643
69
+ * - https://github.com/emberjs/ember.js/issues/20642
70
+ * - https://github.com/emberjs/ember.js/issues/20641
71
+ *
72
+ * Ideally, shadowdom should be built in.
73
+ * Couple paths forward:
74
+ * - (as the overall template tag)
75
+ * <template shadowrootmode="open">
76
+ * </template>
77
+ *
78
+ * - Build a component into the framework that does the above ^
79
+ * - add additional parsing in content-tag to allow
80
+ * nested <template>
81
+ *
82
+ */
83
+ constructor(owner: Owner, args: { includeStyles?: boolean }) {
84
+ super(owner, args);
85
+
86
+ const element = document.createElement("div");
87
+ const shadowRoot = element.attachShadow({ mode: "open" });
88
+ const div = document.createElement("div");
89
+
90
+ shadowRoot.appendChild(div);
91
+ this.host = element;
92
+ this.shadow = div;
93
+ }
94
+
95
+ <template>
96
+ <div ...attributes>{{this.host}}</div>
97
+
98
+ {{#in-element this.shadow}}
99
+
100
+ {{#if @includeStyles}}
101
+ <Styles />
102
+ {{/if}}
103
+
104
+ {{yield}}
105
+
106
+ {{/in-element}}
107
+ </template>
108
+ }
109
+
110
+ export default Shadowed;
@@ -0,0 +1,103 @@
1
+ import { fn, hash } from "@ember/helper";
2
+ import { on } from "@ember/modifier";
3
+
4
+ import { cell } from "ember-resources";
5
+
6
+ import { uniqueId } from "../utils.ts";
7
+ import { Label } from "./-private/typed-elements.gts";
8
+ import { toggleWithFallback } from "./-private/utils.ts";
9
+
10
+ import type { TOC } from "@ember/component/template-only";
11
+ import type { WithBoundArgs } from "@glint/template";
12
+
13
+ export interface Signature {
14
+ Element: HTMLInputElement;
15
+ Args: {
16
+ /**
17
+ * The initial checked value of the Switch.
18
+ * This value is reactive, so if the value that
19
+ * `@checked` is set to updates, the state of the Switch will also update.
20
+ */
21
+ checked?: boolean;
22
+ /**
23
+ * Callback when the Switch state is toggled
24
+ */
25
+ onChange?: (checked: boolean, event: Event) => void;
26
+ };
27
+ Blocks: {
28
+ default?: [
29
+ {
30
+ /**
31
+ * The Switch Element.
32
+ * It has a pre-wired `id` so that the relevant Label is
33
+ * appropriately associated via the `for` property of the Label.
34
+ *
35
+ * ```gjs
36
+ * import { Switch } from 'ember-primitives';
37
+ *
38
+ * <template>
39
+ * <Switch as |s|>
40
+ * <s.Control />
41
+ * </Switch>
42
+ * </template>
43
+ * ```
44
+ */
45
+ Control: WithBoundArgs<typeof Checkbox, "checked" | "id" | "onChange">;
46
+ /**
47
+ * The Switch element requires a label, and this label already has
48
+ * the association to the Control by setting the `for` attribute to the `id` of the Control
49
+ *
50
+ * ```gjs
51
+ * import { Switch } from 'ember-primitives';
52
+ *
53
+ * <template>
54
+ * <Switch as |s|>
55
+ * <s.Label />
56
+ * </Switch>
57
+ * </template>
58
+ * ```
59
+ */
60
+ Label: WithBoundArgs<typeof Label, "for">;
61
+ },
62
+ ];
63
+ };
64
+ }
65
+
66
+ interface ControlSignature {
67
+ Element: HTMLInputElement;
68
+ Args: { id: string; checked?: boolean; onChange: () => void };
69
+ }
70
+
71
+ const Checkbox: TOC<ControlSignature> = <template>
72
+ {{#let (cell @checked) as |checked|}}
73
+ <input
74
+ id={{@id}}
75
+ type="checkbox"
76
+ role="switch"
77
+ checked={{checked.current}}
78
+ aria-checked={{checked.current}}
79
+ data-state={{if checked.current "on" "off"}}
80
+ {{on "click" (fn toggleWithFallback checked.toggle @onChange)}}
81
+ ...attributes
82
+ />
83
+ {{/let}}
84
+ </template>;
85
+
86
+ /**
87
+ * @public
88
+ */
89
+ export const Switch: TOC<Signature> = <template>
90
+ <div ...attributes data-prim-switch>
91
+ {{! @glint-nocheck }}
92
+ {{#let (uniqueId) as |id|}}
93
+ {{yield
94
+ (hash
95
+ Control=(component Checkbox checked=@checked id=id onChange=@onChange)
96
+ Label=(component Label for=id)
97
+ )
98
+ }}
99
+ {{/let}}
100
+ </div>
101
+ </template>;
102
+
103
+ export default Switch;