ember-primitives 0.49.0 → 0.50.1

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 (107) hide show
  1. package/bin/index.mjs +271 -0
  2. package/declarations/color-scheme.d.ts +1 -1
  3. package/declarations/color-scheme.d.ts.map +1 -1
  4. package/declarations/components/rating/public-types.d.ts +0 -4
  5. package/declarations/components/rating/public-types.d.ts.map +1 -1
  6. package/declarations/components/rating/rating.d.ts +9 -1
  7. package/declarations/components/rating/rating.d.ts.map +1 -1
  8. package/declarations/components/rating/stars.d.ts.map +1 -1
  9. package/declarations/components/rating/state.d.ts +4 -0
  10. package/declarations/components/rating/state.d.ts.map +1 -1
  11. package/declarations/components/rating/utils.d.ts +0 -1
  12. package/declarations/components/rating/utils.d.ts.map +1 -1
  13. package/dist/color-scheme.js +13 -4
  14. package/dist/color-scheme.js.map +1 -1
  15. package/dist/components/rating.js +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/{rating-CjBVsX6q.js → rating-BrIiwDLw.js} +21 -17
  18. package/dist/rating-BrIiwDLw.js.map +1 -0
  19. package/package.json +6 -2
  20. package/src/-private.ts +4 -0
  21. package/src/color-scheme.ts +177 -0
  22. package/src/components/-private/typed-elements.gts +13 -0
  23. package/src/components/-private/utils.ts +16 -0
  24. package/src/components/accordion/content.gts +34 -0
  25. package/src/components/accordion/header.gts +36 -0
  26. package/src/components/accordion/item.gts +55 -0
  27. package/src/components/accordion/public.ts +64 -0
  28. package/src/components/accordion/trigger.gts +32 -0
  29. package/src/components/accordion.gts +195 -0
  30. package/src/components/avatar.gts +108 -0
  31. package/src/components/dialog.gts +234 -0
  32. package/src/components/external-link.gts +14 -0
  33. package/src/components/form.gts +75 -0
  34. package/src/components/heading.gts +36 -0
  35. package/src/components/keys.gts +53 -0
  36. package/src/components/layout/hero.css +5 -0
  37. package/src/components/layout/hero.gts +17 -0
  38. package/src/components/layout/sticky-footer.css +9 -0
  39. package/src/components/layout/sticky-footer.gts +40 -0
  40. package/src/components/link.gts +172 -0
  41. package/src/components/menu.gts +373 -0
  42. package/src/components/one-time-password/buttons.gts +31 -0
  43. package/src/components/one-time-password/input.gts +198 -0
  44. package/src/components/one-time-password/otp.gts +130 -0
  45. package/src/components/one-time-password/utils.ts +201 -0
  46. package/src/components/one-time-password.gts +2 -0
  47. package/src/components/popover.gts +248 -0
  48. package/src/components/portal-targets.gts +136 -0
  49. package/src/components/portal.gts +194 -0
  50. package/src/components/progress.gts +154 -0
  51. package/src/components/rating/public-types.ts +44 -0
  52. package/src/components/rating/range.gts +22 -0
  53. package/src/components/rating/rating.gts +228 -0
  54. package/src/components/rating/stars.gts +60 -0
  55. package/src/components/rating/state.gts +144 -0
  56. package/src/components/rating/utils.ts +7 -0
  57. package/src/components/rating.gts +5 -0
  58. package/src/components/scroller.gts +179 -0
  59. package/src/components/shadowed.gts +110 -0
  60. package/src/components/switch.gts +103 -0
  61. package/src/components/tabs.gts +519 -0
  62. package/src/components/toggle-group.gts +265 -0
  63. package/src/components/toggle.gts +81 -0
  64. package/src/components/violations.css +105 -0
  65. package/src/components/violations.css.ts +1 -0
  66. package/src/components/visually-hidden.css +14 -0
  67. package/src/components/visually-hidden.gts +15 -0
  68. package/src/components/zoetrope/index.gts +358 -0
  69. package/src/components/zoetrope/styles.css +40 -0
  70. package/src/components/zoetrope/types.ts +65 -0
  71. package/src/components/zoetrope.ts +3 -0
  72. package/src/dom-context.gts +245 -0
  73. package/src/floating-ui/component.gts +186 -0
  74. package/src/floating-ui/middleware.ts +13 -0
  75. package/src/floating-ui/modifier.ts +183 -0
  76. package/src/floating-ui.ts +2 -0
  77. package/src/head.gts +37 -0
  78. package/src/helpers/body-class.ts +94 -0
  79. package/src/helpers/link.ts +125 -0
  80. package/src/helpers/service.ts +25 -0
  81. package/src/helpers.ts +2 -0
  82. package/src/iframe.ts +31 -0
  83. package/src/index.ts +43 -0
  84. package/src/load.gts +77 -0
  85. package/src/narrowing.ts +7 -0
  86. package/src/on-resize.ts +64 -0
  87. package/src/proper-links.ts +140 -0
  88. package/src/qp.ts +107 -0
  89. package/src/resize-observer.ts +132 -0
  90. package/src/service.ts +103 -0
  91. package/src/store.ts +72 -0
  92. package/src/styles.css.ts +5 -0
  93. package/src/tabster.ts +54 -0
  94. package/src/template-registry.ts +44 -0
  95. package/src/test-support/a11y.ts +50 -0
  96. package/src/test-support/dom.ts +112 -0
  97. package/src/test-support/otp.ts +64 -0
  98. package/src/test-support/rating.ts +144 -0
  99. package/src/test-support/routing.ts +62 -0
  100. package/src/test-support/zoetrope.ts +51 -0
  101. package/src/test-support.gts +6 -0
  102. package/src/type-utils.ts +1 -0
  103. package/src/utils.ts +75 -0
  104. package/src/viewport/in-viewport.gts +128 -0
  105. package/src/viewport/viewport.ts +122 -0
  106. package/src/viewport.ts +2 -0
  107. package/dist/rating-CjBVsX6q.js.map +0 -1
package/bin/index.mjs ADDED
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable n/no-process-exit */
3
+
4
+ import { spawn, spawnSync } from "node:child_process";
5
+ import { existsSync } from "node:fs";
6
+ import { glob, stat } from "node:fs/promises";
7
+ import { extname, isAbsolute, join, relative } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { parseArgs, styleText } from "node:util";
10
+
11
+ const repoURL = "https://github.com/universal-ember/ember-primitives.git";
12
+ const binName = "ember-primitives";
13
+ const repoPrefix = `ember-primitives/src/`;
14
+
15
+ async function findAvailableFiles() {
16
+ const packageRoot = fileURLToPath(new URL("..", import.meta.url));
17
+ const pattern = "./src/**/*";
18
+
19
+ const matches = [];
20
+ for await (const match of glob(pattern, { cwd: packageRoot })) {
21
+ const rel = isAbsolute(match) ? relative(packageRoot, match) : match;
22
+ matches.push(rel.replace(/\\/g, "/"));
23
+ }
24
+
25
+ // The built-in glob can include directories; filter to files.
26
+ // Do this after collecting to keep behavior stable.
27
+ const stats = await Promise.all(
28
+ matches.map(async (p) => {
29
+ try {
30
+ const s = await stat(join(packageRoot, p));
31
+ return s.isFile() ? p : null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }),
36
+ );
37
+
38
+ return stats.filter((p) => p !== null).map((x) => join("ember-primitives", x));
39
+ }
40
+
41
+ function printHelp() {
42
+ console.log(`\
43
+ ${binName}
44
+
45
+ Usage:
46
+ ${binName} emit <filepath> --output-folder <path> [--javascript] [--tag <tag>]
47
+
48
+ Description:
49
+ "emit" is a thin wrapper around unlibrary (https://github.com/NullVoxPopuli/unlibrary)
50
+ with defaults derived from this repository.
51
+
52
+ Examples:
53
+ ${binName} emit store.ts --output-folder ./src/primitives/
54
+ ${binName} emit ember-primitives/src/create-store.ts --output-folder ./src/primitives/ --javascript
55
+
56
+ Options:
57
+ --output-folder, --out <path> Where unlibrary should copy files (required)
58
+ --tag <tag> Override the git tag (default: vMAJOR.MINOR from package version)
59
+ --javascript Force JavaScript output when TS is encountered
60
+ -h, --help Show help
61
+ `);
62
+ }
63
+
64
+ function fail(message) {
65
+ console.error(message);
66
+ console.error("");
67
+ printHelp();
68
+ process.exit(1);
69
+ }
70
+
71
+ function assertNodeVersion() {
72
+ // unlibrary currently requires Node >= 24.12.0 (per its package.json engines).
73
+ const major = Number(String(process.versions.node).split(".")[0]);
74
+ if (Number.isFinite(major) && major < 24) {
75
+ fail(
76
+ `unlibrary requires Node >= 24.12.0, but you're running Node ${process.versions.node}.\n` +
77
+ `Please upgrade Node (or run this in an environment that has Node 24+) and try again.`,
78
+ );
79
+ }
80
+ }
81
+
82
+ function hasCommand(cmd) {
83
+ const result = spawnSync(cmd, ["--version"], { stdio: "ignore" });
84
+ if (result.error && result.error.code === "ENOENT") return false;
85
+ // Some tools return non-zero for --version in odd envs; if it spawned, we treat as present.
86
+ return true;
87
+ }
88
+
89
+ function spawnWithInherit(cmd, args) {
90
+ return new Promise((resolve, reject) => {
91
+ const child = spawn(cmd, args, {
92
+ stdio: "inherit",
93
+ shell: false,
94
+ });
95
+
96
+ child.on("error", reject);
97
+ child.on("exit", (code, signal) => {
98
+ if (signal) {
99
+ resolve(1);
100
+ } else {
101
+ resolve(code ?? 1);
102
+ }
103
+ });
104
+ });
105
+ }
106
+
107
+ async function runUnlibrary(unlibraryArgs) {
108
+ // Prefer GitHub source, then fall back to npm package.
109
+ // We also prefer pnpm (this repo uses pnpm) and fall back to npx.
110
+ const candidates = [];
111
+
112
+ if (hasCommand("pnpm")) {
113
+ candidates.push(["pnpm", ["dlx", "unlibrary@latest", ...unlibraryArgs]]);
114
+ }
115
+
116
+ if (hasCommand("npx")) {
117
+ candidates.push(["npx", ["-y", "unlibrary@latest", ...unlibraryArgs]]);
118
+ }
119
+
120
+ if (candidates.length === 0) {
121
+ fail("Could not find pnpm or npx to run unlibrary. Please install pnpm (recommended) or npm.");
122
+ }
123
+
124
+ console.log(`
125
+ Running:
126
+
127
+ ${styleText("cyan", "unlibrary")} ${unlibraryArgs.map((arg) => (arg.startsWith("--") ? styleText("gray", arg) : styleText("yellow", arg))).join(" ")}
128
+ `);
129
+
130
+ let lastExitCode = 1;
131
+ let lastError;
132
+
133
+ for (const [cmd, args] of candidates) {
134
+ try {
135
+ lastExitCode = await spawnWithInherit(cmd, args);
136
+ if (lastExitCode === 0) return 0;
137
+ } catch (e) {
138
+ lastError = e;
139
+ }
140
+ }
141
+
142
+ if (lastError) throw lastError;
143
+ return lastExitCode;
144
+ }
145
+
146
+ async function check() {
147
+ const parsed = parseArgs({
148
+ args: process.argv.slice(2),
149
+ allowPositionals: true,
150
+ strict: false,
151
+ options: {
152
+ help: { type: "boolean", short: "h" },
153
+ },
154
+ });
155
+
156
+ if (parsed.values.help) {
157
+ printHelp();
158
+ process.exit(0);
159
+ }
160
+
161
+ const [command, ...positionals] = parsed.positionals;
162
+
163
+ if (!command) {
164
+ printHelp();
165
+ process.exit(0);
166
+ }
167
+ if (command !== "emit") {
168
+ fail(`Unknown command: ${command}`);
169
+ }
170
+
171
+ assertNodeVersion();
172
+
173
+ const errors = [];
174
+
175
+ const filepathInput = positionals[0];
176
+ if (!filepathInput) {
177
+ errors.push("Missing required argument: <filepath>");
178
+ }
179
+
180
+ if (errors.length > 0) {
181
+ console.error("Errors:");
182
+ errors.forEach((error) => console.error(` - ${error}`));
183
+ console.error("");
184
+ printHelp();
185
+ process.exit(1);
186
+ }
187
+
188
+ return { filepathInput };
189
+ }
190
+
191
+ async function findFile(filepathInput) {
192
+ const availableFiles = await findAvailableFiles();
193
+
194
+ let candidates = availableFiles.filter((available) => {
195
+ let trimmed = available.replace(repoPrefix, "");
196
+
197
+ if (trimmed === filepathInput) {
198
+ return true;
199
+ }
200
+
201
+ let ext = extname(trimmed);
202
+ let extensionless = trimmed.replace(new RegExp(RegExp.escape(ext) + "$"), "");
203
+
204
+ if (extensionless === filepathInput) {
205
+ return true;
206
+ }
207
+ });
208
+
209
+ if (candidates.length > 1) {
210
+ fail(`Too many candidate files found: ${candidates}. Please specify one only`);
211
+ }
212
+
213
+ if (candidates === 0) {
214
+ let potentials = availableFiles
215
+ .map((x) => x.replace(repoPrefix, ""))
216
+ .filter((x) => x.includes(filepathInput));
217
+
218
+ fail(
219
+ `Not file matches found for ${filepathInput}. Did you mean one of ${potentials ?? availableFiles}`,
220
+ );
221
+ }
222
+
223
+ const filepath = candidates[0];
224
+
225
+ return { filepath };
226
+ }
227
+
228
+ function findOutput() {
229
+ let cwd = process.cwd();
230
+ let src = join(cwd, "src");
231
+ let app = join(cwd, "app");
232
+
233
+ if (existsSync(src)) return "src/primitives";
234
+ if (existsSync(app)) return "app/primitives";
235
+
236
+ fail(
237
+ `Could not determine output folder automatically. Please specify --output-folder ./place-to/emit/files`,
238
+ );
239
+ }
240
+
241
+ async function main() {
242
+ const { filepathInput } = await check();
243
+ const { filepath } = await findFile(filepathInput);
244
+
245
+ // Get remaining args that weren't parsed by parseArgs
246
+ const remainingArgs = process.argv.slice(2).filter((arg, index) => {
247
+ // Skip the command itself
248
+ if (index === 0) return false;
249
+ // Skip positional filepath argument
250
+ if (index === 1 && !arg.startsWith("-")) return false;
251
+ // Skip known parsed options and their values
252
+ if (arg === "--help" || arg === "-h") return false;
253
+ return true;
254
+ });
255
+
256
+ const unlibraryArgs = [
257
+ "--repo",
258
+ repoURL,
259
+ ...(remainingArgs.includes("--filepath") ? [] : ["--filepath", filepath]),
260
+ ...(remainingArgs.includes("--output-folder") ? [] : ["--output-folder", findOutput()]),
261
+ ...remainingArgs,
262
+ ];
263
+
264
+ const exitCode = await runUnlibrary(unlibraryArgs);
265
+ process.exit(exitCode);
266
+ }
267
+
268
+ main().catch((e) => {
269
+ console.error(e);
270
+ process.exit(1);
271
+ });
@@ -36,8 +36,8 @@ export declare function sync(): void;
36
36
  export declare const prefers: {
37
37
  dark: () => boolean;
38
38
  light: () => boolean;
39
- custom: (name: string) => boolean;
40
39
  none: () => boolean;
40
+ custom: (name: string) => boolean;
41
41
  };
42
42
  /**
43
43
  * Helper methods for working with the color scheme preference in local storage
@@ -1 +1 @@
1
- {"version":3,"file":"color-scheme.d.ts","sourceRoot":"","sources":["../src/color-scheme.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;oBACa,MAAM;;QAOpB;;WAEG;2BACgB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI;;;QAKhD;;WAEG;2BACgB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI;;IAKlD;;OAEG;aACY,MAAM,GAAG,SAAS;CAelC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,IAAI,SAyBnB;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO;;;mBAGH,MAAM;;CAEtB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,eAAe;;;oBAGV,MAAM;;CAEvB,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,WAAW,UAInD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;AAkBpD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,WAAW,QAItD"}
1
+ {"version":3,"file":"color-scheme.d.ts","sourceRoot":"","sources":["../src/color-scheme.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;oBACa,MAAM;;QAOpB;;WAEG;2BACgB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI;;;QAKhD;;WAEG;2BACgB,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI;;IAKlD;;OAEG;aACY,MAAM,GAAG,SAAS;CAelC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,IAAI,SAyBnB;AAcD;;;GAGG;AACH,eAAO,MAAM,OAAO;;;;mBAIH,MAAM;CACtB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,eAAe;;;oBAGV,MAAM;;CAEvB,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,WAAW,UAInD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;AAkBpD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,WAAW,QAItD"}
@@ -17,10 +17,6 @@ export interface ComponentIcons {
17
17
  * Is this item selected?
18
18
  */
19
19
  isSelected: boolean;
20
- /**
21
- * How much % of this item is selected?
22
- */
23
- percentSelected: number;
24
20
  /**
25
21
  * Which number of item is this item within the overall rating group.
26
22
  */
@@ -1 +1 @@
1
- {"version":3,"file":"public-types.d.ts","sourceRoot":"","sources":["../../../src/components/rating/public-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,IAAI,EAAE,aAAa,CAAC;QAClB,OAAO,EAAE,WAAW,CAAC;QACrB,IAAI,EAAE;YACJ;;eAEG;YACH,UAAU,EAAE,OAAO,CAAC;YACpB;;eAEG;YACH,eAAe,EAAE,MAAM,CAAC;YACxB;;eAEG;YACH,KAAK,EAAE,MAAM,CAAC;YACd;;eAEG;YACH,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC;KACH,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"public-types.d.ts","sourceRoot":"","sources":["../../../src/components/rating/public-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,IAAI,EAAE,aAAa,CAAC;QAClB,OAAO,EAAE,WAAW,CAAC;QACrB,IAAI,EAAE;YACJ;;eAEG;YACH,UAAU,EAAE,OAAO,CAAC;YACpB;;eAEG;YACH,KAAK,EAAE,MAAM,CAAC;YACd;;eAEG;YACH,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC;KACH,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -18,6 +18,15 @@ export interface Signature {
18
18
  * Defaults to 0
19
19
  */
20
20
  value?: number;
21
+ /**
22
+ * When generating the radio inputs, this changes what value of rating each radio
23
+ * input will be incremented by.
24
+ *
25
+ * e.g.: Set to 0.5 for half-star ratings.
26
+ *
27
+ * Defaults to 1
28
+ */
29
+ step?: number;
21
30
  /**
22
31
  * Prevents click events on the icons and sets aria-readonly.
23
32
  *
@@ -95,7 +104,6 @@ export declare class Rating extends Component<Signature> {
95
104
  Element: HTMLElement;
96
105
  Args: {
97
106
  isSelected: boolean;
98
- percentSelected: number;
99
107
  value: number;
100
108
  readonly: boolean;
101
109
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rating.d.ts","sourceRoot":"","sources":["../../../src/components/rating/rating.gts"],"names":[],"mappings":"AAoNA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAK3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,SAAS;IAOxB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,IAAI,EAAE,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG;QACrC;;;;WAIG;QACH,GAAG,CAAC,EAAE,MAAM,CAAC;QAEb;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf;;;;WAIG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QAEnB;;;;;;WAMG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB;;;WAGG;QACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACpC,CAAC;IAEF,MAAM,EAAE;QACN,OAAO,EAAE;YACP,MAAM,EAAE;gBACN;;mBAEG;gBACH,GAAG,EAAE,MAAM,CAAC;gBACZ;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBACd;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBACd;;mBAEG;gBACH,IAAI,EAAE,MAAM,CAAC;gBACb;;mBAEG;gBACH,UAAU,EAAE,OAAO,CAAC;gBACpB;;mBAEG;gBACH,YAAY,EAAE,OAAO,CAAC;gBACtB;;mBAEG;gBACH,KAAK,EAAE,aAAa,CAClB,OAAO,KAAK,EACZ,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CACpE,CAAC;gBACF;;mBAEG;gBACH,KAAK,EAAE,aAAa,CAAC,OAAO,WAAW,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC,CAAC;aACrF;SACF,CAAC;QACF,KAAK,EAAE;YACL,KAAK,EAAE;gBACL;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBAEd;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;aACf;SACF,CAAC;KACH,CAAC;CACH;AAED,qBAAa,MAAO,SAAQ,SAAS,CAAC,SAAS,CAAC;IAC9C,IAAI,SAA0B;IAE9B,IAAI,IAAI;;;;;;;;OAEP;IAED,IAAI,aAAa,YAEhB;IAED,IAAI,YAAY,YAIf;IAED,IAAI,UAAU,YAEb;IAED,IAAI,gBAAgB,YAEnB;CAgFF"}
1
+ {"version":3,"file":"rating.d.ts","sourceRoot":"","sources":["../../../src/components/rating/rating.gts"],"names":[],"mappings":"AAoOA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAK3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,SAAS;IAOxB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,IAAI,EAAE,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG;QACrC;;;;WAIG;QACH,GAAG,CAAC,EAAE,MAAM,CAAC;QAEb;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf;;;;;;;WAOG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QAEd;;;;WAIG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QAEnB;;;;;;WAMG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC;QAEtB;;;WAGG;QACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACpC,CAAC;IAEF,MAAM,EAAE;QACN,OAAO,EAAE;YACP,MAAM,EAAE;gBACN;;mBAEG;gBACH,GAAG,EAAE,MAAM,CAAC;gBACZ;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBACd;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBACd;;mBAEG;gBACH,IAAI,EAAE,MAAM,CAAC;gBACb;;mBAEG;gBACH,UAAU,EAAE,OAAO,CAAC;gBACpB;;mBAEG;gBACH,YAAY,EAAE,OAAO,CAAC;gBACtB;;mBAEG;gBACH,KAAK,EAAE,aAAa,CAClB,OAAO,KAAK,EACZ,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CACpE,CAAC;gBACF;;mBAEG;gBACH,KAAK,EAAE,aAAa,CAAC,OAAO,WAAW,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC,CAAC;aACrF;SACF,CAAC;QACF,KAAK,EAAE;YACL,KAAK,EAAE;gBACL;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;gBAEd;;mBAEG;gBACH,KAAK,EAAE,MAAM,CAAC;aACf;SACF,CAAC;KACH,CAAC;CACH;AAED,qBAAa,MAAO,SAAQ,SAAS,CAAC,SAAS,CAAC;IAC9C,IAAI,SAA0B;IAE9B,IAAI,IAAI;;;;;;;OAEP;IAED,IAAI,aAAa,YAEhB;IAED,IAAI,YAAY,YAIf;IAED,IAAI,UAAU,YAEb;IAED,IAAI,gBAAgB,YAEnB;CAiFF"}
@@ -1 +1 @@
1
- {"version":3,"file":"stars.d.ts","sourceRoot":"","sources":["../../../src/components/rating/stars.gts"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AAE1D,eAAO,MAAM,KAAK,EAAE,GAAG,CAAC;IACtB,IAAI,EAAE;QAEJ,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACnD,UAAU,EAAE,OAAO,CAAC;QAGpB,IAAI,EAAE,MAAM,CAAC;QAGb,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CA8FC,CAAC"}
1
+ {"version":3,"file":"stars.d.ts","sourceRoot":"","sources":["../../../src/components/rating/stars.gts"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AAE1D,eAAO,MAAM,KAAK,EAAE,GAAG,CAAC;IACtB,IAAI,EAAE;QAEJ,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACnD,UAAU,EAAE,OAAO,CAAC;QAGpB,IAAI,EAAE,MAAM,CAAC;QAGb,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CA6FC,CAAC"}
@@ -3,6 +3,7 @@ export declare class RatingState extends Component<{
3
3
  Args: {
4
4
  max: number | undefined;
5
5
  value: number | undefined;
6
+ step: number | undefined;
6
7
  readonly: boolean | undefined;
7
8
  name: string;
8
9
  onChange?: (value: number) => void;
@@ -11,6 +12,7 @@ export declare class RatingState extends Component<{
11
12
  default: [
12
13
  internalApi: {
13
14
  stars: number[];
15
+ step: number;
14
16
  value: number;
15
17
  total: number;
16
18
  handleClick: (event: Event) => void;
@@ -26,6 +28,8 @@ export declare class RatingState extends Component<{
26
28
  }> {
27
29
  _value: number;
28
30
  get value(): number;
31
+ get step(): number;
32
+ get max(): number;
29
33
  get stars(): number[];
30
34
  setRating: (value: number) => void;
31
35
  setFromString: (value: unknown) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/components/rating/state.gts"],"names":[],"mappings":"AAyHA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAS3C,qBAAa,WAAY,SAAQ,SAAS,CAAC;IACzC,IAAI,EAAE;QACJ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACpC,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE;YACP,WAAW,EAAE;gBACX,KAAK,EAAE,MAAM,EAAE,CAAC;gBAChB,KAAK,EAAE,MAAM,CAAC;gBACd,KAAK,EAAE,MAAM,CAAC;gBACd,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;gBACpC,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;gBACrC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;aAClC;YACD,SAAS,EAAE;gBACT,KAAK,EAAE,MAAM,CAAC;gBACd,KAAK,EAAE,MAAM,CAAC;aACf;SACF,CAAC;KACH,CAAC;CACH,CAAC;IAEiC,MAAM,EAAE,MAAM,CAAC;IAEhD,IAAI,KAAK,WAER;IAED,IACI,KAAK,aAER;IAED,SAAS,GAAI,OAAO,MAAM,UAYxB;IAEF,aAAa,GAAI,OAAO,OAAO,UAa7B;IAEF;;;;OAIG;IACH,WAAW,GAAI,OAAO,KAAK,UAazB;IAEF;;;OAGG;IACH,YAAY,GAAI,OAAO,KAAK,UAM1B;CAgBH"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/components/rating/state.gts"],"names":[],"mappings":"AAgJA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAS3C,qBAAa,WAAY,SAAQ,SAAS,CAAC;IACzC,IAAI,EAAE;QACJ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACpC,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE;YACP,WAAW,EAAE;gBACX,KAAK,EAAE,MAAM,EAAE,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,KAAK,EAAE,MAAM,CAAC;gBACd,KAAK,EAAE,MAAM,CAAC;gBACd,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;gBACpC,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;gBACrC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;aAClC;YACD,SAAS,EAAE;gBACT,KAAK,EAAE,MAAM,CAAC;gBACd,KAAK,EAAE,MAAM,CAAC;aACf;SACF,CAAC;KACH,CAAC;CACH,CAAC;IAEiC,MAAM,EAAE,MAAM,CAAC;IAEhD,IAAI,KAAK,WAER;IAED,IAAI,IAAI,WAEP;IAED,IAAI,GAAG,WAEN;IAED,IACI,KAAK,aAcR;IAED,SAAS,GAAI,OAAO,MAAM,UAYxB;IAEF,aAAa,GAAI,OAAO,OAAO,UAa7B;IAEF;;;;OAIG;IACH,WAAW,GAAI,OAAO,KAAK,UAazB;IAEF;;;OAGG;IACH,YAAY,GAAI,OAAO,KAAK,UAM1B;CAiBH"}
@@ -1,4 +1,3 @@
1
1
  export declare function isString(x: unknown): x is string;
2
2
  export declare function lte(a: number, b: number): boolean;
3
- export declare function percentSelected(a: number, b: number): number;
4
3
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/rating/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,eAElC;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,WAEvC;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,UAUnD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/rating/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,eAElC;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,WAEvC"}
@@ -82,16 +82,25 @@ function sync() {
82
82
  _colorScheme.current = 'light';
83
83
  }
84
84
  }
85
+ const queries = {
86
+ dark: window.matchMedia('(prefers-color-scheme: dark)'),
87
+ light: window.matchMedia('(prefers-color-scheme: light)'),
88
+ none: window.matchMedia('(prefers-color-scheme: no-preference)')
89
+ };
90
+ queries.dark.addEventListener('change', e => {
91
+ const mode = e.matches ? 'dark' : 'light';
92
+ colorScheme.update(mode);
93
+ });
85
94
 
86
95
  /**
87
96
  * Helper methods to determining what the user's preferred color scheme is
88
97
  * based on the system preferences rather than the users explicit preference.
89
98
  */
90
99
  const prefers = {
91
- dark: () => window.matchMedia('(prefers-color-scheme: dark)').matches,
92
- light: () => window.matchMedia('(prefers-color-scheme: light)').matches,
93
- custom: name => window.matchMedia(`(prefers-color-scheme: ${name})`).matches,
94
- none: () => window.matchMedia('(prefers-color-scheme: no-preference)').matches
100
+ dark: () => queries.dark.matches,
101
+ light: () => queries.light.matches,
102
+ none: () => queries.none.matches,
103
+ custom: name => window.matchMedia(`(prefers-color-scheme: ${name})`).matches
95
104
  };
96
105
  const LOCAL_PREF_KEY = 'ember-primitives/color-scheme#local-preference';
97
106
 
@@ -1 +1 @@
1
- {"version":3,"file":"color-scheme.js","sources":["../src/color-scheme.ts"],"sourcesContent":["import { waitForPromise } from '@ember/test-waiters';\n\nimport { cell } from 'ember-resources';\n\nconst _colorScheme = cell<string | undefined>();\n\nlet callbacks: Set<(colorScheme: string) => void> = new Set();\n\nasync function runCallbacks(theme: string) {\n await Promise.resolve();\n\n for (const callback of callbacks.values()) {\n callback(theme);\n }\n}\n\n/**\n * Object for managing the color scheme\n */\nexport const colorScheme = {\n /**\n * Set's the current color scheme to the passed value\n */\n update: (value: string) => {\n colorScheme.current = value;\n\n void waitForPromise(runCallbacks(value));\n },\n\n on: {\n /**\n * register a function to be called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.add(callback);\n },\n },\n off: {\n /**\n * unregister a function that would have been called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.delete(callback);\n },\n },\n\n /**\n * the current valuel of the \"color scheme\"\n */\n get current(): string | undefined {\n return _colorScheme.current;\n },\n set current(value: string | undefined) {\n _colorScheme.current = value;\n\n if (!value) {\n localPreference.delete();\n\n return;\n }\n\n localPreference.update(value);\n setColorScheme(value);\n },\n};\n\n/**\n * Synchronizes state of `colorScheme` with the users preferences as well as reconciles with previously set theme in local storage.\n *\n * This may only be called once per app.\n */\nexport function sync() {\n /**\n * reset the callbacks\n */\n callbacks = new Set();\n\n /**\n * If local prefs are set, then we don't care what prefers-color-scheme is\n */\n const userPreference = localPreference.read();\n\n if (userPreference) {\n setColorScheme(userPreference);\n _colorScheme.current = userPreference;\n\n return;\n }\n\n if (prefers.dark()) {\n setColorScheme('dark');\n _colorScheme.current = 'dark';\n } else if (prefers.light()) {\n setColorScheme('light');\n _colorScheme.current = 'light';\n }\n}\n\n/**\n * Helper methods to determining what the user's preferred color scheme is\n * based on the system preferences rather than the users explicit preference.\n */\nexport const prefers = {\n dark: () => window.matchMedia('(prefers-color-scheme: dark)').matches,\n light: () => window.matchMedia('(prefers-color-scheme: light)').matches,\n custom: (name: string) => window.matchMedia(`(prefers-color-scheme: ${name})`).matches,\n none: () => window.matchMedia('(prefers-color-scheme: no-preference)').matches,\n};\n\nconst LOCAL_PREF_KEY = 'ember-primitives/color-scheme#local-preference';\n\n/**\n * Helper methods for working with the color scheme preference in local storage\n */\nexport const localPreference = {\n isSet: () => Boolean(localPreference.read()),\n read: () => localStorage.getItem(LOCAL_PREF_KEY),\n update: (value: string) => localStorage.setItem(LOCAL_PREF_KEY, value),\n delete: () => localStorage.removeItem(LOCAL_PREF_KEY),\n};\n\n/**\n * For the given element, returns the `color-scheme` of that element.\n */\nexport function getColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n return style.getPropertyValue('color-scheme');\n}\n\nexport function setColorScheme(element: HTMLElement, value: string): void;\nexport function setColorScheme(value: string): void;\n\nexport function setColorScheme(...args: [string] | [HTMLElement, string]): void {\n if (typeof args[0] === 'string') {\n styleOf().setProperty('color-scheme', args[0]);\n\n return;\n }\n\n if (typeof args[1] === 'string') {\n styleOf(args[0]).setProperty('color-scheme', args[1]);\n\n return;\n }\n\n throw new Error(`Invalid arity, expected up to 2 args, received ${args.length}`);\n}\n\n/**\n * Removes the `color-scheme` from the given element\n */\nexport function removeColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n style.removeProperty('color-scheme');\n}\n\nfunction styleOf(element?: HTMLElement) {\n if (element) {\n return element.style;\n }\n\n return document.documentElement.style;\n}\n"],"names":["_colorScheme","cell","callbacks","Set","runCallbacks","theme","Promise","resolve","callback","values","colorScheme","update","value","current","waitForPromise","on","add","off","delete","localPreference","setColorScheme","sync","userPreference","read","prefers","dark","light","window","matchMedia","matches","custom","name","none","LOCAL_PREF_KEY","isSet","Boolean","localStorage","getItem","setItem","removeItem","getColorScheme","element","style","styleOf","getPropertyValue","args","setProperty","Error","length","removeColorScheme","removeProperty","document","documentElement"],"mappings":"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"}
1
+ {"version":3,"file":"color-scheme.js","sources":["../src/color-scheme.ts"],"sourcesContent":["import { waitForPromise } from '@ember/test-waiters';\n\nimport { cell } from 'ember-resources';\n\nconst _colorScheme = cell<string | undefined>();\n\nlet callbacks: Set<(colorScheme: string) => void> = new Set();\n\nasync function runCallbacks(theme: string) {\n await Promise.resolve();\n\n for (const callback of callbacks.values()) {\n callback(theme);\n }\n}\n\n/**\n * Object for managing the color scheme\n */\nexport const colorScheme = {\n /**\n * Set's the current color scheme to the passed value\n */\n update: (value: string) => {\n colorScheme.current = value;\n\n void waitForPromise(runCallbacks(value));\n },\n\n on: {\n /**\n * register a function to be called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.add(callback);\n },\n },\n off: {\n /**\n * unregister a function that would have been called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.delete(callback);\n },\n },\n\n /**\n * the current valuel of the \"color scheme\"\n */\n get current(): string | undefined {\n return _colorScheme.current;\n },\n set current(value: string | undefined) {\n _colorScheme.current = value;\n\n if (!value) {\n localPreference.delete();\n\n return;\n }\n\n localPreference.update(value);\n setColorScheme(value);\n },\n};\n\n/**\n * Synchronizes state of `colorScheme` with the users preferences as well as reconciles with previously set theme in local storage.\n *\n * This may only be called once per app.\n */\nexport function sync() {\n /**\n * reset the callbacks\n */\n callbacks = new Set();\n\n /**\n * If local prefs are set, then we don't care what prefers-color-scheme is\n */\n const userPreference = localPreference.read();\n\n if (userPreference) {\n setColorScheme(userPreference);\n _colorScheme.current = userPreference;\n\n return;\n }\n\n if (prefers.dark()) {\n setColorScheme('dark');\n _colorScheme.current = 'dark';\n } else if (prefers.light()) {\n setColorScheme('light');\n _colorScheme.current = 'light';\n }\n}\n\nconst queries = {\n dark: window.matchMedia('(prefers-color-scheme: dark)'),\n light: window.matchMedia('(prefers-color-scheme: light)'),\n none: window.matchMedia('(prefers-color-scheme: no-preference)'),\n};\n\nqueries.dark.addEventListener('change', (e) => {\n const mode = e.matches ? 'dark' : 'light';\n\n colorScheme.update(mode);\n});\n\n/**\n * Helper methods to determining what the user's preferred color scheme is\n * based on the system preferences rather than the users explicit preference.\n */\nexport const prefers = {\n dark: () => queries.dark.matches,\n light: () => queries.light.matches,\n none: () => queries.none.matches,\n custom: (name: string) => window.matchMedia(`(prefers-color-scheme: ${name})`).matches,\n};\n\nconst LOCAL_PREF_KEY = 'ember-primitives/color-scheme#local-preference';\n\n/**\n * Helper methods for working with the color scheme preference in local storage\n */\nexport const localPreference = {\n isSet: () => Boolean(localPreference.read()),\n read: () => localStorage.getItem(LOCAL_PREF_KEY),\n update: (value: string) => localStorage.setItem(LOCAL_PREF_KEY, value),\n delete: () => localStorage.removeItem(LOCAL_PREF_KEY),\n};\n\n/**\n * For the given element, returns the `color-scheme` of that element.\n */\nexport function getColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n return style.getPropertyValue('color-scheme');\n}\n\nexport function setColorScheme(element: HTMLElement, value: string): void;\nexport function setColorScheme(value: string): void;\n\nexport function setColorScheme(...args: [string] | [HTMLElement, string]): void {\n if (typeof args[0] === 'string') {\n styleOf().setProperty('color-scheme', args[0]);\n\n return;\n }\n\n if (typeof args[1] === 'string') {\n styleOf(args[0]).setProperty('color-scheme', args[1]);\n\n return;\n }\n\n throw new Error(`Invalid arity, expected up to 2 args, received ${args.length}`);\n}\n\n/**\n * Removes the `color-scheme` from the given element\n */\nexport function removeColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n style.removeProperty('color-scheme');\n}\n\nfunction styleOf(element?: HTMLElement) {\n if (element) {\n return element.style;\n }\n\n return document.documentElement.style;\n}\n"],"names":["_colorScheme","cell","callbacks","Set","runCallbacks","theme","Promise","resolve","callback","values","colorScheme","update","value","current","waitForPromise","on","add","off","delete","localPreference","setColorScheme","sync","userPreference","read","prefers","dark","light","queries","window","matchMedia","none","addEventListener","e","mode","matches","custom","name","LOCAL_PREF_KEY","isSet","Boolean","localStorage","getItem","setItem","removeItem","getColorScheme","element","style","styleOf","getPropertyValue","args","setProperty","Error","length","removeColorScheme","removeProperty","document","documentElement"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { R as Rating } from '../rating-CjBVsX6q.js';
1
+ export { R as Rating } from '../rating-BrIiwDLw.js';
2
2
  //# sourceMappingURL=rating.js.map
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ export { Popover } from './components/popover.js';
13
13
  export { Portal } from './components/portal.js';
14
14
  export { TARGETS as PORTALS, PortalTargets } from './components/portal-targets.js';
15
15
  export { Progress } from './components/progress.js';
16
- export { R as Rating } from './rating-CjBVsX6q.js';
16
+ export { R as Rating } from './rating-BrIiwDLw.js';
17
17
  export { Scroller } from './components/scroller.js';
18
18
  export { Shadowed } from './components/shadowed.js';
19
19
  export { Switch } from './components/switch.js';
@@ -23,22 +23,14 @@ function isString(x) {
23
23
  function lte(a, b) {
24
24
  return a <= b;
25
25
  }
26
- function percentSelected(a, b) {
27
- const diff = b + 1 - a;
28
- if (diff < 0) return 0;
29
- if (diff > 1) return 100;
30
- if (a === b) return 100;
31
- const percent = diff * 100;
32
- return percent;
33
- }
34
26
 
35
- const Stars = setComponentTemplate(precompileTemplate("<div class=\"ember-primitives__rating__items\">\n {{#each @stars as |star|}}\n {{#let (uniqueId) as |id|}}\n <span class=\"ember-primitives__rating__item\" data-number={{star}} data-percent-selected={{percentSelected star @currentValue}} data-selected={{lte star @currentValue}} data-readonly={{@isReadonly}}>\n <label for=\"input-{{id}}\">\n <span visually-hidden>{{star}} star</span>\n <span aria-hidden=\"true\">\n {{#if (isString @icon)}}\n {{@icon}}\n {{else}}\n <@icon @value={{star}} @isSelected={{lte star @currentValue}} @percentSelected={{percentSelected star @currentValue}} @readonly={{@isReadonly}} />\n {{/if}}\n </span>\n </label>\n\n <input id=\"input-{{id}}\" type=\"radio\" name={{@name}} value={{star}} readonly={{@isReadonly}} checked={{lte star @currentValue}} />\n </span>\n {{/let}}\n {{/each}}\n</div>", {
27
+ const Stars = setComponentTemplate(precompileTemplate("<div class=\"ember-primitives__rating__items\">\n {{#each @stars as |star|}}\n {{#let (uniqueId) as |id|}}\n <span class=\"ember-primitives__rating__item\" data-number={{star}} data-selected={{lte star @currentValue}} data-readonly={{@isReadonly}}>\n <label for=\"input-{{id}}\">\n <span visually-hidden>{{star}} star</span>\n {{#if @icon}}\n <span aria-hidden=\"true\">\n {{#if (isString @icon)}}\n {{@icon}}\n {{else}}\n <@icon @value={{star}} @isSelected={{lte star @currentValue}} @readonly={{@isReadonly}} />\n {{/if}}\n </span>\n {{/if}}\n </label>\n\n <input id=\"input-{{id}}\" type=\"radio\" name={{@name}} value={{star}} readonly={{@isReadonly}} checked={{Object.is star @currentValue}} />\n </span>\n {{/let}}\n {{/each}}\n</div>", {
36
28
  strictMode: true,
37
29
  scope: () => ({
38
30
  uniqueId,
39
- percentSelected,
40
31
  lte,
41
- isString
32
+ isString,
33
+ Object
42
34
  })
43
35
  }), templateOnly());
44
36
 
@@ -50,10 +42,22 @@ class RatingState extends Component {
50
42
  get value() {
51
43
  return this._value ?? 0;
52
44
  }
45
+ get step() {
46
+ return this.args.step ?? 1;
47
+ }
48
+ get max() {
49
+ return this.args.max ?? 5;
50
+ }
53
51
  get stars() {
54
- return Array.from({
55
- length: this.args.max ?? 5
56
- }, (_, index) => index + 1);
52
+ const result = [];
53
+ // 0 is "none selected"
54
+ let current = 0;
55
+ current += this.step;
56
+ while (current <= this.max) {
57
+ result.push(current);
58
+ current += this.step;
59
+ }
60
+ return result;
57
61
  }
58
62
  static {
59
63
  n(this.prototype, "stars", [cached]);
@@ -103,7 +107,7 @@ class RatingState extends Component {
103
107
  this.setFromString(event.target.value);
104
108
  };
105
109
  static {
106
- setComponentTemplate(precompileTemplate("{{yield (hash stars=this.stars total=this.stars.length handleClick=this.handleClick handleChange=this.handleChange setRating=this.setRating value=this.value) (hash total=this.stars.length value=this.value)}}", {
110
+ setComponentTemplate(precompileTemplate("{{yield (hash stars=this.stars total=this.stars.length handleClick=this.handleClick handleChange=this.handleChange setRating=this.setRating value=this.value step=this.step) (hash total=this.stars.length value=this.value)}}", {
107
111
  strictMode: true,
108
112
  scope: () => ({
109
113
  hash
@@ -131,7 +135,7 @@ class Rating extends Component {
131
135
  return !this.isInteractive;
132
136
  }
133
137
  static {
134
- setComponentTemplate(precompileTemplate("<RatingState @max={{@max}} @value={{@value}} @name={{this.name}} @readonly={{this.isReadonly}} @onChange={{@onChange}} as |r publicState|>\n <fieldset class=\"ember-primitives__rating\" data-total={{r.total}} data-value={{r.value}} data-readonly={{this.isReadonly}} {{!-- We use event delegation, this isn't a primary interactive -- we're capturing events from inputs --}} {{!-- template-lint-disable no-invalid-interactive --}} {{on \"click\" r.handleClick}} ...attributes>\n {{#let (component Stars stars=r.stars icon=this.icon isReadonly=this.isReadonly name=this.name total=r.total currentValue=r.value) as |RatingStars|}}\n\n {{#if (has-block)}}\n {{yield (hash max=r.total total=r.total value=r.value name=this.name isReadonly=this.isReadonly isChangeable=this.isChangeable Stars=RatingStars Range=(component RatingRange max=r.total value=r.value name=this.name handleChange=r.handleChange))}}\n {{else}}\n {{#if this.needsDescription}}\n {{#if (has-block \"label\")}}\n {{yield publicState to=\"label\"}}\n {{else}}\n <span visually-hidden class=\"ember-primitives__rating__label\">Rated\n {{r.value}}\n out of\n {{r.total}}</span>\n {{/if}}\n {{else}}\n {{#if (has-block \"label\")}}\n <legend>\n {{yield publicState to=\"label\"}}\n </legend>\n {{/if}}\n {{/if}}\n\n <RatingStars />\n {{/if}}\n {{/let}}\n\n </fieldset>\n</RatingState>", {
138
+ setComponentTemplate(precompileTemplate("<RatingState @max={{@max}} @step={{@step}} @value={{@value}} @name={{this.name}} @readonly={{this.isReadonly}} @onChange={{@onChange}} as |r publicState|>\n <fieldset class=\"ember-primitives__rating\" data-total={{r.total}} data-value={{r.value}} data-readonly={{this.isReadonly}} {{!-- We use event delegation, this isn't a primary interactive -- we're capturing events from inputs --}} {{!-- template-lint-disable no-invalid-interactive --}} {{on \"click\" r.handleClick}} ...attributes>\n {{#let (component Stars stars=r.stars icon=this.icon isReadonly=this.isReadonly name=this.name total=r.total currentValue=r.value) as |RatingStars|}}\n\n {{#if (has-block)}}\n {{yield (hash max=r.total total=r.total value=r.value name=this.name isReadonly=this.isReadonly isChangeable=this.isChangeable Stars=RatingStars Range=(component RatingRange step=r.step max=r.total value=r.value name=this.name handleChange=r.handleChange))}}\n {{else}}\n {{#if this.needsDescription}}\n {{#if (has-block \"label\")}}\n {{yield publicState to=\"label\"}}\n {{else}}\n <span visually-hidden class=\"ember-primitives__rating__label\">Rated\n {{r.value}}\n out of\n {{r.total}}</span>\n {{/if}}\n {{else}}\n {{#if (has-block \"label\")}}\n <legend>\n {{yield publicState to=\"label\"}}\n </legend>\n {{/if}}\n {{/if}}\n\n <RatingStars />\n {{/if}}\n {{/let}}\n\n </fieldset>\n</RatingState>", {
135
139
  strictMode: true,
136
140
  scope: () => ({
137
141
  RatingState,
@@ -145,4 +149,4 @@ class Rating extends Component {
145
149
  }
146
150
 
147
151
  export { Rating as R };
148
- //# sourceMappingURL=rating-CjBVsX6q.js.map
152
+ //# sourceMappingURL=rating-BrIiwDLw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rating-BrIiwDLw.js","sources":["../src/components/rating/range.gts","../src/components/rating/utils.ts","../src/components/rating/stars.gts","../src/components/rating/state.gts","../src/components/rating/rating.gts"],"sourcesContent":["import { on } from \"@ember/modifier\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport const RatingRange: TOC<{\n Element: HTMLInputElement;\n Args: {\n name: string;\n max: number;\n value: number;\n handleChange: (event: Event) => void;\n };\n}> = <template>\n <input\n ...attributes\n name={{@name}}\n type=\"range\"\n max={{@max}}\n value={{@value}}\n {{on \"change\" @handleChange}}\n />\n</template>;\n","export function isString(x: unknown) {\n return typeof x === 'string';\n}\n\nexport function lte(a: number, b: number) {\n return a <= b;\n}\n","import { uniqueId } from \"../../utils.ts\";\nimport { isString, lte } from \"./utils.ts\";\n\nimport type { ComponentIcons, StringIcons } from \"./public-types.ts\";\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport const Stars: TOC<{\n Args: {\n // Configuration\n stars: number[];\n icon: StringIcons[\"icon\"] | ComponentIcons[\"icon\"];\n isReadonly: boolean;\n\n // HTML Boilerplate\n name: string;\n\n // State\n currentValue: number;\n total: number;\n };\n}> = <template>\n <div class=\"ember-primitives__rating__items\">\n {{#each @stars as |star|}}\n {{#let (uniqueId) as |id|}}\n <span\n class=\"ember-primitives__rating__item\"\n data-number={{star}}\n data-selected={{lte star @currentValue}}\n data-readonly={{@isReadonly}}\n >\n <label for=\"input-{{id}}\">\n <span visually-hidden>{{star}} star</span>\n {{#if @icon}}\n <span aria-hidden=\"true\">\n {{#if (isString @icon)}}\n {{@icon}}\n {{else}}\n <@icon\n @value={{star}}\n @isSelected={{lte star @currentValue}}\n @readonly={{@isReadonly}}\n />\n {{/if}}\n </span>\n {{/if}}\n </label>\n\n <input\n id=\"input-{{id}}\"\n type=\"radio\"\n name={{@name}}\n value={{star}}\n readonly={{@isReadonly}}\n checked={{Object.is star @currentValue}}\n />\n </span>\n {{/let}}\n {{/each}}\n </div>\n</template>;\n","import Component from \"@glimmer/component\";\nimport { cached } from \"@glimmer/tracking\";\nimport { assert } from \"@ember/debug\";\nimport { hash } from \"@ember/helper\";\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport { localCopy } from \"tracked-toolbox\";\n\nexport class RatingState extends Component<{\n Args: {\n max: number | undefined;\n value: number | undefined;\n step: number | undefined;\n readonly: boolean | undefined;\n name: string;\n onChange?: (value: number) => void;\n };\n Blocks: {\n default: [\n internalApi: {\n stars: number[];\n step: number;\n value: number;\n total: number;\n handleClick: (event: Event) => void;\n handleChange: (event: Event) => void;\n setRating: (num: number) => void;\n },\n publicApi: {\n value: number;\n total: number;\n },\n ];\n };\n}> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.value\") declare _value: number;\n\n get value() {\n return this._value ?? 0;\n }\n\n get step() {\n return this.args.step ?? 1;\n }\n\n get max() {\n return this.args.max ?? 5;\n }\n\n @cached\n get stars() {\n const result = [];\n\n // 0 is \"none selected\"\n let current = 0;\n\n current += this.step;\n\n while (current <= this.max) {\n result.push(current);\n current += this.step;\n }\n\n return result;\n }\n\n setRating = (value: number) => {\n if (this.args.readonly) {\n return;\n }\n\n if (value === this._value) {\n this._value = 0;\n } else {\n this._value = value;\n }\n\n this.args.onChange?.(value);\n };\n\n setFromString = (value: unknown) => {\n assert(\"[BUG]: value from input must be a string.\", typeof value === \"string\");\n\n const num = parseFloat(value);\n\n if (isNaN(num)) {\n // something went wrong.\n // Since we're using event delegation,\n // this could be from an unrelated input\n return;\n }\n\n this.setRating(num);\n };\n\n /**\n * Click events are captured by\n * - radio changes (mouse and keyboard)\n * - but only range clicks\n */\n handleClick = (event: Event) => {\n // Since we're doing event delegation on a click, we want to make sure\n // we don't do anything on other elements\n const isValid =\n event.target instanceof HTMLInputElement &&\n event.target.name === this.args.name &&\n event.target.type === \"radio\";\n\n if (!isValid) return;\n\n const selected = event.target?.value;\n\n this.setFromString(selected);\n };\n\n /**\n * Only attached to a range element, if present.\n * Range elements don't fire click events on keyboard usage, like radios do\n */\n handleChange = (event: Event) => {\n const isValid = event.target !== null && \"value\" in event.target;\n\n if (!isValid) return;\n\n this.setFromString(event.target.value);\n };\n\n <template>\n {{yield\n (hash\n stars=this.stars\n total=this.stars.length\n handleClick=this.handleClick\n handleChange=this.handleChange\n setRating=this.setRating\n value=this.value\n step=this.step\n )\n (hash total=this.stars.length value=this.value)\n }}\n </template>\n}\n","import Component from \"@glimmer/component\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { uniqueId } from \"../../utils.ts\";\nimport { RatingRange } from \"./range.gts\";\nimport { Stars } from \"./stars.gts\";\nimport { RatingState } from \"./state.gts\";\n\nimport type { ComponentIcons, StringIcons } from \"./public-types.ts\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n /*\n * The element all passed attributes / modifiers are applied to.\n *\n * This is a `<fieldset>`, becaues the rating elements are\n * powered by a group of radio buttons.\n */\n Element: HTMLFieldSetElement;\n Args: (ComponentIcons | StringIcons) & {\n /**\n * The number of stars/whichever-icon to show\n *\n * Defaults to 5\n */\n max?: number;\n\n /**\n * The current number of stars/whichever-icon to show as selected\n *\n * Defaults to 0\n */\n value?: number;\n\n /**\n * When generating the radio inputs, this changes what value of rating each radio\n * input will be incremented by.\n *\n * e.g.: Set to 0.5 for half-star ratings.\n *\n * Defaults to 1\n */\n step?: number;\n\n /**\n * Prevents click events on the icons and sets aria-readonly.\n *\n * Also sets data-readonly=true on the wrapping element\n */\n readonly?: boolean;\n\n /**\n * Toggles the ability to interact with the rating component.\n * When `true` (the default), the Rating component can be as a form input\n * to gather user feedback.\n *\n * When false, only the `@value` will be shown, and it cannot be changed.\n */\n interactive?: boolean;\n\n /**\n * Callback when the selected rating changes.\n * Can include half-ratings if the iconHalf argument is passed.\n */\n onChange?: (value: number) => void;\n };\n\n Blocks: {\n default: [\n rating: {\n /**\n * The maximum rating\n */\n max: number;\n /**\n * The maxium rating\n */\n total: number;\n /**\n * The current rating\n */\n value: number;\n /**\n * The name shared by the field group\n */\n name: string;\n /**\n * If the rating can be changed\n */\n isReadonly: boolean;\n /**\n * If the rating can be changed\n */\n isChangeable: boolean;\n /**\n * The stars / items radio group\n */\n Stars: WithBoundArgs<\n typeof Stars,\n \"stars\" | \"icon\" | \"isReadonly\" | \"name\" | \"total\" | \"currentValue\"\n >;\n /**\n * Input range for adjusting the rating via fractional means\n */\n Range: WithBoundArgs<typeof RatingRange, \"max\" | \"value\" | \"name\" | \"handleChange\">;\n },\n ];\n label: [\n state: {\n /**\n * The current rating\n */\n value: number;\n\n /**\n * The maximum rating\n */\n total: number;\n },\n ];\n };\n}\n\nexport class Rating extends Component<Signature> {\n name = `rating-${uniqueId()}`;\n\n get icon() {\n return this.args.icon ?? \"★\";\n }\n\n get isInteractive() {\n return this.args.interactive ?? true;\n }\n\n get isChangeable() {\n const readonly = this.args.readonly ?? false;\n\n return !readonly && this.isInteractive;\n }\n\n get isReadonly() {\n return !this.isChangeable;\n }\n\n get needsDescription() {\n return !this.isInteractive;\n }\n\n <template>\n <RatingState\n @max={{@max}}\n @step={{@step}}\n @value={{@value}}\n @name={{this.name}}\n @readonly={{this.isReadonly}}\n @onChange={{@onChange}}\n as |r publicState|\n >\n <fieldset\n class=\"ember-primitives__rating\"\n data-total={{r.total}}\n data-value={{r.value}}\n data-readonly={{this.isReadonly}}\n {{! We use event delegation, this isn't a primary interactive -- we're capturing events from inputs }}\n {{! template-lint-disable no-invalid-interactive }}\n {{on \"click\" r.handleClick}}\n ...attributes\n >\n {{#let\n (component\n Stars\n stars=r.stars\n icon=this.icon\n isReadonly=this.isReadonly\n name=this.name\n total=r.total\n currentValue=r.value\n )\n as |RatingStars|\n }}\n\n {{#if (has-block)}}\n {{yield\n (hash\n max=r.total\n total=r.total\n value=r.value\n name=this.name\n isReadonly=this.isReadonly\n isChangeable=this.isChangeable\n Stars=RatingStars\n Range=(component\n RatingRange\n step=r.step\n max=r.total\n value=r.value\n name=this.name\n handleChange=r.handleChange\n )\n )\n }}\n {{else}}\n {{#if this.needsDescription}}\n {{#if (has-block \"label\")}}\n {{yield publicState to=\"label\"}}\n {{else}}\n <span visually-hidden class=\"ember-primitives__rating__label\">Rated\n {{r.value}}\n out of\n {{r.total}}</span>\n {{/if}}\n {{else}}\n {{#if (has-block \"label\")}}\n <legend>\n {{yield publicState to=\"label\"}}\n </legend>\n {{/if}}\n {{/if}}\n\n <RatingStars />\n {{/if}}\n {{/let}}\n\n </fieldset>\n </RatingState>\n </template>\n}\n"],"names":["RatingRange","setComponentTemplate","precompileTemplate","strictMode","scope","on","templateOnly","isString","x","lte","a","b","Stars","uniqueId","Object","RatingState","Component","localCopy","i","value","_value","step","args","max","stars","result","current","push","n","prototype","cached","setRating","readonly","onChange","setFromString","assert","num","parseFloat","isNaN","handleClick","event","isValid","target","HTMLInputElement","name","type","selected","handleChange","hash","Rating","icon","isInteractive","interactive","isChangeable","isReadonly","needsDescription"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-primitives",
3
- "version": "0.49.0",
3
+ "version": "0.50.1",
4
4
  "description": "Making apps easier to build",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -11,8 +11,11 @@
11
11
  "files": [
12
12
  "addon-main.cjs",
13
13
  "dist",
14
+ "src",
15
+ "bin",
14
16
  "declarations"
15
17
  ],
18
+ "bin": "./bin/index.mjs",
16
19
  "dependencies": {
17
20
  "@babel/runtime": "^7.27.1",
18
21
  "@embroider/addon-shim": "^1.10.0",
@@ -26,7 +29,7 @@
26
29
  "tabster": "^8.7.0",
27
30
  "tracked-built-ins": "^4.1.0",
28
31
  "tracked-toolbox": "^2.0.0",
29
- "which-heading-do-i-need": "0.2.2"
32
+ "which-heading-do-i-need": "0.2.3"
30
33
  },
31
34
  "devDependencies": {
32
35
  "@arethetypeswrong/cli": "^0.18.0",
@@ -37,6 +40,7 @@
37
40
  "@babel/plugin-syntax-decorators": "^7.27.1",
38
41
  "@babel/plugin-transform-class-static-block": "^7.27.1",
39
42
  "@babel/plugin-transform-private-methods": "^7.27.1",
43
+ "@babel/plugin-transform-typescript": "^7.28.5",
40
44
  "@babel/preset-typescript": "^7.28.5",
41
45
  "@ember/library-tsconfig": "^2.0.0",
42
46
  "@ember/test-helpers": "^5.4.1",