fernwell 0.4.0 → 0.6.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 +39 -0
- package/README.md +52 -10
- package/dist/_position.d.cts +73 -0
- package/dist/_tokenData.d.cts +12 -0
- package/dist/_tokenData.d.ts +12 -0
- package/dist/combobox.d.cts +28 -0
- package/dist/css.d.cts +2 -0
- package/dist/css.d.ts +2 -0
- package/dist/fernwell.cjs +5 -3
- package/dist/fernwell.cjs.map +4 -4
- package/dist/fernwell.css +211 -5
- package/dist/fernwell.esm.js +5 -3
- package/dist/fernwell.esm.js.map +4 -4
- package/dist/fernwell.iife.js +5 -3
- package/dist/fernwell.iife.js.map +4 -4
- package/dist/fernwell.min.css +2 -2
- package/dist/fernwell.tokens.css +22 -1
- package/dist/icon.d.cts +30 -0
- package/dist/icon.d.ts +14 -0
- package/dist/iife.d.cts +2 -0
- package/dist/iife.d.ts +2 -2
- package/dist/index.d.cts +61 -0
- package/dist/index.d.ts +30 -23
- package/dist/loading.d.cts +5 -0
- package/dist/menu.d.cts +49 -0
- package/dist/modal.d.cts +13 -0
- package/dist/nav.d.cts +3 -0
- package/dist/number.d.cts +31 -0
- package/dist/number.d.ts +31 -0
- package/dist/popover.d.cts +48 -0
- package/dist/popover.d.ts +1 -1
- package/dist/table.d.cts +40 -0
- package/dist/tabs.d.cts +43 -0
- package/dist/theme.d.cts +12 -0
- package/dist/theme.d.ts +2 -29
- package/dist/toast.d.cts +14 -0
- package/dist/tokens.d.cts +105 -0
- package/dist/tokens.d.ts +105 -0
- package/dist/tokens.json +12 -0
- package/dist/tooltip.d.cts +51 -0
- package/dist/tooltip.d.ts +1 -1
- package/package.json +31 -9
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to this project are documented here. The format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.6.0] — 2026-10-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Number input** (`src/js/number.ts`, `src/css/components/number.css`, exported as `numberInput` / `Fernwell.numberInput`): `input[data-fw-number]` in two modes via `data-fw-number-mode`. `stepper` (default) wraps a native `type="number"` input in `.fw-number` with `−` / `+` buttons either side that step by `data-fw-number-step`, clamp to `-min` / `-max`, avoid float drift, repeat while held, and support ↑ ↓ and PageUp / PageDown on the input; the buttons use `aria-disabled` at the limits so focus is kept. `slider` turns the input into `type="range"` with a live `<output>` readout (`data-fw-number-unit`), `aria-valuetext`, and a filled track driven by `--fw-number-fill`. Both emit native bubbling `input` + `change` and `fw:number-change` (`{ value, mode }`). Programmatic API: `numberInput(input, opts)` → `{ getValue, setValue, stepUp, stepDown, destroy }`. Types `NumberMode`, `NumberOptions`, `NumberInstance`, `NumberChangeDetail` exported.
|
|
12
|
+
- **Icon size & stroke scale**: new `icon` token group — `--fw-icon-size-{xs,sm,md,lg,xl}` (14/18/22/28/36px below 640px, 12/16/20/24/32px from 640px up, emitted as a `min-width` block by `scripts/gen-tokens.mjs` from a `wide` value in `tokens.json`) and paired `--fw-icon-stroke-{xs..xl}` (1.75 → 1.2 grid units, so small icons don't thin out and large ones don't look heavy). Opt in with `data-fw-icon-size` or `.fw-icon-xs…xl`; override weight with `data-fw-icon-stroke` (`thin` `regular` `bold` or a number) or `.fw-icon-stroke-*`. Per-icon knobs `--fw-icon-size` / `--fw-icon-stroke` work on the element or any ancestor. Types `IconSize`, `IconStroke` exported.
|
|
13
|
+
- `minus` icon.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `.fw-icon svg` stroke width is now CSS-driven (`--fw-icon-stroke`, default 1.4 — unchanged) and `.fw-icon` width/height read `--fw-icon-size` (default `1em` — unchanged). `.fw-icon-btn svg` reads `--fw-icon-size` too (default 15px — unchanged).
|
|
18
|
+
|
|
19
|
+
## [0.5.0] — 2026-09-29
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Docs: new **API Usage** page (`docs/api.html`, styles in `docs/styles/api.css`), linked from the docs-wide page nav on the Overview and Components pages. It covers installing via CDN, npm, CSS-only, fonts and page setup; initialising with `init(root?)` (including after injecting markup, manual start with `data-fw-no-init`, and React); building custom components on `--fw-*` tokens with live pricing-card, copy-to-clipboard and scoped-retheme (`theme.setTokens()`) examples; and reference tables for the JavaScript API, `data-fw-*` hooks and `fw:*` events. Version numbers in its code samples are filled in from the published `Fernwell.version` at load time rather than hardcoded.
|
|
24
|
+
- **Tokens module** (`src/js/tokens.ts`, exported as `tokens` / `Fernwell.tokens`): the runtime token-override API now lives in its own module and grows two ways to theme beyond a single page load. `theme.setTokens` / `resetTokens` / `getToken` are unchanged and remain as aliases of `tokens.setTokens` / `resetTokens` / `getToken`.
|
|
25
|
+
- **App-wide persistence.** `setTokens(tokens, { persist: true })` saves that scope to `localStorage` (`fw-tokens`, plus a pre-rendered `fw-tokens-css`) and `init()` re-applies it on every page and reload; `resetTokens()` clears persisted overrides too. Without `persist`, overrides last for the current page load. A one-line inline `<head>` snippet (in the README and `docs/api.html`) applies them before first paint so there's no flash of the default palette. Also exports `restoreTokens()` for re-reading storage by hand.
|
|
26
|
+
- **Page and subtree scoping helpers.** `<script type="application/json" data-fw-theme-tokens>` themes the page from JSON (a flat map or `{ light, dark }`; `data-fw-scope="…"` targets a subtree, `data-fw-persist` makes it app-wide), and `data-fw-theme-scope='{…}'` themes just one element's subtree. `setTokens` now returns a function that undoes just that call — for SPA routes that theme themselves on mount.
|
|
27
|
+
- **`fw:tokenschange`** on `document` (`detail: { scope? }`), and exported `TokenName` / `TokenKey` / `SetTokensOptions` types so token names autocomplete in editors. `TokenOverrides` and `TokenThemeOverrides` are unchanged apart from now being declared in `tokens.ts`.
|
|
28
|
+
- `scripts/gen-tokens.mjs` now also writes `src/js/_tokenData.ts` (the token names and the derived-token formulas the runtime needs), generated from `tokens.json` alongside `tokens.css`.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **`setTokens()` now rejects unsafe input with a console warning** instead of writing it into the stylesheet: token values containing `{`, `}`, `;` or `/*` or an unclosed `(` or quote, token names that aren't a plain identifier, and scope selectors the browser can't parse. Bare and full names (`primary` / `--fw-primary`) now merge into one override instead of being kept as two.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **`import 'fernwell/css'` no longer fails type-checking** with "Cannot find module or type declarations for side-effect import". The `./css`, `./css/min`, and `./tokens.css` entries in the `exports` map now carry a `types` condition pointing at a new `dist/css.d.ts` stub, and a matching `typesVersions` map covers projects still on `moduleResolution: "node10"` (which ignores `exports`). The runtime target of each entry is unchanged.
|
|
37
|
+
- **The main `fernwell` entry now type-checks under `moduleResolution: "node16"` / `"nodenext"`.** This covers CommonJS files too: the `require` condition now resolves to CJS-typed `dist/*.d.cts` declarations (generated by `scripts/cjs-types.mjs`) instead of the ESM `.d.ts`, which a `.cts` file rejected with TS1479. `npm run test:types` (vitest, `__tests__/types.test.ts`) type-checks ESM, CJS, `bundler` and `node10` consumers against the built package. The generated `dist/index.d.ts` (and the other declaration files) re-exported components through extensionless relative paths such as `./modal`, which strict ESM resolution rejects with TS2834. Relative imports in `src/js` now use explicit `.js` extensions, so the emitted declarations resolve in every `moduleResolution` mode. No change for `bundler` or `node10` consumers.
|
|
38
|
+
- **Comma-separated `scope` selectors no longer leak dark values into light mode.** For `scope: '.a, .b'` the dark rule was built as `[data-theme="dark"] .a, .b, .a, .b[data-theme="dark"]`, so a bare `.b` got the dark values in every theme. Each list item is now prefixed on its own (commas inside `:is()`, attribute values and strings are left alone).
|
|
39
|
+
- **Declarative token hooks clean up after themselves.** A `data-fw-theme-scope` element or non-persisted `<script data-fw-theme-tokens>` that has left the page is undone on the next `init()`, so re-rendered route markup no longer piles up rules; putting the same node back and calling `init()` re-applies it. `data-fw-persist` hooks are unaffected.
|
|
40
|
+
- **`fw:tokenschange` fires once** for the first `setTokens()` / `resetTokens()` of a page load, not once for loading persisted storage and again for the call.
|
|
41
|
+
- **`version` is typed `string`** in the published declarations; it was emitted as the literal `"__FW_VERSION__"`, so comparing it to a real version string was a type error.
|
|
42
|
+
- **`data-fw-theme-scope` / `data-fw-theme-tokens` no longer stop other enhancers initialising.** They marked elements with the shared `data-fw-bound` flag, so a themed `<table data-fw-table>`, modal or menu was skipped by its own `init()`. They now use a private `data-fw-tokens-bound` marker.
|
|
43
|
+
- **Persisted / pre-paint token overrides now win over your stylesheet, as documented.** The inline `<head>` snippet inserts `<style data-fw-tokens>` ahead of your CSS; `setTokens` now moves it to the end of `<head>` when it first renders.
|
|
44
|
+
- **Scoped token overrides now retint derived tokens too.** `setTokens({ primary }, { scope: '.tenant' })` used to leave `--fw-primary-hover`, `--fw-primary-soft`, `--fw-focus-ring`, the `*-bg` tints and the `--fw-shadow-primary` / `-success` glows on the root palette, because derived tokens are declared on `:root` and `var()` resolves where it's declared. `setTokens` now re-declares every derived token that reads an overridden seed at the scope, in both themes. A hand-written `.tenant { --fw-primary: … }` in your own stylesheet still behaves as before — redeclare the derived tokens you need there, or use `setTokens` with a `scope`.
|
|
45
|
+
|
|
7
46
|
## [0.4.0] — 2026-09-16
|
|
8
47
|
|
|
9
48
|
### Changed (breaking)
|
package/README.md
CHANGED
|
@@ -140,19 +140,57 @@ Override any **seed** token and every derived token follows automatically, in bo
|
|
|
140
140
|
|
|
141
141
|
This works because Fernwell's own token declarations live in `@layer fw-tokens` — an unlayered rule (yours, unless you also use `@layer`) always beats a layered one, regardless of selector specificity or source order. If your app declares its own CSS layers, list them (e.g. `@layer reset, base, components;`) before importing Fernwell's CSS so `fw-tokens` isn't implicitly nested inside one of them.
|
|
142
142
|
|
|
143
|
+
Override seeds on `:root` (or `[data-theme="dark"]`) and derived tokens follow. On any *other* selector, `var()` still resolves where the derived token is declared (`:root`), so a hand-written `.tenant { --fw-primary: … }` retints `--fw-primary` only — use `tokens.setTokens(…, { scope })` below, which re-declares the derived tokens at the scope for you.
|
|
144
|
+
|
|
143
145
|
**JS — runtime.** For per-tenant branding, a user-picked accent, or a live preview:
|
|
144
146
|
|
|
145
147
|
```js
|
|
146
|
-
import {
|
|
148
|
+
import { tokens } from 'fernwell';
|
|
149
|
+
|
|
150
|
+
tokens.setTokens({ primary: '#2266ff' }); // both themes
|
|
151
|
+
tokens.setTokens({ light: { primary: '#2266ff' }, dark: { primary: '#5c9dff' } }); // per theme
|
|
152
|
+
tokens.setTokens({ secondary: '#a33' }, { scope: '.tenant-acme' }); // one subtree
|
|
153
|
+
tokens.getToken('primary'); // live resolved value, e.g. '#2266ff'
|
|
154
|
+
tokens.resetTokens(); // clear every runtime override
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`theme.setTokens` / `resetTokens` / `getToken` are the same functions, kept as aliases so existing code keeps working.
|
|
158
|
+
|
|
159
|
+
Runtime overrides render into one `<style data-fw-tokens>` appended to `<head>` and win over both the `@layer fw-tokens` defaults and any static override, so `setTokens` always has the last word. Derived tokens (hovers, tints, the focus ring, CTA glows) follow the seed they're built from — including inside a `scope`, where Fernwell re-declares them at that selector so they don't stay stuck on the root value. Values that could break out of a declaration (`{`, `}`, `;`, `/*`) and invalid selectors are rejected with a console warning.
|
|
160
|
+
|
|
161
|
+
**App-wide — persist it.** Pass `persist: true` and the scope is saved to `localStorage`, then applied on every page and reload by `init()`:
|
|
147
162
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
163
|
+
```js
|
|
164
|
+
tokens.setTokens({ primary: '#2266ff' }, { persist: true });
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Without `persist`, an override lasts for the current page load — that's the "this page only" case in a multi-page app. Page-level overrides render after persisted ones, so a page can still tweak an app-wide value. `resetTokens()` also clears persisted overrides. To apply them before first paint (no flash of the default palette), inline this in `<head>` ahead of your stylesheet, next to the theme snippet above:
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<script>try{var c=localStorage.getItem('fw-tokens-css');if(c){var s=document.createElement('style');s.setAttribute('data-fw-tokens','');s.textContent=c;document.head.appendChild(s)}}catch(e){}</script>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**This page or section only — declaratively.** `init()` also reads two hooks, so you can theme without writing JS:
|
|
174
|
+
|
|
175
|
+
```html
|
|
176
|
+
<!-- this page (add data-fw-persist to make it app-wide; data-fw-scope="…" to theme a subtree) -->
|
|
177
|
+
<script type="application/json" data-fw-theme-tokens>{ "primary": "#2266ff" }</script>
|
|
178
|
+
|
|
179
|
+
<!-- just this element's subtree; never persisted -->
|
|
180
|
+
<section data-fw-theme-scope='{ "secondary": "#a33" }'>…</section>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The `<script>` form takes the same shapes as `setTokens` — a flat map or `{ "light": {…}, "dark": {…} }`.
|
|
184
|
+
|
|
185
|
+
**Undoing a page's theme (SPAs).** `setTokens` returns a function that reverts just that call — call it when a route unmounts:
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
const undo = tokens.setTokens({ primary: '#a33' }, { scope: '#checkout' });
|
|
189
|
+
// …later
|
|
190
|
+
undo();
|
|
153
191
|
```
|
|
154
192
|
|
|
155
|
-
|
|
193
|
+
A light-only scoped override (`{ light: { … } }` with no `dark`) also applies in the dark theme — give a `dark` value if it should differ. Removing a `data-fw-theme-*` element doesn't clear its overrides; use `undo()` or `resetTokens(scope)`. Listen for `fw:tokenschange` on `document` (`detail.scope`) to react to any change.
|
|
156
194
|
|
|
157
195
|
**Browser support.** `color-mix()` and `@layer` need Chrome 111+, Safari 16.2+, Firefox 113+. There's no polyfill shipped — on an older browser the seed tokens still apply, but derived tokens fall back to whatever the browser does with an unsupported `color-mix()` value (typically the property's initial value), so hovers/tints/focus rings may go missing rather than mis-colour.
|
|
158
196
|
|
|
@@ -169,6 +207,8 @@ All class names are prefixed `fw-`; state classes are `is-*`. Each stylesheet in
|
|
|
169
207
|
| Field | `.fw-field` (`.fw-field-full`), `.fw-label`, `.fw-input`, `.fw-hint`, `.fw-error-msg`, `.fw-required`; `.is-error`, `.is-disabled` |
|
|
170
208
|
| Selection | `.fw-checkbox` / `.fw-radio` (`<input>` + `.fw-box`; checkbox styles `:indeterminate`), `.fw-toggle` (`<input>` + `.fw-track > .fw-thumb`), `.fw-option-group` (`-inline`) |
|
|
171
209
|
| Combobox | `.fw-combobox` wrapper, `input[data-fw-combobox][list]` + `<datalist>` |
|
|
210
|
+
| Number input | `.fw-number` (`-stepper`, `-slider`) wrapper, `.fw-number-btn`, `.fw-number-input`, `.fw-number-value`; built by `input[data-fw-number]` |
|
|
211
|
+
| Icon | `.fw-icon` + size `-xs` `-sm` `-md` `-lg` `-xl` and weight `.fw-icon-stroke-thin` `-regular` `-bold` |
|
|
172
212
|
| Alert | `.fw-alert` + `-success` `-error` `-pending` `-info` `-with-action`; `.fw-alert-dot` `-title` `-body` |
|
|
173
213
|
| Progress | `.fw-progress` (`-sm`, `.is-indeterminate`, `.is-success`) > `.fw-progress-fill`; `.fw-progress-label` |
|
|
174
214
|
| Spinner | `.fw-spinner` + `-sm` `-md` `-lg` (colour from `currentColor`) |
|
|
@@ -193,6 +233,8 @@ Everything is progressive enhancement over plain HTML. `init(root?)` is idempote
|
|
|
193
233
|
|
|
194
234
|
| Hook | What it does |
|
|
195
235
|
| --- | --- |
|
|
236
|
+
| `input[data-fw-number]` (+ `-mode`, `-min`, `-max`, `-step`, `-unit`) | number input: `stepper` (− / + buttons, hold to repeat, ↑ ↓ / PageUp / PageDown) or `slider` (range + live readout); emits `input`, `change`, `fw:number-change` |
|
|
237
|
+
| `[data-fw-icon]` (+ `-size`, `-stroke`) | named SVG icon; optional size scale `xs`–`xl` and stroke weight |
|
|
196
238
|
| `[data-fw-theme-toggle]` | flips `data-theme`, persists to `localStorage['fw-theme']`, sets `aria-pressed` |
|
|
197
239
|
| `input[data-fw-combobox]` | typeahead over the `<datalist>` in `list=` (↑ ↓ Enter Esc, `aria-activedescendant`) |
|
|
198
240
|
| `[data-fw-open-modal="id"]` / `[data-fw-close-modal]` | modal with backdrop-click (drag-safe), Escape, focus return, scroll lock |
|
|
@@ -212,7 +254,7 @@ import { theme, combobox, modal, nav, loading, toast, table, menu, popover, tool
|
|
|
212
254
|
theme.get();
|
|
213
255
|
theme.set('dark');
|
|
214
256
|
theme.toggle();
|
|
215
|
-
|
|
257
|
+
tokens.setTokens({ primary: '#2266ff' }); tokens.resetTokens(); tokens.getToken('primary'); // see Theming
|
|
216
258
|
|
|
217
259
|
const cb = combobox(inputEl,
|
|
218
260
|
{
|
|
@@ -239,7 +281,7 @@ const tip = tooltip(triggerEl, { placement: 'top', delay: 400 });
|
|
|
239
281
|
tip.show(); tip.hide(); tip.destroy();
|
|
240
282
|
```
|
|
241
283
|
|
|
242
|
-
Events: `fw:themechange` on `document` (detail: `'light' | 'dark'`), `fw:open` / `fw:close` bubbling from the modal, drawer, or popover, `fw:sort` (detail: `{ column, direction, th }`) and `fw:select` (detail: `{ rows, all }`) bubbling from the table, `fw:toggle` (detail: `{ group, open }`) bubbling from a `.fw-menu-group`.
|
|
284
|
+
Events: `fw:themechange` on `document` (detail: `'light' | 'dark'`), `fw:tokenschange` on `document` (detail: `{ scope? }`), `fw:open` / `fw:close` bubbling from the modal, drawer, or popover, `fw:sort` (detail: `{ column, direction, th }`) and `fw:select` (detail: `{ rows, all }`) bubbling from the table, `fw:toggle` (detail: `{ group, open }`) bubbling from a `.fw-menu-group`.
|
|
243
285
|
|
|
244
286
|
## Principles
|
|
245
287
|
|
|
@@ -253,7 +295,7 @@ Events: `fw:themechange` on `document` (detail: `'light' | 'dark'`), `fw:open` /
|
|
|
253
295
|
|
|
254
296
|
**Voice.** Buttons name the action ("Send invoice", not "Submit"). Errors say what happened and what to do next, without apologising. Empty states are invitations. Confirmations echo the verb on the button.
|
|
255
297
|
|
|
256
|
-
**Icons.** Outline only,
|
|
298
|
+
**Icons.** Outline only, 12–32px box from the `--fw-icon-size-*` scale (larger below 640px) with the paired `--fw-icon-stroke-*` (1.2–1.75 units, heavier when small), ~1.3–1.4px rendered stroke, round caps and joins, `currentColor`. No fills — except a checkmark on a completed item.
|
|
257
299
|
|
|
258
300
|
## Development
|
|
259
301
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal positioning helpers shared by popover.ts and tooltip.ts. Not part
|
|
3
|
+
* of the public API — not re-exported from index.ts.
|
|
4
|
+
*
|
|
5
|
+
* Both callers use `position: fixed`, so all math here is viewport-relative
|
|
6
|
+
* (matching `getBoundingClientRect()`) rather than document-relative.
|
|
7
|
+
*/
|
|
8
|
+
export type Side = 'top' | 'bottom' | 'left' | 'right';
|
|
9
|
+
/**
|
|
10
|
+
* `top` / `bottom` / `left` / `right` center the floating element on the
|
|
11
|
+
* anchor's cross-axis midpoint. `top-left` / `top-right` / `bottom-left` /
|
|
12
|
+
* `bottom-right` keep the anchor above/below but shift the floating element
|
|
13
|
+
* so it leans toward that corner instead of centering — useful to steer a
|
|
14
|
+
* panel away from something else on the page (another fixed control, a
|
|
15
|
+
* viewport edge) without losing the "above/below the trigger" placement.
|
|
16
|
+
*
|
|
17
|
+
* "Lean right" means the floating element's LEFT edge lines up with the
|
|
18
|
+
* anchor's left edge, so the (usually wider) box extends further right of
|
|
19
|
+
* the anchor than a centered box would; "lean left" mirrors that off the
|
|
20
|
+
* anchor's right edge.
|
|
21
|
+
*/
|
|
22
|
+
export type Placement = Side | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
23
|
+
export interface PositionOptions {
|
|
24
|
+
/** Preferred placement. */
|
|
25
|
+
placement?: Placement;
|
|
26
|
+
/** Gap between anchor and floating element, px. */
|
|
27
|
+
offset?: number;
|
|
28
|
+
/** Minimum distance from the viewport edge, px. */
|
|
29
|
+
padding?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface PositionResult {
|
|
32
|
+
/** Final placement, after a possible flip. */
|
|
33
|
+
placement: Placement;
|
|
34
|
+
top: number;
|
|
35
|
+
left: number;
|
|
36
|
+
/**
|
|
37
|
+
* Distance, in px, from the floating element's near edge (left, for a
|
|
38
|
+
* top/bottom placement; top, for a left/right placement) to the anchor's
|
|
39
|
+
* center — for positioning an optional arrow so it keeps pointing at the
|
|
40
|
+
* anchor even after the cross-axis got clamped to stay in the viewport.
|
|
41
|
+
* Already inset from the floating element's own edges so the arrow never
|
|
42
|
+
* overhangs a rounded corner.
|
|
43
|
+
*/
|
|
44
|
+
arrowOffset: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Positions `floating` relative to `anchor`: flips to the opposite side when
|
|
48
|
+
* the preferred side doesn't fit and the opposite side has more room (a
|
|
49
|
+
* 2-entry fallback, not a 4-way rotation — both callers are single-edge
|
|
50
|
+
* anchored, unlike a corner-anchored menu), and clamps the cross-axis into
|
|
51
|
+
* the viewport ("shift") rather than flipping it.
|
|
52
|
+
*
|
|
53
|
+
* The cross-axis is centered on the anchor by default (`align: 'center'`,
|
|
54
|
+
* implied by a bare `top`/`bottom`/`left`/`right` placement) — the corner
|
|
55
|
+
* placements (`top-left`, etc.) opt into edge-alignment instead. Centering
|
|
56
|
+
* is what makes an arrow drawn at the floating element's own midpoint line
|
|
57
|
+
* up with the anchor; `arrowOffset` carries the exact anchor-relative
|
|
58
|
+
* position so the arrow still lines up even when a corner placement or a
|
|
59
|
+
* viewport clamp shifts the box off-center.
|
|
60
|
+
*/
|
|
61
|
+
export declare function computePosition(anchor: HTMLElement, floating: HTMLElement, opts?: PositionOptions): PositionResult;
|
|
62
|
+
/**
|
|
63
|
+
* Fires `onDismiss` only when a click lands outside every element in
|
|
64
|
+
* `anchors` — generalizes modal.ts's `bindOutsideClickToClose` (which checks
|
|
65
|
+
* a single backdrop) to an arbitrary set of "not outside" elements (e.g. a
|
|
66
|
+
* popover's trigger AND its panel).
|
|
67
|
+
*
|
|
68
|
+
* Guards the same false positive: a browser's `click` fires on the nearest
|
|
69
|
+
* common ancestor of mousedown and mouseup, so a text-selection drag that
|
|
70
|
+
* starts inside an anchor and ends outside it would otherwise look like an
|
|
71
|
+
* outside click. Close only when BOTH mousedown and click landed outside.
|
|
72
|
+
*/
|
|
73
|
+
export declare function bindOutsideDismiss(anchors: HTMLElement[], onDismiss: () => void): () => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Every token name, without the `--fw-` prefix. */
|
|
2
|
+
export type TokenName = 'text' | 'text-soft' | 'bg' | 'bg-dim' | 'surface' | 'primary' | 'primary-hover' | 'primary-soft' | 'secondary' | 'secondary-hover' | 'secondary-bg' | 'success' | 'success-bg' | 'warning' | 'warning-bg' | 'danger' | 'danger-bg' | 'info' | 'info-bg' | 'on-primary' | 'on-secondary' | 'on-secondary-soft' | 'on-secondary-fill' | 'on-secondary-line' | 'overlay' | 'overlay-soft' | 'focus-ring' | 'scrollbar-thumb' | 'scrollbar-thumb-hover' | 'scrollbar-track' | 'font-display' | 'font-body' | 'font-mono' | 'sp-1' | 'sp-2' | 'sp-3' | 'sp-4' | 'sp-5' | 'sp-6' | 'sp-7' | 'sp-8' | 'sp-9' | 'r-sm' | 'r-md' | 'r-lg' | 'r-xl' | 'r-full' | 'shadow-sm' | 'shadow-md' | 'shadow-lg' | 'shadow-primary' | 'shadow-success' | 'icon-size-xs' | 'icon-size-sm' | 'icon-size-md' | 'icon-size-lg' | 'icon-size-xl' | 'icon-stroke-xs' | 'icon-stroke-sm' | 'icon-stroke-md' | 'icon-stroke-lg' | 'icon-stroke-xl' | 'border-w' | 'motion-fast' | 'motion-base' | 'motion-ease';
|
|
3
|
+
/** A token whose value is computed from other tokens (hovers, tints, focus ring, glows). */
|
|
4
|
+
export interface DerivedToken {
|
|
5
|
+
readonly name: TokenName;
|
|
6
|
+
/** The CSS value in the light theme, with `{ref}`s already resolved to `var(--fw-…)`. */
|
|
7
|
+
readonly light: string;
|
|
8
|
+
readonly dark: string;
|
|
9
|
+
/** Names of the tokens this one is computed from (either theme). */
|
|
10
|
+
readonly deps: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export declare const DERIVED: readonly DerivedToken[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Every token name, without the `--fw-` prefix. */
|
|
2
|
+
export type TokenName = 'text' | 'text-soft' | 'bg' | 'bg-dim' | 'surface' | 'primary' | 'primary-hover' | 'primary-soft' | 'secondary' | 'secondary-hover' | 'secondary-bg' | 'success' | 'success-bg' | 'warning' | 'warning-bg' | 'danger' | 'danger-bg' | 'info' | 'info-bg' | 'on-primary' | 'on-secondary' | 'on-secondary-soft' | 'on-secondary-fill' | 'on-secondary-line' | 'overlay' | 'overlay-soft' | 'focus-ring' | 'scrollbar-thumb' | 'scrollbar-thumb-hover' | 'scrollbar-track' | 'font-display' | 'font-body' | 'font-mono' | 'sp-1' | 'sp-2' | 'sp-3' | 'sp-4' | 'sp-5' | 'sp-6' | 'sp-7' | 'sp-8' | 'sp-9' | 'r-sm' | 'r-md' | 'r-lg' | 'r-xl' | 'r-full' | 'shadow-sm' | 'shadow-md' | 'shadow-lg' | 'shadow-primary' | 'shadow-success' | 'icon-size-xs' | 'icon-size-sm' | 'icon-size-md' | 'icon-size-lg' | 'icon-size-xl' | 'icon-stroke-xs' | 'icon-stroke-sm' | 'icon-stroke-md' | 'icon-stroke-lg' | 'icon-stroke-xl' | 'border-w' | 'motion-fast' | 'motion-base' | 'motion-ease';
|
|
3
|
+
/** A token whose value is computed from other tokens (hovers, tints, focus ring, glows). */
|
|
4
|
+
export interface DerivedToken {
|
|
5
|
+
readonly name: TokenName;
|
|
6
|
+
/** The CSS value in the light theme, with `{ref}`s already resolved to `var(--fw-…)`. */
|
|
7
|
+
readonly light: string;
|
|
8
|
+
readonly dark: string;
|
|
9
|
+
/** Names of the tokens this one is computed from (either theme). */
|
|
10
|
+
readonly deps: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export declare const DERIVED: readonly DerivedToken[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combobox / typeahead — progressive enhancement over an <input> + <datalist>.
|
|
3
|
+
*
|
|
4
|
+
* <div class="fw-combobox">
|
|
5
|
+
* <input class="fw-input" data-fw-combobox list="cities" placeholder="Start typing…">
|
|
6
|
+
* <datalist id="cities"><option value="Seattle"></option>…</datalist>
|
|
7
|
+
* </div>
|
|
8
|
+
*
|
|
9
|
+
* Or programmatically: combobox(input, { options: ['Seattle', …], onSelect })
|
|
10
|
+
*/
|
|
11
|
+
export interface ComboboxOptions {
|
|
12
|
+
/** Static option list. Defaults to the <datalist> the input's `list` attribute points at. */
|
|
13
|
+
options?: string[];
|
|
14
|
+
/** Filter function; default is case-insensitive substring match. */
|
|
15
|
+
filter?: (option: string, query: string) => boolean;
|
|
16
|
+
/** Text shown when nothing matches. */
|
|
17
|
+
emptyText?: string;
|
|
18
|
+
onSelect?: (value: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface ComboboxInstance {
|
|
21
|
+
open(): void;
|
|
22
|
+
close(): void;
|
|
23
|
+
setOptions(options: string[]): void;
|
|
24
|
+
destroy(): void;
|
|
25
|
+
}
|
|
26
|
+
export declare function combobox(input: HTMLInputElement, opts?: ComboboxOptions): ComboboxInstance;
|
|
27
|
+
/** Enhance every `[data-fw-combobox]` input under `root`. */
|
|
28
|
+
export declare function init(root?: ParentNode): void;
|
package/dist/css.d.cts
ADDED
package/dist/css.d.ts
ADDED
package/dist/fernwell.cjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
/*! fernwell v0.
|
|
2
|
-
"use strict";var Ee=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var Ft=Object.prototype.hasOwnProperty;var y=(e,t)=>{for(var n in t)Ee(e,n,{get:t[n],enumerable:!0})},Vt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of $t(t))!Ft.call(e,r)&&r!==n&&Ee(e,r,{get:()=>t[r],enumerable:!(o=Rt(t,r))||o.enumerable});return e};var Kt=e=>Vt(Ee({},"__esModule",{value:!0}),e);var Sn={};y(Sn,{combobox:()=>J,default:()=>gn,icon:()=>z,init:()=>Bt,loading:()=>ne,menu:()=>ae,modal:()=>Q,nav:()=>te,popover:()=>ue,table:()=>ie,tabs:()=>ve,theme:()=>X,toast:()=>oe,tooltip:()=>me,version:()=>Nt});module.exports=Kt(Sn);var X={};y(X,{get:()=>ye,getToken:()=>Yt,init:()=>Le,resetTokens:()=>zt,set:()=>Y,setTokens:()=>Gt,toggle:()=>Je});var z={};y(z,{init:()=>he,render:()=>G});var jt={add:'<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',close:'<line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/>',check:'<polyline points="5,13 10,18 19,7"/>',edit:'<path d="M16.8 3.5a2.1 2.1 0 0 1 3 3L8.5 17.8 4 19l1.2-4.5Z"/><line x1="14.5" y1="5.8" x2="17.7" y2="9"/>',trash:'<path d="M4 7h16"/><path d="M9 7V4.6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1V7"/><path d="M6.5 7l.8 12.4A2 2 0 0 0 9.3 21h5.4a2 2 0 0 0 2-1.6L18 7"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',save:'<path d="M5 4a1 1 0 0 1 1-1h9.2a1 1 0 0 1 .7.3l2.8 2.8a1 1 0 0 1 .3.7V20a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4Z"/><path d="M8 3v5h7V3"/><path d="M8 21v-6h8v6"/>',search:'<circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.6" y2="16.6"/>',settings:'<circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"/>',download:'<line x1="12" y1="3" x2="12" y2="15"/><polyline points="7,10 12,15 17,10"/><line x1="5" y1="21" x2="19" y2="21"/>',upload:'<line x1="12" y1="15" x2="12" y2="3"/><polyline points="7,8 12,3 17,8"/><line x1="5" y1="21" x2="19" y2="21"/>',share:'<circle cx="6" cy="12" r="2.3"/><circle cx="18" cy="6" r="2.3"/><circle cx="18" cy="18" r="2.3"/><line x1="8.1" y1="10.8" x2="15.9" y2="7.2"/><line x1="8.1" y1="13.2" x2="15.9" y2="16.8"/>',copy:'<rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1"/>',menu:'<line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/>',more:'<circle cx="5" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.4" fill="currentColor" stroke="none"/>',user:'<circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/>',bell:'<path d="M6 8a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6"/><path d="M10 20a2 2 0 0 0 4 0"/>',heart:'<path d="M12 20s-7-4.4-9.5-8.5C.8 8 2 4.5 5.5 4.5c2 0 3.5 1 6.5 4 3-3 4.5-4 6.5-4 3.5 0 4.7 3.5 3 7-2.5 4.1-9.5 8.5-9.5 8.5Z"/>',star:'<polygon points="12,3 14.6,9.1 21.2,9.3 16,13.4 17.8,19.8 12,16.3 6.2,19.8 8,13.4 2.8,9.3 9.4,9.1"/>',calendar:'<rect x="3" y="5" width="18" height="16" rx="2"/><line x1="8" y1="3" x2="8" y2="7"/><line x1="16" y1="3" x2="16" y2="7"/><line x1="3" y1="10" x2="21" y2="10"/>',refresh:'<path d="M20 11A8 8 0 0 0 6.3 6.3L4 8.6"/><path d="M4 4v5h5"/><path d="M4 13a8 8 0 0 0 13.7 4.7L20 15.4"/><path d="M20 20v-5h-5"/>',filter:'<polygon points="4,4 20,4 14,12 14,19 10,21 10,12"/>',info:'<circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><circle cx="12" cy="8" r="1" fill="currentColor" stroke="none"/>',warning:'<path d="M12 3 22 20H2Z"/><line x1="12" y1="9.5" x2="12" y2="14.5"/><circle cx="12" cy="17.3" r="1" fill="currentColor" stroke="none"/>',lock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>',eye:'<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',"chevron-down":'<polyline points="6,9 12,15 18,9"/>',"arrow-left":'<line x1="19" y1="12" x2="5" y2="12"/><polyline points="12,5 5,12 12,19"/>',"arrow-right":'<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12,5 19,12 12,19"/>',folder:'<path d="M3.5 6.5a1 1 0 0 1 1-1H10l2 2.2h7.5a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H4.5a1 1 0 0 1-1-1Z"/>',bookmark:'<path d="M6 3h12a1 1 0 0 1 1 1v17l-7-4-7 4V4a1 1 0 0 1 1-1Z"/>',home:'<path d="M4 11.5 12 4l8 7.5"/><path d="M6 10v10a1 1 0 0 0 1 1h3.5v-6h2.8v6H17a1 1 0 0 0 1-1V10"/>',logout:'<path d="M9 4H5.5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1H9"/><line x1="14" y1="12" x2="21" y2="12"/><polyline points="17.5,8.5 21,12 17.5,15.5"/>',paperclip:'<path d="M21 11.5 12.4 20a4.3 4.3 0 0 1-6-6.1L15 5.3a2.9 2.9 0 0 1 4.1 4.1l-8.6 8.6a1.4 1.4 0 0 1-2-2l7.9-7.9"/>',envelope:'<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M4 6.5 12 13l8-6.5"/>',"chevron-up":'<polyline points="6,15 12,9 18,15"/>',"chevron-left":'<polyline points="15,6 9,12 15,18"/>',"chevron-right":'<polyline points="9,6 15,12 9,18"/>',"arrow-up":'<line x1="12" y1="19" x2="12" y2="5"/><polyline points="5,12 12,5 19,12"/>',"arrow-down":'<line x1="12" y1="5" x2="12" y2="19"/><polyline points="5,12 12,19 19,12"/>',unlock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 7.8-1.3"/>',"thumbs-up":'<path d="M7 11v9H4.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1H7Z"/><path d="M7 11l4.3-7.3a1.4 1.4 0 0 1 2.6.8L13 9h5.6a2 2 0 0 1 1.9 2.6l-2 6.5A2 2 0 0 1 16.6 19.5H10a3 3 0 0 1-3-3"/>',"thumbs-down":'<path d="M7 13V4h2.5a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H7Z"/><path d="M7 13l4.3 7.3a1.4 1.4 0 0 0 2.6-.8L13 15h5.6a2 2 0 0 0 1.9-2.6l-2-6.5A2 2 0 0 0 16.6 4.5H10a3 3 0 0 0-3 3"/>',"eye-closed":'<path d="M3.5 12S7 6 12 6s8.5 6 8.5 6-3.5 6-8.5 6-8.5-6-8.5-6Z"/><line x1="4" y1="19" x2="20" y2="5"/>',"help-circle":'<circle cx="12" cy="12" r="9"/><path d="M9.2 9.2a2.8 2.8 0 1 1 4.3 2.4c-.9.6-1.5 1.1-1.5 2.2"/><circle cx="12" cy="17" r="1" fill="currentColor" stroke="none"/>',chat:'<path d="M4 5.5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9.5L5 20.5V16.5H5a1 1 0 0 1-1-1Z"/>',kebab:'<circle cx="12" cy="5" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="19" r="1.4" fill="currentColor" stroke="none"/>',sun:'<circle cx="12" cy="12" r="4"/><line x1="12" y1="2" x2="12" y2="4.5"/><line x1="12" y1="19.5" x2="12" y2="22"/><line x1="2" y1="12" x2="4.5" y2="12"/><line x1="19.5" y1="12" x2="22" y2="12"/><line x1="4.9" y1="4.9" x2="6.6" y2="6.6"/><line x1="17.4" y1="17.4" x2="19.1" y2="19.1"/><line x1="4.9" y1="19.1" x2="6.6" y2="17.4"/><line x1="17.4" y1="6.6" x2="19.1" y2="4.9"/>',moon:'<path d="M20.5 14.2A8.5 8.5 0 1 1 9.8 3.5a7 7 0 0 0 10.7 10.7Z"/>'};function G(e){let t=jt[e];return t?`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${t}</svg>`:""}function he(e=document){e.querySelectorAll("[data-fw-icon]").forEach(t=>{var r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=t.dataset.fwIcon)!=null?r:"",o=G(n);o||console.warn(`fernwell: unknown icon "${n}"`),t.innerHTML=o,t.classList.add("fw-icon")})}var we="fw-theme",_t="fw:themechange",Zt="--fw-",Ge="data-fw-tokens",ze="data-fw-theme-init";function Te(){try{return window.localStorage}catch{return null}}function ye(){var t;let e=document.documentElement.getAttribute("data-theme");return e==="dark"||e==="light"?e:(t=window.matchMedia)!=null&&t.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function Y(e,{persist:t=!0}={}){var n;document.documentElement.setAttribute("data-theme",e),t&&((n=Te())==null||n.setItem(we,e)),document.querySelectorAll("[data-fw-theme-toggle]").forEach(o=>Qe(o,e)),document.dispatchEvent(new CustomEvent(_t,{detail:e}))}function Je(){let e=ye()==="dark"?"light":"dark";return Y(e),e}function Qe(e,t){e.setAttribute("aria-pressed",String(t==="dark"));let n=t==="dark"?e.dataset.fwThemeIconDark:e.dataset.fwThemeIconLight,o=t==="dark"?e.dataset.fwThemeLabelDark:e.dataset.fwThemeLabelLight;if(n!==void 0){let r=`<span class="fw-icon" aria-hidden="true">${G(n)}</span>`;e.innerHTML=o!==void 0?`${r} ${o}`:r}else o!==void 0&&(e.textContent=o)}function Wt(e){let t=typeof requestAnimationFrame=="function"?requestAnimationFrame:n=>setTimeout(n,16);t(()=>t(e))}function Le(e=document){var r,i,l,a;let t=(r=Te())==null?void 0:r.getItem(we),n=t==="dark"||t==="light"?t:ye(),o=document.documentElement;o.setAttribute(ze,""),Y(n,{persist:!1}),Wt(()=>o.removeAttribute(ze)),e.querySelectorAll("[data-fw-theme-toggle]").forEach(c=>{c.dataset.fwBound||(c.dataset.fwBound="1",Qe(c,n),c.addEventListener("click",()=>Je()))}),(a=(i=window.matchMedia)==null?void 0:(l=i.call(window,"(prefers-color-scheme: dark)")).addEventListener)==null||a.call(l,"change",c=>{var d;(d=Te())!=null&&d.getItem(we)||Y(c.matches?"dark":"light",{persist:!1})})}var B=new Map;function et(e){return e.startsWith("--")?e:`${Zt}${e}`}function Ut(e){return Object.values(e).some(t=>t!==null&&typeof t=="object")}function Ye(e){return Object.entries(e).map(([t,n])=>`${et(t)}:${n};`).join("")}function Xe(e){let t=document.head.querySelector(`style[${Ge}]`);if(t||!e)return t;let n=document.createElement("style");return n.setAttribute(Ge,""),document.head.appendChild(n),n}function tt(){var t;if(B.size===0){(t=Xe(!1))==null||t.remove();return}let e=[];B.forEach(({light:n,dark:o},r)=>{if(Object.keys(n).length&&e.push(`${r}{${Ye(n)}}`),Object.keys(o).length){let i=r===":root"?'[data-theme="dark"]':`[data-theme="dark"] ${r}, ${r}[data-theme="dark"]`;e.push(`${i}{${Ye(o)}}`)}}),Xe(!0).textContent=e.join(`
|
|
3
|
-
`)}function Gt(e,t={}){var r,i;let n=(r=t.scope)!=null?r:":root",o=(i=B.get(n))!=null?i:{light:{},dark:{}};Ut(e)?(Object.assign(o.light,e.light),Object.assign(o.dark,e.dark)):(Object.assign(o.light,e),Object.assign(o.dark,e)),B.set(n,o),tt()}function zt(e){e?B.delete(e):B.clear(),tt()}function Yt(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(et(e)).trim()}var J={};y(J,{combobox:()=>nt,init:()=>be});var Xt=0;function K(e){return e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}function nt(e,t={}){var h,N,O,Ue;let n=(h=t.filter)!=null?h:((f,w)=>f.toLowerCase().includes(w)),o=(N=t.emptyText)!=null?N:"No matches",r=(O=t.options)!=null?O:Jt(e),i=[],l=-1,a=!1,c=e.getAttribute("list");c&&(e.dataset.fwList=c,e.removeAttribute("list"));let d=(Ue=e.closest(".fw-combobox"))!=null?Ue:Qt(e),s=document.createElement("ul"),u=`fw-combobox-${++Xt}`;s.className="fw-combobox-list",s.id=u,s.setAttribute("role","listbox"),d.appendChild(s),e.setAttribute("role","combobox"),e.setAttribute("aria-autocomplete","list"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",u),e.autocomplete="off";function E(f){i=f,l=-1;let w=e.value.trim().toLowerCase();if(f.length===0){s.innerHTML=`<li class="fw-combobox-empty">${K(o)}</li>`;return}s.innerHTML=f.map((H,F)=>{let V=w?H.toLowerCase().indexOf(w):-1,qt=V>-1?`${K(H.slice(0,V))}<b>${K(H.slice(V,V+w.length))}</b>${K(H.slice(V+w.length))}`:K(H);return`<li class="fw-combobox-option" role="option" id="${u}-${F}" data-index="${F}" aria-selected="false">${qt}</li>`}).join("")}function m(){let f=e.value.trim().toLowerCase();E(f?r.filter(w=>n(w,f)):r),s.classList.add("is-open"),e.setAttribute("aria-expanded","true")}function p(){s.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),e.removeAttribute("aria-activedescendant"),l=-1}function v(f){let w=s.querySelectorAll(".fw-combobox-option");w.forEach(F=>{F.classList.remove("is-active"),F.setAttribute("aria-selected","false")});let H=w[f];H&&(H.classList.add("is-active"),H.setAttribute("aria-selected","true"),H.scrollIntoView({block:"nearest"}),e.setAttribute("aria-activedescendant",H.id)),l=f}function b(f){var w;e.value=f,p(),a=!0,e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),a=!1,(w=t.onSelect)==null||w.call(t,f)}let M=()=>{a||m()},T=()=>{a||m()},g=f=>{f.key==="ArrowDown"?(f.preventDefault(),s.classList.contains("is-open")||m(),v(Math.min(l+1,i.length-1))):f.key==="ArrowUp"?(f.preventDefault(),v(Math.max(l-1,0))):f.key==="Enter"?l>-1&&i[l]!==void 0&&(f.preventDefault(),b(i[l])):f.key==="Escape"&&p()},S=f=>{let w=f.target.closest(".fw-combobox-option");w&&(f.preventDefault(),b(i[Number(w.dataset.index)]))},$=f=>{d.contains(f.target)||p()};return e.addEventListener("input",M),e.addEventListener("focus",T),e.addEventListener("keydown",g),s.addEventListener("mousedown",S),document.addEventListener("click",$),{open:m,close:p,setOptions(f){r=f,s.classList.contains("is-open")&&m()},destroy(){e.removeEventListener("input",M),e.removeEventListener("focus",T),e.removeEventListener("keydown",g),s.removeEventListener("mousedown",S),document.removeEventListener("click",$),s.remove(),e.dataset.fwList&&e.setAttribute("list",e.dataset.fwList),delete e.dataset.fwBound}}}function Jt(e){var o;let t=(o=e.getAttribute("list"))!=null?o:e.dataset.fwList,n=t?document.getElementById(t):null;return n?Array.from(n.querySelectorAll("option")).map(r=>r.value||r.textContent||""):[]}function Qt(e){var n;let t=document.createElement("div");return t.className="fw-combobox",(n=e.parentNode)==null||n.insertBefore(t,e),t.appendChild(e),t}function be(e=document){e.querySelectorAll("input[data-fw-combobox]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",nt(t))})}var Q={};y(Q,{bindOutsideClickToClose:()=>Me,close:()=>C,init:()=>ge,open:()=>ke,toggle:()=>tn});var D="is-open",rt="fw-scroll-lock",P=[],xe=new WeakMap,en='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function He(e){return typeof e=="string"?document.getElementById(e):e}function Ae(e){if(e.classList.contains("fw-modal-overlay"))return e;let t=e.id?document.querySelector(`[data-fw-drawer-overlay="${e.id}"]`):null;if(t)return t;let n=e.previousElementSibling;return n instanceof HTMLElement&&n.classList.contains("fw-drawer-overlay")?n:null}function ke(e,t=(n=>(n=document.activeElement)!=null?n:null)()){var i;let o=He(e);if(!o||o.classList.contains(D))return;o.classList.add(D),(i=Ae(o))==null||i.classList.add(D),xe.set(o,t),P.push(o),document.body.classList.add(rt),o.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}));let r=o.querySelector(en);r?r.focus({preventScroll:!0}):(o.hasAttribute("tabindex")||o.setAttribute("tabindex","-1"),o.focus({preventScroll:!0}))}function C(e){var o,r,i;let t=He(e);if(!t||!t.classList.contains(D))return;t.classList.remove(D),(o=Ae(t))==null||o.classList.remove(D);let n=P.indexOf(t);n>-1&&P.splice(n,1),P.length===0&&document.body.classList.remove(rt),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),(i=(r=xe.get(t))==null?void 0:r.focus)==null||i.call(r,{preventScroll:!0}),xe.delete(t)}function tn(e){let t=He(e);t&&(t.classList.contains(D)?C:ke)(t)}function Me(e,t){let n=!1;e.addEventListener("mousedown",o=>{n=o.target===e}),e.addEventListener("click",o=>{o.target===e&&n&&t()})}var ot=!1;function ge(e=document){e.querySelectorAll("[data-fw-open-modal], [data-fw-open-drawer]").forEach(t=>{var o,r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=(o=t.dataset.fwOpenModal)!=null?o:t.dataset.fwOpenDrawer)!=null?r:"";t.addEventListener("click",()=>ke(n,t))}),e.querySelectorAll(".fw-modal-overlay").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Me(t,()=>C(t)),t.querySelectorAll("[data-fw-close-modal]").forEach(n=>n.addEventListener("click",()=>C(t))))}),e.querySelectorAll(".fw-drawer").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Ae(t);n&&Me(n,()=>C(t)),t.querySelectorAll("[data-fw-close-drawer]").forEach(o=>o.addEventListener("click",()=>C(t)))}),ot||(ot=!0,document.addEventListener("keydown",t=>{t.key==="Escape"&&P.length&&C(P[P.length-1])}))}var te={};y(te,{close:()=>ee,init:()=>Ce,open:()=>it});var Se="is-open";function it(e){let t=Oe(e);t&&(t.classList.add(Se),e.setAttribute("aria-expanded","true"))}function ee(e){let t=Oe(e);t&&(t.classList.remove(Se),e.setAttribute("aria-expanded","false"))}function Oe(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function Ce(e=document){e.querySelectorAll("[data-fw-nav-toggle]").forEach(t=>{var r,i;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Oe(t);if(!n)return;let o=(i=(r=t.closest(".fw-nav"))!=null?r:t.parentElement)!=null?i:t;t.addEventListener("click",l=>{l.stopPropagation(),(n.classList.contains(Se)?ee:it)(t)}),document.addEventListener("click",l=>{!o.contains(l.target)&&!n.contains(l.target)&&ee(t)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&ee(t)})})}var ne={};y(ne,{init:()=>De,resetAll:()=>ct,resetButtonLoading:()=>at,setButtonLoading:()=>lt});var j="fw-btn-loading";function lt(e,t){var o,r;if(!e||e.classList.contains(j))return;e.dataset.fwOriginalHtml=e.innerHTML,e.disabled=!0,e.setAttribute("aria-busy","true"),e.classList.add(j);let n=(r=(o=t!=null?t:e.dataset.fwLoadingText)!=null?o:e.textContent)!=null?r:"";e.innerHTML='<span class="fw-spinner fw-spinner-sm" aria-hidden="true"></span>',e.appendChild(document.createTextNode(n))}function at(e){!e||!e.classList.contains(j)||(e.disabled=!1,e.removeAttribute("aria-busy"),e.classList.remove(j),e.dataset.fwOriginalHtml!==void 0&&(e.innerHTML=e.dataset.fwOriginalHtml,delete e.dataset.fwOriginalHtml))}function ct(e=document){e.querySelectorAll(`.${j}`).forEach(at)}var st=!1;function De(e=document){e.querySelectorAll("form[data-fw-loading]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",t.addEventListener("submit",()=>{let n=t.querySelector('button[type="submit"], button:not([type])');lt(n)}))}),st||(st=!0,window.addEventListener("pageshow",t=>{t.persisted&&ct()}))}var oe={};y(oe,{hide:()=>dt,show:()=>on});var L=null,q=null;function nn(){return L&&L.isConnected||(L=document.createElement("div"),L.className="fw-toast",L.setAttribute("role","status"),L.setAttribute("aria-live","polite"),L.innerHTML='<span class="fw-toast-dot" aria-hidden="true"></span><span class="fw-toast-text"></span>',document.body.appendChild(L)),L}function on(e,{variant:t="success",duration:n=4e3}={}){let o=nn();return o.className=`fw-toast${t==="success"?"":` fw-toast-${t}`}`,o.querySelector(".fw-toast-text").textContent=e,q&&clearTimeout(q),o.classList.remove("is-show"),o.offsetWidth,o.classList.add("is-show"),n>0&&(q=setTimeout(dt,n)),o}function dt(){L==null||L.classList.remove("is-show"),q&&clearTimeout(q),q=null}var ie={};y(ie,{getSelected:()=>qe,init:()=>Re,selectAll:()=>vt,setRowSelected:()=>pt,sort:()=>Pe});var rn="is-selected";function Ie(e,t,n){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n}))}function ut(e,t){var o,r,i;let n=e.cells[t];return(i=(r=n==null?void 0:n.dataset.fwSortValue)!=null?r:(o=n==null?void 0:n.textContent)==null?void 0:o.trim())!=null?i:""}function sn(e,t){let n=Number(e),o=Number(t);return e!==""&&t!==""&&Number.isFinite(n)&&Number.isFinite(o)?n-o:e.localeCompare(t,void 0,{numeric:!0,sensitivity:"base"})}function mt(e){var t,n;return Array.from((n=(t=e.tHead)==null?void 0:t.querySelectorAll("th[data-fw-sort]"))!=null?n:[])}function ft(e){return e.getAttribute("aria-sort")==="ascending"?"descending":"ascending"}function Pe(e,t,n){let o=e.tBodies[0];if(!o)return;let r=Array.from(o.rows),i=r.filter(d=>d.cells.length>t),l=r.filter(d=>d.cells.length<=t),a=n==="ascending"?1:-1;i.sort((d,s)=>a*sn(ut(d,t),ut(s,t))),[...i,...l].forEach(d=>o.appendChild(d));let c=null;mt(e).forEach(d=>{let s=d.cellIndex===t;d.setAttribute("aria-sort",s?n:"none"),s&&(c=d)}),c&&Ie(e,"fw:sort",{column:t,direction:n,th:c})}function re(e){return Array.from(e.querySelectorAll("tbody input[data-fw-select-row]"))}function Ne(e,t){e.classList.toggle(rn,t),e.setAttribute("aria-selected",t?"true":"false")}function Be(e){let t=e.querySelector("[data-fw-select-all]");if(!t)return;let n=re(e),o=n.filter(r=>r.checked).length;t.checked=o>0&&o===n.length,t.indeterminate=o>0&&o<n.length}function qe(e){return re(e).filter(t=>t.checked).map(t=>t.closest("tr")).filter(t=>t!==null)}function pt(e,t){let n=e.querySelector("input[data-fw-select-row]");n&&(n.checked=t),Ne(e,t);let o=e.closest("table");o&&(Be(o),Ie(o,"fw:select",{rows:qe(o),all:!1}))}function vt(e,t){re(e).forEach(n=>{n.checked=t;let o=n.closest("tr");o&&Ne(o,t)}),Be(e),Ie(e,"fw:select",{rows:qe(e),all:!0})}function Re(e=document){e.querySelectorAll("table[data-fw-table]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",mt(t).forEach(n=>{n.hasAttribute("aria-sort")||n.setAttribute("aria-sort","none")}),t.addEventListener("click",n=>{let o=n.target.closest("th[data-fw-sort]");o&&t.contains(o)&&Pe(t,o.cellIndex,ft(o))}),t.addEventListener("keydown",n=>{if(n.key!=="Enter"&&n.key!==" ")return;let o=n.target;if(!o.matches("th[data-fw-sort], th[data-fw-sort] .fw-table-sort"))return;let r=o.closest("th[data-fw-sort]");r&&(n.preventDefault(),Pe(t,r.cellIndex,ft(r)))}),t.addEventListener("change",n=>{let o=n.target;if(o.matches("[data-fw-select-all]"))vt(t,o.checked);else if(o.matches("[data-fw-select-row]")){let r=o.closest("tr");r&&pt(r,o.checked)}}),re(t).forEach(n=>{let o=n.closest("tr");o&&n.checked&&Ne(o,!0)}),Be(t))})}var ae={};y(ae,{close:()=>le,collapseAll:()=>un,expandAll:()=>dn,init:()=>$e,open:()=>se,reveal:()=>wt,toggle:()=>cn});var A=".fw-menu-group",ht=".fw-menu-link, .fw-menu-summary",ln="is-current";function an(e,t){e.dispatchEvent(new CustomEvent("fw:toggle",{bubbles:!0,detail:t}))}function se(e){e.open=!0}function le(e){e.open=!1}function cn(e,t){e.open=t!=null?t:!e.open}function dn(e){e.querySelectorAll(A).forEach(se)}function un(e){e.querySelectorAll(A).forEach(le)}function wt(e){var n,o,r,i;let t=(o=(n=e.parentElement)==null?void 0:n.closest(A))!=null?o:null;for(;t;)se(t),t=(i=(r=t.parentElement)==null?void 0:r.closest(A))!=null?i:null}function Et(e){e.querySelectorAll(A).forEach(t=>{let n=t.querySelector(":scope > .fw-menu-summary");if(!n)return;let o=!t.open&&t.querySelector("[aria-current]")!==null;n.classList.toggle(ln,o)})}function Tt(e){return e.matches(".fw-menu-summary")?e.closest(A):null}function yt(e){var n,o,r;return(r=(o=((n=Tt(e))!=null?n:e).parentElement)==null?void 0:o.closest(A))!=null?r:null}function fn(e){var t,n;for(let o=yt(e);o;o=(n=(t=o.parentElement)==null?void 0:t.closest(A))!=null?n:null)if(!o.open)return!1;return!0}function mn(e){return Array.from(e.querySelectorAll(ht)).filter(fn)}function I(e){return e?(e.focus(),!0):!1}function pn(e){var n;let t=e.closest(".fw-menu-split");return(n=t==null?void 0:t.querySelector(":scope > .fw-menu-group > .fw-menu-summary"))!=null?n:null}function vn(e,t){var a;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)return;let n=t.target instanceof HTMLElement&&t.target.matches(ht)?t.target:null;if(!n||!e.contains(n))return;let o=mn(e),r=o.indexOf(n),i=Tt(n),l=!0;switch(t.key){case"ArrowDown":I(o[r+1]);break;case"ArrowUp":I(o[r-1]);break;case"Home":I(o[0]);break;case"End":I(o[o.length-1]);break;case"ArrowRight":i?i.open?i.contains((a=o[r+1])!=null?a:e)&&I(o[r+1]):se(i):I(pn(n));break;case"ArrowLeft":if(i!=null&&i.open)le(i);else{let c=yt(n);I(c==null?void 0:c.querySelector(":scope > .fw-menu-summary"))}break;default:l=!1}l&&t.preventDefault()}function $e(e=document){e.querySelectorAll("[data-fw-menu]").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.hasAttribute("data-fw-menu-exclusive");t.addEventListener("toggle",o=>{let r=o.target;!(r instanceof HTMLDetailsElement)||!r.matches(A)||(n&&r.open&&r.parentElement&&Array.from(r.parentElement.children).forEach(i=>{i!==r&&i instanceof HTMLDetailsElement&&i.matches(A)&&le(i)}),Et(t),an(r,{group:r,open:r.open}))},!0),t.addEventListener("keydown",o=>vn(t,o)),t.querySelectorAll("[aria-current]").forEach(wt),Et(t)})}var ue={};y(ue,{init:()=>Ve,popover:()=>Mt});var En={top:"bottom",bottom:"top",left:"right",right:"left"},R=10;function hn(e){switch(e){case"top-left":return{side:"top",align:"end"};case"top-right":return{side:"top",align:"start"};case"bottom-left":return{side:"bottom",align:"end"};case"bottom-right":return{side:"bottom",align:"start"};default:return{side:e,align:"center"}}}var wn={start:"right",end:"left"};function Tn(e,t){return t==="center"?e:`${e}-${wn[t]}`}function Fe(e,t,n,o){switch(e){case"top":return t.top;case"bottom":return o-t.bottom;case"left":return t.left;case"right":return n-t.right}}function Lt(e,t,n,o){switch(e){case"top":return t.top-o-n.height;case"bottom":return t.bottom+o;case"left":return t.left-o-n.width;case"right":return t.right+o}}function bt(e,t,n,o){switch(e){case"start":return t;case"end":return t+n-o;case"center":return t+n/2-o/2}}function ce(e,t,n){return Math.min(Math.max(e,t),n>t?n:t)}function de(e,t,n={}){var T,g,S;let o=(T=n.placement)!=null?T:"bottom",r=(g=n.offset)!=null?g:8,i=(S=n.padding)!=null?S:8,l=e.getBoundingClientRect(),a=t.getBoundingClientRect(),c=window.innerWidth,d=window.innerHeight,{side:s,align:u}=hn(o),E=En[s],m=s==="top"||s==="bottom"?a.height:a.width,p=Fe(s,l,c,d)-r<m&&Fe(E,l,c,d)-r>Fe(s,l,c,d)-r?E:s,v,b,M;return p==="top"||p==="bottom"?(v=Lt(p,l,a,r),b=ce(bt(u,l.left,l.width,a.width),i,c-a.width-i),M=ce(l.left+l.width/2-b,R,Math.max(a.width-R,R))):(b=Lt(p,l,a,r),v=ce(bt("center",l.top,l.height,a.height),i,d-a.height-i),M=ce(l.top+l.height/2-v,R,Math.max(a.height-R,R))),{placement:Tn(p,u),top:v,left:b,arrowOffset:M}}function xt(e,t){let n=l=>!e.some(a=>a.contains(l)),o=!1,r=l=>{o=n(l.target)},i=l=>{o&&n(l.target)&&t()};return document.addEventListener("mousedown",r,!0),document.addEventListener("click",i,!0),()=>{document.removeEventListener("mousedown",r,!0),document.removeEventListener("click",i,!0)}}var yn='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Mt(e,t,n={}){var S,$;let o=(S=n.placement)!=null?S:"bottom",r=($=n.offset)!=null?$:8;e.setAttribute("aria-haspopup","dialog"),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded","false"),t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.classList.add("fw-popover");let i=t.parentNode,l=t.nextSibling,a=!1,c=null,d=0;function s(){let h=de(e,t,{placement:o,offset:r});t.style.top=`${h.top}px`,t.style.left=`${h.left}px`,t.setAttribute("data-placement",h.placement)}function u(){cancelAnimationFrame(d),d=requestAnimationFrame(s)}function E(h){h.key==="Escape"&&(h.stopPropagation(),v())}function m(h){let N=h.relatedTarget;N&&(t.contains(N)||e.contains(N))||setTimeout(()=>{if(!a)return;let O=document.activeElement;O===document.body||O===null||t.contains(O)||e.contains(O)||v()},0)}function p(){if(a)return;a=!0,t.parentNode!==document.body&&document.body.appendChild(t),s(),t.classList.add("is-open"),e.setAttribute("aria-expanded","true");let h=t.querySelector(yn);h?h.focus({preventScroll:!0}):(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0})),c=xt([e,t],v),window.addEventListener("scroll",u,!0),window.addEventListener("resize",u),t.addEventListener("keydown",E),t.addEventListener("focusout",m),t.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}))}function v(){if(!a)return;a=!1,t.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),c==null||c(),c=null,window.removeEventListener("scroll",u,!0),window.removeEventListener("resize",u),t.removeEventListener("keydown",E),t.removeEventListener("focusout",m),cancelAnimationFrame(d),l===null||l.parentNode===i?i.insertBefore(t,l):i.appendChild(t),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),e.focus({preventScroll:!0})}function b(){(a?v:p)()}let M=()=>b(),T=Array.from(t.querySelectorAll("[data-fw-popover-close]")),g=()=>v();return e.addEventListener("click",M),T.forEach(h=>h.addEventListener("click",g)),{open:p,close:v,toggle:b,destroy(){a&&v(),e.removeEventListener("click",M),T.forEach(h=>h.removeEventListener("click",g)),delete e.dataset.fwBound}}}function Ve(e=document){e.querySelectorAll("[data-fw-popover-trigger]").forEach(t=>{var r;if(t.dataset.fwBound)return;let n=(r=t.dataset.fwPopoverTrigger)!=null?r:"",o=document.getElementById(n);if(!o){console.warn(`fernwell: popover trigger references missing panel #${n}`);return}t.dataset.fwBound="1",Mt(t,o,{placement:t.dataset.fwPopoverPlacement||void 0,offset:t.dataset.fwPopoverOffset?Number(t.dataset.fwPopoverOffset):void 0})})}var me={};y(me,{init:()=>_e,tooltip:()=>Ot});var Ln=400,bn=300,xn=100,Z=new WeakMap,x=null,k=null,W=0,U=0,je=0,At=0;function Mn(){if(x&&x.isConnected)return x;let e=document.createElement("div");return e.className="fw-tooltip",e.id="fw-tooltip",e.setAttribute("role","tooltip"),document.body.appendChild(e),e.addEventListener("mouseenter",kt),e.addEventListener("mouseleave",()=>St()),x=e,e}function kt(){clearTimeout(U)}function gt(){if(!k||!x)return;let e=Z.get(k);if(!e)return;let t=de(k,x,{placement:e.placement,offset:e.offset});x.style.top=`${t.top}px`,x.style.left=`${t.left}px`,x.style.setProperty("--fw-tooltip-arrow-pos",`${t.arrowOffset}px`),x.setAttribute("data-placement",t.placement)}function fe(){cancelAnimationFrame(je),je=requestAnimationFrame(gt)}function Ht(e){var o;if(clearTimeout(W),kt(),!Z.get(e))return;k=e;let n=Mn();n.textContent=(o=e.dataset.fwTooltipText)!=null?o:"",gt(),n.classList.add("is-open"),window.addEventListener("scroll",fe,!0),window.addEventListener("resize",fe)}function _(){clearTimeout(W),clearTimeout(U),x&&x.classList.remove("is-open"),window.removeEventListener("scroll",fe,!0),window.removeEventListener("resize",fe),cancelAnimationFrame(je),k&&(At=performance.now()),k=null}function Ke(e,t){clearTimeout(U),clearTimeout(W);let n=Z.get(e);n&&(t||performance.now()-At<bn?Ht(e):W=window.setTimeout(()=>Ht(e),n.delay))}function St(){clearTimeout(W),clearTimeout(U),U=window.setTimeout(_,xn)}function Ot(e,t={}){var d,s,u;let n={placement:(d=t.placement)!=null?d:"top",offset:(s=t.offset)!=null?s:6,delay:(u=t.delay)!=null?u:Ln};Z.set(e,n);let o=e.getAttribute("title");o!==null&&(e.dataset.fwTooltipText=o,e.removeAttribute("title")),e.setAttribute("aria-describedby","fw-tooltip");let r=()=>Ke(e,!1),i=()=>St(),l=()=>Ke(e,!0),a=()=>{k===e&&_()},c=E=>{E.key==="Escape"&&k===e&&_()};return e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",i),e.addEventListener("focus",l),e.addEventListener("blur",a),e.addEventListener("keydown",c),{show:()=>Ke(e,!0),hide:()=>{k===e&&_()},destroy(){k===e&&_(),e.removeEventListener("mouseenter",r),e.removeEventListener("mouseleave",i),e.removeEventListener("focus",l),e.removeEventListener("blur",a),e.removeEventListener("keydown",c),e.removeAttribute("aria-describedby"),e.dataset.fwTooltipText!==void 0&&(e.setAttribute("title",e.dataset.fwTooltipText),delete e.dataset.fwTooltipText),Z.delete(e),delete e.dataset.fwBound}}}function _e(e=document){e.querySelectorAll("[data-fw-tooltip]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Ot(t,{placement:t.dataset.fwTooltipPlacement||void 0,offset:t.dataset.fwTooltipOffset?Number(t.dataset.fwTooltipOffset):void 0,delay:t.dataset.fwTooltipDelay?Number(t.dataset.fwTooltipDelay):void 0}))})}var ve={};y(ve,{init:()=>We,tabs:()=>It});function Hn(e,t){e.dispatchEvent(new CustomEvent("fw:tabs-change",{bubbles:!0,detail:t}))}function pe(e){return e.getAttribute("aria-disabled")==="true"}function Ze(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function Ct(e){return e instanceof Element?e.closest('[role="tab"]'):null}function Dt(e,t,n){for(let o=1;o<=e.length;o++){let r=((t+n*o)%e.length+e.length)%e.length;if(!pe(e[r]))return e[r]}}function Pt(e){return e.find(t=>!pe(t))}function An(e){for(let t=e.length-1;t>=0;t--)if(!pe(e[t]))return e[t]}function It(e,t={}){var d;let n=(d=t.activation)!=null?d:"automatic";function o(){return Array.from(e.querySelectorAll('[role="tab"]'))}function r(s,u=!1){if(pe(s))return;o().forEach(m=>{let p=m===s;m.setAttribute("aria-selected",String(p)),m.tabIndex=p?0:-1;let v=Ze(m);v&&(v.hidden=!p)}),u&&s.focus();let E=Ze(s);E&&Hn(e,{tab:s,panel:E})}function i(s){o().forEach(u=>{u.tabIndex=u===s?0:-1}),s.focus()}function l(){var E;let s=o(),u=(E=s.find(m=>m.getAttribute("aria-selected")==="true"))!=null?E:Pt(s);s.forEach(m=>{let p=m===u;m.setAttribute("aria-selected",String(p)),m.tabIndex=p?0:-1;let v=Ze(m);v&&(v.hidden=!p)})}function a(s){let u=Ct(s.target);u&&e.contains(u)&&r(u,!1)}function c(s){let u=Ct(s.target);if(!u)return;let E=o(),m=E.indexOf(u);if(m===-1)return;if(s.key===" "||s.key==="Enter"){n==="manual"&&(s.preventDefault(),r(u,!1));return}let p=e.getAttribute("aria-orientation")==="vertical",v=getComputedStyle(e).direction==="rtl",b=p?"ArrowDown":v?"ArrowLeft":"ArrowRight",M=p?"ArrowUp":v?"ArrowRight":"ArrowLeft",T;if(s.key===b)T=Dt(E,m,1);else if(s.key===M)T=Dt(E,m,-1);else if(s.key==="Home")T=Pt(E);else if(s.key==="End")T=An(E);else return;T&&(s.preventDefault(),n==="manual"?i(T):r(T,!0))}return e.addEventListener("click",a),e.addEventListener("keydown",c),l(),{activate:r,destroy(){e.removeEventListener("click",a),e.removeEventListener("keydown",c),delete e.dataset.fwBound}}}function We(e=document){e.querySelectorAll('[role="tablist"][data-fw-tabs]').forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.dataset.fwTabsActivation==="manual"?"manual":"automatic";It(t,{activation:n})})}var Nt="0.4.0";function Bt(e=document){Le(e),be(e),ge(e),Ce(e),De(e),Re(e),$e(e),he(e),Ve(e),_e(e),We(e)}var kn={version:Nt,init:Bt,theme:X,combobox:J,modal:Q,nav:te,loading:ne,toast:oe,table:ie,menu:ae,icon:z,popover:ue,tooltip:me,tabs:ve},gn=kn;
|
|
1
|
+
/*! fernwell v0.6.0 | MIT | https://github.com/JacobKnaack/fernwell */
|
|
2
|
+
"use strict";var De=Object.defineProperty;var Dn=Object.getOwnPropertyDescriptor;var Bn=Object.getOwnPropertyNames;var Pn=Object.prototype.hasOwnProperty;var g=(e,t)=>{for(var n in t)De(e,n,{get:t[n],enumerable:!0})},$n=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Bn(t))!Pn.call(e,r)&&r!==n&&De(e,r,{get:()=>t[r],enumerable:!(o=Dn(t,r))||o.enumerable});return e};var qn=e=>$n(De({},"__esModule",{value:!0}),e);var Do={};g(Do,{combobox:()=>ve,default:()=>Io,icon:()=>se,init:()=>Nn,loading:()=>ye,menu:()=>Me,modal:()=>be,nav:()=>he,numberInput:()=>Ie,popover:()=>Ae,table:()=>Te,tabs:()=>Ce,theme:()=>pe,toast:()=>Ee,tokens:()=>fe,tooltip:()=>Oe,version:()=>On});module.exports=qn(Do);var pe={};g(pe,{get:()=>Ue,getToken:()=>Ve,init:()=>We,resetTokens:()=>Fe,set:()=>me,setTokens:()=>Q,toggle:()=>Ut});var se={};g(se,{init:()=>Be,render:()=>F});var Rn={add:'<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',minus:'<line x1="5" y1="12" x2="19" y2="12"/>',close:'<line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/>',check:'<polyline points="5,13 10,18 19,7"/>',edit:'<path d="M16.8 3.5a2.1 2.1 0 0 1 3 3L8.5 17.8 4 19l1.2-4.5Z"/><line x1="14.5" y1="5.8" x2="17.7" y2="9"/>',trash:'<path d="M4 7h16"/><path d="M9 7V4.6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1V7"/><path d="M6.5 7l.8 12.4A2 2 0 0 0 9.3 21h5.4a2 2 0 0 0 2-1.6L18 7"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',save:'<path d="M5 4a1 1 0 0 1 1-1h9.2a1 1 0 0 1 .7.3l2.8 2.8a1 1 0 0 1 .3.7V20a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4Z"/><path d="M8 3v5h7V3"/><path d="M8 21v-6h8v6"/>',search:'<circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.6" y2="16.6"/>',settings:'<circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"/>',download:'<line x1="12" y1="3" x2="12" y2="15"/><polyline points="7,10 12,15 17,10"/><line x1="5" y1="21" x2="19" y2="21"/>',upload:'<line x1="12" y1="15" x2="12" y2="3"/><polyline points="7,8 12,3 17,8"/><line x1="5" y1="21" x2="19" y2="21"/>',share:'<circle cx="6" cy="12" r="2.3"/><circle cx="18" cy="6" r="2.3"/><circle cx="18" cy="18" r="2.3"/><line x1="8.1" y1="10.8" x2="15.9" y2="7.2"/><line x1="8.1" y1="13.2" x2="15.9" y2="16.8"/>',copy:'<rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1"/>',menu:'<line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/>',more:'<circle cx="5" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.4" fill="currentColor" stroke="none"/>',user:'<circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/>',bell:'<path d="M6 8a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6"/><path d="M10 20a2 2 0 0 0 4 0"/>',heart:'<path d="M12 20s-7-4.4-9.5-8.5C.8 8 2 4.5 5.5 4.5c2 0 3.5 1 6.5 4 3-3 4.5-4 6.5-4 3.5 0 4.7 3.5 3 7-2.5 4.1-9.5 8.5-9.5 8.5Z"/>',star:'<polygon points="12,3 14.6,9.1 21.2,9.3 16,13.4 17.8,19.8 12,16.3 6.2,19.8 8,13.4 2.8,9.3 9.4,9.1"/>',calendar:'<rect x="3" y="5" width="18" height="16" rx="2"/><line x1="8" y1="3" x2="8" y2="7"/><line x1="16" y1="3" x2="16" y2="7"/><line x1="3" y1="10" x2="21" y2="10"/>',refresh:'<path d="M20 11A8 8 0 0 0 6.3 6.3L4 8.6"/><path d="M4 4v5h5"/><path d="M4 13a8 8 0 0 0 13.7 4.7L20 15.4"/><path d="M20 20v-5h-5"/>',filter:'<polygon points="4,4 20,4 14,12 14,19 10,21 10,12"/>',info:'<circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><circle cx="12" cy="8" r="1" fill="currentColor" stroke="none"/>',warning:'<path d="M12 3 22 20H2Z"/><line x1="12" y1="9.5" x2="12" y2="14.5"/><circle cx="12" cy="17.3" r="1" fill="currentColor" stroke="none"/>',lock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>',eye:'<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',"chevron-down":'<polyline points="6,9 12,15 18,9"/>',"arrow-left":'<line x1="19" y1="12" x2="5" y2="12"/><polyline points="12,5 5,12 12,19"/>',"arrow-right":'<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12,5 19,12 12,19"/>',folder:'<path d="M3.5 6.5a1 1 0 0 1 1-1H10l2 2.2h7.5a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H4.5a1 1 0 0 1-1-1Z"/>',bookmark:'<path d="M6 3h12a1 1 0 0 1 1 1v17l-7-4-7 4V4a1 1 0 0 1 1-1Z"/>',home:'<path d="M4 11.5 12 4l8 7.5"/><path d="M6 10v10a1 1 0 0 0 1 1h3.5v-6h2.8v6H17a1 1 0 0 0 1-1V10"/>',logout:'<path d="M9 4H5.5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1H9"/><line x1="14" y1="12" x2="21" y2="12"/><polyline points="17.5,8.5 21,12 17.5,15.5"/>',paperclip:'<path d="M21 11.5 12.4 20a4.3 4.3 0 0 1-6-6.1L15 5.3a2.9 2.9 0 0 1 4.1 4.1l-8.6 8.6a1.4 1.4 0 0 1-2-2l7.9-7.9"/>',envelope:'<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M4 6.5 12 13l8-6.5"/>',"chevron-up":'<polyline points="6,15 12,9 18,15"/>',"chevron-left":'<polyline points="15,6 9,12 15,18"/>',"chevron-right":'<polyline points="9,6 15,12 9,18"/>',"arrow-up":'<line x1="12" y1="19" x2="12" y2="5"/><polyline points="5,12 12,5 19,12"/>',"arrow-down":'<line x1="12" y1="5" x2="12" y2="19"/><polyline points="5,12 12,19 19,12"/>',unlock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 7.8-1.3"/>',"thumbs-up":'<path d="M7 11v9H4.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1H7Z"/><path d="M7 11l4.3-7.3a1.4 1.4 0 0 1 2.6.8L13 9h5.6a2 2 0 0 1 1.9 2.6l-2 6.5A2 2 0 0 1 16.6 19.5H10a3 3 0 0 1-3-3"/>',"thumbs-down":'<path d="M7 13V4h2.5a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H7Z"/><path d="M7 13l4.3 7.3a1.4 1.4 0 0 0 2.6-.8L13 15h5.6a2 2 0 0 0 1.9-2.6l-2-6.5A2 2 0 0 0 16.6 4.5H10a3 3 0 0 0-3 3"/>',"eye-closed":'<path d="M3.5 12S7 6 12 6s8.5 6 8.5 6-3.5 6-8.5 6-8.5-6-8.5-6Z"/><line x1="4" y1="19" x2="20" y2="5"/>',"help-circle":'<circle cx="12" cy="12" r="9"/><path d="M9.2 9.2a2.8 2.8 0 1 1 4.3 2.4c-.9.6-1.5 1.1-1.5 2.2"/><circle cx="12" cy="17" r="1" fill="currentColor" stroke="none"/>',chat:'<path d="M4 5.5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9.5L5 20.5V16.5H5a1 1 0 0 1-1-1Z"/>',kebab:'<circle cx="12" cy="5" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="19" r="1.4" fill="currentColor" stroke="none"/>',sun:'<circle cx="12" cy="12" r="4"/><line x1="12" y1="2" x2="12" y2="4.5"/><line x1="12" y1="19.5" x2="12" y2="22"/><line x1="2" y1="12" x2="4.5" y2="12"/><line x1="19.5" y1="12" x2="22" y2="12"/><line x1="4.9" y1="4.9" x2="6.6" y2="6.6"/><line x1="17.4" y1="17.4" x2="19.1" y2="19.1"/><line x1="4.9" y1="19.1" x2="6.6" y2="17.4"/><line x1="17.4" y1="6.6" x2="19.1" y2="4.9"/>',moon:'<path d="M20.5 14.2A8.5 8.5 0 1 1 9.8 3.5a7 7 0 0 0 10.7 10.7Z"/>'},St=["xs","sm","md","lg","xl"],Ot=["thin","regular","bold"];function F(e){let t=Rn[e];return t?`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${t}</svg>`:""}function Fn(e,t){if(t){if(!St.includes(t)){console.warn(`fernwell: unknown icon size "${t}" (expected ${St.join(", ")})`);return}e.classList.add(`fw-icon-${t}`)}}function jn(e,t){if(!t)return;if(Ot.includes(t)){e.classList.add(`fw-icon-stroke-${t}`);return}let n=Number(t);if(!Number.isFinite(n)||n<=0){console.warn(`fernwell: unknown icon stroke "${t}" (expected ${Ot.join(", ")} or a positive number)`);return}e.style.setProperty("--fw-icon-stroke",String(n))}function Be(e=document){e.querySelectorAll("[data-fw-icon]").forEach(t=>{var r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=t.dataset.fwIcon)!=null?r:"",o=F(n);o||console.warn(`fernwell: unknown icon "${n}"`),t.innerHTML=o,t.classList.add("fw-icon"),Fn(t,t.dataset.fwIconSize),jn(t,t.dataset.fwIconStroke)})}var fe={};g(fe,{getToken:()=>Ve,init:()=>Ke,resetTokens:()=>Fe,restoreTokens:()=>_t,setTokens:()=>Q});var Nt=[{name:"primary-hover",light:"color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%)",dark:"color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%)",deps:["primary","text"]},{name:"primary-soft",light:"color-mix(in srgb, var(--fw-primary), white 35%)",dark:"color-mix(in srgb, var(--fw-primary), white 35%)",deps:["primary"]},{name:"secondary-hover",light:"color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%)",dark:"color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%)",deps:["secondary","text"]},{name:"secondary-bg",light:"color-mix(in srgb, var(--fw-secondary) 10%, var(--fw-surface))",dark:"color-mix(in srgb, var(--fw-secondary) 16%, transparent)",deps:["secondary","surface"]},{name:"success-bg",light:"color-mix(in srgb, var(--fw-success) 12%, var(--fw-surface))",dark:"color-mix(in srgb, var(--fw-success) 14%, transparent)",deps:["success","surface"]},{name:"warning-bg",light:"color-mix(in srgb, var(--fw-warning) 14%, var(--fw-surface))",dark:"color-mix(in srgb, var(--fw-warning) 16%, transparent)",deps:["warning","surface"]},{name:"danger-bg",light:"color-mix(in srgb, var(--fw-danger) 13%, var(--fw-surface))",dark:"color-mix(in srgb, var(--fw-danger) 14%, transparent)",deps:["danger","surface"]},{name:"info-bg",light:"color-mix(in srgb, var(--fw-info) 12%, var(--fw-surface))",dark:"color-mix(in srgb, var(--fw-info) 14%, transparent)",deps:["info","surface"]},{name:"on-secondary-soft",light:"color-mix(in srgb, var(--fw-on-secondary) 72%, transparent)",dark:"color-mix(in srgb, var(--fw-on-secondary) 72%, transparent)",deps:["on-secondary"]},{name:"on-secondary-fill",light:"color-mix(in srgb, var(--fw-on-secondary) 10%, transparent)",dark:"color-mix(in srgb, var(--fw-on-secondary) 10%, transparent)",deps:["on-secondary"]},{name:"on-secondary-line",light:"color-mix(in srgb, var(--fw-on-secondary) 16%, transparent)",dark:"color-mix(in srgb, var(--fw-on-secondary) 16%, transparent)",deps:["on-secondary"]},{name:"focus-ring",light:"0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent)",dark:"0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent)",deps:["primary"]},{name:"scrollbar-thumb",light:"var(--fw-text-soft)",dark:"var(--fw-text-soft)",deps:["text-soft"]},{name:"scrollbar-thumb-hover",light:"color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%)",dark:"color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%)",deps:["text-soft","text"]},{name:"shadow-primary",light:"0 6px 16px color-mix(in srgb, var(--fw-primary) 35%, transparent)",dark:"0 6px 16px color-mix(in srgb, var(--fw-primary) 22%, transparent)",deps:["primary"]},{name:"shadow-success",light:"0 6px 16px color-mix(in srgb, var(--fw-success) 28%, transparent)",dark:"0 6px 16px color-mix(in srgb, var(--fw-success) 22%, transparent)",deps:["success"]}];var Y="--fw-",Ct="data-fw-tokens",Pe="fw-tokens",It="fw-tokens-css",Vn="fw:tokenschange",de=":root",N=new Map,ae=new Map,ue=!1,Kn=0,X=new Map,Re=new WeakSet;function jt(){try{return window.localStorage}catch{return null}}function Vt(e){return e.startsWith("--")?e:`${Y}${e}`}function _n(e){return e.startsWith(Y)?e.slice(Y.length):e}function le(e){console.warn(`fernwell: ${e}`)}function Kt(e){try{return document.querySelector(e),!0}catch{return!1}}function zn(e){let t=0,n="";for(let o=0;o<e.length;o++){let r=e[o];if(r==="\\")o++;else if(n){if(r===n)n="";else if(r===`
|
|
3
|
+
`)return!1}else if(r==='"'||r==="'")n=r;else if(r==="(")t++;else if(r===")"&&--t<0)return!1}return t===0&&!n}function J(e){let t={};if(e===null||typeof e!="object")return t;for(let[n,o]of Object.entries(e))/^(--)?[\w-]+$/.test(n)?typeof o!="string"||/[{};]|\/\*/.test(o)||!zn(o)?le(`ignoring invalid value for token "${n}"`):t[Vt(n)]=o.trim():le(`ignoring token with invalid name "${n}"`);return t}function Un(e){return Object.values(e).some(t=>t!==null&&typeof t=="object")}function Wn(e){let t=[],n=0,o="",r=0;for(let i=0;i<e.length;i++){let s=e[i];s==="\\"?i++:o?s===o&&(o=""):s==='"'||s==="'"?o=s:s==="("||s==="["?n++:s===")"||s==="]"?n--:s===","&&n===0&&(t.push(e.slice(r,i).trim()),r=i+1)}return t.push(e.slice(r).trim()),t.filter(Boolean)}function Zn(e){return e===de?'[data-theme="dark"]':Wn(e).map(t=>`[data-theme="dark"] ${t}, ${t}[data-theme="dark"]`).join(", ")}function Dt(e){return Object.entries(e).map(([t,n])=>`${t}:${n};`).join("")}function Bt(e,t){let n=new Set(Object.keys(e).map(_n)),o=new Set(n),r={};for(let i=!0;i;){i=!1;for(let s of Nt)n.has(s.name)||`${Y}${s.name}`in r||s.deps.some(c=>o.has(c))&&(r[`${Y}${s.name}`]=s[t],o.add(s.name),i=!0)}return r}function $e(e){let t=[];return e.forEach(({light:n,dark:o},r)=>{let i=r===de,s=i?n:{...Bt(n,"light"),...n},c=i?o:{...Bt(o,"dark"),...o};Object.keys(s).length&&t.push(`${r}{${Dt(s)}}`),Object.keys(c).length&&t.push(`${Zn(r)}{${Dt(c)}}`)}),t}function Pt(e){let t=document.head.querySelector(`style[${Ct}]`);if(t)return e&&t!==document.head.lastElementChild&&document.head.appendChild(t),t;if(!e)return null;let n=document.createElement("style");return n.setAttribute(Ct,""),document.head.appendChild(n),n}function qe(){let e=jt();if(e)try{if(N.size===0){e.removeItem(Pe),e.removeItem(It);return}let t={};N.forEach((n,o)=>t[o]=n),e.setItem(Pe,JSON.stringify({v:1,scopes:t})),e.setItem(It,$e(N).join(`
|
|
4
|
+
`))}catch{}}function ce(e){var n;let t=[...$e(N),...$e(ae)];t.length===0?(n=Pt(!1))==null||n.remove():Pt(!0).textContent=t.join(`
|
|
5
|
+
`),document.dispatchEvent(new CustomEvent(Vn,{detail:{scope:e}}))}function $t(e,t){let n=new Map(Object.keys(t).map(o=>[o,o in e?e[o]:void 0]));return Object.assign(e,t),()=>n.forEach((o,r)=>{e[r]===t[r]&&(o===void 0?delete e[r]:e[r]=o)})}function Q(e,t={}){var a,m;let n=(a=t.scope)!=null?a:de;if(!Kt(n))return le(`ignoring tokens for invalid scope "${n}"`),()=>{};ue||je();let o,r;Un(e)?(o=J(e.light),r=J(e.dark)):(o=J(e),r={...o});let i=t.persist?N:ae,s=(m=i.get(n))!=null?m:{light:{},dark:{}},c=$t(s.light,o),d=$t(s.dark,r);i.set(n,s),t.persist&&qe(),ce(n);let u=!1;return()=>{u||(u=!0,c(),d(),!Object.keys(s.light).length&&!Object.keys(s.dark).length&&i.get(n)===s&&i.delete(n),i===N&&qe(),ce(n))}}function Fe(e){ue||je(),X.forEach((n,o)=>{(!e||n.scope===e)&&X.delete(o)});let t=e?N.delete(e):N.size>0;e?ae.delete(e):(N.clear(),ae.clear()),t&&qe(),ce(e)}function _t(){je(),ce()}function je(){var n;ue=!0,N.clear();let e=null;try{let o=(n=jt())==null?void 0:n.getItem(Pe);o&&(e=JSON.parse(o))}catch{}let t=e==null?void 0:e.scopes;if((e==null?void 0:e.v)===1&&t&&typeof t=="object")for(let[o,r]of Object.entries(t)){if(!Kt(o))continue;let i=J(r==null?void 0:r.light),s=J(r==null?void 0:r.dark);(Object.keys(i).length||Object.keys(s).length)&&N.set(o,{light:i,dark:s})}}function Ve(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(Vt(e)).trim()}function qt(e,t){try{let n=JSON.parse(e!=null?e:"");if(n!==null&&typeof n=="object"&&!Array.isArray(n))return n}catch{}return le(`${t} must be a JSON object of tokens`),null}function Gn(){X.forEach((e,t)=>{t.isConnected||(X.delete(t),Re.add(t),e.undo())})}function Rt(e){return!!e.dataset.fwTokensBound&&!Re.has(e)}function Ft(e,t,n){e.dataset.fwTokensBound="1",Re.delete(e),e.isConnected&&X.set(e,{scope:t,undo:n})}function Ke(e=document){ue||_t(),Gn(),e.querySelectorAll('script[type="application/json"][data-fw-theme-tokens]').forEach(t=>{var s;if(Rt(t))return;let n=qt(t.textContent,"data-fw-theme-tokens");if(t.dataset.fwTokensBound="1",!n)return;let o=t.hasAttribute("data-fw-persist"),r=(s=t.dataset.fwScope)!=null?s:de,i=Q(n,{scope:r,persist:o});o||Ft(t,r,i)}),e.querySelectorAll("[data-fw-theme-scope]").forEach(t=>{var i;if(Rt(t))return;let n=qt(t.getAttribute("data-fw-theme-scope"),"data-fw-theme-scope");if(t.dataset.fwTokensBound="1",!n)return;let o=(i=t.getAttribute("data-fw-scope-id"))!=null?i:`fw-s${++Kn}`;t.setAttribute("data-fw-scope-id",o);let r=`[data-fw-scope-id="${o}"]`;Ft(t,r,Q(n,{scope:r}))})}var _e="fw-theme",Jn="fw:themechange",zt="data-fw-theme-init";function ze(){try{return window.localStorage}catch{return null}}function Ue(){var t;let e=document.documentElement.getAttribute("data-theme");return e==="dark"||e==="light"?e:(t=window.matchMedia)!=null&&t.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function me(e,{persist:t=!0}={}){var n;document.documentElement.setAttribute("data-theme",e),t&&((n=ze())==null||n.setItem(_e,e)),document.querySelectorAll("[data-fw-theme-toggle]").forEach(o=>Wt(o,e)),document.dispatchEvent(new CustomEvent(Jn,{detail:e}))}function Ut(){let e=Ue()==="dark"?"light":"dark";return me(e),e}function Wt(e,t){e.setAttribute("aria-pressed",String(t==="dark"));let n=t==="dark"?e.dataset.fwThemeIconDark:e.dataset.fwThemeIconLight,o=t==="dark"?e.dataset.fwThemeLabelDark:e.dataset.fwThemeLabelLight;if(n!==void 0){let r=`<span class="fw-icon" aria-hidden="true">${F(n)}</span>`;e.innerHTML=o!==void 0?`${r} ${o}`:r}else o!==void 0&&(e.textContent=o)}function Yn(e){let t=typeof requestAnimationFrame=="function"?requestAnimationFrame:n=>setTimeout(n,16);t(()=>t(e))}function We(e=document){var r,i,s,c;let t=(r=ze())==null?void 0:r.getItem(_e),n=t==="dark"||t==="light"?t:Ue(),o=document.documentElement;o.setAttribute(zt,""),me(n,{persist:!1}),Yn(()=>o.removeAttribute(zt)),e.querySelectorAll("[data-fw-theme-toggle]").forEach(d=>{d.dataset.fwBound||(d.dataset.fwBound="1",Wt(d,n),d.addEventListener("click",()=>Ut()))}),(c=(i=window.matchMedia)==null?void 0:(s=i.call(window,"(prefers-color-scheme: dark)")).addEventListener)==null||c.call(s,"change",d=>{var u;(u=ze())!=null&&u.getItem(_e)||me(d.matches?"dark":"light",{persist:!1})})}var ve={};g(ve,{combobox:()=>Zt,init:()=>Ze});var Xn=0;function ee(e){return e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}function Zt(e,t={}){var b,B,C,z;let n=(b=t.filter)!=null?b:((p,y)=>p.toLowerCase().includes(y)),o=(B=t.emptyText)!=null?B:"No matches",r=(C=t.options)!=null?C:Qn(e),i=[],s=-1,c=!1,d=e.getAttribute("list");d&&(e.dataset.fwList=d,e.removeAttribute("list"));let u=(z=e.closest(".fw-combobox"))!=null?z:eo(e),a=document.createElement("ul"),m=`fw-combobox-${++Xn}`;a.className="fw-combobox-list",a.id=m,a.setAttribute("role","listbox"),u.appendChild(a),e.setAttribute("role","combobox"),e.setAttribute("aria-autocomplete","list"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",m),e.autocomplete="off";function E(p){i=p,s=-1;let y=e.value.trim().toLowerCase();if(p.length===0){a.innerHTML=`<li class="fw-combobox-empty">${ee(o)}</li>`;return}a.innerHTML=p.map((A,$)=>{let P=y?A.toLowerCase().indexOf(y):-1,G=P>-1?`${ee(A.slice(0,P))}<b>${ee(A.slice(P,P+y.length))}</b>${ee(A.slice(P+y.length))}`:ee(A);return`<li class="fw-combobox-option" role="option" id="${m}-${$}" data-index="${$}" aria-selected="false">${G}</li>`}).join("")}function w(){let p=e.value.trim().toLowerCase();E(p?r.filter(y=>n(y,p)):r),a.classList.add("is-open"),e.setAttribute("aria-expanded","true")}function v(){a.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),e.removeAttribute("aria-activedescendant"),s=-1}function f(p){let y=a.querySelectorAll(".fw-combobox-option");y.forEach($=>{$.classList.remove("is-active"),$.setAttribute("aria-selected","false")});let A=y[p];A&&(A.classList.add("is-active"),A.setAttribute("aria-selected","true"),A.scrollIntoView({block:"nearest"}),e.setAttribute("aria-activedescendant",A.id)),s=p}function M(p){var y;e.value=p,v(),c=!0,e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),c=!1,(y=t.onSelect)==null||y.call(t,p)}let k=()=>{c||w()},T=()=>{c||w()},H=p=>{p.key==="ArrowDown"?(p.preventDefault(),a.classList.contains("is-open")||w(),f(Math.min(s+1,i.length-1))):p.key==="ArrowUp"?(p.preventDefault(),f(Math.max(s-1,0))):p.key==="Enter"?s>-1&&i[s]!==void 0&&(p.preventDefault(),M(i[s])):p.key==="Escape"&&v()},x=p=>{let y=p.target.closest(".fw-combobox-option");y&&(p.preventDefault(),M(i[Number(y.dataset.index)]))},L=p=>{u.contains(p.target)||v()};return e.addEventListener("input",k),e.addEventListener("focus",T),e.addEventListener("keydown",H),a.addEventListener("mousedown",x),document.addEventListener("click",L),{open:w,close:v,setOptions(p){r=p,a.classList.contains("is-open")&&w()},destroy(){e.removeEventListener("input",k),e.removeEventListener("focus",T),e.removeEventListener("keydown",H),a.removeEventListener("mousedown",x),document.removeEventListener("click",L),a.remove(),e.dataset.fwList&&e.setAttribute("list",e.dataset.fwList),delete e.dataset.fwBound}}}function Qn(e){var o;let t=(o=e.getAttribute("list"))!=null?o:e.dataset.fwList,n=t?document.getElementById(t):null;return n?Array.from(n.querySelectorAll("option")).map(r=>r.value||r.textContent||""):[]}function eo(e){var n;let t=document.createElement("div");return t.className="fw-combobox",(n=e.parentNode)==null||n.insertBefore(t,e),t.appendChild(e),t}function Ze(e=document){e.querySelectorAll("input[data-fw-combobox]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Zt(t))})}var be={};g(be,{bindOutsideClickToClose:()=>Je,close:()=>j,init:()=>et,open:()=>Qe,toggle:()=>no});var V="is-open",Jt="fw-scroll-lock",K=[],Ge=new WeakMap,to='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ye(e){return typeof e=="string"?document.getElementById(e):e}function Xe(e){if(e.classList.contains("fw-modal-overlay"))return e;let t=e.id?document.querySelector(`[data-fw-drawer-overlay="${e.id}"]`):null;if(t)return t;let n=e.previousElementSibling;return n instanceof HTMLElement&&n.classList.contains("fw-drawer-overlay")?n:null}function Qe(e,t=(n=>(n=document.activeElement)!=null?n:null)()){var i;let o=Ye(e);if(!o||o.classList.contains(V))return;o.classList.add(V),(i=Xe(o))==null||i.classList.add(V),Ge.set(o,t),K.push(o),document.body.classList.add(Jt),o.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}));let r=o.querySelector(to);r?r.focus({preventScroll:!0}):(o.hasAttribute("tabindex")||o.setAttribute("tabindex","-1"),o.focus({preventScroll:!0}))}function j(e){var o,r,i;let t=Ye(e);if(!t||!t.classList.contains(V))return;t.classList.remove(V),(o=Xe(t))==null||o.classList.remove(V);let n=K.indexOf(t);n>-1&&K.splice(n,1),K.length===0&&document.body.classList.remove(Jt),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),(i=(r=Ge.get(t))==null?void 0:r.focus)==null||i.call(r,{preventScroll:!0}),Ge.delete(t)}function no(e){let t=Ye(e);t&&(t.classList.contains(V)?j:Qe)(t)}function Je(e,t){let n=!1;e.addEventListener("mousedown",o=>{n=o.target===e}),e.addEventListener("click",o=>{o.target===e&&n&&t()})}var Gt=!1;function et(e=document){e.querySelectorAll("[data-fw-open-modal], [data-fw-open-drawer]").forEach(t=>{var o,r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=(o=t.dataset.fwOpenModal)!=null?o:t.dataset.fwOpenDrawer)!=null?r:"";t.addEventListener("click",()=>Qe(n,t))}),e.querySelectorAll(".fw-modal-overlay").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Je(t,()=>j(t)),t.querySelectorAll("[data-fw-close-modal]").forEach(n=>n.addEventListener("click",()=>j(t))))}),e.querySelectorAll(".fw-drawer").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Xe(t);n&&Je(n,()=>j(t)),t.querySelectorAll("[data-fw-close-drawer]").forEach(o=>o.addEventListener("click",()=>j(t)))}),Gt||(Gt=!0,document.addEventListener("keydown",t=>{t.key==="Escape"&&K.length&&j(K[K.length-1])}))}var he={};g(he,{close:()=>we,init:()=>ot,open:()=>Yt});var tt="is-open";function Yt(e){let t=nt(e);t&&(t.classList.add(tt),e.setAttribute("aria-expanded","true"))}function we(e){let t=nt(e);t&&(t.classList.remove(tt),e.setAttribute("aria-expanded","false"))}function nt(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function ot(e=document){e.querySelectorAll("[data-fw-nav-toggle]").forEach(t=>{var r,i;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=nt(t);if(!n)return;let o=(i=(r=t.closest(".fw-nav"))!=null?r:t.parentElement)!=null?i:t;t.addEventListener("click",s=>{s.stopPropagation(),(n.classList.contains(tt)?we:Yt)(t)}),document.addEventListener("click",s=>{!o.contains(s.target)&&!n.contains(s.target)&&we(t)}),document.addEventListener("keydown",s=>{s.key==="Escape"&&we(t)})})}var ye={};g(ye,{init:()=>rt,resetAll:()=>tn,resetButtonLoading:()=>en,setButtonLoading:()=>Qt});var te="fw-btn-loading";function Qt(e,t){var o,r;if(!e||e.classList.contains(te))return;e.dataset.fwOriginalHtml=e.innerHTML,e.disabled=!0,e.setAttribute("aria-busy","true"),e.classList.add(te);let n=(r=(o=t!=null?t:e.dataset.fwLoadingText)!=null?o:e.textContent)!=null?r:"";e.innerHTML='<span class="fw-spinner fw-spinner-sm" aria-hidden="true"></span>',e.appendChild(document.createTextNode(n))}function en(e){!e||!e.classList.contains(te)||(e.disabled=!1,e.removeAttribute("aria-busy"),e.classList.remove(te),e.dataset.fwOriginalHtml!==void 0&&(e.innerHTML=e.dataset.fwOriginalHtml,delete e.dataset.fwOriginalHtml))}function tn(e=document){e.querySelectorAll(`.${te}`).forEach(en)}var Xt=!1;function rt(e=document){e.querySelectorAll("form[data-fw-loading]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",t.addEventListener("submit",()=>{let n=t.querySelector('button[type="submit"], button:not([type])');Qt(n)}))}),Xt||(Xt=!0,window.addEventListener("pageshow",t=>{t.persisted&&tn()}))}var Ee={};g(Ee,{hide:()=>nn,show:()=>ro});var S=null,W=null;function oo(){return S&&S.isConnected||(S=document.createElement("div"),S.className="fw-toast",S.setAttribute("role","status"),S.setAttribute("aria-live","polite"),S.innerHTML='<span class="fw-toast-dot" aria-hidden="true"></span><span class="fw-toast-text"></span>',document.body.appendChild(S)),S}function ro(e,{variant:t="success",duration:n=4e3}={}){let o=oo();return o.className=`fw-toast${t==="success"?"":` fw-toast-${t}`}`,o.querySelector(".fw-toast-text").textContent=e,W&&clearTimeout(W),o.classList.remove("is-show"),o.offsetWidth,o.classList.add("is-show"),n>0&&(W=setTimeout(nn,n)),o}function nn(){S==null||S.classList.remove("is-show"),W&&clearTimeout(W),W=null}var Te={};g(Te,{getSelected:()=>ct,init:()=>dt,selectAll:()=>ln,setRowSelected:()=>an,sort:()=>it});var io="is-selected";function st(e,t,n){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n}))}function on(e,t){var o,r,i;let n=e.cells[t];return(i=(r=n==null?void 0:n.dataset.fwSortValue)!=null?r:(o=n==null?void 0:n.textContent)==null?void 0:o.trim())!=null?i:""}function so(e,t){let n=Number(e),o=Number(t);return e!==""&&t!==""&&Number.isFinite(n)&&Number.isFinite(o)?n-o:e.localeCompare(t,void 0,{numeric:!0,sensitivity:"base"})}function sn(e){var t,n;return Array.from((n=(t=e.tHead)==null?void 0:t.querySelectorAll("th[data-fw-sort]"))!=null?n:[])}function rn(e){return e.getAttribute("aria-sort")==="ascending"?"descending":"ascending"}function it(e,t,n){let o=e.tBodies[0];if(!o)return;let r=Array.from(o.rows),i=r.filter(u=>u.cells.length>t),s=r.filter(u=>u.cells.length<=t),c=n==="ascending"?1:-1;i.sort((u,a)=>c*so(on(u,t),on(a,t))),[...i,...s].forEach(u=>o.appendChild(u));let d=null;sn(e).forEach(u=>{let a=u.cellIndex===t;u.setAttribute("aria-sort",a?n:"none"),a&&(d=u)}),d&&st(e,"fw:sort",{column:t,direction:n,th:d})}function xe(e){return Array.from(e.querySelectorAll("tbody input[data-fw-select-row]"))}function at(e,t){e.classList.toggle(io,t),e.setAttribute("aria-selected",t?"true":"false")}function lt(e){let t=e.querySelector("[data-fw-select-all]");if(!t)return;let n=xe(e),o=n.filter(r=>r.checked).length;t.checked=o>0&&o===n.length,t.indeterminate=o>0&&o<n.length}function ct(e){return xe(e).filter(t=>t.checked).map(t=>t.closest("tr")).filter(t=>t!==null)}function an(e,t){let n=e.querySelector("input[data-fw-select-row]");n&&(n.checked=t),at(e,t);let o=e.closest("table");o&&(lt(o),st(o,"fw:select",{rows:ct(o),all:!1}))}function ln(e,t){xe(e).forEach(n=>{n.checked=t;let o=n.closest("tr");o&&at(o,t)}),lt(e),st(e,"fw:select",{rows:ct(e),all:!0})}function dt(e=document){e.querySelectorAll("table[data-fw-table]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",sn(t).forEach(n=>{n.hasAttribute("aria-sort")||n.setAttribute("aria-sort","none")}),t.addEventListener("click",n=>{let o=n.target.closest("th[data-fw-sort]");o&&t.contains(o)&&it(t,o.cellIndex,rn(o))}),t.addEventListener("keydown",n=>{if(n.key!=="Enter"&&n.key!==" ")return;let o=n.target;if(!o.matches("th[data-fw-sort], th[data-fw-sort] .fw-table-sort"))return;let r=o.closest("th[data-fw-sort]");r&&(n.preventDefault(),it(t,r.cellIndex,rn(r)))}),t.addEventListener("change",n=>{let o=n.target;if(o.matches("[data-fw-select-all]"))ln(t,o.checked);else if(o.matches("[data-fw-select-row]")){let r=o.closest("tr");r&&an(r,o.checked)}}),xe(t).forEach(n=>{let o=n.closest("tr");o&&n.checked&&at(o,!0)}),lt(t))})}var Me={};g(Me,{close:()=>ge,collapseAll:()=>fo,expandAll:()=>uo,init:()=>ut,open:()=>Le,reveal:()=>un,toggle:()=>co});var I=".fw-menu-group",dn=".fw-menu-link, .fw-menu-summary",ao="is-current";function lo(e,t){e.dispatchEvent(new CustomEvent("fw:toggle",{bubbles:!0,detail:t}))}function Le(e){e.open=!0}function ge(e){e.open=!1}function co(e,t){e.open=t!=null?t:!e.open}function uo(e){e.querySelectorAll(I).forEach(Le)}function fo(e){e.querySelectorAll(I).forEach(ge)}function un(e){var n,o,r,i;let t=(o=(n=e.parentElement)==null?void 0:n.closest(I))!=null?o:null;for(;t;)Le(t),t=(i=(r=t.parentElement)==null?void 0:r.closest(I))!=null?i:null}function cn(e){e.querySelectorAll(I).forEach(t=>{let n=t.querySelector(":scope > .fw-menu-summary");if(!n)return;let o=!t.open&&t.querySelector("[aria-current]")!==null;n.classList.toggle(ao,o)})}function fn(e){return e.matches(".fw-menu-summary")?e.closest(I):null}function mn(e){var n,o,r;return(r=(o=((n=fn(e))!=null?n:e).parentElement)==null?void 0:o.closest(I))!=null?r:null}function mo(e){var t,n;for(let o=mn(e);o;o=(n=(t=o.parentElement)==null?void 0:t.closest(I))!=null?n:null)if(!o.open)return!1;return!0}function po(e){return Array.from(e.querySelectorAll(dn)).filter(mo)}function _(e){return e?(e.focus(),!0):!1}function vo(e){var n;let t=e.closest(".fw-menu-split");return(n=t==null?void 0:t.querySelector(":scope > .fw-menu-group > .fw-menu-summary"))!=null?n:null}function bo(e,t){var c;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)return;let n=t.target instanceof HTMLElement&&t.target.matches(dn)?t.target:null;if(!n||!e.contains(n))return;let o=po(e),r=o.indexOf(n),i=fn(n),s=!0;switch(t.key){case"ArrowDown":_(o[r+1]);break;case"ArrowUp":_(o[r-1]);break;case"Home":_(o[0]);break;case"End":_(o[o.length-1]);break;case"ArrowRight":i?i.open?i.contains((c=o[r+1])!=null?c:e)&&_(o[r+1]):Le(i):_(vo(n));break;case"ArrowLeft":if(i!=null&&i.open)ge(i);else{let d=mn(n);_(d==null?void 0:d.querySelector(":scope > .fw-menu-summary"))}break;default:s=!1}s&&t.preventDefault()}function ut(e=document){e.querySelectorAll("[data-fw-menu]").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.hasAttribute("data-fw-menu-exclusive");t.addEventListener("toggle",o=>{let r=o.target;!(r instanceof HTMLDetailsElement)||!r.matches(I)||(n&&r.open&&r.parentElement&&Array.from(r.parentElement.children).forEach(i=>{i!==r&&i instanceof HTMLDetailsElement&&i.matches(I)&&ge(i)}),cn(t),lo(r,{group:r,open:r.open}))},!0),t.addEventListener("keydown",o=>bo(t,o)),t.querySelectorAll("[aria-current]").forEach(un),cn(t)})}var Ae={};g(Ae,{init:()=>mt,popover:()=>wn});var wo={top:"bottom",bottom:"top",left:"right",right:"left"},Z=10;function ho(e){switch(e){case"top-left":return{side:"top",align:"end"};case"top-right":return{side:"top",align:"start"};case"bottom-left":return{side:"bottom",align:"end"};case"bottom-right":return{side:"bottom",align:"start"};default:return{side:e,align:"center"}}}var yo={start:"right",end:"left"};function Eo(e,t){return t==="center"?e:`${e}-${yo[t]}`}function ft(e,t,n,o){switch(e){case"top":return t.top;case"bottom":return o-t.bottom;case"left":return t.left;case"right":return n-t.right}}function pn(e,t,n,o){switch(e){case"top":return t.top-o-n.height;case"bottom":return t.bottom+o;case"left":return t.left-o-n.width;case"right":return t.right+o}}function vn(e,t,n,o){switch(e){case"start":return t;case"end":return t+n-o;case"center":return t+n/2-o/2}}function ke(e,t,n){return Math.min(Math.max(e,t),n>t?n:t)}function He(e,t,n={}){var T,H,x;let o=(T=n.placement)!=null?T:"bottom",r=(H=n.offset)!=null?H:8,i=(x=n.padding)!=null?x:8,s=e.getBoundingClientRect(),c=t.getBoundingClientRect(),d=window.innerWidth,u=window.innerHeight,{side:a,align:m}=ho(o),E=wo[a],w=a==="top"||a==="bottom"?c.height:c.width,v=ft(a,s,d,u)-r<w&&ft(E,s,d,u)-r>ft(a,s,d,u)-r?E:a,f,M,k;return v==="top"||v==="bottom"?(f=pn(v,s,c,r),M=ke(vn(m,s.left,s.width,c.width),i,d-c.width-i),k=ke(s.left+s.width/2-M,Z,Math.max(c.width-Z,Z))):(M=pn(v,s,c,r),f=ke(vn("center",s.top,s.height,c.height),i,u-c.height-i),k=ke(s.top+s.height/2-f,Z,Math.max(c.height-Z,Z))),{placement:Eo(v,m),top:f,left:M,arrowOffset:k}}function bn(e,t){let n=s=>!e.some(c=>c.contains(s)),o=!1,r=s=>{o=n(s.target)},i=s=>{o&&n(s.target)&&t()};return document.addEventListener("mousedown",r,!0),document.addEventListener("click",i,!0),()=>{document.removeEventListener("mousedown",r,!0),document.removeEventListener("click",i,!0)}}var xo='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function wn(e,t,n={}){var x,L;let o=(x=n.placement)!=null?x:"bottom",r=(L=n.offset)!=null?L:8;e.setAttribute("aria-haspopup","dialog"),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded","false"),t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.classList.add("fw-popover");let i=t.parentNode,s=t.nextSibling,c=!1,d=null,u=0;function a(){let b=He(e,t,{placement:o,offset:r});t.style.top=`${b.top}px`,t.style.left=`${b.left}px`,t.setAttribute("data-placement",b.placement)}function m(){cancelAnimationFrame(u),u=requestAnimationFrame(a)}function E(b){b.key==="Escape"&&(b.stopPropagation(),f())}function w(b){let B=b.relatedTarget;B&&(t.contains(B)||e.contains(B))||setTimeout(()=>{if(!c)return;let C=document.activeElement;C===document.body||C===null||t.contains(C)||e.contains(C)||f()},0)}function v(){if(c)return;c=!0,t.parentNode!==document.body&&document.body.appendChild(t),a(),t.classList.add("is-open"),e.setAttribute("aria-expanded","true");let b=t.querySelector(xo);b?b.focus({preventScroll:!0}):(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0})),d=bn([e,t],f),window.addEventListener("scroll",m,!0),window.addEventListener("resize",m),t.addEventListener("keydown",E),t.addEventListener("focusout",w),t.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}))}function f(){if(!c)return;c=!1,t.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),d==null||d(),d=null,window.removeEventListener("scroll",m,!0),window.removeEventListener("resize",m),t.removeEventListener("keydown",E),t.removeEventListener("focusout",w),cancelAnimationFrame(u),s===null||s.parentNode===i?i.insertBefore(t,s):i.appendChild(t),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),e.focus({preventScroll:!0})}function M(){(c?f:v)()}let k=()=>M(),T=Array.from(t.querySelectorAll("[data-fw-popover-close]")),H=()=>f();return e.addEventListener("click",k),T.forEach(b=>b.addEventListener("click",H)),{open:v,close:f,toggle:M,destroy(){c&&f(),e.removeEventListener("click",k),T.forEach(b=>b.removeEventListener("click",H)),delete e.dataset.fwBound}}}function mt(e=document){e.querySelectorAll("[data-fw-popover-trigger]").forEach(t=>{var r;if(t.dataset.fwBound)return;let n=(r=t.dataset.fwPopoverTrigger)!=null?r:"",o=document.getElementById(n);if(!o){console.warn(`fernwell: popover trigger references missing panel #${n}`);return}t.dataset.fwBound="1",wn(t,o,{placement:t.dataset.fwPopoverPlacement||void 0,offset:t.dataset.fwPopoverOffset?Number(t.dataset.fwPopoverOffset):void 0})})}var Oe={};g(Oe,{init:()=>bt,tooltip:()=>Ln});var To=400,Lo=300,go=100,oe=new WeakMap,O=null,D=null,re=0,ie=0,vt=0,yn=0;function Mo(){if(O&&O.isConnected)return O;let e=document.createElement("div");return e.className="fw-tooltip",e.id="fw-tooltip",e.setAttribute("role","tooltip"),document.body.appendChild(e),e.addEventListener("mouseenter",En),e.addEventListener("mouseleave",()=>Tn()),O=e,e}function En(){clearTimeout(ie)}function xn(){if(!D||!O)return;let e=oe.get(D);if(!e)return;let t=He(D,O,{placement:e.placement,offset:e.offset});O.style.top=`${t.top}px`,O.style.left=`${t.left}px`,O.style.setProperty("--fw-tooltip-arrow-pos",`${t.arrowOffset}px`),O.setAttribute("data-placement",t.placement)}function Se(){cancelAnimationFrame(vt),vt=requestAnimationFrame(xn)}function hn(e){var o;if(clearTimeout(re),En(),!oe.get(e))return;D=e;let n=Mo();n.textContent=(o=e.dataset.fwTooltipText)!=null?o:"",xn(),n.classList.add("is-open"),window.addEventListener("scroll",Se,!0),window.addEventListener("resize",Se)}function ne(){clearTimeout(re),clearTimeout(ie),O&&O.classList.remove("is-open"),window.removeEventListener("scroll",Se,!0),window.removeEventListener("resize",Se),cancelAnimationFrame(vt),D&&(yn=performance.now()),D=null}function pt(e,t){clearTimeout(ie),clearTimeout(re);let n=oe.get(e);n&&(t||performance.now()-yn<Lo?hn(e):re=window.setTimeout(()=>hn(e),n.delay))}function Tn(){clearTimeout(re),clearTimeout(ie),ie=window.setTimeout(ne,go)}function Ln(e,t={}){var u,a,m;let n={placement:(u=t.placement)!=null?u:"top",offset:(a=t.offset)!=null?a:6,delay:(m=t.delay)!=null?m:To};oe.set(e,n);let o=e.getAttribute("title");o!==null&&(e.dataset.fwTooltipText=o,e.removeAttribute("title")),e.setAttribute("aria-describedby","fw-tooltip");let r=()=>pt(e,!1),i=()=>Tn(),s=()=>pt(e,!0),c=()=>{D===e&&ne()},d=E=>{E.key==="Escape"&&D===e&&ne()};return e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",i),e.addEventListener("focus",s),e.addEventListener("blur",c),e.addEventListener("keydown",d),{show:()=>pt(e,!0),hide:()=>{D===e&&ne()},destroy(){D===e&&ne(),e.removeEventListener("mouseenter",r),e.removeEventListener("mouseleave",i),e.removeEventListener("focus",s),e.removeEventListener("blur",c),e.removeEventListener("keydown",d),e.removeAttribute("aria-describedby"),e.dataset.fwTooltipText!==void 0&&(e.setAttribute("title",e.dataset.fwTooltipText),delete e.dataset.fwTooltipText),oe.delete(e),delete e.dataset.fwBound}}}function bt(e=document){e.querySelectorAll("[data-fw-tooltip]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Ln(t,{placement:t.dataset.fwTooltipPlacement||void 0,offset:t.dataset.fwTooltipOffset?Number(t.dataset.fwTooltipOffset):void 0,delay:t.dataset.fwTooltipDelay?Number(t.dataset.fwTooltipDelay):void 0}))})}var Ce={};g(Ce,{init:()=>ht,tabs:()=>Hn});function ko(e,t){e.dispatchEvent(new CustomEvent("fw:tabs-change",{bubbles:!0,detail:t}))}function Ne(e){return e.getAttribute("aria-disabled")==="true"}function wt(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function gn(e){return e instanceof Element?e.closest('[role="tab"]'):null}function Mn(e,t,n){for(let o=1;o<=e.length;o++){let r=((t+n*o)%e.length+e.length)%e.length;if(!Ne(e[r]))return e[r]}}function kn(e){return e.find(t=>!Ne(t))}function Ho(e){for(let t=e.length-1;t>=0;t--)if(!Ne(e[t]))return e[t]}function Hn(e,t={}){var u;let n=(u=t.activation)!=null?u:"automatic";function o(){return Array.from(e.querySelectorAll('[role="tab"]'))}function r(a,m=!1){if(Ne(a))return;o().forEach(w=>{let v=w===a;w.setAttribute("aria-selected",String(v)),w.tabIndex=v?0:-1;let f=wt(w);f&&(f.hidden=!v)}),m&&a.focus();let E=wt(a);E&&ko(e,{tab:a,panel:E})}function i(a){o().forEach(m=>{m.tabIndex=m===a?0:-1}),a.focus()}function s(){var E;let a=o(),m=(E=a.find(w=>w.getAttribute("aria-selected")==="true"))!=null?E:kn(a);a.forEach(w=>{let v=w===m;w.setAttribute("aria-selected",String(v)),w.tabIndex=v?0:-1;let f=wt(w);f&&(f.hidden=!v)})}function c(a){let m=gn(a.target);m&&e.contains(m)&&r(m,!1)}function d(a){let m=gn(a.target);if(!m)return;let E=o(),w=E.indexOf(m);if(w===-1)return;if(a.key===" "||a.key==="Enter"){n==="manual"&&(a.preventDefault(),r(m,!1));return}let v=e.getAttribute("aria-orientation")==="vertical",f=getComputedStyle(e).direction==="rtl",M=v?"ArrowDown":f?"ArrowLeft":"ArrowRight",k=v?"ArrowUp":f?"ArrowRight":"ArrowLeft",T;if(a.key===M)T=Mn(E,w,1);else if(a.key===k)T=Mn(E,w,-1);else if(a.key==="Home")T=kn(E);else if(a.key==="End")T=Ho(E);else return;T&&(a.preventDefault(),n==="manual"?i(T):r(T,!0))}return e.addEventListener("click",c),e.addEventListener("keydown",d),s(),{activate:r,destroy(){e.removeEventListener("click",c),e.removeEventListener("keydown",d),delete e.dataset.fwBound}}}function ht(e=document){e.querySelectorAll('[role="tablist"][data-fw-tabs]').forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.dataset.fwTabsActivation==="manual"?"manual":"automatic";Hn(t,{activation:n})})}var Ie={};g(Ie,{init:()=>xt,numberInput:()=>Sn});var Ao=400,So=60,Oo=0;function yt(e){if(e==null||e.trim()==="")return;let t=Number(e);return Number.isFinite(t)?t:void 0}function An(e){if(e===void 0)return 0;let t=String(e),n=t.indexOf(".");return n<0?0:t.length-n-1}function Sn(e,t={}){var Lt,gt,Mt,kt,Ht,At;let n=t.mode==="slider"?"slider":"stepper",o=n==="slider",r=(Lt=t.min)!=null?Lt:o?0:void 0,i=(gt=t.max)!=null?gt:o?100:void 0,s=(Mt=t.step)!=null?Mt:1,c=Number.isFinite(s)&&s>0?s:1,d=(kt=t.unit)!=null?kt:"",u=Math.max(An(c),An(r)),a=e.type,m=e.getAttribute("min"),E=e.getAttribute("max"),w=e.getAttribute("step");e.type=o?"range":"number",r!==void 0&&(e.min=String(r)),i!==void 0&&(e.max=String(i)),e.step=String(c),e.id||(e.id=`fw-number-${++Oo}`);let v=e.closest(".fw-number"),f=v!=null?v:No(e),M=!v;f.classList.add(o?"fw-number-slider":"fw-number-stepper"),e.classList.add("fw-number-input");let k=l=>Math.min(i!=null?i:1/0,Math.max(r!=null?r:-1/0,l)),T=l=>Number(l.toFixed(u)),H=()=>e.value.trim()===""?NaN:Number(e.value),x,L,b;if(o)b=document.createElement("output"),b.className="fw-number-value",b.setAttribute("for",e.id),f.appendChild(b);else{let l=e.getAttribute("aria-label");x=B("dec",F("minus"),(Ht=t.decreaseLabel)!=null?Ht:l?`Decrease ${l}`:"Decrease"),L=B("inc",F("add"),(At=t.increaseLabel)!=null?At:l?`Increase ${l}`:"Increase"),x.setAttribute("aria-controls",e.id),L.setAttribute("aria-controls",e.id),f.insertBefore(x,e),f.appendChild(L)}function B(l,h,q){let R=document.createElement("button");return R.type="button",R.className=`fw-number-btn fw-number-${l}`,R.setAttribute("aria-label",q),R.innerHTML=`<span class="fw-icon" aria-hidden="true">${h}</span>`,R}function C(){let l=H();if(o&&b){let h=Number.isFinite(l)?`${l}${d}`:"";b.textContent=h,e.setAttribute("aria-valuetext",h);let q=(i!=null?i:100)-(r!=null?r:0),R=Number.isFinite(l)&&q>0?(l-(r!=null?r:0))/q*100:0;e.style.setProperty("--fw-number-fill",`${Math.min(100,Math.max(0,R))}%`)}if(x&&L){let h=Number.isFinite(l)?l:void 0;x.setAttribute("aria-disabled",String(e.disabled||h!==void 0&&r!==void 0&&h<=r)),L.setAttribute("aria-disabled",String(e.disabled||h!==void 0&&i!==void 0&&h>=i))}}function z(l){return l.getAttribute("aria-disabled")==="true"}function p(l){if(!Number.isFinite(l))return;let h=T(k(l));h!==H()&&(e.value=String(h),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})))}function y(l){if(e.disabled||e.readOnly)return;let h=H();p((Number.isFinite(h)?h:k(0))+l*c)}let A=()=>{var h;C();let l=H();f.dispatchEvent(new CustomEvent("fw:number-change",{bubbles:!0,detail:{value:l,mode:n}})),(h=t.onChange)==null||h.call(t,l)},$=l=>{if(l.altKey||l.ctrlKey||l.metaKey)return;let h=!0;switch(l.key){case"ArrowUp":y(1);break;case"ArrowDown":y(-1);break;case"PageUp":y(10);break;case"PageDown":y(-10);break;default:h=!1}h&&l.preventDefault()},P,G,U=()=>{clearTimeout(P),clearInterval(G),P=G=void 0},Tt=l=>l===x?-1:1,Cn=l=>{let h=l.currentTarget;if(l.button>0||z(h))return;let q=Tt(h);y(q),U(),P=setTimeout(()=>{G=setInterval(()=>{if(z(h))return U();y(q)},So)},Ao)},In=l=>{let h=l.currentTarget;l.detail!==0||z(h)||y(Tt(h))};if(e.addEventListener("input",A),!o){e.addEventListener("keydown",$);for(let l of[x,L])l&&(l.addEventListener("pointerdown",Cn),l.addEventListener("pointerup",U),l.addEventListener("pointerleave",U),l.addEventListener("pointercancel",U),l.addEventListener("click",In))}return C(),{getValue:H,setValue:p,stepUp:(l=1)=>y(l),stepDown:(l=1)=>y(-l),destroy(){U(),e.removeEventListener("input",A),e.removeEventListener("keydown",$),x==null||x.remove(),L==null||L.remove(),b==null||b.remove(),e.style.removeProperty("--fw-number-fill"),e.removeAttribute("aria-valuetext"),e.classList.remove("fw-number-input"),f.classList.remove("fw-number-slider","fw-number-stepper"),e.type=a,Et(e,"min",m),Et(e,"max",E),Et(e,"step",w),M&&f.parentNode&&(f.parentNode.insertBefore(e,f),f.remove()),delete e.dataset.fwBound}}}function Et(e,t,n){n===null?e.removeAttribute(t):e.setAttribute(t,n)}function No(e){var n;let t=document.createElement("div");return t.className="fw-number",(n=e.parentNode)==null||n.insertBefore(t,e),t.appendChild(e),t}function xt(e=document){e.querySelectorAll("input[data-fw-number]").forEach(t=>{var o,r,i;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.dataset;Sn(t,{mode:n.fwNumberMode==="slider"?"slider":"stepper",min:yt((o=n.fwNumberMin)!=null?o:t.getAttribute("min")),max:yt((r=n.fwNumberMax)!=null?r:t.getAttribute("max")),step:yt((i=n.fwNumberStep)!=null?i:t.getAttribute("step")),unit:n.fwNumberUnit})})}var On="0.6.0";function Nn(e=document){We(e),Ke(e),Ze(e),et(e),ot(e),rt(e),dt(e),ut(e),Be(e),mt(e),bt(e),ht(e),xt(e)}var Co={version:On,init:Nn,theme:pe,tokens:fe,combobox:ve,modal:be,nav:he,loading:ye,toast:Ee,table:Te,menu:Me,icon:se,popover:Ae,tooltip:Oe,tabs:Ce,numberInput:Ie},Io=Co;
|
|
4
6
|
//# sourceMappingURL=fernwell.cjs.map
|