@luisrodonccs/simplest-ui 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +163 -3
- package/components.manifest.json +54 -0
- package/dist/accordion.js +96 -0
- package/dist/base.css +1 -0
- package/dist/chunks/a11y-BYNN9rH7.js +59 -0
- package/dist/chunks/position-BdzQ8shu.js +7 -0
- package/dist/components/accordion.css +1 -0
- package/dist/components/accordion.d.ts +29 -0
- package/dist/components/accordion.d.ts.map +1 -0
- package/dist/components/alert.css +1 -0
- package/dist/components/avatar.css +1 -0
- package/dist/components/badge.css +1 -0
- package/dist/components/button.css +1 -0
- package/dist/components/card.css +1 -0
- package/dist/components/checkbox.css +1 -0
- package/dist/components/drawer.d.ts +38 -0
- package/dist/components/drawer.d.ts.map +1 -0
- package/dist/components/dropdown.d.ts +39 -0
- package/dist/components/dropdown.d.ts.map +1 -0
- package/dist/components/empty-state.css +1 -0
- package/dist/components/index.d.ts +17 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/input.css +1 -0
- package/dist/components/internal/a11y.d.ts +20 -0
- package/dist/components/internal/a11y.d.ts.map +1 -0
- package/dist/components/internal/position.d.ts +12 -0
- package/dist/components/internal/position.d.ts.map +1 -0
- package/dist/components/modal.d.ts +40 -0
- package/dist/components/modal.d.ts.map +1 -0
- package/dist/components/nav.css +1 -0
- package/dist/components/popover.css +1 -0
- package/dist/components/popover.d.ts +30 -0
- package/dist/components/popover.d.ts.map +1 -0
- package/dist/components/progress.css +1 -0
- package/dist/components/radio.css +1 -0
- package/dist/components/select.css +1 -0
- package/dist/components/skeleton.css +1 -0
- package/dist/components/spinner.css +1 -0
- package/dist/components/stat.css +1 -0
- package/dist/components/switch.css +1 -0
- package/dist/components/table.css +1 -0
- package/dist/components/tabs.d.ts +30 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/textarea.css +1 -0
- package/dist/components/toast.css +1 -0
- package/dist/components/toast.d.ts +31 -0
- package/dist/components/toast.d.ts.map +1 -0
- package/dist/components/tooltip.css +1 -0
- package/dist/components/tooltip.d.ts +15 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/components/topbar.css +1 -0
- package/dist/components.css +1 -0
- package/dist/components.js +19 -0
- package/dist/drawer.js +182 -0
- package/dist/dropdown.js +278 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/modal.js +199 -0
- package/dist/popover.js +83 -0
- package/dist/reset.css +1 -0
- package/dist/styles.css +1 -0
- package/dist/tabs.js +253 -0
- package/dist/toast.js +61 -0
- package/dist/tokens.css +1 -0
- package/dist/tooltip.js +27 -0
- package/package.json +138 -6
- package/skills/simplest-ui/INSTALL.md +46 -0
- package/skills/simplest-ui/SKILL.md +62 -0
- package/skills/simplest-ui/evals/README.md +20 -0
- package/skills/simplest-ui/evals/RESULTS.md +23 -0
- package/skills/simplest-ui/evals/evals.json +23 -0
- package/skills/simplest-ui/references/authoring.md +18 -0
- package/skills/simplest-ui/references/catalog.md +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luis Rodríguez
|
|
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
CHANGED
|
@@ -1,3 +1,163 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Simplest UI
|
|
2
|
+
|
|
3
|
+
Framework-agnostic design system with CSS tokens, semantic components, layouts, and accessible Web Components.
|
|
4
|
+
|
|
5
|
+
> `v0.1.0` is the next public release. See [ROADMAP.md](./ROADMAP.md) for planned work, [CHANGELOG.md](./CHANGELOG.md) for release history, and [VERSIONING.md](./VERSIONING.md) for the release policy.
|
|
6
|
+
|
|
7
|
+
Browse the visual documentation at [luisrodonccs.github.io/simplest-ui](https://luisrodonccs.github.io/simplest-ui/).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @luisrodonccs/simplest-ui
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import "@luisrodonccs/simplest-ui/tokens.css";
|
|
17
|
+
import "@luisrodonccs/simplest-ui/styles.css";
|
|
18
|
+
import "@luisrodonccs/simplest-ui/components.js";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For one interactive element only:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import "@luisrodonccs/simplest-ui/components/drawer";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## CSS entrypoints
|
|
28
|
+
|
|
29
|
+
| Entrypoint | Purpose |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `tokens.css` | Color, spacing, typography, radius, shadow, motion, and effect tokens. |
|
|
32
|
+
| `reset.css` | Optional global reset. |
|
|
33
|
+
| `base.css` | Base typography, utilities, and layouts. |
|
|
34
|
+
| `components.css` | Component classes without a global reset. |
|
|
35
|
+
| `styles.css` | Complete bundle ordered in `sui.reset`, `sui.base`, and `sui.components` layers. |
|
|
36
|
+
|
|
37
|
+
Every CSS component is also available as an individual import. Import `tokens.css` first; add `base.css` only when you need its typography, utilities, or layouts.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import "@luisrodonccs/simplest-ui/tokens.css";
|
|
41
|
+
import "@luisrodonccs/simplest-ui/components/button.css";
|
|
42
|
+
import "@luisrodonccs/simplest-ui/components/card.css";
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This is suitable for vanilla applications and Laravel Blade projects built with Vite. The package uses `ui-` CSS classes, `sui-` custom-element names, and `--sui-` tokens.
|
|
46
|
+
|
|
47
|
+
## CSS components
|
|
48
|
+
|
|
49
|
+
Use semantic HTML with `ui-*` classes. Cards, tables, alerts, avatars, progress indicators, form controls, and layouts are CSS components rather than custom elements.
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<article class="ui-card ui-card--glass">
|
|
53
|
+
<h2 class="ui-card__title">Project summary</h2>
|
|
54
|
+
<p class="ui-card__body">A semantic card component.</p>
|
|
55
|
+
</article>
|
|
56
|
+
|
|
57
|
+
<div class="ui-table-wrap" role="region" aria-label="Users" tabindex="0">
|
|
58
|
+
<table class="ui-table">...</table>
|
|
59
|
+
</div>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Web Components
|
|
63
|
+
|
|
64
|
+
| Element | Import | Highlights |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| `<sui-modal>` | `components/modal` | Focus trap, scroll lock, Escape, focus restoration. |
|
|
67
|
+
| `<sui-drawer>` | `components/drawer` | Accessible modal side panel. |
|
|
68
|
+
| `<sui-dropdown>` | `components/dropdown` | Action menu and keyboard navigation. |
|
|
69
|
+
| `<sui-tabs>` | `components/tabs` | Arrow-key tab navigation. |
|
|
70
|
+
| `<sui-accordion>` | `components/accordion` | Single or multiple disclosure panels. |
|
|
71
|
+
| `<sui-popover>` | `components/popover` | Contextual dialog and viewport placement. |
|
|
72
|
+
| `<sui-tooltip>` | `components/tooltip` | Automatic `aria-describedby`. |
|
|
73
|
+
| `<sui-toast>` | `components/toast` | Live announcements and `SuiToast.show()`. |
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<sui-drawer label="Filters" close-label="Close filters">
|
|
77
|
+
<span slot="title">Filters</span>
|
|
78
|
+
<p>Adjust the current result set.</p>
|
|
79
|
+
<div slot="footer"><button class="ui-button" type="button">Apply</button></div>
|
|
80
|
+
</sui-drawer>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Interactive components expose `sui-*` custom events and include keyboard behavior, ARIA relationships, visible focus, and reduced-motion support.
|
|
84
|
+
|
|
85
|
+
## Theme
|
|
86
|
+
|
|
87
|
+
Override semantic tokens to adapt the full system:
|
|
88
|
+
|
|
89
|
+
```css
|
|
90
|
+
:root {
|
|
91
|
+
--sui-color-primary: #7c3aed;
|
|
92
|
+
--sui-radius-lg: 0.75rem;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Use `<html data-theme="dark">` to apply the built-in dark token mapping.
|
|
97
|
+
|
|
98
|
+
## Support
|
|
99
|
+
|
|
100
|
+
| Area | Support |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| Browsers | Chrome, Edge, Firefox, and Safari, last two versions; current Chrome Android and Safari iOS. |
|
|
103
|
+
| Environments | Vanilla HTML/JavaScript and Laravel Blade with Vite. |
|
|
104
|
+
| Rendering | CSS during SSR; Web Components in the client bundle. |
|
|
105
|
+
| Accessibility | WCAG 2.2 AA target; no `critical` or `serious` Axe violations. |
|
|
106
|
+
|
|
107
|
+
React, Vue, Bootstrap, and Tailwind integration are not validated for `0.1.0`. See [SUPPORT.md](./SUPPORT.md) for the complete policy, including SSR and known limitations.
|
|
108
|
+
|
|
109
|
+
## Documentation
|
|
110
|
+
|
|
111
|
+
The visual documentation lives in `docs/` and supports English and Spanish. It covers every public CSS component, Web Component, layout, token category, and example page.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run docs:dev
|
|
115
|
+
npm run docs:build
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The Dashboard page is available at `docs/pages/dashboard.html` while running the documentation server.
|
|
119
|
+
|
|
120
|
+
## Agent skill
|
|
121
|
+
|
|
122
|
+
`skills/simplest-ui` is a versioned Agent Skill. It guides agents to inspect `components.manifest.json`, reuse existing primitives first, and only extend the system when composition is insufficient. It is included in the npm package but is not activated automatically. See the [installation guide](./skills/simplest-ui/INSTALL.md) for OpenCode, Claude Code, and other Agent Skills clients.
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
Unit and component tests use Vitest:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npm test
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
End-to-end tests use Playwright and Axe across Chromium, Firefox, and WebKit. They cover documentation navigation, component keyboard and focus behavior, the 320px responsive floor, Axe audits in light and dark themes, and the vanilla and Laravel/Vite consumer fixtures.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run test:e2e:install # first run only
|
|
136
|
+
npm run test:e2e
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`npm run test:e2e` builds the package before starting the suite. Tests fail on any `critical` or `serious` Axe violation.
|
|
140
|
+
|
|
141
|
+
Visual regression tests compare documentation and dashboard screenshots in light and dark themes at desktop and 320px widths. Baselines are stored with the `-win32` suffix and generated on Windows to match the dedicated CI job.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm run test:visual
|
|
145
|
+
npm run test:visual:update # after an intentional visual change
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npm run typecheck
|
|
152
|
+
npm test
|
|
153
|
+
npm run build
|
|
154
|
+
npm run test:consumer
|
|
155
|
+
npm run docs:build
|
|
156
|
+
npm pack --dry-run
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`npm run build` validates every package export. `npm run test:consumer` bundles the Laravel/Vite and SSR fixtures. `npm run docs:build` verifies that every manifest entry has a visual documentation entry. CI runs these checks plus the Playwright suite.
|
|
160
|
+
|
|
161
|
+
## Contributing
|
|
162
|
+
|
|
163
|
+
Read [CONTRIBUTING.md](./CONTRIBUTING.md). Contributions must preserve the token system, prefixes, semantic HTML, accessibility, tests, manifest coverage, and visual documentation.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Simplest UI",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"prefixes": { "customElement": "sui-", "cssClass": "ui-", "token": "--sui-" },
|
|
5
|
+
"cssEntrypoints": {
|
|
6
|
+
"tokens": "@luisrodonccs/simplest-ui/tokens.css",
|
|
7
|
+
"reset": "@luisrodonccs/simplest-ui/reset.css",
|
|
8
|
+
"base": "@luisrodonccs/simplest-ui/base.css",
|
|
9
|
+
"components": "@luisrodonccs/simplest-ui/components.css",
|
|
10
|
+
"all": "@luisrodonccs/simplest-ui/styles.css"
|
|
11
|
+
},
|
|
12
|
+
"webComponents": [
|
|
13
|
+
{ "tag": "sui-modal", "documentationId": "modal", "import": "@luisrodonccs/simplest-ui/components/modal", "attributes": ["open", "label", "close-label", "disable-backdrop-close"], "slots": ["title", "default", "footer"], "events": ["sui-open", "sui-close"], "keyboard": ["Escape", "focus trap"] },
|
|
14
|
+
{ "tag": "sui-drawer", "documentationId": "drawer", "import": "@luisrodonccs/simplest-ui/components/drawer", "attributes": ["open", "label", "close-label", "disable-backdrop-close"], "slots": ["title", "default", "footer"], "events": ["sui-open", "sui-close"], "keyboard": ["Escape", "focus trap"] },
|
|
15
|
+
{ "tag": "sui-dropdown", "documentationId": "dropdown", "import": "@luisrodonccs/simplest-ui/components/dropdown", "attributes": ["open"], "slots": ["trigger", "default"], "events": ["sui-open", "sui-close", "sui-toggle", "sui-select"], "keyboard": ["ArrowUp", "ArrowDown", "Home", "End", "Enter", "Space", "Escape", "Tab"] },
|
|
16
|
+
{ "tag": "sui-tabs", "documentationId": "tabs", "import": "@luisrodonccs/simplest-ui/components/tabs", "attributes": ["value"], "slots": ["default"], "events": ["sui-change"], "keyboard": ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"] },
|
|
17
|
+
{ "tag": "sui-accordion", "documentationId": "accordion", "import": "@luisrodonccs/simplest-ui/components/accordion", "attributes": ["multiple"], "slots": ["default"], "events": ["sui-change"], "keyboard": ["ArrowUp", "ArrowDown", "Home", "End"] },
|
|
18
|
+
{ "tag": "sui-popover", "documentationId": "popover", "import": "@luisrodonccs/simplest-ui/components/popover", "attributes": ["open", "label"], "slots": ["trigger", "content"], "events": ["sui-open", "sui-close"], "keyboard": ["ArrowDown", "Enter", "Space", "Escape", "Tab"] },
|
|
19
|
+
{ "tag": "sui-tooltip", "documentationId": "tooltip", "import": "@luisrodonccs/simplest-ui/components/tooltip", "attributes": ["content"], "slots": ["trigger", "content"], "events": [], "keyboard": ["focus"] },
|
|
20
|
+
{ "tag": "sui-toast", "documentationId": "toast", "import": "@luisrodonccs/simplest-ui/components/toast", "attributes": ["title", "message", "variant", "duration"], "slots": ["default"], "events": ["sui-dismiss"], "keyboard": [], "api": ["SuiToast.show({ title, message, variant, duration })"] }
|
|
21
|
+
],
|
|
22
|
+
"cssComponents": [
|
|
23
|
+
{ "name": "button", "documentationId": "button", "classes": ["ui-button", "ui-button--primary", "ui-button--danger", "ui-button--ghost", "ui-button--sm"] },
|
|
24
|
+
{ "name": "input-field", "documentationId": "input-field", "classes": ["ui-field", "ui-label", "ui-help", "ui-error", "ui-input", "ui-input--invalid"] },
|
|
25
|
+
{ "name": "textarea", "documentationId": "textarea", "classes": ["ui-textarea", "ui-textarea--invalid"] },
|
|
26
|
+
{ "name": "select", "documentationId": "select", "classes": ["ui-select", "ui-select--invalid"] },
|
|
27
|
+
{ "name": "checkbox", "documentationId": "checkbox", "classes": ["ui-checkbox", "ui-checkbox--disabled"] },
|
|
28
|
+
{ "name": "radio", "documentationId": "radio", "classes": ["ui-radio", "ui-radio-group"] },
|
|
29
|
+
{ "name": "switch", "documentationId": "switch", "classes": ["ui-switch", "ui-switch__track"] },
|
|
30
|
+
{ "name": "card", "documentationId": "card", "classes": ["ui-card", "ui-card--raised", "ui-card--glass", "ui-card__header", "ui-card__title", "ui-card__body", "ui-card__footer"] },
|
|
31
|
+
{ "name": "badge-chip", "documentationId": "badge-chip", "classes": ["ui-badge", "ui-badge--primary", "ui-badge--success", "ui-badge--warning", "ui-badge--danger", "ui-badge--info", "ui-badge--outline", "ui-chip"] },
|
|
32
|
+
{ "name": "alert", "documentationId": "alert", "classes": ["ui-alert", "ui-alert--success", "ui-alert--warning", "ui-alert--danger", "ui-alert--info"] },
|
|
33
|
+
{ "name": "spinner", "documentationId": "spinner", "classes": ["ui-spinner", "ui-spinner--sm", "ui-spinner--lg"] },
|
|
34
|
+
{ "name": "skeleton", "documentationId": "skeleton", "classes": ["ui-skeleton", "ui-skeleton--text", "ui-skeleton--title", "ui-skeleton--avatar", "ui-skeleton--block"] },
|
|
35
|
+
{ "name": "progress", "documentationId": "progress", "classes": ["ui-progress", "ui-progress__bar", "ui-progress--indeterminate"] },
|
|
36
|
+
{ "name": "table", "documentationId": "table", "classes": ["ui-table-wrap", "ui-table"] },
|
|
37
|
+
{ "name": "avatar", "documentationId": "avatar", "classes": ["ui-avatar", "ui-avatar--sm", "ui-avatar--lg", "ui-avatar-group"] },
|
|
38
|
+
{ "name": "stat", "documentationId": "stat", "classes": ["ui-stat", "ui-stat__label", "ui-stat__value", "ui-stat__hint"] },
|
|
39
|
+
{ "name": "empty-state", "documentationId": "empty-state", "classes": ["ui-empty", "ui-empty__title", "ui-empty__body"] },
|
|
40
|
+
{ "name": "nav", "documentationId": "nav", "classes": ["ui-nav", "ui-nav__item", "ui-nav__item--active", "ui-nav__group-title"] },
|
|
41
|
+
{ "name": "topbar", "documentationId": "topbar", "classes": ["ui-topbar", "ui-topbar__brand", "ui-topbar__mark", "ui-topbar__controls", "ui-topbar--glass"] }
|
|
42
|
+
],
|
|
43
|
+
"layouts": [
|
|
44
|
+
{ "name": "container", "documentationId": "container", "classes": ["ui-container"] },
|
|
45
|
+
{ "name": "stack", "documentationId": "stack", "classes": ["ui-stack"] },
|
|
46
|
+
{ "name": "cluster", "documentationId": "cluster", "classes": ["ui-cluster"] },
|
|
47
|
+
{ "name": "grid", "documentationId": "grid", "classes": ["ui-grid", "ui-grid--auto"] },
|
|
48
|
+
{ "name": "app-shell", "documentationId": "app-shell", "classes": ["ui-app-shell", "ui-app-shell--contained", "ui-app-shell__sidebar", "ui-app-shell__header", "ui-app-shell__main"] },
|
|
49
|
+
{ "name": "skip-link", "documentationId": "skip-link", "classes": ["ui-skip-link"] }
|
|
50
|
+
],
|
|
51
|
+
"pages": [
|
|
52
|
+
{ "name": "dashboard", "documentationId": "dashboard", "path": "docs/pages/dashboard.html" }
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const o = ".ui-accordion__item", a = ".ui-accordion__trigger";
|
|
2
|
+
class c extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments), this.suppressEvents = !1, this.observer = new MutationObserver(() => this.upgradeItems()), this.handleClick = (e) => {
|
|
5
|
+
const s = e.target.closest(a);
|
|
6
|
+
if (!s || !this.contains(s) || s.disabled) return;
|
|
7
|
+
const t = s.closest(o);
|
|
8
|
+
t != null && t.hasAttribute("disabled") || t && this.toggle(t);
|
|
9
|
+
}, this.handleKeydown = (e) => {
|
|
10
|
+
const s = e.target.closest(a);
|
|
11
|
+
if (!s) return;
|
|
12
|
+
const t = this.triggers, i = t.indexOf(s);
|
|
13
|
+
if (i < 0) return;
|
|
14
|
+
let r;
|
|
15
|
+
switch (e.key) {
|
|
16
|
+
case "ArrowDown":
|
|
17
|
+
r = t[(i + 1) % t.length];
|
|
18
|
+
break;
|
|
19
|
+
case "ArrowUp":
|
|
20
|
+
r = t[(i - 1 + t.length) % t.length];
|
|
21
|
+
break;
|
|
22
|
+
case "Home":
|
|
23
|
+
r = t[0];
|
|
24
|
+
break;
|
|
25
|
+
case "End":
|
|
26
|
+
r = t[t.length - 1];
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
e.preventDefault(), r == null || r.focus();
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
static get observedAttributes() {
|
|
35
|
+
return ["multiple"];
|
|
36
|
+
}
|
|
37
|
+
get multiple() {
|
|
38
|
+
return this.hasAttribute("multiple");
|
|
39
|
+
}
|
|
40
|
+
connectedCallback() {
|
|
41
|
+
this.classList.add("ui-accordion"), this.setAttribute("role", "presentation"), this.upgradeItems(), this.observer.observe(this, { childList: !0, subtree: !0 }), queueMicrotask(() => this.upgradeItems()), this.addEventListener("click", this.handleClick), this.addEventListener("keydown", this.handleKeydown);
|
|
42
|
+
}
|
|
43
|
+
disconnectedCallback() {
|
|
44
|
+
this.observer.disconnect(), this.removeEventListener("click", this.handleClick), this.removeEventListener("keydown", this.handleKeydown);
|
|
45
|
+
}
|
|
46
|
+
attributeChangedCallback() {
|
|
47
|
+
this.isConnected && this.ensureSingleOpen();
|
|
48
|
+
}
|
|
49
|
+
get items() {
|
|
50
|
+
return Array.from(this.children).filter(
|
|
51
|
+
(e) => e instanceof HTMLElement && e.matches(o)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
get triggers() {
|
|
55
|
+
return this.items.map((e) => e.querySelector(a)).filter((e) => !!e && !e.disabled);
|
|
56
|
+
}
|
|
57
|
+
upgradeItems() {
|
|
58
|
+
this.suppressEvents = !0, this.items.forEach((e, s) => {
|
|
59
|
+
var n;
|
|
60
|
+
const t = e.querySelector(a), i = e.querySelector(".ui-accordion__content");
|
|
61
|
+
if (!t || !i) return;
|
|
62
|
+
t.type = "button", i.id || (i.id = `sui-accordion-panel-${((n = crypto.randomUUID) == null ? void 0 : n.call(crypto)) ?? `${Date.now()}-${s}`}`), t.id || (t.id = `sui-accordion-trigger-${i.id}`), t.setAttribute("aria-controls", i.id), i.setAttribute("role", "region"), i.setAttribute("aria-labelledby", t.id);
|
|
63
|
+
const r = e.hasAttribute("disabled") || t.disabled;
|
|
64
|
+
t.disabled = r, r ? t.setAttribute("aria-disabled", "true") : t.removeAttribute("aria-disabled"), this.setItemOpen(e, e.classList.contains("open") && !r, !1);
|
|
65
|
+
}), this.ensureSingleOpen(), this.suppressEvents = !1;
|
|
66
|
+
}
|
|
67
|
+
ensureSingleOpen() {
|
|
68
|
+
if (this.multiple) return;
|
|
69
|
+
const e = this.items.find((s) => s.classList.contains("open"));
|
|
70
|
+
for (const s of this.items)
|
|
71
|
+
s !== e && s.classList.contains("open") && this.setItemOpen(s, !1, !1);
|
|
72
|
+
}
|
|
73
|
+
setItemOpen(e, s, t = !0) {
|
|
74
|
+
const i = e.querySelector(a), r = e.querySelector(".ui-accordion__content");
|
|
75
|
+
!i || !r || (e.classList.toggle("open", s), i.setAttribute("aria-expanded", String(s)), r.hidden = !s, t && !this.suppressEvents && this.dispatchEvent(
|
|
76
|
+
new CustomEvent("sui-change", {
|
|
77
|
+
detail: { open: this.items.filter((n) => n.classList.contains("open")).map((n) => n.id) },
|
|
78
|
+
bubbles: !0,
|
|
79
|
+
composed: !0
|
|
80
|
+
})
|
|
81
|
+
));
|
|
82
|
+
}
|
|
83
|
+
toggle(e) {
|
|
84
|
+
if (e.hasAttribute("disabled")) return;
|
|
85
|
+
const s = e.querySelector(a);
|
|
86
|
+
if (s != null && s.disabled) return;
|
|
87
|
+
const t = !e.classList.contains("open");
|
|
88
|
+
t && !this.multiple && this.items.forEach((i) => {
|
|
89
|
+
i !== e && this.setItemOpen(i, !1, !1);
|
|
90
|
+
}), this.setItemOpen(e, t);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
customElements.get("sui-accordion") || customElements.define("sui-accordion", c);
|
|
94
|
+
export {
|
|
95
|
+
c as SuiAccordion
|
|
96
|
+
};
|
package/dist/base.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
h1,h2,h3,h4,h5,h6{line-height:var(--sui-line-height-tight);font-weight:var(--sui-font-weight-semibold)}*{scrollbar-width:thin;scrollbar-color:var(--sui-scrollbar-thumb) var(--sui-scrollbar-track)}*::-webkit-scrollbar{width:var(--sui-scrollbar-size);height:var(--sui-scrollbar-size)}*::-webkit-scrollbar-track{background:var(--sui-scrollbar-track)}*::-webkit-scrollbar-thumb{background:var(--sui-scrollbar-thumb);border:2px solid transparent;border-radius:var(--sui-radius-full);background-clip:content-box}*::-webkit-scrollbar-thumb:hover{background:var(--sui-scrollbar-thumb-hover);background-clip:content-box}p{margin-bottom:var(--sui-space-3)}a{color:var(--sui-color-primary);text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:var(--sui-font-family-mono)}hr{border:0;border-top:1px solid var(--sui-color-border);margin:var(--sui-space-4) 0}.ui-stack{display:flex;flex-direction:column;gap:var(--ui-stack-gap, var(--sui-space-4))}.ui-cluster{display:flex;flex-wrap:wrap;gap:var(--ui-cluster-gap, var(--sui-space-2));align-items:center}.ui-container{width:100%;max-width:var(--ui-container-max, var(--sui-container-lg));margin-inline:auto;padding-inline:var(--sui-space-4)}.ui-grid{display:grid;gap:var(--ui-grid-gap, var(--sui-space-4));grid-template-columns:repeat(var(--ui-grid-cols, 1),minmax(0,1fr))}.ui-skip-link{position:fixed;top:var(--sui-space-3);left:var(--sui-space-3);z-index:calc(var(--sui-z-toast) + 1);padding:var(--sui-space-2) var(--sui-space-3);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text);background:var(--sui-color-surface-raised);border:1px solid var(--sui-color-border-strong);border-radius:var(--sui-radius-md);box-shadow:var(--sui-shadow-menu);transform:translateY(calc(-100% - var(--sui-space-6)))}.ui-skip-link:focus{transform:translateY(0);text-decoration:none}@media (min-width: 768px){.ui-grid--auto{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}}.ui-app-shell{display:grid;grid-template-columns:var(--sui-sidebar-width) 1fr;min-height:100vh}.ui-app-shell--contained{min-height:400px;border:1px solid var(--sui-color-border);border-radius:var(--sui-radius-xl);overflow:hidden;background:var(--sui-color-surface);backdrop-filter:blur(var(--sui-blur-md));-webkit-backdrop-filter:blur(var(--sui-blur-md));box-shadow:var(--sui-shadow-card)}.ui-app-shell__sidebar{border-right:1px solid var(--sui-color-border);padding:var(--sui-space-4) var(--sui-space-3);background:var(--sui-gradient-sidebar)}.ui-app-shell__brand{margin-bottom:var(--sui-space-3);font-size:var(--sui-font-size-md);font-weight:var(--sui-font-weight-semibold);color:var(--sui-color-text)}.ui-app-shell__content{display:flex;flex-direction:column;min-width:0}.ui-app-shell__header{position:relative;z-index:var(--sui-z-dropdown);border-bottom:1px solid var(--sui-color-border);padding:var(--sui-space-3) var(--sui-space-4-5);background:var(--sui-color-surface-raised);backdrop-filter:blur(var(--sui-blur-sm));-webkit-backdrop-filter:blur(var(--sui-blur-sm));display:flex;align-items:center;justify-content:space-between}.ui-app-shell__title{font-size:var(--sui-font-size-md);font-weight:var(--sui-font-weight-semibold);line-height:var(--sui-line-height-tight)}.ui-app-shell__main{padding:var(--sui-space-4-5);flex:1;display:flex;flex-direction:column;gap:var(--sui-space-3-5)}@media (max-width: 767px){.ui-app-shell{grid-template-columns:1fr}.ui-app-shell__sidebar{border-right:0;border-bottom:1px solid var(--sui-color-border)}}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const c = [
|
|
2
|
+
"button:not([disabled])",
|
|
3
|
+
"a[href]",
|
|
4
|
+
"input:not([disabled])",
|
|
5
|
+
"select:not([disabled])",
|
|
6
|
+
"textarea:not([disabled])",
|
|
7
|
+
"[tabindex]:not([tabindex='-1'])"
|
|
8
|
+
].join(", ");
|
|
9
|
+
function u(t) {
|
|
10
|
+
return t.hasAttribute("disabled") || t.hasAttribute("hidden") || t.getAttribute("aria-hidden") === "true" || t.getAttribute("tabindex") === "-1" ? !1 : t.matches(c);
|
|
11
|
+
}
|
|
12
|
+
function f(t) {
|
|
13
|
+
const o = [], e = (r) => {
|
|
14
|
+
for (const i of Array.from(r.children)) {
|
|
15
|
+
const n = i;
|
|
16
|
+
n.shadowRoot && e(n.shadowRoot), u(n) && o.push(n), e(n);
|
|
17
|
+
}
|
|
18
|
+
}, s = t;
|
|
19
|
+
return s.shadowRoot && e(s.shadowRoot), e(t), o;
|
|
20
|
+
}
|
|
21
|
+
function d() {
|
|
22
|
+
var o;
|
|
23
|
+
let t = document.activeElement;
|
|
24
|
+
for (; (o = t == null ? void 0 : t.shadowRoot) != null && o.activeElement; )
|
|
25
|
+
t = t.shadowRoot.activeElement;
|
|
26
|
+
return t;
|
|
27
|
+
}
|
|
28
|
+
function h(t, o) {
|
|
29
|
+
let e = o;
|
|
30
|
+
for (; e; ) {
|
|
31
|
+
if (e === t) return !0;
|
|
32
|
+
const s = e;
|
|
33
|
+
e = e.parentNode ?? s.host ?? null;
|
|
34
|
+
}
|
|
35
|
+
return !1;
|
|
36
|
+
}
|
|
37
|
+
function b(t, o) {
|
|
38
|
+
const e = f(o);
|
|
39
|
+
if (!e.length) {
|
|
40
|
+
t.preventDefault();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const s = e[0], r = e[e.length - 1], i = d(), n = h(o, i);
|
|
44
|
+
t.shiftKey && (i === s || !n) ? (t.preventDefault(), r.focus()) : !t.shiftKey && (i === r || !n) && (t.preventDefault(), s.focus());
|
|
45
|
+
}
|
|
46
|
+
let l = 0, a = "";
|
|
47
|
+
function w() {
|
|
48
|
+
l++ > 0 || (a = document.body.style.overflow, document.body.style.overflow = "hidden");
|
|
49
|
+
}
|
|
50
|
+
function p() {
|
|
51
|
+
l !== 0 && (l--, l === 0 && (document.body.style.overflow = a));
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
h as c,
|
|
55
|
+
u as i,
|
|
56
|
+
w as l,
|
|
57
|
+
b as t,
|
|
58
|
+
p as u
|
|
59
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
function h(t, e, o = 8) {
|
|
2
|
+
const s = window.innerHeight - t.bottom - o, i = t.top - o, n = e.height > s && i > s ? "top" : "bottom", c = window.innerWidth - t.left - o, d = t.right - e.width >= o, w = e.width > c && d ? "end" : "start";
|
|
3
|
+
return { side: n, align: w };
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
h as c
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-accordion{display:block;border:1px solid var(--sui-color-border);border-radius:var(--sui-radius-lg);overflow:hidden;background:var(--sui-color-surface);backdrop-filter:blur(var(--sui-blur-md));-webkit-backdrop-filter:blur(var(--sui-blur-md))}.ui-accordion__item+.ui-accordion__item{border-top:1px solid var(--sui-color-border)}.ui-accordion__trigger{width:100%;display:flex;align-items:center;justify-content:space-between;padding:var(--sui-space-3) var(--sui-space-4);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text);background:transparent;border:0;cursor:pointer;text-align:left}.ui-accordion__trigger:hover{background:var(--sui-color-surface-muted)}.ui-accordion__trigger:disabled,.ui-accordion__item[aria-disabled=true] .ui-accordion__trigger{opacity:.5;cursor:not-allowed}.ui-accordion__item[aria-disabled=true]{opacity:.6}.ui-accordion__content{padding:0 var(--sui-space-4) var(--sui-space-3);font-size:var(--sui-font-size-sm);color:var(--sui-color-text-muted);display:none}.ui-accordion__item.open .ui-accordion__content{display:block}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progressive accordion controller.
|
|
3
|
+
*
|
|
4
|
+
* The element deliberately keeps its children in the light DOM so the regular
|
|
5
|
+
* `.ui-accordion*` CSS classes remain usable in plain HTML and server views.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SuiAccordion extends HTMLElement {
|
|
8
|
+
private suppressEvents;
|
|
9
|
+
private readonly observer;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
get multiple(): boolean;
|
|
12
|
+
connectedCallback(): void;
|
|
13
|
+
disconnectedCallback(): void;
|
|
14
|
+
attributeChangedCallback(): void;
|
|
15
|
+
private get items();
|
|
16
|
+
private get triggers();
|
|
17
|
+
private upgradeItems;
|
|
18
|
+
private ensureSingleOpen;
|
|
19
|
+
private setItemOpen;
|
|
20
|
+
private toggle;
|
|
21
|
+
private handleClick;
|
|
22
|
+
private handleKeydown;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface HTMLElementTagNameMap {
|
|
26
|
+
"sui-accordion": SuiAccordion;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=accordion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmD;IAE5E,MAAM,KAAK,kBAAkB,aAE5B;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,iBAAiB;IAUjB,oBAAoB;IAMpB,wBAAwB;IAIxB,OAAO,KAAK,KAAK,GAIhB;IAED,OAAO,KAAK,QAAQ,GAInB;IAED,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,WAAW,CAMjB;IAEF,OAAO,CAAC,aAAa,CAkBnB;CACH;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-alert{display:flex;gap:var(--sui-space-3);padding:var(--sui-space-3-5) var(--sui-space-4);border:1px solid transparent;border-left:3px solid var(--sui-color-primary);border-radius:var(--sui-radius-xl);font-size:var(--sui-font-size-sm);backdrop-filter:blur(var(--sui-blur-md));-webkit-backdrop-filter:blur(var(--sui-blur-md))}.ui-alert--success{background:var(--sui-color-success-surface);color:var(--sui-color-success-text);border-color:var(--sui-color-success-border);border-left-color:var(--sui-color-success)}.ui-alert--warning{background:var(--sui-color-warning-surface);color:var(--sui-color-warning-text);border-color:var(--sui-color-warning-border);border-left-color:var(--sui-color-warning)}.ui-alert--danger{background:var(--sui-color-danger-surface);color:var(--sui-color-danger-text);border-color:var(--sui-color-danger-border);border-left-color:var(--sui-color-danger)}.ui-alert--info{background:var(--sui-color-info-surface);color:var(--sui-color-info-text);border-color:var(--sui-color-info-border);border-left-color:var(--sui-color-info)}.ui-alert__title{font-weight:var(--sui-font-weight-semibold);margin-bottom:var(--sui-space-0-5)}.ui-alert__body{opacity:.85}.ui-alert__close{background:transparent;border:0;color:inherit;font-size:var(--sui-font-size-lg);line-height:1;padding:0;opacity:.6}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-avatar{display:inline-flex;align-items:center;justify-content:center;width:var(--sui-avatar-size, 36px);height:var(--sui-avatar-size, 36px);border-radius:var(--sui-radius-full);background:var(--sui-gradient-primary);color:var(--sui-color-primary-contrast);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-semibold);overflow:hidden;flex-shrink:0}.ui-avatar img{width:100%;height:100%;object-fit:cover}.ui-avatar--sm{--sui-avatar-size: 24px;font-size:var(--sui-font-size-3xs)}.ui-avatar--lg{--sui-avatar-size: 48px;font-size:var(--sui-font-size-base)}.ui-avatar-group{display:flex;align-items:center}.ui-avatar-group .ui-avatar{margin-left:calc(var(--sui-space-2) * -1);border:2px solid var(--sui-color-surface-raised)}.ui-avatar-group .ui-avatar:first-child{margin-left:0}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-badge{display:inline-flex;align-items:center;height:var(--sui-badge-height, 22px);padding:0 var(--sui-space-2);font-size:var(--sui-font-size-2xs);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-full);background:var(--sui-color-surface-raised);color:var(--sui-color-text);border:1px solid var(--sui-color-border);backdrop-filter:blur(var(--sui-blur-sm));-webkit-backdrop-filter:blur(var(--sui-blur-sm))}.ui-badge--primary{background:var(--sui-color-info-surface);color:var(--sui-color-primary-text);border-color:transparent}.ui-badge--success{background:var(--sui-color-success-surface);color:var(--sui-color-success-text);border-color:transparent}.ui-badge--warning{background:var(--sui-color-warning-surface);color:var(--sui-color-warning-text);border-color:transparent}.ui-badge--danger{background:var(--sui-color-danger-surface);color:var(--sui-color-danger-text);border-color:transparent}.ui-badge--info{background:var(--sui-color-info-surface);color:var(--sui-color-info-text);border-color:transparent}.ui-badge--outline{background:transparent;color:var(--sui-color-text)}.ui-chip{display:inline-flex;align-items:center;gap:var(--sui-space-1-5);height:var(--sui-chip-height, 26px);padding:0 var(--sui-space-2-5);font-size:var(--sui-font-size-xs);font-weight:var(--sui-font-weight-medium);border-radius:var(--sui-radius-full);background:var(--sui-color-surface-raised);color:var(--sui-color-text-muted);border:1px solid var(--sui-color-border);backdrop-filter:blur(var(--sui-blur-sm));-webkit-backdrop-filter:blur(var(--sui-blur-sm))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--sui-space-1-5);height:var(--sui-control-height-md);padding:0 var(--sui-space-4);font-size:var(--sui-font-size-sm);font-weight:var(--sui-font-weight-medium);line-height:1;border:1px solid var(--sui-color-border);border-radius:var(--sui-radius-full);background:var(--sui-color-surface-raised);color:var(--sui-color-text);backdrop-filter:blur(var(--sui-blur-sm));-webkit-backdrop-filter:blur(var(--sui-blur-sm));transition:background var(--sui-duration-fast) var(--sui-easing-standard),border-color var(--sui-duration-fast) var(--sui-easing-standard),color var(--sui-duration-fast) var(--sui-easing-standard);cursor:pointer}.ui-button:hover,.ui-button:focus-visible{background:var(--sui-color-surface-muted);border-color:var(--sui-color-primary-hover);color:var(--sui-color-text)}.ui-button:active{border-color:var(--sui-color-primary-active)}.ui-button--primary{background:var(--sui-gradient-primary);color:var(--sui-color-primary-contrast);border:0}.ui-button--primary:hover,.ui-button--primary:focus-visible{filter:brightness(1.05);color:var(--sui-color-text);border:1px solid transparent;background-image:linear-gradient(var(--sui-color-surface-raised),var(--sui-color-surface-raised)),var(--sui-gradient-primary);background-origin:border-box;background-clip:padding-box,border-box}.ui-button--primary:active{filter:brightness(.95)}.ui-button--danger{background:var(--sui-color-danger-surface);color:var(--sui-color-danger-text);border-color:var(--sui-color-danger-border)}.ui-button--danger:hover{background:var(--sui-color-danger-surface-hover);border-color:var(--sui-color-danger);color:var(--sui-color-danger-text)}.ui-button--ghost{background:transparent;border-color:transparent}.ui-button--ghost:hover{background:var(--sui-color-surface-muted);border-color:var(--sui-color-border)}.ui-button--sm{height:var(--sui-control-height-sm);padding:0 var(--sui-space-3);font-size:var(--sui-font-size-xs)}.ui-button:disabled{opacity:.5;cursor:not-allowed}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-card{background:var(--sui-color-surface);border:1px solid var(--sui-color-border);border-radius:var(--sui-radius-xl);box-shadow:var(--sui-shadow-card);padding:var(--sui-space-5);backdrop-filter:blur(var(--sui-blur-md));-webkit-backdrop-filter:blur(var(--sui-blur-md));transition:transform var(--sui-duration-normal) var(--sui-easing-standard),box-shadow var(--sui-duration-normal) var(--sui-easing-standard)}.ui-card:hover{transform:translateY(-2px);box-shadow:var(--sui-shadow-card-hover)}.ui-card--raised{background:var(--sui-color-surface-raised)}.ui-card--glass{background:var(--sui-color-surface);backdrop-filter:blur(var(--sui-blur-lg));-webkit-backdrop-filter:blur(var(--sui-blur-lg));box-shadow:var(--sui-shadow-card)}.ui-card--glass:hover{box-shadow:var(--sui-shadow-card-hover)}.ui-card__header{margin-bottom:var(--sui-space-2)}.ui-card__title{font-size:var(--sui-font-size-md);font-weight:var(--sui-font-weight-semibold)}.ui-card__body{color:var(--sui-color-text-muted);font-size:var(--sui-font-size-sm)}.ui-card__footer{margin-top:var(--sui-space-3);padding-top:var(--sui-space-3);border-top:1px solid var(--sui-color-border);display:flex;gap:var(--sui-space-1-5)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-checkbox{display:inline-flex;align-items:center;gap:var(--sui-space-2);font-size:var(--sui-font-size-sm);color:var(--sui-color-text);cursor:pointer;-webkit-user-select:none;user-select:none}.ui-checkbox input{width:var(--sui-check-size);height:var(--sui-check-size);accent-color:var(--sui-color-primary);cursor:pointer}.ui-checkbox--disabled{opacity:.5;cursor:not-allowed}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LitElement, nothing } from "lit";
|
|
2
|
+
import type { PropertyValues } from "lit";
|
|
3
|
+
/**
|
|
4
|
+
* Accessible modal side panel. It keeps its content in light DOM so regular
|
|
5
|
+
* Simplest UI classes can be used inside the title, body and footer slots.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SuiDrawer extends LitElement {
|
|
8
|
+
private static instanceCount;
|
|
9
|
+
private readonly uid;
|
|
10
|
+
private previouslyFocused;
|
|
11
|
+
private holdsScrollLock;
|
|
12
|
+
static styles: import("lit").CSSResult;
|
|
13
|
+
open: boolean;
|
|
14
|
+
/** Accessible name used when no `title` slot content is provided. */
|
|
15
|
+
label: string;
|
|
16
|
+
/** Accessible label for the drawer close button. */
|
|
17
|
+
closeLabel: string;
|
|
18
|
+
/** Set to true to keep the drawer open when its backdrop is clicked. */
|
|
19
|
+
disableBackdropClose: boolean;
|
|
20
|
+
private get titleId();
|
|
21
|
+
private get bodyId();
|
|
22
|
+
protected updated(changed: PropertyValues): void;
|
|
23
|
+
private focusInitial;
|
|
24
|
+
private handleKeydown;
|
|
25
|
+
private handleBackdropClick;
|
|
26
|
+
openDrawer(): void;
|
|
27
|
+
close(): void;
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
disconnectedCallback(): void;
|
|
30
|
+
private releaseScrollLock;
|
|
31
|
+
render(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
32
|
+
}
|
|
33
|
+
declare global {
|
|
34
|
+
interface HTMLElementTagNameMap {
|
|
35
|
+
"sui-drawer": SuiDrawer;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../../src/components/drawer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,OAAO,EAAE,MAAM,KAAK,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAG1C;;;GAGG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IACjD,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,eAAe,CAAS;IAEhC,MAAM,CAAC,MAAM,0BAgFX;IAE0C,IAAI,UAAS;IAEzD,qEAAqE;IACzC,KAAK,SAAM;IAEvC,oDAAoD;IACE,UAAU,SAAW;IAE3E,wEAAwE;IACN,oBAAoB,UAAS;IAE/F,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,MAAM,GAEjB;IAED,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc;IAkBzC,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,aAAa,CAUnB;IAEF,OAAO,CAAC,mBAAmB,CAGzB;IAEF,UAAU;IAIV,KAAK;IAIL,iBAAiB;IAKjB,oBAAoB;IAMpB,OAAO,CAAC,iBAAiB;IAMzB,MAAM;CAyBP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import type { PropertyValues } from "lit";
|
|
3
|
+
export declare class SuiDropdown extends LitElement {
|
|
4
|
+
private static instanceCount;
|
|
5
|
+
private readonly uid;
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
open: boolean;
|
|
8
|
+
private align;
|
|
9
|
+
private side;
|
|
10
|
+
private trigger;
|
|
11
|
+
private menu;
|
|
12
|
+
private startFromEnd;
|
|
13
|
+
private get triggerId();
|
|
14
|
+
private get menuId();
|
|
15
|
+
private get enabledItems();
|
|
16
|
+
private get allItems();
|
|
17
|
+
protected updated(changed: PropertyValues): void;
|
|
18
|
+
private prepareItems;
|
|
19
|
+
private measure;
|
|
20
|
+
private focusItem;
|
|
21
|
+
private setOpen;
|
|
22
|
+
private toggle;
|
|
23
|
+
private handleTriggerClick;
|
|
24
|
+
private handleTriggerKeydown;
|
|
25
|
+
private handleMenuKeydown;
|
|
26
|
+
private handleDocumentClick;
|
|
27
|
+
private handleFocusOut;
|
|
28
|
+
private handleMenuClick;
|
|
29
|
+
private handleSlotChange;
|
|
30
|
+
connectedCallback(): void;
|
|
31
|
+
disconnectedCallback(): void;
|
|
32
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
33
|
+
}
|
|
34
|
+
declare global {
|
|
35
|
+
interface HTMLElementTagNameMap {
|
|
36
|
+
"sui-dropdown": SuiDropdown;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=dropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../src/components/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAK1C,qBACa,WAAY,SAAQ,UAAU;IACzC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+B;IAEnD,MAAM,CAAC,MAAM,0BAuGX;IAE0C,IAAI,UAAS;IAEhD,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAEpB,OAAO,CAAC,OAAO,CAAqB;IACvC,OAAO,CAAC,IAAI,CAAe;IAE3C,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,KAAK,YAAY,GAIvB;IAED,OAAO,KAAK,QAAQ,GAInB;IAED,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc;IAuBzC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,kBAAkB,CAGxB;IAEF,OAAO,CAAC,oBAAoB,CAe1B;IAEF,OAAO,CAAC,iBAAiB,CAgCvB;IAEF,OAAO,CAAC,mBAAmB,CAIzB;IAEF,OAAO,CAAC,cAAc,CAKpB;IAEF,OAAO,CAAC,eAAe,CAarB;IAEF,OAAO,CAAC,gBAAgB,CAEtB;IAEF,iBAAiB;IAQjB,oBAAoB;IAQpB,MAAM;CAgCP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,WAAW,CAAC;KAC7B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--sui-space-10) var(--sui-space-5);color:var(--sui-color-text-muted);background:var(--sui-color-surface);border:1px dashed var(--sui-color-border-strong);border-radius:var(--sui-radius-xl);backdrop-filter:blur(var(--sui-blur-md));-webkit-backdrop-filter:blur(var(--sui-blur-md))}.ui-empty__title{font-size:var(--sui-font-size-base);font-weight:var(--sui-font-weight-semibold);color:var(--sui-color-text);margin-bottom:var(--sui-space-1)}.ui-empty__body{font-size:var(--sui-font-size-sm);max-width:36ch;margin-bottom:var(--sui-space-3)}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import "./modal";
|
|
2
|
+
import "./drawer";
|
|
3
|
+
import "./dropdown";
|
|
4
|
+
import "./tabs";
|
|
5
|
+
import "./accordion";
|
|
6
|
+
import "./popover";
|
|
7
|
+
import "./tooltip";
|
|
8
|
+
import "./toast";
|
|
9
|
+
export { SuiModal } from "./modal";
|
|
10
|
+
export { SuiDrawer } from "./drawer";
|
|
11
|
+
export { SuiDropdown } from "./dropdown";
|
|
12
|
+
export { SuiTabs } from "./tabs";
|
|
13
|
+
export { SuiAccordion } from "./accordion";
|
|
14
|
+
export { SuiPopover } from "./popover";
|
|
15
|
+
export { SuiTooltip } from "./tooltip";
|
|
16
|
+
export { SuiToast, SuiToastContainer } from "./toast";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AACjB,OAAO,UAAU,CAAC;AAClB,OAAO,YAAY,CAAC;AACpB,OAAO,QAAQ,CAAC;AAChB,OAAO,aAAa,CAAC;AACrB,OAAO,WAAW,CAAC;AACnB,OAAO,WAAW,CAAC;AACnB,OAAO,SAAS,CAAC;AAEjB,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ui-input{display:block;width:100%;height:var(--sui-field-height);padding:0 var(--sui-space-3);font-size:var(--sui-font-size-sm);line-height:var(--sui-line-height-normal);color:var(--sui-color-text);background:var(--sui-color-surface-raised);border:1px solid var(--sui-color-border);border-radius:var(--sui-radius-md);backdrop-filter:blur(var(--sui-blur-sm));-webkit-backdrop-filter:blur(var(--sui-blur-sm));transition:border-color var(--sui-duration-fast) var(--sui-easing-standard),box-shadow var(--sui-duration-fast) var(--sui-easing-standard);outline:none}.ui-input::placeholder{color:var(--sui-color-text-subtle)}.ui-input:focus{border-color:var(--sui-color-focus);box-shadow:var(--sui-focus-ring)}.ui-input:disabled{background:var(--sui-color-surface-muted);cursor:not-allowed;opacity:.7}.ui-input--invalid{border-color:var(--sui-color-danger-border)}.ui-input--invalid:focus{box-shadow:0 0 0 3px var(--sui-color-danger-ring)}.ui-label{display:block;margin-bottom:var(--sui-space-1);font-size:var(--sui-font-size-xs);font-weight:var(--sui-font-weight-medium);color:var(--sui-color-text)}.ui-field{margin-bottom:var(--sui-space-3-5)}.ui-help{margin-top:var(--sui-space-1);font-size:var(--sui-font-size-2xs);color:var(--sui-color-text-muted)}.ui-error{margin-top:var(--sui-space-1);font-size:var(--sui-font-size-2xs);color:var(--sui-color-danger)}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** True when the element can receive keyboard focus via normal tabbing. */
|
|
2
|
+
export declare function isFocusable(el: HTMLElement): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Collects focusable elements in DOM order, including the ones living inside
|
|
5
|
+
* nested shadow roots (web components composed inside a dialog, toasts, etc.).
|
|
6
|
+
*/
|
|
7
|
+
export declare function collectFocusable(root: ParentNode): HTMLElement[];
|
|
8
|
+
/** `document.activeElement` resolved through open shadow roots. */
|
|
9
|
+
export declare function getDeepActiveElement(): HTMLElement | null;
|
|
10
|
+
/** `contains` that also traverses shadow boundaries. */
|
|
11
|
+
export declare function containsDeep(host: Node, node: Node | null): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Keeps Tab focus inside `host`. Call from a `keydown` listener while the
|
|
14
|
+
* overlay is open.
|
|
15
|
+
*/
|
|
16
|
+
export declare function trapTabKey(event: KeyboardEvent, host: Node): void;
|
|
17
|
+
/** Body scroll lock shared by overlays; safe with nested overlays. */
|
|
18
|
+
export declare function lockScroll(): void;
|
|
19
|
+
export declare function unlockScroll(): void;
|
|
20
|
+
//# sourceMappingURL=a11y.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../../src/components/internal/a11y.ts"],"names":[],"mappings":"AASA,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAMpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,EAAE,CAqBhE;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,IAAI,WAAW,GAAG,IAAI,CAMzD;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAQnE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAmBjE;AAKD,sEAAsE;AACtE,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAMnC"}
|