@viniaraujo68/plinth 0.0.0-stage → 0.2.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 (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +361 -2
  3. package/dist/anchoring.d.ts +61 -0
  4. package/dist/anchoring.js +151 -0
  5. package/dist/async-action.svelte.d.ts +37 -0
  6. package/dist/async-action.svelte.js +64 -0
  7. package/dist/attachments/index.d.ts +1 -0
  8. package/dist/attachments/index.js +1 -0
  9. package/dist/attachments/tooltip.d.ts +37 -0
  10. package/dist/attachments/tooltip.js +166 -0
  11. package/dist/components/AsyncButton.svelte +49 -0
  12. package/dist/components/AsyncButton.svelte.d.ts +32 -0
  13. package/dist/components/Combobox.svelte +380 -0
  14. package/dist/components/Combobox.svelte.d.ts +74 -0
  15. package/dist/components/Copyable.svelte +116 -0
  16. package/dist/components/Copyable.svelte.d.ts +37 -0
  17. package/dist/components/DateRangePicker.svelte +266 -0
  18. package/dist/components/DateRangePicker.svelte.d.ts +66 -0
  19. package/dist/components/Dialog.svelte +102 -0
  20. package/dist/components/Dialog.svelte.d.ts +38 -0
  21. package/dist/components/Dropdown.svelte +204 -0
  22. package/dist/components/Dropdown.svelte.d.ts +49 -0
  23. package/dist/components/ErrorDisplay.svelte +59 -0
  24. package/dist/components/ErrorDisplay.svelte.d.ts +24 -0
  25. package/dist/components/ErrorPage.svelte +119 -0
  26. package/dist/components/ErrorPage.svelte.d.ts +52 -0
  27. package/dist/components/JsonInput.svelte +106 -0
  28. package/dist/components/JsonInput.svelte.d.ts +40 -0
  29. package/dist/components/Listbox.svelte +257 -0
  30. package/dist/components/Listbox.svelte.d.ts +78 -0
  31. package/dist/components/LoadingButton.svelte +36 -0
  32. package/dist/components/LoadingButton.svelte.d.ts +22 -0
  33. package/dist/components/Logo.svelte +112 -0
  34. package/dist/components/Logo.svelte.d.ts +29 -0
  35. package/dist/components/Modal.svelte +187 -0
  36. package/dist/components/Modal.svelte.d.ts +62 -0
  37. package/dist/components/MultiSelect.svelte +256 -0
  38. package/dist/components/MultiSelect.svelte.d.ts +89 -0
  39. package/dist/components/OptionPanel.svelte +241 -0
  40. package/dist/components/OptionPanel.svelte.d.ts +51 -0
  41. package/dist/components/Paginator.svelte +205 -0
  42. package/dist/components/Paginator.svelte.d.ts +48 -0
  43. package/dist/components/RefreshButton.svelte +246 -0
  44. package/dist/components/RefreshButton.svelte.d.ts +46 -0
  45. package/dist/components/SegmentedControl.svelte +147 -0
  46. package/dist/components/SegmentedControl.svelte.d.ts +71 -0
  47. package/dist/components/Select.svelte +312 -0
  48. package/dist/components/Select.svelte.d.ts +68 -0
  49. package/dist/components/Skeleton.svelte +97 -0
  50. package/dist/components/Skeleton.svelte.d.ts +32 -0
  51. package/dist/components/Tooltip.svelte +60 -0
  52. package/dist/components/Tooltip.svelte.d.ts +58 -0
  53. package/dist/components/date-range.d.ts +101 -0
  54. package/dist/components/date-range.js +144 -0
  55. package/dist/components/index.d.ts +25 -0
  56. package/dist/components/index.js +37 -0
  57. package/dist/components/json-text.d.ts +22 -0
  58. package/dist/components/json-text.js +22 -0
  59. package/dist/components/pick.d.ts +18 -0
  60. package/dist/components/pick.js +18 -0
  61. package/dist/components/segmented.d.ts +7 -0
  62. package/dist/components/segmented.js +1 -0
  63. package/dist/components/select.d.ts +66 -0
  64. package/dist/components/select.js +90 -0
  65. package/dist/confirm/Confirmer.svelte +194 -0
  66. package/dist/confirm/Confirmer.svelte.d.ts +45 -0
  67. package/dist/confirm/challenge.d.ts +16 -0
  68. package/dist/confirm/challenge.js +16 -0
  69. package/dist/confirm/confirm-manager.svelte.d.ts +91 -0
  70. package/dist/confirm/confirm-manager.svelte.js +149 -0
  71. package/dist/confirm/index.d.ts +3 -0
  72. package/dist/confirm/index.js +3 -0
  73. package/dist/error.d.ts +25 -0
  74. package/dist/error.js +39 -0
  75. package/dist/formatters.d.ts +95 -0
  76. package/dist/formatters.js +146 -0
  77. package/dist/http.d.ts +68 -0
  78. package/dist/http.js +138 -0
  79. package/dist/index.d.ts +10 -0
  80. package/dist/index.js +14 -0
  81. package/dist/routing.svelte.d.ts +169 -0
  82. package/dist/routing.svelte.js +208 -0
  83. package/dist/shell/AppShell.svelte +874 -0
  84. package/dist/shell/AppShell.svelte.d.ts +93 -0
  85. package/dist/shell/Breadcrumbs.svelte +78 -0
  86. package/dist/shell/Breadcrumbs.svelte.d.ts +25 -0
  87. package/dist/shell/crumbs.d.ts +23 -0
  88. package/dist/shell/crumbs.js +1 -0
  89. package/dist/shell/index.d.ts +3 -0
  90. package/dist/shell/index.js +6 -0
  91. package/dist/table/ColumnMenu.svelte +249 -0
  92. package/dist/table/ColumnMenu.svelte.d.ts +47 -0
  93. package/dist/table/DataTable.svelte +643 -0
  94. package/dist/table/DataTable.svelte.d.ts +153 -0
  95. package/dist/table/columns.d.ts +55 -0
  96. package/dist/table/columns.js +153 -0
  97. package/dist/table/index.d.ts +4 -0
  98. package/dist/table/index.js +8 -0
  99. package/dist/table/sort.d.ts +48 -0
  100. package/dist/table/sort.js +139 -0
  101. package/dist/table/types.d.ts +93 -0
  102. package/dist/table/types.js +1 -0
  103. package/dist/theme/ThemeController.svelte +54 -0
  104. package/dist/theme/ThemeController.svelte.d.ts +27 -0
  105. package/dist/theme/ThemeToggle.svelte +119 -0
  106. package/dist/theme/ThemeToggle.svelte.d.ts +52 -0
  107. package/dist/theme/css-color.d.ts +23 -0
  108. package/dist/theme/css-color.js +31 -0
  109. package/dist/theme/index.d.ts +4 -0
  110. package/dist/theme/index.js +5 -0
  111. package/dist/theme/theme.css +410 -0
  112. package/dist/theme/theme.svelte.d.ts +54 -0
  113. package/dist/theme/theme.svelte.js +58 -0
  114. package/dist/toast/Toaster.svelte +257 -0
  115. package/dist/toast/Toaster.svelte.d.ts +35 -0
  116. package/dist/toast/index.d.ts +2 -0
  117. package/dist/toast/index.js +2 -0
  118. package/dist/toast/toast-manager.svelte.d.ts +99 -0
  119. package/dist/toast/toast-manager.svelte.js +176 -0
  120. package/dist/user/ScopedComponent.svelte +47 -0
  121. package/dist/user/ScopedComponent.svelte.d.ts +29 -0
  122. package/dist/user/anonymous.d.ts +21 -0
  123. package/dist/user/anonymous.js +26 -0
  124. package/dist/user/context.d.ts +55 -0
  125. package/dist/user/context.js +13 -0
  126. package/dist/user/index.d.ts +3 -0
  127. package/dist/user/index.js +6 -0
  128. package/package.json +133 -4
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The user context in force until an app installs its own.
3
+ *
4
+ * Nobody is signed in, and every role check answers `true`. That reads backwards for something
5
+ * whose job is to deny, so it is worth being explicit about why it is the right default.
6
+ *
7
+ * A role gate is a *statement about the app's intent*, not a security control — the server is
8
+ * what actually refuses to serve the data. So the question is only what an unauthenticated
9
+ * library should do with an intent it has no way to evaluate. Denying would mean a route tree
10
+ * annotated with `requiredRoles` renders as an empty shell the moment you clone it, and the
11
+ * annotation would have to be commented out to develop against it. Allowing makes the gates
12
+ * advisory: they sit in the config, describing the eventual policy, doing nothing, until the
13
+ * day the app calls `setUserContext` with something that can actually answer. From that call
14
+ * on, every gate is live at once, with no other edit.
15
+ *
16
+ * The failure mode of the opposite choice — an app that ships without ever setting a context
17
+ * and hides its own UI — is silent and confusing. This one is loud: everything is visible,
18
+ * `status` says `"anonymous"`, and nothing pretends a user exists.
19
+ */
20
+ export const anonymousUser = {
21
+ status: "anonymous",
22
+ data: null,
23
+ hasRole: () => true,
24
+ hasAnyRole: () => true,
25
+ hasAllRoles: () => true,
26
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Where the app is in figuring out who the user is.
3
+ *
4
+ * Four states, and each one exists because chrome has to render differently for it: nobody is
5
+ * signed in, we do not know yet, we know, and we tried and failed. Everything finer — token
6
+ * about to expire, silent renewal in flight, re-authentication required — is the business of
7
+ * whichever auth library the app chose, and stays there.
8
+ */
9
+ export type UserStatus = "anonymous" | "loading" | "authenticated" | "error";
10
+ /** The only user fields the library itself renders: an avatar's name and the address under it. */
11
+ export interface UserData {
12
+ name: string;
13
+ email: string;
14
+ }
15
+ /**
16
+ * The seam between an app's authentication and this library's gates.
17
+ *
18
+ * Deliberately an interface with no implementation behind it. The library needs to ask two
19
+ * questions — who is this, and may they see this — and any answer will do: a cookie session
20
+ * against your own backend, a JWT from a hosted provider, a hard-coded object in a test. None
21
+ * of that leaks in here, and no dependency comes with it.
22
+ *
23
+ * Implementations are expected to be reactive (a class with `$state` fields, typically), since
24
+ * `ScopedComponent` reads them inside a `$derived`.
25
+ *
26
+ * ```ts
27
+ * import { setUserContext } from "@viniaraujo68/plinth/user";
28
+ *
29
+ * setUserContext(myUserStore);
30
+ * ```
31
+ */
32
+ export interface UserContext {
33
+ status: UserStatus;
34
+ /** `null` unless `status` is `"authenticated"`. */
35
+ data: UserData | null;
36
+ hasRole: (role: string) => boolean;
37
+ /** True when `roles` is empty — an ungated resource is open to everyone. */
38
+ hasAnyRole: (roles: readonly string[]) => boolean;
39
+ /** True when `roles` is empty, for the same reason as `hasAnyRole`. */
40
+ hasAllRoles: (roles: readonly string[]) => boolean;
41
+ /** Present only if the app has somewhere to sign out to. Shell chrome hides its sign-out
42
+ * control when it is missing rather than rendering a button that does nothing. */
43
+ logout?: () => void | Promise<void>;
44
+ }
45
+ declare const setUserContext: (context: UserContext) => UserContext;
46
+ /**
47
+ * The user context for the current component tree, or {@link anonymousUser} when the app never
48
+ * set one.
49
+ *
50
+ * The fallback is what lets a component that gates on roles be dropped into an app with no
51
+ * authentication at all and still render. Like every context read, this has to run while the
52
+ * component is initialising.
53
+ */
54
+ export declare const getUserContext: () => UserContext;
55
+ export { setUserContext };
@@ -0,0 +1,13 @@
1
+ import { createContext } from "svelte";
2
+ import { anonymousUser } from "./anonymous.js";
3
+ const [readUserContext, setUserContext, hasUserContext] = createContext();
4
+ /**
5
+ * The user context for the current component tree, or {@link anonymousUser} when the app never
6
+ * set one.
7
+ *
8
+ * The fallback is what lets a component that gates on roles be dropped into an app with no
9
+ * authentication at all and still render. Like every context read, this has to run while the
10
+ * component is initialising.
11
+ */
12
+ export const getUserContext = () => hasUserContext() ? readUserContext() : anonymousUser;
13
+ export { setUserContext };
@@ -0,0 +1,3 @@
1
+ export { anonymousUser } from "./anonymous.js";
2
+ export { getUserContext, setUserContext, type UserContext, type UserData, type UserStatus, } from "./context.js";
3
+ export { default as ScopedComponent } from "./ScopedComponent.svelte";
@@ -0,0 +1,6 @@
1
+ // The identity seam, and nothing more. There is no store, no provider and no network call here
2
+ // on purpose: the library only ever needs to ask who the user is and whether they hold a role,
3
+ // and every app answers that differently. `@viniaraujo68/plinth/user`.
4
+ export { anonymousUser } from "./anonymous.js";
5
+ export { getUserContext, setUserContext, } from "./context.js";
6
+ export { default as ScopedComponent } from "./ScopedComponent.svelte";
package/package.json CHANGED
@@ -1,6 +1,135 @@
1
1
  {
2
2
  "name": "@viniaraujo68/plinth",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "A personal Svelte 5 design system: theme, application shell, interface primitives, routing metadata, a fetch wrapper and locale-aware formatters.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/viniaraujo68/plinth.git"
10
+ },
11
+ "homepage": "https://viniaraujo68.github.io/plinth",
12
+ "bugs": {
13
+ "url": "https://github.com/viniaraujo68/plinth/issues"
14
+ },
15
+ "keywords": [
16
+ "svelte",
17
+ "svelte5",
18
+ "sveltekit",
19
+ "design-system",
20
+ "component-library",
21
+ "tailwindcss",
22
+ "daisyui"
23
+ ],
24
+ "scripts": {
25
+ "dev": "vite dev",
26
+ "build": "vite build && npm run prepack",
27
+ "preview": "vite preview",
28
+ "prepare": "svelte-kit sync && svelte-package",
29
+ "prepack": "svelte-kit sync && svelte-package && publint",
30
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
31
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
32
+ "lint": "prettier --check . && eslint .",
33
+ "format": "prettier --write .",
34
+ "test:unit": "vitest",
35
+ "test": "npm run test:unit -- --run && npm run test:e2e",
36
+ "test:e2e": "playwright install chromium && playwright test"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "!dist/**/*.test.*",
41
+ "!dist/**/*.spec.*",
42
+ "!dist/**/*.e2e.*"
43
+ ],
44
+ "sideEffects": [
45
+ "**/*.css"
46
+ ],
47
+ "svelte": "./dist/index.js",
48
+ "types": "./dist/index.d.ts",
49
+ "exports": {
50
+ ".": {
51
+ "types": "./dist/index.d.ts",
52
+ "svelte": "./dist/index.js"
53
+ },
54
+ "./theme": {
55
+ "types": "./dist/theme/index.d.ts",
56
+ "svelte": "./dist/theme/index.js"
57
+ },
58
+ "./theme.css": "./dist/theme/theme.css",
59
+ "./attachments": {
60
+ "types": "./dist/attachments/index.d.ts",
61
+ "svelte": "./dist/attachments/index.js"
62
+ },
63
+ "./components": {
64
+ "types": "./dist/components/index.d.ts",
65
+ "svelte": "./dist/components/index.js"
66
+ },
67
+ "./confirm": {
68
+ "types": "./dist/confirm/index.d.ts",
69
+ "svelte": "./dist/confirm/index.js"
70
+ },
71
+ "./shell": {
72
+ "types": "./dist/shell/index.d.ts",
73
+ "svelte": "./dist/shell/index.js"
74
+ },
75
+ "./table": {
76
+ "types": "./dist/table/index.d.ts",
77
+ "svelte": "./dist/table/index.js"
78
+ },
79
+ "./toast": {
80
+ "types": "./dist/toast/index.d.ts",
81
+ "svelte": "./dist/toast/index.js"
82
+ },
83
+ "./routing": {
84
+ "types": "./dist/routing.svelte.d.ts",
85
+ "svelte": "./dist/routing.svelte.js"
86
+ },
87
+ "./user": {
88
+ "types": "./dist/user/index.d.ts",
89
+ "svelte": "./dist/user/index.js"
90
+ },
91
+ "./http": {
92
+ "types": "./dist/http.d.ts",
93
+ "default": "./dist/http.js"
94
+ },
95
+ "./formatters": {
96
+ "types": "./dist/formatters.d.ts",
97
+ "default": "./dist/formatters.js"
98
+ },
99
+ "./package.json": "./package.json"
100
+ },
101
+ "peerDependencies": {
102
+ "@sveltejs/kit": "^2.0.0",
103
+ "svelte": "^5.57.0"
104
+ },
105
+ "devDependencies": {
106
+ "@eslint/js": "^10.0.1",
107
+ "@playwright/test": "^1.60.0",
108
+ "@sveltejs/adapter-static": "^3.0.10",
109
+ "@sveltejs/kit": "^2.63.0",
110
+ "@sveltejs/package": "^2.5.8",
111
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
112
+ "@tailwindcss/vite": "^4.3.0",
113
+ "@types/node": "^24",
114
+ "@vitest/browser-playwright": "^4.1.8",
115
+ "daisyui": "^5.6.10",
116
+ "eslint": "^10.4.1",
117
+ "eslint-config-prettier": "^10.1.8",
118
+ "eslint-plugin-svelte": "^3.19.0",
119
+ "globals": "^17.6.0",
120
+ "playwright": "^1.60.0",
121
+ "prettier": "^3.8.3",
122
+ "prettier-plugin-svelte": "^4.1.0",
123
+ "prettier-plugin-tailwindcss": "^0.8.0",
124
+ "publint": "^0.3.21",
125
+ "svelte": "^5.57.0",
126
+ "svelte-check": "^4.6.0",
127
+ "tailwindcss": "^4.3.0",
128
+ "typescript": "^6.0.3",
129
+ "typescript-eslint": "^8.60.1",
130
+ "vite": "^8.0.16",
131
+ "vite-plugin-devtools-json": "^1.1.0",
132
+ "vitest": "^4.1.8",
133
+ "vitest-browser-svelte": "^2.1.1"
134
+ }
135
+ }