@auldrant/ui 0.0.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/CHANGELOG.md +58 -0
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/dist/auldrant-ui.css +1 -0
- package/dist/auldrant-ui.js +424 -0
- package/dist/components/Button.d.ts +16 -0
- package/dist/components/Card.d.ts +10 -0
- package/dist/components/Checkbox.d.ts +12 -0
- package/dist/components/DownloadLink.d.ts +14 -0
- package/dist/components/Form.d.ts +16 -0
- package/dist/components/FormField.d.ts +19 -0
- package/dist/components/Input.d.ts +26 -0
- package/dist/components/Link.d.ts +18 -0
- package/dist/components/Nav.d.ts +15 -0
- package/dist/components/NumberInput.d.ts +20 -0
- package/dist/components/PasswordInput.d.ts +16 -0
- package/dist/components/RadioGroup.d.ts +29 -0
- package/dist/components/Route.d.ts +14 -0
- package/dist/components/Section.d.ts +17 -0
- package/dist/components/Select.d.ts +30 -0
- package/dist/components/SkipLink.d.ts +15 -0
- package/dist/components/Table.d.ts +15 -0
- package/dist/components/Textarea.d.ts +16 -0
- package/dist/components/Theme.d.ts +32 -0
- package/dist/components/VisuallyHidden.d.ts +12 -0
- package/dist/index.d.ts +24 -0
- package/dist/scripts/types.d.ts +16 -0
- package/dist/scripts/utils.d.ts +35 -0
- package/dist/signals/head.d.ts +2 -0
- package/dist/signals/routing.d.ts +11 -0
- package/package.json +63 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [0.4.0] - 2026-02-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **feat(test)**: add axe-core a11y test suite (19 files, setup helpers, 18 test files) ([#20](https://github.com/coloneljade/auldrant-ui/pull/20))
|
|
13
|
+
- **refactor(test)**: migrate a11y assertions out of behavioral tests (cleanup + deletions) ([#20](https://github.com/coloneljade/auldrant-ui/pull/20))
|
|
14
|
+
- **docs(rules)**: mandate AAA comments and WCAG SC references in tests ([#20](https://github.com/coloneljade/auldrant-ui/pull/20))
|
|
15
|
+
|
|
16
|
+
## [0.3.0] - 2026-02-25
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Configure Vite, TypeScript, Biome, devcontainer, and test setup ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
21
|
+
- Add routing and title signals for SPA navigation ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
22
|
+
- Shared types, utilities, and composable CSS classes ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
23
|
+
- Semantic HTML-first — native elements before ARIA ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
24
|
+
- CSS Grid layout, em-based spacing, CSS modules ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
25
|
+
- Accessible form field management (`FormField` wrapper) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
26
|
+
- SkipLink and Nav for keyboard navigation ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
27
|
+
- Type-safe component props (TypeScript strict mode) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
28
|
+
- Comprehensive test coverage (114 tests) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
29
|
+
- Pit of success design principle for component APIs ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
30
|
+
- Binary tools principle (Biome fixes, not manual edits) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
31
|
+
- Mandatory skills workflow (staging, pushing, PRs) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
32
|
+
- Import aliases (`@components`, `@scripts`, `@signals`, `@styles`) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
33
|
+
- **Head component** — meta/document head management (issue #18) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
34
|
+
- **Form data typing** — generic type parameter for typed onSubmit (issue #8) ([#7](https://github.com/coloneljade/auldrant-ui/pull/7))
|
|
35
|
+
|
|
36
|
+
## [0.2.0] - 2026-02-24
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- Remove CJS output and UMD name — ESM-only library ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
41
|
+
- Fix CI publish failure by skipping lefthook in CI environment ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
42
|
+
- Add `@components` and `@styles` import path aliases (tsconfig + vite) ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
43
|
+
- Add GitHub CLI feature and YAML extension to devcontainer ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
44
|
+
- Create VSCode tasks for all project scripts (test, build, check, typecheck, storybook) ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
45
|
+
- Add component base types (BaseProps, FieldProps) and cx() class utility ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
46
|
+
|
|
47
|
+
## [0.1.0] - 2026-02-24
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- Remove CJS output and UMD name — ESM-only library ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
52
|
+
- Fix CI publish failure by skipping lefthook in CI environment ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
53
|
+
- Add `@components` and `@styles` import path aliases (tsconfig + vite) ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
54
|
+
- Add GitHub CLI feature and YAML extension to devcontainer ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
55
|
+
- Create VSCode tasks for all project scripts (test, build, check, typecheck, storybook) ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
56
|
+
- Add component base types (BaseProps, FieldProps) and cx() class utility ([#6](https://github.com/coloneljade/auldrant-ui/pull/6))
|
|
57
|
+
|
|
58
|
+
## [Unreleased]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Colonel Jade
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @auldrant/ui
|
|
2
|
+
|
|
3
|
+
Accessible Preact component library with design tokens and CSS modules.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @auldrant/ui preact @preact/signals
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Import the stylesheet in your app entry point:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import '@auldrant/ui/styles';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Button, Form, Theme } from '@auldrant/ui';
|
|
21
|
+
import '@auldrant/ui/styles';
|
|
22
|
+
|
|
23
|
+
function App() {
|
|
24
|
+
return (
|
|
25
|
+
<Theme class="my-theme">
|
|
26
|
+
<Form onSubmit={(data) => console.log(data)}>
|
|
27
|
+
<Button label="Submit" type="submit" />
|
|
28
|
+
</Form>
|
|
29
|
+
</Theme>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Components
|
|
35
|
+
|
|
36
|
+
### Form Controls
|
|
37
|
+
|
|
38
|
+
| Component | Description | Key Props |
|
|
39
|
+
|-----------|-------------|-----------|
|
|
40
|
+
| `Button` | Standard button with configurable type and click handler | `label`, `onClick?`, `type?` |
|
|
41
|
+
| `Checkbox` | Checkbox with label | `label`, `checked?`, `onChange?` |
|
|
42
|
+
| `Form` | Form with submit/reset buttons. Prevents default and provides FormData | `onSubmit`, `children`, `submitLabel?` |
|
|
43
|
+
| `Input` | Text input with label | `type?`, `value?`, `onInput?` |
|
|
44
|
+
| `NumberInput` | Numeric input with label | `min?`, `max?`, `onInput?` |
|
|
45
|
+
| `PasswordInput` | Password input with show/hide toggle | `purpose` (`'current'` \| `'new'`), `value?`, `onInput?` |
|
|
46
|
+
| `RadioGroup` | Radio button group inside a fieldset | `legend`, `name`, `options` |
|
|
47
|
+
| `Select` | Select dropdown with label | `options`, `value?`, `onChange?` |
|
|
48
|
+
| `Textarea` | Textarea with character counter | `maxChars`, `value?`, `onInput?` |
|
|
49
|
+
|
|
50
|
+
### Layout
|
|
51
|
+
|
|
52
|
+
| Component | Description | Key Props |
|
|
53
|
+
|-----------|-------------|-----------|
|
|
54
|
+
| `Card` | Visual surface container | `children` |
|
|
55
|
+
| `Section` | Semantic `<section>` with configurable heading level | `title`, `level?`, `children` |
|
|
56
|
+
| `Table` | Accessible data table with required headers | `headers`, `data` |
|
|
57
|
+
| `Theme` | Scopes `--aui-*` custom properties to its subtree | `children` |
|
|
58
|
+
| `VisuallyHidden` | Screen-reader-only content | `children` |
|
|
59
|
+
|
|
60
|
+
### Navigation
|
|
61
|
+
|
|
62
|
+
| Component | Description | Key Props |
|
|
63
|
+
|-----------|-------------|-----------|
|
|
64
|
+
| `Link` | Auto-detects internal vs external URLs | `href`, `children`, `external?` |
|
|
65
|
+
| `DownloadLink` | Download link using `<a download>` | `href`, `fileName`, `label` |
|
|
66
|
+
| `Nav` | Semantic `<nav>` wrapper with optional title | `title?`, `children` |
|
|
67
|
+
| `Route` | Renders children when location matches path | `path`, `children` |
|
|
68
|
+
| `SkipLink` | Skip navigation link, hidden until focused | `target?`, `label?` |
|
|
69
|
+
|
|
70
|
+
All components extend `IBaseProps` which includes `class?` and `id?`. Form controls extend `IFieldProps` which adds `label`, `name?`, `required?`, and `disabled?`. Full prop types are available in the `.d.ts` files.
|
|
71
|
+
|
|
72
|
+
## Theming
|
|
73
|
+
|
|
74
|
+
Wrap your app in `<Theme>` and define `--aui-*` custom properties in your CSS:
|
|
75
|
+
|
|
76
|
+
```css
|
|
77
|
+
.my-theme {
|
|
78
|
+
--aui-color-text: #1a1a1a;
|
|
79
|
+
--aui-color-text-muted: #6b7280;
|
|
80
|
+
--aui-color-background: #ffffff;
|
|
81
|
+
--aui-color-surface: #f9fafb;
|
|
82
|
+
--aui-color-border: #d1d5db;
|
|
83
|
+
--aui-color-primary: #2563eb;
|
|
84
|
+
--aui-color-primary-hover: #1d4ed8;
|
|
85
|
+
--aui-color-focus-ring: #3b82f6;
|
|
86
|
+
--aui-color-error: #dc2626;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
<Theme class="my-theme">
|
|
92
|
+
<App />
|
|
93
|
+
</Theme>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
| Token | Purpose |
|
|
97
|
+
|-------|---------|
|
|
98
|
+
| `--aui-color-text` | Body text |
|
|
99
|
+
| `--aui-color-text-muted` | Placeholder text, secondary content |
|
|
100
|
+
| `--aui-color-background` | Input and page backgrounds |
|
|
101
|
+
| `--aui-color-background-hover` | Hover state for interactive backgrounds |
|
|
102
|
+
| `--aui-color-surface` | Card and container backgrounds |
|
|
103
|
+
| `--aui-color-border` | Borders on inputs, cards, tables |
|
|
104
|
+
| `--aui-color-primary` | Buttons, links, accents |
|
|
105
|
+
| `--aui-color-primary-hover` | Hover state for buttons and links |
|
|
106
|
+
| `--aui-color-focus-ring` | Focus indicator outline |
|
|
107
|
+
| `--aui-color-error` | Validation error text |
|
|
108
|
+
|
|
109
|
+
Themes are nestable for sub-themes (e.g. dark mode sections).
|
|
110
|
+
|
|
111
|
+
## Routing & Signals
|
|
112
|
+
|
|
113
|
+
Built-in routing uses Preact signals and the History API:
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { location, hash, navigate, title, Route, Link } from '@auldrant/ui';
|
|
117
|
+
|
|
118
|
+
// Read current path
|
|
119
|
+
console.log(location.value); // "/about"
|
|
120
|
+
console.log(hash.value); // "section-1"
|
|
121
|
+
|
|
122
|
+
// Navigate programmatically
|
|
123
|
+
navigate('/dashboard');
|
|
124
|
+
navigate('/login', { replace: true });
|
|
125
|
+
|
|
126
|
+
// Set document title reactively
|
|
127
|
+
title.value = 'My Page';
|
|
128
|
+
|
|
129
|
+
// Declarative routing
|
|
130
|
+
<Route path="/about">
|
|
131
|
+
<AboutPage />
|
|
132
|
+
</Route>
|
|
133
|
+
|
|
134
|
+
<Link href="/about">About</Link>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Utilities
|
|
138
|
+
|
|
139
|
+
### `cx(...classes)`
|
|
140
|
+
|
|
141
|
+
Combine CSS class names, filtering out falsy values:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { cx } from '@auldrant/ui';
|
|
145
|
+
|
|
146
|
+
cx('btn', isActive && 'active'); // "btn active" or "btn"
|
|
147
|
+
cx(styles.card, props.class); // handles undefined class prop
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
### Prerequisites
|
|
153
|
+
|
|
154
|
+
- [Bun](https://bun.sh/) >= 1.0.0
|
|
155
|
+
- Or use the included DevContainer
|
|
156
|
+
|
|
157
|
+
### Setup
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
bun install
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Commands
|
|
164
|
+
|
|
165
|
+
| Command | Description |
|
|
166
|
+
|---------|-------------|
|
|
167
|
+
| `bun run build` | Build the library |
|
|
168
|
+
| `bun run check` | Lint and format check (Biome) |
|
|
169
|
+
| `bun run check:fix` | Auto-fix lint and format issues |
|
|
170
|
+
| `bun run typecheck` | TypeScript type checking |
|
|
171
|
+
| `bun run test` | Run tests |
|
|
172
|
+
| `bun run test:watch` | Run tests in watch mode |
|
|
173
|
+
| `bun run storybook` | Start Storybook dev server |
|
|
174
|
+
| `bun run build-storybook` | Build static Storybook |
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._button_4gn7y_1{padding:.5em 1em;border:1px solid var(--aui-color-border);border-radius:.25em;background:var(--aui-color-primary);color:var(--aui-color-background);font:inherit;cursor:pointer}._button_4gn7y_1:hover{background:var(--aui-color-primary-hover)}._card_awzw5_1{display:grid;gap:.5em;padding:1em;border:1px solid var(--aui-color-border);border-radius:.25em;background:var(--aui-color-surface)}._field_sfa1d_1{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:.5em}._form_rchcx_1{display:grid;gap:1em}._actions_rchcx_6{display:grid;grid-auto-flow:column;justify-content:start;gap:.5em}._field_18ejg_1{display:grid;grid-template-columns:auto 1fr;align-items:start;gap:.5em}._label_18ejg_8{padding-top:.25em}._required_18ejg_12{color:var(--aui-color-error)}._nav_778nl_1{display:grid;gap:.5em}._title_778nl_6{font-weight:700}._wrapper_1mu6v_1{display:grid;grid-template-columns:1fr auto}._input_1mu6v_6{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}._toggle_1mu6v_13{padding:.375em .75em;border:1px solid var(--aui-color-border);border-top-right-radius:.25em;border-bottom-right-radius:.25em;background:var(--aui-color-background);color:var(--aui-color-text);font:inherit;font-size:.875em;cursor:pointer}._toggle_1mu6v_13:hover:not(:disabled){background:var(--aui-color-background-hover, var(--aui-color-background))}._fieldset_19vke_1{border:none;padding:0}._legend_19vke_6{font-weight:700;margin-bottom:.5em}._option_19vke_11{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:.5em;margin-bottom:.25em}._section_4nogy_1{display:grid;gap:1em}._skip_xbsul_1{position:absolute;top:-100%;left:0;padding:.5em 1em;background:var(--aui-color-background);color:var(--aui-color-primary);z-index:1000}._skip_xbsul_1:focus{top:0}._table_roeo7_1{width:100%;border-collapse:collapse}._table_roeo7_1 th,._table_roeo7_1 td{padding:.5em;text-align:left;border-bottom:1px solid var(--aui-color-border)}._table_roeo7_1 th{font-weight:700;color:var(--aui-color-text)}._table_roeo7_1 td{color:var(--aui-color-text)}._wrapper_1kyv1_1{display:grid;gap:.25em}._textarea_1kyv1_6{resize:vertical}._counter_1kyv1_11{justify-self:end;font-size:.875em;color:var(--aui-color-text-muted)}._theme_13mb7_1{display:contents}._focus-ring_4m0e1_3:focus-visible{outline:2px solid var(--aui-color-focus-ring);outline-offset:2px}._disabled_4m0e1_8:disabled{opacity:.5;cursor:not-allowed}._text-input_4m0e1_13{padding:.375em .5em;border:1px solid var(--aui-color-border);border-radius:.25em;background:var(--aui-color-background);color:var(--aui-color-text);font:inherit}._link_4m0e1_22{color:var(--aui-color-primary);text-decoration:underline;cursor:pointer}._link_4m0e1_22:hover{color:var(--aui-color-primary-hover)}._check-input_4m0e1_32{accent-color:var(--aui-color-primary)}._visually-hidden_4m0e1_36{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import { jsx as a, jsxs as _, Fragment as T } from "preact/jsx-runtime";
|
|
2
|
+
import { useId as b } from "preact/hooks";
|
|
3
|
+
import { signal as $, useSignal as j, effect as D } from "@preact/signals";
|
|
4
|
+
function h(...t) {
|
|
5
|
+
return t.filter(Boolean).join(" ");
|
|
6
|
+
}
|
|
7
|
+
const E = "_button_4gn7y_1 _focus-ring_4m0e1_3 _disabled_4m0e1_8", B = {
|
|
8
|
+
button: E
|
|
9
|
+
}, I = (t) => {
|
|
10
|
+
const { label: e, onClick: l, type: n = "button", disabled: s, class: c } = t;
|
|
11
|
+
return /* @__PURE__ */ a("button", { type: n, class: h(B.button, c), onClick: l, disabled: s, children: e });
|
|
12
|
+
}, H = "_card_awzw5_1", O = {
|
|
13
|
+
card: H
|
|
14
|
+
}, Te = (t) => {
|
|
15
|
+
const { children: e, class: l } = t;
|
|
16
|
+
return /* @__PURE__ */ a("div", { class: h(O.card, l), children: e });
|
|
17
|
+
}, R = "_field_sfa1d_1", G = "_input_sfa1d_8 _check-input_4m0e1_32 _focus-ring_4m0e1_3 _disabled_4m0e1_8", C = {
|
|
18
|
+
field: R,
|
|
19
|
+
input: G
|
|
20
|
+
}, De = (t) => {
|
|
21
|
+
const { label: e, name: l, checked: n, required: s, disabled: c, onChange: o, class: d } = t, u = b();
|
|
22
|
+
return /* @__PURE__ */ _("div", { class: h(C.field, d), children: [
|
|
23
|
+
/* @__PURE__ */ a(
|
|
24
|
+
"input",
|
|
25
|
+
{
|
|
26
|
+
id: u,
|
|
27
|
+
class: C.input,
|
|
28
|
+
type: "checkbox",
|
|
29
|
+
name: l,
|
|
30
|
+
checked: n,
|
|
31
|
+
required: s,
|
|
32
|
+
disabled: c,
|
|
33
|
+
onChange: o && ((m) => o(m.target.checked))
|
|
34
|
+
}
|
|
35
|
+
),
|
|
36
|
+
/* @__PURE__ */ a("label", { for: u, children: e })
|
|
37
|
+
] });
|
|
38
|
+
}, W = "_link_7wgic_1 _link_4m0e1_22 _focus-ring_4m0e1_3", z = {
|
|
39
|
+
link: W
|
|
40
|
+
}, Ee = (t) => {
|
|
41
|
+
const { href: e, fileName: l, label: n, class: s } = t;
|
|
42
|
+
return /* @__PURE__ */ a("a", { href: e, download: l, class: h(z.link, s), children: n });
|
|
43
|
+
}, A = "_form_rchcx_1", M = "_actions_rchcx_6", q = {
|
|
44
|
+
form: A,
|
|
45
|
+
actions: M
|
|
46
|
+
}, Be = (t) => {
|
|
47
|
+
const { onSubmit: e, submitLabel: l = "Submit", resetLabel: n, children: s, class: c } = t;
|
|
48
|
+
return /* @__PURE__ */ _(
|
|
49
|
+
"form",
|
|
50
|
+
{
|
|
51
|
+
class: h(q.form, c),
|
|
52
|
+
onSubmit: (o) => {
|
|
53
|
+
o.preventDefault();
|
|
54
|
+
const d = new FormData(o.currentTarget);
|
|
55
|
+
e(d);
|
|
56
|
+
},
|
|
57
|
+
children: [
|
|
58
|
+
s,
|
|
59
|
+
/* @__PURE__ */ _("div", { class: q.actions, children: [
|
|
60
|
+
/* @__PURE__ */ a(I, { type: "submit", label: l }),
|
|
61
|
+
n && /* @__PURE__ */ a(I, { type: "reset", label: n })
|
|
62
|
+
] })
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}, U = "_field_18ejg_1", V = "_label_18ejg_8", J = "_required_18ejg_12", x = {
|
|
67
|
+
field: U,
|
|
68
|
+
label: V,
|
|
69
|
+
required: J
|
|
70
|
+
}, g = (t) => {
|
|
71
|
+
const { for: e, label: l, required: n, children: s, class: c } = t;
|
|
72
|
+
return /* @__PURE__ */ _("div", { class: h(x.field, c), children: [
|
|
73
|
+
/* @__PURE__ */ _("label", { class: x.label, for: e, children: [
|
|
74
|
+
l,
|
|
75
|
+
":",
|
|
76
|
+
n && /* @__PURE__ */ _("span", { class: x.required, "aria-hidden": "true", children: [
|
|
77
|
+
" ",
|
|
78
|
+
"*"
|
|
79
|
+
] })
|
|
80
|
+
] }),
|
|
81
|
+
s
|
|
82
|
+
] });
|
|
83
|
+
}, K = "_input_1j10x_1 _text-input_4m0e1_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", Q = {
|
|
84
|
+
input: K
|
|
85
|
+
}, X = {
|
|
86
|
+
email: "email",
|
|
87
|
+
tel: "tel",
|
|
88
|
+
url: "url"
|
|
89
|
+
}, He = (t) => {
|
|
90
|
+
const {
|
|
91
|
+
label: e,
|
|
92
|
+
name: l,
|
|
93
|
+
type: n = "text",
|
|
94
|
+
value: s,
|
|
95
|
+
placeholder: c,
|
|
96
|
+
maxLength: o,
|
|
97
|
+
autocomplete: d,
|
|
98
|
+
readOnly: u,
|
|
99
|
+
pattern: m,
|
|
100
|
+
required: r,
|
|
101
|
+
disabled: i,
|
|
102
|
+
onInput: p,
|
|
103
|
+
class: f
|
|
104
|
+
} = t, v = b();
|
|
105
|
+
return /* @__PURE__ */ a(g, { label: e, for: v, required: r, class: f, children: /* @__PURE__ */ a(
|
|
106
|
+
"input",
|
|
107
|
+
{
|
|
108
|
+
id: v,
|
|
109
|
+
class: Q.input,
|
|
110
|
+
type: n,
|
|
111
|
+
name: l,
|
|
112
|
+
value: s,
|
|
113
|
+
placeholder: c,
|
|
114
|
+
maxLength: o,
|
|
115
|
+
autoComplete: d ?? X[n],
|
|
116
|
+
readOnly: u,
|
|
117
|
+
pattern: m,
|
|
118
|
+
required: r,
|
|
119
|
+
disabled: i,
|
|
120
|
+
onInput: p && ((P) => p(P.target.value))
|
|
121
|
+
}
|
|
122
|
+
) });
|
|
123
|
+
}, N = $(window.location.pathname), F = $(window.location.hash.slice(1));
|
|
124
|
+
function Y(t) {
|
|
125
|
+
const e = t.indexOf("#");
|
|
126
|
+
let l = "", n = t;
|
|
127
|
+
e >= 0 && (l = t.slice(e + 1), n = t.slice(0, e));
|
|
128
|
+
const s = n.indexOf("?");
|
|
129
|
+
let c = "", o = n;
|
|
130
|
+
return s >= 0 && (c = n.slice(s), o = n.slice(0, s)), { pathname: o || "/", search: c, hash: l };
|
|
131
|
+
}
|
|
132
|
+
function Z(t, e) {
|
|
133
|
+
const { pathname: l, search: n, hash: s } = Y(t), c = l + n + (s ? `#${s}` : "");
|
|
134
|
+
e?.replace ? history.replaceState(null, "", c) : history.pushState(null, "", c), N.value = l, F.value = s;
|
|
135
|
+
}
|
|
136
|
+
window.addEventListener("popstate", () => {
|
|
137
|
+
N.value = window.location.pathname, F.value = window.location.hash.slice(1);
|
|
138
|
+
});
|
|
139
|
+
const ee = "_link_7wgic_1 _link_4m0e1_22 _focus-ring_4m0e1_3", S = {
|
|
140
|
+
link: ee
|
|
141
|
+
};
|
|
142
|
+
function te(t) {
|
|
143
|
+
try {
|
|
144
|
+
return new URL(t, window.location.href).origin !== window.location.origin;
|
|
145
|
+
} catch {
|
|
146
|
+
return !1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const Oe = (t) => {
|
|
150
|
+
const { href: e, children: l, external: n, class: s } = t;
|
|
151
|
+
return n ?? te(e) ? /* @__PURE__ */ a("a", { href: e, class: h(S.link, s), rel: "noopener noreferrer", children: l }) : /* @__PURE__ */ a(
|
|
152
|
+
"a",
|
|
153
|
+
{
|
|
154
|
+
href: e,
|
|
155
|
+
class: h(S.link, s),
|
|
156
|
+
onClick: (o) => {
|
|
157
|
+
o.preventDefault(), Z(e);
|
|
158
|
+
},
|
|
159
|
+
children: l
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}, se = "_nav_778nl_1", ne = "_title_778nl_6", L = {
|
|
163
|
+
nav: se,
|
|
164
|
+
title: ne
|
|
165
|
+
}, Re = (t) => {
|
|
166
|
+
const { title: e, children: l, class: n } = t, s = b();
|
|
167
|
+
return /* @__PURE__ */ _("nav", { class: h(L.nav, n), "aria-labelledby": e ? s : void 0, children: [
|
|
168
|
+
e && /* @__PURE__ */ a("h2", { id: s, class: L.title, children: e }),
|
|
169
|
+
l
|
|
170
|
+
] });
|
|
171
|
+
}, le = "_input_1j10x_1 _text-input_4m0e1_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", ae = {
|
|
172
|
+
input: le
|
|
173
|
+
}, Ge = (t) => {
|
|
174
|
+
const {
|
|
175
|
+
label: e,
|
|
176
|
+
name: l,
|
|
177
|
+
min: n,
|
|
178
|
+
max: s,
|
|
179
|
+
step: c,
|
|
180
|
+
value: o,
|
|
181
|
+
placeholder: d,
|
|
182
|
+
required: u,
|
|
183
|
+
disabled: m,
|
|
184
|
+
onInput: r,
|
|
185
|
+
class: i
|
|
186
|
+
} = t, p = b();
|
|
187
|
+
return /* @__PURE__ */ a(g, { label: e, for: p, required: u, class: i, children: /* @__PURE__ */ a(
|
|
188
|
+
"input",
|
|
189
|
+
{
|
|
190
|
+
id: p,
|
|
191
|
+
class: ae.input,
|
|
192
|
+
type: "number",
|
|
193
|
+
name: l,
|
|
194
|
+
min: n,
|
|
195
|
+
max: s,
|
|
196
|
+
step: c,
|
|
197
|
+
value: o,
|
|
198
|
+
placeholder: d,
|
|
199
|
+
required: u,
|
|
200
|
+
disabled: m,
|
|
201
|
+
onInput: r && ((f) => r(f.target.valueAsNumber))
|
|
202
|
+
}
|
|
203
|
+
) });
|
|
204
|
+
}, ce = "_wrapper_1mu6v_1", oe = "_input_1mu6v_6 _text-input_4m0e1_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", ie = "_toggle_1mu6v_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", y = {
|
|
205
|
+
wrapper: ce,
|
|
206
|
+
input: oe,
|
|
207
|
+
toggle: ie
|
|
208
|
+
}, re = {
|
|
209
|
+
current: "current-password",
|
|
210
|
+
new: "new-password"
|
|
211
|
+
}, We = (t) => {
|
|
212
|
+
const {
|
|
213
|
+
label: e,
|
|
214
|
+
name: l,
|
|
215
|
+
purpose: n,
|
|
216
|
+
value: s,
|
|
217
|
+
placeholder: c,
|
|
218
|
+
required: o,
|
|
219
|
+
disabled: d,
|
|
220
|
+
onInput: u,
|
|
221
|
+
class: m
|
|
222
|
+
} = t, r = b(), i = j(!1);
|
|
223
|
+
return /* @__PURE__ */ a(g, { label: e, for: r, required: o, class: m, children: /* @__PURE__ */ _("div", { class: y.wrapper, children: [
|
|
224
|
+
/* @__PURE__ */ a(
|
|
225
|
+
"input",
|
|
226
|
+
{
|
|
227
|
+
id: r,
|
|
228
|
+
class: y.input,
|
|
229
|
+
type: i.value ? "text" : "password",
|
|
230
|
+
name: l,
|
|
231
|
+
value: s,
|
|
232
|
+
placeholder: c,
|
|
233
|
+
autoComplete: re[n],
|
|
234
|
+
required: o,
|
|
235
|
+
disabled: d,
|
|
236
|
+
onInput: u && ((p) => u(p.target.value))
|
|
237
|
+
}
|
|
238
|
+
),
|
|
239
|
+
/* @__PURE__ */ a(
|
|
240
|
+
"button",
|
|
241
|
+
{
|
|
242
|
+
type: "button",
|
|
243
|
+
class: y.toggle,
|
|
244
|
+
disabled: d,
|
|
245
|
+
onClick: () => {
|
|
246
|
+
i.value = !i.value;
|
|
247
|
+
},
|
|
248
|
+
children: i.value ? "Hide password" : "Show password"
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
] }) });
|
|
252
|
+
}, de = "_fieldset_19vke_1", ue = "_legend_19vke_6", _e = "_option_19vke_11", pe = "_input_19vke_19 _check-input_4m0e1_32 _focus-ring_4m0e1_3", w = {
|
|
253
|
+
fieldset: de,
|
|
254
|
+
legend: ue,
|
|
255
|
+
option: _e,
|
|
256
|
+
input: pe
|
|
257
|
+
}, ze = (t) => {
|
|
258
|
+
const { legend: e, name: l, options: n, value: s, required: c, disabled: o, onChange: d, class: u } = t, m = b();
|
|
259
|
+
return /* @__PURE__ */ _("fieldset", { class: h(w.fieldset, u), children: [
|
|
260
|
+
/* @__PURE__ */ a("legend", { class: w.legend, children: e }),
|
|
261
|
+
n.map((r) => {
|
|
262
|
+
const i = `${m}-${r.value}`;
|
|
263
|
+
return /* @__PURE__ */ _("div", { class: w.option, children: [
|
|
264
|
+
/* @__PURE__ */ a(
|
|
265
|
+
"input",
|
|
266
|
+
{
|
|
267
|
+
id: i,
|
|
268
|
+
class: w.input,
|
|
269
|
+
type: "radio",
|
|
270
|
+
name: l,
|
|
271
|
+
value: r.value,
|
|
272
|
+
checked: s === r.value,
|
|
273
|
+
required: c,
|
|
274
|
+
disabled: o,
|
|
275
|
+
onChange: d && (() => d(r.value))
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
/* @__PURE__ */ a("label", { for: i, children: r.label })
|
|
279
|
+
] }, r.value);
|
|
280
|
+
})
|
|
281
|
+
] });
|
|
282
|
+
}, Ae = (t) => {
|
|
283
|
+
const { path: e, children: l } = t, n = N.value;
|
|
284
|
+
if (e.endsWith("/*")) {
|
|
285
|
+
const s = e.slice(0, -1);
|
|
286
|
+
if (!n.startsWith(s) && n !== s.slice(0, -1))
|
|
287
|
+
return null;
|
|
288
|
+
} else if (n !== e)
|
|
289
|
+
return null;
|
|
290
|
+
return /* @__PURE__ */ a(T, { children: l });
|
|
291
|
+
}, he = "_section_4nogy_1", me = {
|
|
292
|
+
section: he
|
|
293
|
+
}, Me = (t) => {
|
|
294
|
+
const { title: e, level: l = 2, children: n, class: s } = t, c = b(), o = `h${l}`;
|
|
295
|
+
return /* @__PURE__ */ _("section", { class: h(me.section, s), "aria-labelledby": c, children: [
|
|
296
|
+
/* @__PURE__ */ a(o, { id: c, children: e }),
|
|
297
|
+
n
|
|
298
|
+
] });
|
|
299
|
+
}, be = "_select_1cxnx_1 _text-input_4m0e1_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", fe = {
|
|
300
|
+
select: be
|
|
301
|
+
}, ve = (t) => "options" in t, Ue = (t) => {
|
|
302
|
+
const {
|
|
303
|
+
label: e,
|
|
304
|
+
name: l,
|
|
305
|
+
value: n,
|
|
306
|
+
placeholder: s,
|
|
307
|
+
options: c,
|
|
308
|
+
required: o,
|
|
309
|
+
disabled: d,
|
|
310
|
+
onChange: u,
|
|
311
|
+
class: m
|
|
312
|
+
} = t, r = b();
|
|
313
|
+
return /* @__PURE__ */ a(g, { label: e, for: r, required: o, class: m, children: /* @__PURE__ */ _(
|
|
314
|
+
"select",
|
|
315
|
+
{
|
|
316
|
+
id: r,
|
|
317
|
+
class: fe.select,
|
|
318
|
+
name: l,
|
|
319
|
+
value: n,
|
|
320
|
+
required: o,
|
|
321
|
+
disabled: d,
|
|
322
|
+
onChange: u && ((i) => u(i.target.value)),
|
|
323
|
+
children: [
|
|
324
|
+
s && /* @__PURE__ */ a("option", { value: "", disabled: !0, children: s }),
|
|
325
|
+
c.map(
|
|
326
|
+
(i) => ve(i) ? /* @__PURE__ */ a("optgroup", { label: i.label, children: i.options.map((p) => /* @__PURE__ */ a("option", { value: p.value, children: p.label }, p.value)) }, i.label) : /* @__PURE__ */ a("option", { value: i.value, children: i.label }, i.value)
|
|
327
|
+
)
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
) });
|
|
331
|
+
}, ge = "_skip_xbsul_1 _focus-ring_4m0e1_3", we = {
|
|
332
|
+
skip: ge
|
|
333
|
+
}, Ve = (t) => {
|
|
334
|
+
const { target: e = "#main", label: l = "Skip to main content", class: n } = t;
|
|
335
|
+
return /* @__PURE__ */ a("a", { href: e, class: h(we.skip, n), children: l });
|
|
336
|
+
}, xe = "_table_roeo7_1", ye = {
|
|
337
|
+
table: xe
|
|
338
|
+
}, Je = (t) => {
|
|
339
|
+
const { headers: e, data: l, class: n } = t;
|
|
340
|
+
return /* @__PURE__ */ _("table", { class: h(ye.table, n), children: [
|
|
341
|
+
/* @__PURE__ */ a("thead", { children: /* @__PURE__ */ a("tr", { children: e.map((s, c) => /* @__PURE__ */ a("th", { scope: "col", children: s }, `${s}-${c}`)) }) }),
|
|
342
|
+
/* @__PURE__ */ a("tbody", { children: l.map((s, c) => /* @__PURE__ */ a("tr", { children: s.map((o, d) => /* @__PURE__ */ a("td", { children: o }, `${e[d]}-${c}-${d}`)) }, c)) })
|
|
343
|
+
] });
|
|
344
|
+
}, ke = "_wrapper_1kyv1_1", $e = "_textarea_1kyv1_6 _text-input_4m0e1_13 _focus-ring_4m0e1_3 _disabled_4m0e1_8", Ne = "_counter_1kyv1_11", k = {
|
|
345
|
+
wrapper: ke,
|
|
346
|
+
textarea: $e,
|
|
347
|
+
counter: Ne
|
|
348
|
+
}, Ke = (t) => {
|
|
349
|
+
const {
|
|
350
|
+
label: e,
|
|
351
|
+
name: l,
|
|
352
|
+
maxChars: n,
|
|
353
|
+
value: s,
|
|
354
|
+
placeholder: c,
|
|
355
|
+
required: o,
|
|
356
|
+
disabled: d,
|
|
357
|
+
onInput: u,
|
|
358
|
+
class: m
|
|
359
|
+
} = t, r = b(), i = `${r}-counter`, p = j(s?.length ?? 0);
|
|
360
|
+
return /* @__PURE__ */ a(g, { label: e, for: r, required: o, class: m, children: /* @__PURE__ */ _("div", { class: k.wrapper, children: [
|
|
361
|
+
/* @__PURE__ */ a(
|
|
362
|
+
"textarea",
|
|
363
|
+
{
|
|
364
|
+
id: r,
|
|
365
|
+
class: k.textarea,
|
|
366
|
+
name: l,
|
|
367
|
+
maxLength: n,
|
|
368
|
+
placeholder: c,
|
|
369
|
+
required: o,
|
|
370
|
+
disabled: d,
|
|
371
|
+
"aria-describedby": i,
|
|
372
|
+
onInput: (f) => {
|
|
373
|
+
const v = f.target.value;
|
|
374
|
+
p.value = v.length, u?.(v);
|
|
375
|
+
},
|
|
376
|
+
children: s
|
|
377
|
+
}
|
|
378
|
+
),
|
|
379
|
+
/* @__PURE__ */ _("span", { id: i, class: k.counter, children: [
|
|
380
|
+
p,
|
|
381
|
+
" / ",
|
|
382
|
+
n
|
|
383
|
+
] })
|
|
384
|
+
] }) });
|
|
385
|
+
}, Ie = "_theme_13mb7_1", Ce = {
|
|
386
|
+
theme: Ie
|
|
387
|
+
}, Qe = (t) => {
|
|
388
|
+
const { children: e, class: l } = t;
|
|
389
|
+
return /* @__PURE__ */ a("div", { class: h(Ce.theme, l), children: e });
|
|
390
|
+
}, qe = "_hidden_19nib_1 _visually-hidden_4m0e1_36", Se = {
|
|
391
|
+
hidden: qe
|
|
392
|
+
}, Xe = (t) => {
|
|
393
|
+
const { children: e } = t;
|
|
394
|
+
return /* @__PURE__ */ a("span", { class: Se.hidden, children: e });
|
|
395
|
+
}, Le = $(document.title);
|
|
396
|
+
D(() => {
|
|
397
|
+
document.title = Le.value;
|
|
398
|
+
});
|
|
399
|
+
export {
|
|
400
|
+
I as Button,
|
|
401
|
+
Te as Card,
|
|
402
|
+
De as Checkbox,
|
|
403
|
+
Ee as DownloadLink,
|
|
404
|
+
Be as Form,
|
|
405
|
+
He as Input,
|
|
406
|
+
Oe as Link,
|
|
407
|
+
Re as Nav,
|
|
408
|
+
Ge as NumberInput,
|
|
409
|
+
We as PasswordInput,
|
|
410
|
+
ze as RadioGroup,
|
|
411
|
+
Ae as Route,
|
|
412
|
+
Me as Section,
|
|
413
|
+
Ue as Select,
|
|
414
|
+
Ve as SkipLink,
|
|
415
|
+
Je as Table,
|
|
416
|
+
Ke as Textarea,
|
|
417
|
+
Qe as Theme,
|
|
418
|
+
Xe as VisuallyHidden,
|
|
419
|
+
h as cx,
|
|
420
|
+
F as hash,
|
|
421
|
+
N as location,
|
|
422
|
+
Z as navigate,
|
|
423
|
+
Le as title
|
|
424
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Button}. */
|
|
4
|
+
interface IButtonProps extends IBaseProps {
|
|
5
|
+
/** Visible button text. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Click handler. */
|
|
8
|
+
onClick?: () => void;
|
|
9
|
+
/** HTML button type. Defaults to `'button'`. */
|
|
10
|
+
type?: 'button' | 'submit' | 'reset';
|
|
11
|
+
/** Whether the button is disabled. */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Standard button with configurable type and click handler. */
|
|
15
|
+
declare const Button: FunctionComponent<IButtonProps>;
|
|
16
|
+
export default Button;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Card}. */
|
|
4
|
+
interface ICardProps extends IBaseProps {
|
|
5
|
+
/** Card body content. */
|
|
6
|
+
children: ComponentChildren;
|
|
7
|
+
}
|
|
8
|
+
/** Visual surface container. Consumers provide their own headings as children. */
|
|
9
|
+
declare const Card: FunctionComponent<ICardProps>;
|
|
10
|
+
export default Card;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Checkbox}. */
|
|
4
|
+
interface ICheckboxProps extends IFieldProps {
|
|
5
|
+
/** Whether the checkbox is checked. */
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
/** Called with the new checked state on change. */
|
|
8
|
+
onChange?: (checked: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
/** Checkbox with label. Layout: input before label, no colon suffix. */
|
|
11
|
+
declare const Checkbox: FunctionComponent<ICheckboxProps>;
|
|
12
|
+
export default Checkbox;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link DownloadLink}. */
|
|
4
|
+
interface IDownloadLinkProps extends IBaseProps {
|
|
5
|
+
/** URL of the file to download. */
|
|
6
|
+
href: string;
|
|
7
|
+
/** Filename for the downloaded file. */
|
|
8
|
+
fileName: string;
|
|
9
|
+
/** Visible link text. */
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
/** Download link using `<a download>` for file downloads. */
|
|
13
|
+
declare const DownloadLink: FunctionComponent<IDownloadLinkProps>;
|
|
14
|
+
export default DownloadLink;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Form}. */
|
|
4
|
+
interface IFormProps extends IBaseProps {
|
|
5
|
+
/** Called with FormData when the form is submitted. */
|
|
6
|
+
onSubmit: (data: FormData) => void;
|
|
7
|
+
/** Label for the submit button. Defaults to `'Submit'`. */
|
|
8
|
+
submitLabel?: string;
|
|
9
|
+
/** Label for the optional reset button. Omit to hide. */
|
|
10
|
+
resetLabel?: string;
|
|
11
|
+
/** Form field children. */
|
|
12
|
+
children: ComponentChildren;
|
|
13
|
+
}
|
|
14
|
+
/** Form with submit/reset buttons. Prevents default and provides FormData. */
|
|
15
|
+
declare const Form: FunctionComponent<IFormProps>;
|
|
16
|
+
export default Form;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link FormField}. */
|
|
4
|
+
interface IFormFieldProps extends IBaseProps {
|
|
5
|
+
/** Visible label text. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** ID of the input element this label is for. */
|
|
8
|
+
for: string;
|
|
9
|
+
/** Whether the field shows a required indicator. Accepts `undefined` for prop forwarding. */
|
|
10
|
+
required?: boolean | undefined;
|
|
11
|
+
/** Field input element(s). */
|
|
12
|
+
children: ComponentChildren;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Internal layout component for form fields.
|
|
16
|
+
* Renders a CSS Grid row with label (colon suffix) and input.
|
|
17
|
+
*/
|
|
18
|
+
declare const FormField: FunctionComponent<IFormFieldProps>;
|
|
19
|
+
export default FormField;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Input types supported by the {@link Input} component. */
|
|
4
|
+
export type InputType = 'text' | 'email' | 'url' | 'tel' | 'date' | 'time' | 'datetime-local';
|
|
5
|
+
/** Props for {@link Input}. */
|
|
6
|
+
interface IInputProps extends IFieldProps {
|
|
7
|
+
/** HTML input type. Defaults to `'text'`. */
|
|
8
|
+
type?: InputType;
|
|
9
|
+
/** Current input value. */
|
|
10
|
+
value?: string;
|
|
11
|
+
/** Placeholder text. */
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
/** Maximum character length. */
|
|
14
|
+
maxLength?: number;
|
|
15
|
+
/** Autocomplete hint. Defaults automatically for `email`, `tel`, and `url` types. */
|
|
16
|
+
autocomplete?: string;
|
|
17
|
+
/** Whether the field is read-only (focusable, submitted, copyable — distinct from disabled). */
|
|
18
|
+
readOnly?: boolean;
|
|
19
|
+
/** Validation pattern (regex string). */
|
|
20
|
+
pattern?: string;
|
|
21
|
+
/** Called with the new value on input. */
|
|
22
|
+
onInput?: (value: string) => void;
|
|
23
|
+
}
|
|
24
|
+
/** Text input with label, wrapped in FormField for layout. */
|
|
25
|
+
declare const Input: FunctionComponent<IInputProps>;
|
|
26
|
+
export default Input;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Link}. */
|
|
4
|
+
interface ILinkProps extends IBaseProps {
|
|
5
|
+
/** URL to navigate to. */
|
|
6
|
+
href: string;
|
|
7
|
+
/** Link content. */
|
|
8
|
+
children: ComponentChildren;
|
|
9
|
+
/** Force external behavior (same tab, rel attributes). */
|
|
10
|
+
external?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Link that auto-detects internal vs external URLs.
|
|
14
|
+
* Internal links use the routing signal's `navigate()`.
|
|
15
|
+
* External links render a plain `<a>` in the same tab.
|
|
16
|
+
*/
|
|
17
|
+
declare const Link: FunctionComponent<ILinkProps>;
|
|
18
|
+
export default Link;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Nav}. */
|
|
4
|
+
interface INavProps extends IBaseProps {
|
|
5
|
+
/** Optional title shown as a heading above the nav. */
|
|
6
|
+
title?: string;
|
|
7
|
+
/** Navigation links. */
|
|
8
|
+
children: ComponentChildren;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Semantic `<nav>` wrapper with optional title heading.
|
|
12
|
+
* When a title is provided, `aria-labelledby` links the landmark to the heading.
|
|
13
|
+
*/
|
|
14
|
+
declare const Nav: FunctionComponent<INavProps>;
|
|
15
|
+
export default Nav;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link NumberInput}. */
|
|
4
|
+
interface INumberInputProps extends IFieldProps {
|
|
5
|
+
/** Minimum allowed value. */
|
|
6
|
+
min?: number;
|
|
7
|
+
/** Maximum allowed value. */
|
|
8
|
+
max?: number;
|
|
9
|
+
/** Step increment. */
|
|
10
|
+
step?: number;
|
|
11
|
+
/** Current numeric value. */
|
|
12
|
+
value?: number;
|
|
13
|
+
/** Placeholder text. */
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
/** Called with the new numeric value on input. Returns `NaN` for empty input. */
|
|
16
|
+
onInput?: (value: number) => void;
|
|
17
|
+
}
|
|
18
|
+
/** Numeric input with label, wrapped in FormField for layout. */
|
|
19
|
+
declare const NumberInput: FunctionComponent<INumberInputProps>;
|
|
20
|
+
export default NumberInput;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link PasswordInput}. */
|
|
4
|
+
interface IPasswordInputProps extends IFieldProps {
|
|
5
|
+
/** Whether this is for the current password or a new one. Drives `autocomplete` automatically. */
|
|
6
|
+
purpose: 'current' | 'new';
|
|
7
|
+
/** Current input value. */
|
|
8
|
+
value?: string;
|
|
9
|
+
/** Placeholder text. */
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
/** Called with the new value on input. */
|
|
12
|
+
onInput?: (value: string) => void;
|
|
13
|
+
}
|
|
14
|
+
/** Password input with show/hide toggle, wrapped in FormField for layout. */
|
|
15
|
+
declare const PasswordInput: FunctionComponent<IPasswordInputProps>;
|
|
16
|
+
export default PasswordInput;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** A single option in a {@link RadioGroup}. */
|
|
4
|
+
export interface IRadioOption {
|
|
5
|
+
/** Visible label text. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Form value when selected. */
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
/** Props for {@link RadioGroup}. */
|
|
11
|
+
interface IRadioGroupProps extends IBaseProps {
|
|
12
|
+
/** Fieldset legend text. */
|
|
13
|
+
legend: string;
|
|
14
|
+
/** Field name attribute for form submission. */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Available radio options. */
|
|
17
|
+
options: IRadioOption[];
|
|
18
|
+
/** Currently selected value. */
|
|
19
|
+
value?: string;
|
|
20
|
+
/** Whether a selection is required. */
|
|
21
|
+
required?: boolean;
|
|
22
|
+
/** Whether the group is disabled. */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Called with the selected value on change. */
|
|
25
|
+
onChange?: (value: string) => void;
|
|
26
|
+
}
|
|
27
|
+
/** Radio button group inside a fieldset with legend. */
|
|
28
|
+
declare const RadioGroup: FunctionComponent<IRadioGroupProps>;
|
|
29
|
+
export default RadioGroup;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
2
|
+
/** Props for {@link Route}. */
|
|
3
|
+
interface IRouteProps {
|
|
4
|
+
/** URL path pattern. Supports trailing wildcard (`/users/*`). */
|
|
5
|
+
path: string;
|
|
6
|
+
/** Content to render when the route matches. */
|
|
7
|
+
children: ComponentChildren;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Renders children when the current location matches the path pattern.
|
|
11
|
+
* Supports exact matches and trailing wildcard (`/users/*`).
|
|
12
|
+
*/
|
|
13
|
+
declare const Route: FunctionComponent<IRouteProps>;
|
|
14
|
+
export default Route;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Section}. */
|
|
4
|
+
interface ISectionProps extends IBaseProps {
|
|
5
|
+
/** Section heading text. */
|
|
6
|
+
title: string;
|
|
7
|
+
/** Heading level. Defaults to `2`. */
|
|
8
|
+
level?: 2 | 3 | 4 | 5 | 6;
|
|
9
|
+
/** Section body content. */
|
|
10
|
+
children: ComponentChildren;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Semantic `<section>` with configurable heading level (defaults to h2).
|
|
14
|
+
* `aria-labelledby` links the region landmark to its heading.
|
|
15
|
+
*/
|
|
16
|
+
declare const Section: FunctionComponent<ISectionProps>;
|
|
17
|
+
export default Section;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** A single option in a {@link Select}. */
|
|
4
|
+
export interface ISelectOption {
|
|
5
|
+
/** Visible label text. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Form value when selected. */
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
/** A labeled group of options in a {@link Select}. */
|
|
11
|
+
export interface ISelectGroup {
|
|
12
|
+
/** Group label shown as the optgroup heading. */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Options within this group. */
|
|
15
|
+
options: ISelectOption[];
|
|
16
|
+
}
|
|
17
|
+
/** Props for {@link Select}. */
|
|
18
|
+
interface ISelectProps extends IFieldProps {
|
|
19
|
+
/** Current selected value. */
|
|
20
|
+
value?: string;
|
|
21
|
+
/** Placeholder text shown as a disabled first option. Omit to hide. */
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
/** Available options — flat, grouped, or mixed. */
|
|
24
|
+
options: (ISelectOption | ISelectGroup)[];
|
|
25
|
+
/** Called with the new value on change. */
|
|
26
|
+
onChange?: (value: string) => void;
|
|
27
|
+
}
|
|
28
|
+
/** Select dropdown with label, wrapped in FormField for layout. */
|
|
29
|
+
declare const Select: FunctionComponent<ISelectProps>;
|
|
30
|
+
export default Select;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link SkipLink}. */
|
|
4
|
+
interface ISkipLinkProps extends IBaseProps {
|
|
5
|
+
/** Target element ID (including `#`). Defaults to `'#main'`. */
|
|
6
|
+
target?: string;
|
|
7
|
+
/** Visible link text. Defaults to `'Skip to main content'`. */
|
|
8
|
+
label?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Skip navigation link. Hidden until focused via keyboard Tab.
|
|
12
|
+
* Targets `#main` by default.
|
|
13
|
+
*/
|
|
14
|
+
declare const SkipLink: FunctionComponent<ISkipLinkProps>;
|
|
15
|
+
export default SkipLink;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Table}. */
|
|
4
|
+
interface ITableProps extends IBaseProps {
|
|
5
|
+
/** Column header labels. */
|
|
6
|
+
headers: string[];
|
|
7
|
+
/** Row data as a 2D array of renderable content. */
|
|
8
|
+
data: ComponentChildren[][];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Accessible data table with required headers.
|
|
12
|
+
* Headers render as `<th scope="col">`, data auto-formats into `<tbody>`/`<td>`.
|
|
13
|
+
*/
|
|
14
|
+
declare const Table: FunctionComponent<ITableProps>;
|
|
15
|
+
export default Table;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IFieldProps } from '../scripts/types';
|
|
2
|
+
import { FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Textarea}. */
|
|
4
|
+
interface ITextareaProps extends IFieldProps {
|
|
5
|
+
/** Maximum character limit. Sets `maxLength` on the textarea. */
|
|
6
|
+
maxChars: number;
|
|
7
|
+
/** Current textarea value. */
|
|
8
|
+
value?: string;
|
|
9
|
+
/** Placeholder text. */
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
/** Called with the new value on input. */
|
|
12
|
+
onInput?: (value: string) => void;
|
|
13
|
+
}
|
|
14
|
+
/** Textarea with label and character counter, wrapped in FormField for layout. */
|
|
15
|
+
declare const Textarea: FunctionComponent<ITextareaProps>;
|
|
16
|
+
export default Textarea;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IBaseProps } from '../scripts/types';
|
|
2
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
3
|
+
/** Props for {@link Theme}. */
|
|
4
|
+
interface IThemeProps extends IBaseProps {
|
|
5
|
+
/** Content to theme. */
|
|
6
|
+
children: ComponentChildren;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Theme wrapper that scopes `--aui-*` custom properties to its subtree.
|
|
10
|
+
*
|
|
11
|
+
* The consumer defines the custom properties in their own CSS class:
|
|
12
|
+
*
|
|
13
|
+
* ```css
|
|
14
|
+
* .my-theme {
|
|
15
|
+
* --aui-color-text: #1a1a1a;
|
|
16
|
+
* --aui-color-background: #ffffff;
|
|
17
|
+
* --aui-color-primary: #2563eb;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Then wrap your app:
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <Theme class="my-theme">
|
|
25
|
+
* <App />
|
|
26
|
+
* </Theme>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Nestable for sub-themes (e.g. dark mode sections).
|
|
30
|
+
*/
|
|
31
|
+
declare const Theme: FunctionComponent<IThemeProps>;
|
|
32
|
+
export default Theme;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ComponentChildren, FunctionComponent } from 'preact';
|
|
2
|
+
/** Props for {@link VisuallyHidden}. */
|
|
3
|
+
interface IVisuallyHiddenProps {
|
|
4
|
+
/** Content visible to assistive technology only. */
|
|
5
|
+
children: ComponentChildren;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* CSS-only screen-reader utility. Content is hidden visually
|
|
9
|
+
* but remains accessible to assistive technology.
|
|
10
|
+
*/
|
|
11
|
+
declare const VisuallyHidden: FunctionComponent<IVisuallyHiddenProps>;
|
|
12
|
+
export default VisuallyHidden;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { default as Button } from './components/Button';
|
|
2
|
+
export { default as Card } from './components/Card';
|
|
3
|
+
export { default as Checkbox } from './components/Checkbox';
|
|
4
|
+
export { default as DownloadLink } from './components/DownloadLink';
|
|
5
|
+
export { default as Form } from './components/Form';
|
|
6
|
+
export { default as Input } from './components/Input';
|
|
7
|
+
export { default as Link } from './components/Link';
|
|
8
|
+
export { default as Nav } from './components/Nav';
|
|
9
|
+
export { default as NumberInput } from './components/NumberInput';
|
|
10
|
+
export { default as PasswordInput } from './components/PasswordInput';
|
|
11
|
+
export type { IRadioOption } from './components/RadioGroup';
|
|
12
|
+
export { default as RadioGroup } from './components/RadioGroup';
|
|
13
|
+
export { default as Route } from './components/Route';
|
|
14
|
+
export { default as Section } from './components/Section';
|
|
15
|
+
export type { ISelectGroup, ISelectOption } from './components/Select';
|
|
16
|
+
export { default as Select } from './components/Select';
|
|
17
|
+
export { default as SkipLink } from './components/SkipLink';
|
|
18
|
+
export { default as Table } from './components/Table';
|
|
19
|
+
export { default as Textarea } from './components/Textarea';
|
|
20
|
+
export { default as Theme } from './components/Theme';
|
|
21
|
+
export { default as VisuallyHidden } from './components/VisuallyHidden';
|
|
22
|
+
export { cx } from './scripts/utils';
|
|
23
|
+
export { title } from './signals/head';
|
|
24
|
+
export { hash, location, navigate } from './signals/routing';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Base props shared by all components. */
|
|
2
|
+
export interface IBaseProps {
|
|
3
|
+
/** CSS class name for custom styling. Accepts `undefined` for prop forwarding. */
|
|
4
|
+
class?: string | undefined;
|
|
5
|
+
}
|
|
6
|
+
/** Props for form field components that render a label. */
|
|
7
|
+
export interface IFieldProps extends IBaseProps {
|
|
8
|
+
/** Visible label text for the field. */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Field name attribute for form submission. */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Whether the field is required. Adds a visual asterisk to the label. */
|
|
13
|
+
required?: boolean;
|
|
14
|
+
/** Whether the field is disabled. */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combine CSS class names, filtering out falsy values.
|
|
3
|
+
*
|
|
4
|
+
* The type accepts `false` and `undefined` because those are the two falsy
|
|
5
|
+
* values that naturally appear when building class lists:
|
|
6
|
+
*
|
|
7
|
+
* - **`false`** — from the `&&` short-circuit pattern:
|
|
8
|
+
* ```ts
|
|
9
|
+
* cx(styles.button, isActive && styles.active)
|
|
10
|
+
* // ^^^^^^^^^^^^^^^^^^^^^^^^^ → string | false
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* - **`undefined`** — from optional props like `class?`:
|
|
14
|
+
* ```ts
|
|
15
|
+
* cx(styles.card, className)
|
|
16
|
+
* // ^^^^^^^^^ → string | undefined
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Static classes
|
|
21
|
+
* cx(styles.button, styles.primary) // "btn_x1 primary_x2"
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Conditional class via &&
|
|
25
|
+
* cx(styles.button, disabled && styles.disabled)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Forwarding an optional class prop
|
|
29
|
+
* cx(styles.card, props.class)
|
|
30
|
+
*
|
|
31
|
+
* @param classes - Class names to combine. `false` and `undefined` values are
|
|
32
|
+
* filtered out; only truthy strings are joined.
|
|
33
|
+
* @returns Space-separated class string, or empty string if no truthy values.
|
|
34
|
+
*/
|
|
35
|
+
export declare function cx(...classes: (string | false | undefined)[]): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Current URL pathname. */
|
|
2
|
+
export declare const location: import('@preact/signals-core').Signal<string>;
|
|
3
|
+
/** Current URL hash (without the `#` prefix). */
|
|
4
|
+
export declare const hash: import('@preact/signals-core').Signal<string>;
|
|
5
|
+
/**
|
|
6
|
+
* Navigate to a new URL path using the History API.
|
|
7
|
+
* Updates all routing signals accordingly.
|
|
8
|
+
*/
|
|
9
|
+
export declare function navigate(path: string, options?: {
|
|
10
|
+
replace?: boolean;
|
|
11
|
+
}): void;
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@auldrant/ui",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Accessible Preact component library with design tokens and CSS modules",
|
|
6
|
+
"author": "Colonel Jade",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": ["preact", "components", "ui", "component-library", "accessibility", "a11y", "css-modules", "design-tokens", "typescript"],
|
|
9
|
+
"publishConfig": { "access": "public" },
|
|
10
|
+
"module": "./dist/auldrant-ui.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/auldrant-ui.js"
|
|
16
|
+
},
|
|
17
|
+
"./styles": "./dist/auldrant-ui.css"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"**/*.css"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "vite build",
|
|
30
|
+
"check": "biome check .",
|
|
31
|
+
"check:fix": "biome check --fix .",
|
|
32
|
+
"format": "biome format --fix .",
|
|
33
|
+
"lint": "biome lint .",
|
|
34
|
+
"test": "bun test",
|
|
35
|
+
"test:a11y": "bun test tests/a11y/",
|
|
36
|
+
"test:watch": "bun test --watch",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"prepublishOnly": "bun run build",
|
|
39
|
+
"storybook": "storybook dev -p 6006",
|
|
40
|
+
"build-storybook": "storybook build",
|
|
41
|
+
"prepare": "test -n \"$CI\" || lefthook install"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@biomejs/biome": "^2.4.4",
|
|
45
|
+
"@happy-dom/global-registrator": "^20.7.0",
|
|
46
|
+
"@preact/preset-vite": "^2.10.3",
|
|
47
|
+
"@preact/signals": "^2.8.1",
|
|
48
|
+
"@storybook/preact-vite": "^10.2.10",
|
|
49
|
+
"@testing-library/preact": "^3.2.4",
|
|
50
|
+
"@types/bun": "latest",
|
|
51
|
+
"axe-core": "^4.11.1",
|
|
52
|
+
"lefthook": "^2.1.1",
|
|
53
|
+
"preact": "^10.28.4",
|
|
54
|
+
"storybook": "^10.2.10",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"vite": "^7.3.1",
|
|
57
|
+
"vite-plugin-dts": "^4.5.4"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@preact/signals": "^2.8.1",
|
|
61
|
+
"preact": "^10.28.4"
|
|
62
|
+
}
|
|
63
|
+
}
|