@marianmeres/stuic 2.0.0-next.4 → 2.0.2

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 (61) hide show
  1. package/dist/actions/file-dropzone.svelte.d.ts +8 -0
  2. package/dist/actions/file-dropzone.svelte.js +43 -0
  3. package/dist/actions/highlight-dragover.svelte.js +16 -3
  4. package/dist/actions/index.d.ts +2 -0
  5. package/dist/actions/index.js +2 -0
  6. package/dist/actions/resizable-width.svelte.d.ts +21 -0
  7. package/dist/actions/resizable-width.svelte.js +162 -0
  8. package/dist/actions/validate.svelte.js +13 -13
  9. package/dist/components/Backdrop/Backdrop.svelte +1 -1
  10. package/dist/components/Button/Button.svelte +2 -2
  11. package/dist/components/Button/Button.svelte.d.ts +1 -1
  12. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte +170 -0
  13. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte.d.ts +26 -0
  14. package/dist/components/ButtonGroupRadio/index.css +23 -0
  15. package/dist/components/ButtonGroupRadio/index.d.ts +1 -0
  16. package/dist/components/ButtonGroupRadio/index.js +1 -0
  17. package/dist/components/CommandMenu/CommandMenu.svelte +365 -0
  18. package/dist/components/CommandMenu/CommandMenu.svelte.d.ts +25 -0
  19. package/dist/components/CommandMenu/index.d.ts +1 -0
  20. package/dist/components/CommandMenu/index.js +1 -0
  21. package/dist/components/Input/FieldInput.svelte +1 -0
  22. package/dist/components/Input/FieldLikeButton.svelte +16 -7
  23. package/dist/components/Input/FieldLikeButton.svelte.d.ts +1 -1
  24. package/dist/components/Input/FieldOptions.svelte +308 -136
  25. package/dist/components/Input/FieldOptions.svelte.d.ts +15 -8
  26. package/dist/components/Input/_internal/InputWrap.svelte +7 -6
  27. package/dist/components/Modal/Modal.svelte +10 -5
  28. package/dist/components/ModalDialog/ModalDialog.svelte +25 -0
  29. package/dist/components/Notifications/Notifications.svelte +1 -1
  30. package/dist/components/Progress/_internal/Bar.svelte +1 -1
  31. package/dist/components/Spinner/SpinnerUnicode.svelte +130 -0
  32. package/dist/components/Spinner/SpinnerUnicode.svelte.d.ts +12 -0
  33. package/dist/components/Spinner/index.d.ts +1 -0
  34. package/dist/components/Spinner/index.js +1 -0
  35. package/dist/components/TypeaheadInput/TypeaheadInput.svelte +261 -0
  36. package/dist/components/TypeaheadInput/TypeaheadInput.svelte.d.ts +40 -0
  37. package/dist/components/TypeaheadInput/index.d.ts +1 -0
  38. package/dist/components/TypeaheadInput/index.js +1 -0
  39. package/dist/index.css +1 -0
  40. package/dist/index.d.ts +3 -0
  41. package/dist/index.js +3 -0
  42. package/dist/types.d.ts +1 -0
  43. package/dist/utils/escape-regex.d.ts +1 -0
  44. package/dist/utils/escape-regex.js +1 -0
  45. package/dist/utils/event-emitter.d.ts +18 -0
  46. package/dist/utils/event-emitter.js +40 -0
  47. package/dist/utils/index.d.ts +5 -0
  48. package/dist/utils/index.js +5 -0
  49. package/dist/utils/is-plain-object.d.ts +2 -0
  50. package/dist/utils/is-plain-object.js +4 -0
  51. package/dist/utils/replace-map.d.ts +5 -0
  52. package/dist/utils/replace-map.js +22 -0
  53. package/dist/utils/seconds.d.ts +7 -0
  54. package/dist/utils/seconds.js +35 -0
  55. package/dist/utils/tw-merge.d.ts +2 -0
  56. package/dist/utils/tw-merge.js +4 -0
  57. package/dist/utils/unaccent.d.ts +6 -0
  58. package/dist/utils/unaccent.js +8 -0
  59. package/package.json +70 -66
  60. package/dist/components/ColResize/ColResize.svelte +0 -0
  61. package/dist/components/ColResize/ColResize.svelte.d.ts +0 -26
@@ -0,0 +1,40 @@
1
+ /** Sugar, Ah, Honey, Honey... */
2
+ export class EventEmitter extends EventTarget {
3
+ #abortController = new AbortController();
4
+ constructor() {
5
+ super();
6
+ }
7
+ /** Overriding so we can use removeAll (via the abortController) later... */
8
+ addEventListener(type, listener, // fuck it (we would need 3 signatures)
9
+ options = {}) {
10
+ // normalize opts (for the `once` shorthand)
11
+ options = typeof options === "boolean" ? { capture: options } : options;
12
+ // make sure to always add abort signal
13
+ options = { ...options, signal: this.#abortController.signal };
14
+ super.addEventListener(type, listener, options);
15
+ }
16
+ /** Yeah! */
17
+ removeAllListeners() {
18
+ this.#abortController.abort();
19
+ this.#abortController = new AbortController(); // reset for future listeners
20
+ }
21
+ /** Alias for dispatchEvent(CustomEvent) */
22
+ emit(eventName, detail = null) {
23
+ this.dispatchEvent(new CustomEvent(eventName, { detail }));
24
+ }
25
+ /** Alias for addEventListener */
26
+ on(eventName, listener, options) {
27
+ this.addEventListener(eventName, listener, options);
28
+ return () => this.removeEventListener(eventName, listener);
29
+ }
30
+ /** Alias for removeEventListener */
31
+ off(eventName, listener) {
32
+ this.removeEventListener(eventName, listener);
33
+ return this;
34
+ }
35
+ /** Alias for addEventListener with once flag */
36
+ once(eventName, listener) {
37
+ this.addEventListener(eventName, listener, { once: true });
38
+ return () => this.removeEventListener(eventName, listener);
39
+ }
40
+ }
@@ -1,6 +1,8 @@
1
1
  export * from "./breakpoint.svelte.js";
2
2
  export * from "./debounce.js";
3
3
  export * from "./device-pointer.svelte.js";
4
+ export * from "./escape-regex.js";
5
+ export * from "./event-emitter.js";
4
6
  export * from "./event-modifiers.js";
5
7
  export * from "./get-id.js";
6
8
  export * from "./is-browser.js";
@@ -12,6 +14,8 @@ export * from "./paint.js";
12
14
  export * from "./persistent-state.svelte.js";
13
15
  export * from "./prefers-reduced-motion.svelte.js";
14
16
  export * from "./qsa.js";
17
+ export * from "./replace-map.js";
18
+ export * from "./seconds.js";
15
19
  export * from "./sleep.js";
16
20
  export * from "./storage-abstraction.js";
17
21
  export * from "./str-hash.js";
@@ -19,3 +23,4 @@ export * from "./throttle.js";
19
23
  export * from "./tr.js";
20
24
  export * from "./tw-merge.js";
21
25
  export * from "./ucfirst.js";
26
+ export * from "./unaccent.js";
@@ -1,6 +1,8 @@
1
1
  export * from "./breakpoint.svelte.js";
2
2
  export * from "./debounce.js";
3
3
  export * from "./device-pointer.svelte.js";
4
+ export * from "./escape-regex.js";
5
+ export * from "./event-emitter.js";
4
6
  export * from "./event-modifiers.js";
5
7
  export * from "./get-id.js";
6
8
  export * from "./is-browser.js";
@@ -12,6 +14,8 @@ export * from "./paint.js";
12
14
  export * from "./persistent-state.svelte.js";
13
15
  export * from "./prefers-reduced-motion.svelte.js";
14
16
  export * from "./qsa.js";
17
+ export * from "./replace-map.js";
18
+ export * from "./seconds.js";
15
19
  export * from "./sleep.js";
16
20
  export * from "./storage-abstraction.js";
17
21
  export * from "./str-hash.js";
@@ -19,3 +23,4 @@ export * from "./throttle.js";
19
23
  export * from "./tr.js";
20
24
  export * from "./tw-merge.js";
21
25
  export * from "./ucfirst.js";
26
+ export * from "./unaccent.js";
@@ -0,0 +1,2 @@
1
+ /** Checks if value is a plain object */
2
+ export declare function isPlainObject(v: any): boolean;
@@ -0,0 +1,4 @@
1
+ /** Checks if value is a plain object */
2
+ export function isPlainObject(v) {
3
+ return (v !== null && typeof v === "object" && [undefined, Object].includes(v.constructor));
4
+ }
@@ -0,0 +1,5 @@
1
+ /** Will replace all keys from k-v pair map with corresponding value */
2
+ export declare function replaceMap(str: string, replacementMap: Record<string, string | CallableFunction>, options?: Partial<{
3
+ ignoreCase: boolean;
4
+ preSearchKeyTransform: (k: string) => string;
5
+ }>): string;
@@ -0,0 +1,22 @@
1
+ import { escapeRegex } from "./escape-regex.js";
2
+ /** Will replace all keys from k-v pair map with corresponding value */
3
+ export function replaceMap(str, replacementMap, options = {}) {
4
+ let result = str;
5
+ const { ignoreCase = true,
6
+ // adding mustache like {{key}} identifiers by default
7
+ preSearchKeyTransform = (k) => `{{${k}}}`, } = options || {};
8
+ const keys = Object.keys(replacementMap);
9
+ // sort keys by length (longest first) to avoid partial replacements
10
+ // e.g., if we have keys "cat" and "category", we want to replace "category" first
11
+ keys.sort((a, b) => b.length - a.length);
12
+ // Replace each key with its corresponding value
13
+ for (const key of keys) {
14
+ const value = typeof replacementMap[key] === "function"
15
+ ? replacementMap[key]()
16
+ : replacementMap[key];
17
+ const needle = preSearchKeyTransform(key);
18
+ const regex = new RegExp(escapeRegex(needle), ignoreCase ? "gi" : "g");
19
+ result = result.replace(regex, value);
20
+ }
21
+ return result;
22
+ }
@@ -0,0 +1,7 @@
1
+ export declare function convertSeconds(totalSeconds: number): {
2
+ days: number;
3
+ hours: number;
4
+ minutes: number;
5
+ seconds: number;
6
+ };
7
+ export declare function formatDuration(totalSeconds: number): string;
@@ -0,0 +1,35 @@
1
+ export function convertSeconds(totalSeconds) {
2
+ if (totalSeconds < 0) {
3
+ throw new Error("Seconds cannot be negative");
4
+ }
5
+ if (!Number.isInteger(totalSeconds)) {
6
+ totalSeconds = Math.floor(totalSeconds);
7
+ }
8
+ const days = Math.floor(totalSeconds / 86400);
9
+ const hours = Math.floor((totalSeconds % 86400) / 3600);
10
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
11
+ const seconds = totalSeconds % 60;
12
+ return {
13
+ days,
14
+ hours,
15
+ minutes,
16
+ seconds,
17
+ };
18
+ }
19
+ export function formatDuration(totalSeconds) {
20
+ const time = convertSeconds(totalSeconds);
21
+ const parts = [];
22
+ if (time.days > 0) {
23
+ parts.push(`${time.days} day${time.days !== 1 ? "s" : ""}`);
24
+ }
25
+ if (time.hours > 0) {
26
+ parts.push(`${time.hours} hour${time.hours !== 1 ? "s" : ""}`);
27
+ }
28
+ if (time.minutes > 0) {
29
+ parts.push(`${time.minutes} minute${time.minutes !== 1 ? "s" : ""}`);
30
+ }
31
+ if (time.seconds > 0) {
32
+ parts.push(`${time.seconds} second${time.seconds !== 1 ? "s" : ""}`);
33
+ }
34
+ return parts.length > 0 ? parts.join(", ") : "0 seconds";
35
+ }
@@ -6,5 +6,7 @@ export declare function clsClean(s: ClassNameValue): string;
6
6
  /**
7
7
  * twMerge does not seem to handle "\r", "\n" and/or "\t" within the input strings correctly,
8
8
  * so we need to do the cleanup ourselves
9
+ *
10
+ * Note: adding clsx preprocess, so we can accept nested/arrays as well (should we need it)
9
11
  */
10
12
  export declare function twMerge(...args: ClassNameValue[]): string;
@@ -1,4 +1,5 @@
1
1
  import { twMerge as _twMerge } from "tailwind-merge";
2
+ import { clsx } from "clsx";
2
3
  /**
3
4
  * Normalizes and dedupes whitespaces
4
5
  */
@@ -10,7 +11,10 @@ export function clsClean(s) {
10
11
  /**
11
12
  * twMerge does not seem to handle "\r", "\n" and/or "\t" within the input strings correctly,
12
13
  * so we need to do the cleanup ourselves
14
+ *
15
+ * Note: adding clsx preprocess, so we can accept nested/arrays as well (should we need it)
13
16
  */
14
17
  export function twMerge(...args) {
18
+ // return _twMerge(...args.map(clsx).filter(Boolean).map(clsClean));
15
19
  return _twMerge(...args.map(clsClean));
16
20
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Uses Unicode normalization form "NFD" (Normalization Form Decomposition) which separates
3
+ * characters with diacritical marks into their base character plus the combining diacritical
4
+ * mark. And then removes (replaces with "") those diacritical marks.
5
+ */
6
+ export declare function unaccent(input: string): string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Uses Unicode normalization form "NFD" (Normalization Form Decomposition) which separates
3
+ * characters with diacritical marks into their base character plus the combining diacritical
4
+ * mark. And then removes (replaces with "") those diacritical marks.
5
+ */
6
+ export function unaccent(input) {
7
+ return `${input}`.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
8
+ }
package/package.json CHANGED
@@ -1,67 +1,71 @@
1
1
  {
2
- "name": "@marianmeres/stuic",
3
- "version": "2.0.0-next.4",
4
- "files": [
5
- "dist",
6
- "!dist/**/*.test.*",
7
- "!dist/**/*.spec.*"
8
- ],
9
- "sideEffects": [
10
- "**/*.css"
11
- ],
12
- "svelte": "./dist/index.js",
13
- "types": "./dist/index.d.ts",
14
- "type": "module",
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "svelte": "./dist/index.js"
19
- }
20
- },
21
- "peerDependencies": {
22
- "svelte": "^5.0.0"
23
- },
24
- "devDependencies": {
25
- "@marianmeres/icons-fns": "^4.3.1",
26
- "@marianmeres/random-human-readable": "^1.6.1",
27
- "@sveltejs/adapter-auto": "^4.0.0",
28
- "@sveltejs/kit": "^2.21.1",
29
- "@sveltejs/package": "^2.3.11",
30
- "@sveltejs/vite-plugin-svelte": "^5.0.3",
31
- "@tailwindcss/cli": "^4.1.8",
32
- "@tailwindcss/forms": "^0.5.10",
33
- "@tailwindcss/typography": "^0.5.16",
34
- "@tailwindcss/vite": "^4.1.8",
35
- "dotenv": "^16.5.0",
36
- "prettier": "^3.5.3",
37
- "prettier-plugin-svelte": "^3.4.0",
38
- "publint": "^0.3.12",
39
- "svelte": "^5.33.10",
40
- "svelte-check": "^4.2.1",
41
- "tailwindcss": "^4.1.8",
42
- "typescript": "^5.8.3",
43
- "vite": "^6.3.5",
44
- "vitest": "^3.1.4"
45
- },
46
- "dependencies": {
47
- "@marianmeres/clog": "^2.2.3",
48
- "@marianmeres/item-collection": "^1.2.14",
49
- "@marianmeres/parse-boolean": "^1.1.7",
50
- "@marianmeres/ticker": "^1.15.0",
51
- "esm-env": "^1.2.2",
52
- "runed": "^0.23.4",
53
- "tailwind-merge": "^3.3.0"
54
- },
55
- "scripts": {
56
- "dev": "vite dev",
57
- "build": "vite build && npm run prepack",
58
- "preview": "vite preview",
59
- "package": "npm run prepack",
60
- "package:watch": "svelte-kit sync && svelte-package --watch && publint",
61
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
62
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
63
- "format": "prettier --write .",
64
- "lint": "prettier --check .",
65
- "test": "vitest --dir src/"
66
- }
67
- }
2
+ "name": "@marianmeres/stuic",
3
+ "version": "2.0.2",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "preview": "vite preview",
8
+ "prepare": "svelte-kit sync || echo ''",
9
+ "prepack": "svelte-kit sync && svelte-package && publint",
10
+ "package": "npm run prepack",
11
+ "package:watch": "svelte-kit sync && svelte-package --watch && publint",
12
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
13
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
14
+ "format": "prettier --write .",
15
+ "lint": "prettier --check .",
16
+ "test": "vitest --dir src/"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "!dist/**/*.test.*",
21
+ "!dist/**/*.spec.*"
22
+ ],
23
+ "sideEffects": [
24
+ "**/*.css"
25
+ ],
26
+ "svelte": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "type": "module",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "svelte": "./dist/index.js"
33
+ }
34
+ },
35
+ "peerDependencies": {
36
+ "svelte": "^5.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@marianmeres/icons-fns": "^4.3.1",
40
+ "@marianmeres/random-human-readable": "^1.6.1",
41
+ "@sveltejs/adapter-auto": "^4.0.0",
42
+ "@sveltejs/kit": "^2.36.1",
43
+ "@sveltejs/package": "^2.5.0",
44
+ "@sveltejs/vite-plugin-svelte": "^5.1.1",
45
+ "@tailwindcss/cli": "^4.1.12",
46
+ "@tailwindcss/forms": "^0.5.10",
47
+ "@tailwindcss/typography": "^0.5.16",
48
+ "@tailwindcss/vite": "^4.1.12",
49
+ "dotenv": "^16.6.1",
50
+ "prettier": "^3.6.2",
51
+ "prettier-plugin-svelte": "^3.4.0",
52
+ "publint": "^0.3.12",
53
+ "svelte": "^5.38.2",
54
+ "svelte-check": "^4.3.1",
55
+ "tailwindcss": "^4.1.12",
56
+ "typescript": "^5.9.2",
57
+ "vite": "^6.3.5",
58
+ "vitest": "^3.2.4"
59
+ },
60
+ "packageManager": "pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af",
61
+ "dependencies": {
62
+ "@marianmeres/clog": "^2.3.3",
63
+ "@marianmeres/item-collection": "^1.2.19",
64
+ "@marianmeres/parse-boolean": "^1.1.7",
65
+ "@marianmeres/ticker": "^1.15.0",
66
+ "clsx": "^2.1.1",
67
+ "esm-env": "^1.2.2",
68
+ "runed": "^0.23.4",
69
+ "tailwind-merge": "^3.3.1"
70
+ }
71
+ }
File without changes
@@ -1,26 +0,0 @@
1
- export default ColResize;
2
- type ColResize = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const ColResize: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
24
- };
25
- z_$$bindings?: Bindings;
26
- }