@vit-foundation/ui 0.7.0 → 0.10.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 (39) hide show
  1. package/dist/admin.d.ts +11 -0
  2. package/dist/admin.js +11 -0
  3. package/dist/components/admin/AdminShell.svelte +42 -0
  4. package/dist/components/admin/AdminShell.svelte.d.ts +18 -0
  5. package/dist/components/admin/DecorMosaic.svelte +129 -0
  6. package/dist/components/admin/DecorMosaic.svelte.d.ts +10 -0
  7. package/dist/components/admin/PageHeading.svelte +41 -0
  8. package/dist/components/admin/PageHeading.svelte.d.ts +14 -0
  9. package/dist/components/admin/Sidebar.svelte +149 -0
  10. package/dist/components/admin/Sidebar.svelte.d.ts +23 -0
  11. package/dist/components/contact/ContactForm.svelte +4 -0
  12. package/dist/components/projects/ProjectCard.svelte +11 -3
  13. package/dist/components/timeline/TimelineMilestone.svelte +21 -6
  14. package/dist/components/ui/Button.svelte +118 -23
  15. package/dist/components/ui/Button.svelte.d.ts +30 -4
  16. package/dist/components/ui/Field.svelte +23 -2
  17. package/dist/components/ui/Field.svelte.d.ts +8 -0
  18. package/dist/components/ui/FilterChips.svelte +21 -8
  19. package/dist/components/ui/FilterChips.svelte.d.ts +8 -0
  20. package/dist/components/ui/Icon.svelte +46 -0
  21. package/dist/components/ui/Icon.svelte.d.ts +24 -0
  22. package/dist/components/ui/IconButton.svelte +41 -0
  23. package/dist/components/ui/IconButton.svelte.d.ts +11 -0
  24. package/dist/components/ui/Logo.svelte +63 -0
  25. package/dist/components/ui/Logo.svelte.d.ts +9 -0
  26. package/dist/components/ui/Modal.svelte +79 -0
  27. package/dist/components/ui/Modal.svelte.d.ts +14 -0
  28. package/dist/components/ui/TextField.svelte +116 -0
  29. package/dist/components/ui/TextField.svelte.d.ts +36 -0
  30. package/dist/components/weeklies/SortSelect.svelte +12 -7
  31. package/dist/edit/types.d.ts +1 -1
  32. package/dist/forms/index.d.ts +1 -0
  33. package/dist/forms/index.js +1 -0
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +2 -1
  36. package/dist/primitives.d.ts +4 -0
  37. package/dist/primitives.js +4 -0
  38. package/dist/styles/tokens.css +7 -0
  39. package/package.json +6 -1
@@ -0,0 +1,116 @@
1
+ <script lang="ts">
2
+ import type { FullAutoFill, HTMLInputAttributes } from 'svelte/elements';
3
+
4
+ interface Props {
5
+ label: string;
6
+ type?: 'text' | 'email' | 'password' | 'time' | 'date';
7
+ id: string;
8
+ value?: string;
9
+ required?: boolean;
10
+ autocomplete?: FullAutoFill;
11
+ /**
12
+ * How the field presents itself. Three, which is what the call sites
13
+ * always were:
14
+ *
15
+ * - `field` — the labelled form field, the default.
16
+ * - `cell` — a table or modal cell. Smaller, and the label goes to the
17
+ * screen reader only.
18
+ * - `bare` — full size, label for the screen reader only, wording
19
+ * carried by the placeholder.
20
+ *
21
+ * It replaces two booleans that encoded three variants between them: no
22
+ * call site ever passed both, one of the four combinations meant
23
+ * nothing, and the compact one quietly did THREE things.
24
+ */
25
+ variant?: 'field' | 'cell' | 'bare';
26
+ /** Overrides the label-derived default ('user' rather than 'email'). */
27
+ placeholder?: string;
28
+ error?: string | null;
29
+ /**
30
+ * A remote form field's attachment (`login.fields.email.as('email')`),
31
+ * spread onto the input instead of binding — without it every remote
32
+ * form routes around this module and re-declares the underline styling.
33
+ */
34
+ attributes?: HTMLInputAttributes;
35
+ }
36
+
37
+ let {
38
+ label,
39
+ type = 'text',
40
+ id,
41
+ value = $bindable(''),
42
+ required = false,
43
+ autocomplete,
44
+ variant = 'field',
45
+ placeholder,
46
+ error = null,
47
+ attributes
48
+ }: Props = $props();
49
+
50
+ const shared = $derived({
51
+ id,
52
+ type,
53
+ required,
54
+ autocomplete,
55
+ placeholder: placeholder ?? (variant === 'field' ? label.toLowerCase() : undefined),
56
+ 'aria-invalid': error ? true : undefined,
57
+ 'aria-describedby': error ? `${id}-error` : undefined
58
+ });
59
+ </script>
60
+
61
+ <div class="field" class:cell={variant === 'cell'}>
62
+ <label for={id} class:visually-hidden={variant !== 'field'}>{label}</label>
63
+ {#if attributes}
64
+ <!-- The form owns the value and its name; `type` comes from `as(...)`. -->
65
+ <input {...shared} {...attributes} />
66
+ {:else}
67
+ <input {...shared} bind:value />
68
+ {/if}
69
+ {#if error}
70
+ <p class="error" id="{id}-error">{error}</p>
71
+ {/if}
72
+ </div>
73
+
74
+ <style>
75
+ .field {
76
+ display: flex;
77
+ flex-direction: column;
78
+ gap: var(--space-1);
79
+ }
80
+
81
+ label {
82
+ font-size: var(--text-sm);
83
+ font-weight: 500;
84
+ }
85
+
86
+ input {
87
+ border: none;
88
+ border-bottom: 1.5px solid var(--color-brand);
89
+ background: transparent;
90
+ padding: 0.4rem 0.1rem;
91
+ font-family: var(--font-sans);
92
+ font-size: var(--text-base);
93
+ color: var(--color-ink);
94
+ }
95
+
96
+ input::placeholder {
97
+ font-style: italic;
98
+ color: var(--color-ink-muted);
99
+ }
100
+
101
+ input:focus-visible {
102
+ outline: none;
103
+ border-bottom-color: var(--color-navy);
104
+ }
105
+
106
+ .cell input {
107
+ font-size: 0.9rem;
108
+ padding: 0.2rem 0.1rem;
109
+ }
110
+
111
+ .error {
112
+ color: var(--series-8);
113
+ font-size: 0.8rem;
114
+ margin: 0;
115
+ }
116
+ </style>
@@ -0,0 +1,36 @@
1
+ import type { FullAutoFill, HTMLInputAttributes } from 'svelte/elements';
2
+ interface Props {
3
+ label: string;
4
+ type?: 'text' | 'email' | 'password' | 'time' | 'date';
5
+ id: string;
6
+ value?: string;
7
+ required?: boolean;
8
+ autocomplete?: FullAutoFill;
9
+ /**
10
+ * How the field presents itself. Three, which is what the call sites
11
+ * always were:
12
+ *
13
+ * - `field` — the labelled form field, the default.
14
+ * - `cell` — a table or modal cell. Smaller, and the label goes to the
15
+ * screen reader only.
16
+ * - `bare` — full size, label for the screen reader only, wording
17
+ * carried by the placeholder.
18
+ *
19
+ * It replaces two booleans that encoded three variants between them: no
20
+ * call site ever passed both, one of the four combinations meant
21
+ * nothing, and the compact one quietly did THREE things.
22
+ */
23
+ variant?: 'field' | 'cell' | 'bare';
24
+ /** Overrides the label-derived default ('user' rather than 'email'). */
25
+ placeholder?: string;
26
+ error?: string | null;
27
+ /**
28
+ * A remote form field's attachment (`login.fields.email.as('email')`),
29
+ * spread onto the input instead of binding — without it every remote
30
+ * form routes around this module and re-declares the underline styling.
31
+ */
32
+ attributes?: HTMLInputAttributes;
33
+ }
34
+ declare const TextField: import("svelte").Component<Props, {}, "value">;
35
+ type TextField = ReturnType<typeof TextField>;
36
+ export default TextField;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { getUiConfig } from '../../config/context.js';
3
3
  import type { SortDirection } from '../../content/types.js';
4
+ import ActionLabel from '../../edit/ActionLabel.svelte';
4
5
 
5
6
  interface Props {
6
7
  value: SortDirection;
@@ -18,13 +19,17 @@
18
19
  }
19
20
  </script>
20
21
 
21
- <label>
22
- <span>{msg.weeklies_sortLabel()}</span>
23
- <select class="control" {value} onchange={handleChange}>
24
- <option value="desc">{msg.weeklies_sortDesc()}</option>
25
- <option value="asc">{msg.weeklies_sortAsc()}</option>
26
- </select>
27
- </label>
22
+ <ActionLabel edit={config.messageEdit?.('weeklies_sortLabel')} value={msg.weeklies_sortLabel()}>
23
+ {#snippet control()}
24
+ <label>
25
+ <span>{msg.weeklies_sortLabel()}</span>
26
+ <select class="control" {value} onchange={handleChange}>
27
+ <option value="desc">{msg.weeklies_sortDesc()}</option>
28
+ <option value="asc">{msg.weeklies_sortAsc()}</option>
29
+ </select>
30
+ </label>
31
+ {/snippet}
32
+ </ActionLabel>
28
33
 
29
34
  <style>
30
35
  label {
@@ -15,7 +15,7 @@ export declare function localize(value: LocalizedText, locale: Locale): string;
15
15
  * The entities whose fields the components can mark editable. Names match
16
16
  * the content tables so an adapter can route a save without a mapping layer.
17
17
  */
18
- export type EditableEntity = 'weeklies' | 'projects' | 'milestones' | 'team_members' | 'job_openings';
18
+ export type EditableEntity = 'weeklies' | 'projects' | 'milestones' | 'team_members' | 'job_openings' | 'themes';
19
19
  /**
20
20
  * The identity of one editable string in the content model: a page copy
21
21
  * block (`page_content` row), one localized field of a domain entity, or one
@@ -5,6 +5,7 @@ export { default as FormResultSlot } from '../components/ui/FormResultSlot.svelt
5
5
  export { default as Honeypot } from '../components/ui/Honeypot.svelte';
6
6
  export { default as LocaleField } from '../components/ui/LocaleField.svelte';
7
7
  export { default as NewsletterIntentField } from '../components/ui/NewsletterIntentField.svelte';
8
+ export { default as TextField } from '../components/ui/TextField.svelte';
8
9
  export { COMMENT_BODY, CONTACT_MESSAGE, CONTACT_NAME, DISPLAY_NAME, EMAIL, LOGIN_PASSWORD, PASSWORD } from './constraints.js';
9
10
  export { hasNewsletterIntent, HONEYPOT_FIELD, isNewsletterIntent, NEWSLETTER_INTENT_PARAM, NEWSLETTER_INTENT_VALUE, withNewsletterIntent } from './transport.js';
10
11
  export type { FormFail, FormFieldIssue, FormResultLike, FormResultOf, KeyedRemoteForms, RemoteField, RemoteFormAttributes, RemoteFormInstance } from './types.js';
@@ -5,5 +5,6 @@ export { default as FormResultSlot } from '../components/ui/FormResultSlot.svelt
5
5
  export { default as Honeypot } from '../components/ui/Honeypot.svelte';
6
6
  export { default as LocaleField } from '../components/ui/LocaleField.svelte';
7
7
  export { default as NewsletterIntentField } from '../components/ui/NewsletterIntentField.svelte';
8
+ export { default as TextField } from '../components/ui/TextField.svelte';
8
9
  export { COMMENT_BODY, CONTACT_MESSAGE, CONTACT_NAME, DISPLAY_NAME, EMAIL, LOGIN_PASSWORD, PASSWORD } from './constraints.js';
9
10
  export { hasNewsletterIntent, HONEYPOT_FIELD, isNewsletterIntent, NEWSLETTER_INTENT_PARAM, NEWSLETTER_INTENT_VALUE, withNewsletterIntent } from './transport.js';
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './primitives.js';
2
2
  export * from './chrome.js';
3
3
  export * from './content-components.js';
4
4
  export * from './community.js';
5
+ export * from './admin.js';
5
6
  export * from './forms/index.js';
6
7
  export * from './config/index.js';
7
8
  export * from './edit/index.js';
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  // The whole surface, flat — importable piecemeal through the semantic
2
2
  // subpaths: ./primitives, ./forms, ./chrome, ./content, ./community,
3
- // ./edit, ./config, ./testing.
3
+ // ./edit, ./config, ./admin, ./testing.
4
4
  export * from './primitives.js';
5
5
  export * from './chrome.js';
6
6
  export * from './content-components.js';
7
7
  export * from './community.js';
8
+ export * from './admin.js';
8
9
  // The form seam: form components, structural remote-form types, transport
9
10
  // constants, field bounds.
10
11
  export * from './forms/index.js';
@@ -10,7 +10,11 @@ export { default as DateText } from './components/ui/DateText.svelte';
10
10
  export { default as DecorShapes } from './components/ui/DecorShapes.svelte';
11
11
  export { default as FilterChips } from './components/ui/FilterChips.svelte';
12
12
  export { default as GhostButton } from './components/ui/GhostButton.svelte';
13
+ export { default as Icon, type IconName } from './components/ui/Icon.svelte';
14
+ export { default as IconButton } from './components/ui/IconButton.svelte';
13
15
  export { default as Link } from './components/ui/Link.svelte';
16
+ export { default as Logo } from './components/ui/Logo.svelte';
17
+ export { default as Modal } from './components/ui/Modal.svelte';
14
18
  export { default as Pagination } from './components/ui/Pagination.svelte';
15
19
  export { default as RichText } from './components/ui/RichText.svelte';
16
20
  export { default as SearchInput } from './components/ui/SearchInput.svelte';
@@ -10,7 +10,11 @@ export { default as DateText } from './components/ui/DateText.svelte';
10
10
  export { default as DecorShapes } from './components/ui/DecorShapes.svelte';
11
11
  export { default as FilterChips } from './components/ui/FilterChips.svelte';
12
12
  export { default as GhostButton } from './components/ui/GhostButton.svelte';
13
+ export { default as Icon } from './components/ui/Icon.svelte';
14
+ export { default as IconButton } from './components/ui/IconButton.svelte';
13
15
  export { default as Link } from './components/ui/Link.svelte';
16
+ export { default as Logo } from './components/ui/Logo.svelte';
17
+ export { default as Modal } from './components/ui/Modal.svelte';
14
18
  export { default as Pagination } from './components/ui/Pagination.svelte';
15
19
  export { default as RichText } from './components/ui/RichText.svelte';
16
20
  export { default as SearchInput } from './components/ui/SearchInput.svelte';
@@ -30,6 +30,7 @@
30
30
 
31
31
  /* Typography */
32
32
  --font-sans: system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
33
+ --font-serif: Georgia, 'Times New Roman', serif;
33
34
  --text-sm: 0.875rem;
34
35
  --text-base: 1rem;
35
36
  --text-lg: 1.25rem;
@@ -52,6 +53,12 @@
52
53
  --radius-lg: 16px;
53
54
  --content-max: 1200px;
54
55
 
56
+ /* Elevation & layering */
57
+ --shadow-1: 0 2px 10px rgb(16 20 24 / 10%);
58
+ --shadow-2: 0 12px 40px rgb(16 20 24 / 20%);
59
+ --z-raised: 10;
60
+ --z-overlay: 100;
61
+
55
62
  /* Motion */
56
63
  --transition-fast: 150ms ease;
57
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vit-foundation/ui",
3
- "version": "0.7.0",
3
+ "version": "0.10.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -72,6 +72,11 @@
72
72
  "svelte": "./dist/config/index.js",
73
73
  "default": "./dist/config/index.js"
74
74
  },
75
+ "./admin": {
76
+ "types": "./dist/admin.d.ts",
77
+ "svelte": "./dist/admin.js",
78
+ "default": "./dist/admin.js"
79
+ },
75
80
  "./testing": {
76
81
  "types": "./dist/testing/remote-form.d.ts",
77
82
  "svelte": "./dist/testing/remote-form.js",