@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.
- package/dist/admin.d.ts +11 -0
- package/dist/admin.js +11 -0
- package/dist/components/admin/AdminShell.svelte +42 -0
- package/dist/components/admin/AdminShell.svelte.d.ts +18 -0
- package/dist/components/admin/DecorMosaic.svelte +129 -0
- package/dist/components/admin/DecorMosaic.svelte.d.ts +10 -0
- package/dist/components/admin/PageHeading.svelte +41 -0
- package/dist/components/admin/PageHeading.svelte.d.ts +14 -0
- package/dist/components/admin/Sidebar.svelte +149 -0
- package/dist/components/admin/Sidebar.svelte.d.ts +23 -0
- package/dist/components/contact/ContactForm.svelte +4 -0
- package/dist/components/projects/ProjectCard.svelte +11 -3
- package/dist/components/timeline/TimelineMilestone.svelte +21 -6
- package/dist/components/ui/Button.svelte +118 -23
- package/dist/components/ui/Button.svelte.d.ts +30 -4
- package/dist/components/ui/Field.svelte +23 -2
- package/dist/components/ui/Field.svelte.d.ts +8 -0
- package/dist/components/ui/FilterChips.svelte +21 -8
- package/dist/components/ui/FilterChips.svelte.d.ts +8 -0
- package/dist/components/ui/Icon.svelte +46 -0
- package/dist/components/ui/Icon.svelte.d.ts +24 -0
- package/dist/components/ui/IconButton.svelte +41 -0
- package/dist/components/ui/IconButton.svelte.d.ts +11 -0
- package/dist/components/ui/Logo.svelte +63 -0
- package/dist/components/ui/Logo.svelte.d.ts +9 -0
- package/dist/components/ui/Modal.svelte +79 -0
- package/dist/components/ui/Modal.svelte.d.ts +14 -0
- package/dist/components/ui/TextField.svelte +116 -0
- package/dist/components/ui/TextField.svelte.d.ts +36 -0
- package/dist/components/weeklies/SortSelect.svelte +12 -7
- package/dist/edit/types.d.ts +1 -1
- package/dist/forms/index.d.ts +1 -0
- package/dist/forms/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/primitives.d.ts +4 -0
- package/dist/primitives.js +4 -0
- package/dist/styles/tokens.css +7 -0
- 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
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
</
|
|
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 {
|
package/dist/edit/types.d.ts
CHANGED
|
@@ -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
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/forms/index.js
CHANGED
|
@@ -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';
|
package/dist/primitives.d.ts
CHANGED
|
@@ -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';
|
package/dist/primitives.js
CHANGED
|
@@ -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';
|
package/dist/styles/tokens.css
CHANGED
|
@@ -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.
|
|
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",
|