@owlmeans/web-panel 0.1.18-rc.74 → 0.1.18-rc.76
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/README.md +89 -7
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-panel/SKILL.md +207 -7
- package/build/@/components/ui/popover.d.ts +8 -0
- package/build/@/components/ui/popover.d.ts.map +1 -0
- package/build/@/components/ui/popover.js +17 -0
- package/build/@/components/ui/popover.js.map +1 -0
- package/build/components/picker/color-picker.d.ts +9 -0
- package/build/components/picker/color-picker.d.ts.map +1 -0
- package/build/components/picker/color-picker.js +9 -0
- package/build/components/picker/color-picker.js.map +1 -0
- package/build/components/picker/consts.local.d.ts +76 -0
- package/build/components/picker/consts.local.d.ts.map +1 -0
- package/build/components/picker/consts.local.js +213 -0
- package/build/components/picker/consts.local.js.map +1 -0
- package/build/components/picker/dot.d.ts +8 -0
- package/build/components/picker/dot.d.ts.map +1 -0
- package/build/components/picker/dot.js +10 -0
- package/build/components/picker/dot.js.map +1 -0
- package/build/components/picker/grid.d.ts +17 -0
- package/build/components/picker/grid.d.ts.map +1 -0
- package/build/components/picker/grid.js +73 -0
- package/build/components/picker/grid.js.map +1 -0
- package/build/components/picker/i18n/be.json +60 -0
- package/build/components/picker/i18n/de.json +60 -0
- package/build/components/picker/i18n/en.json +60 -0
- package/build/components/picker/i18n/es.json +60 -0
- package/build/components/picker/i18n/fr.json +60 -0
- package/build/components/picker/i18n/pl.json +60 -0
- package/build/components/picker/i18n/ru.json +60 -0
- package/build/components/picker/i18n/uk.json +60 -0
- package/build/components/picker/i18n.d.ts +2 -0
- package/build/components/picker/i18n.d.ts.map +1 -0
- package/build/components/picker/i18n.js +18 -0
- package/build/components/picker/i18n.js.map +1 -0
- package/build/components/picker/icon-color-picker.d.ts +14 -0
- package/build/components/picker/icon-color-picker.d.ts.map +1 -0
- package/build/components/picker/icon-color-picker.js +15 -0
- package/build/components/picker/icon-color-picker.js.map +1 -0
- package/build/components/picker/icon-picker.d.ts +8 -0
- package/build/components/picker/icon-picker.d.ts.map +1 -0
- package/build/components/picker/icon-picker.js +8 -0
- package/build/components/picker/icon-picker.js.map +1 -0
- package/build/components/picker/index.d.ts +11 -0
- package/build/components/picker/index.d.ts.map +1 -0
- package/build/components/picker/index.js +10 -0
- package/build/components/picker/index.js.map +1 -0
- package/build/components/picker/panel.d.ts +9 -0
- package/build/components/picker/panel.d.ts.map +1 -0
- package/build/components/picker/panel.js +23 -0
- package/build/components/picker/panel.js.map +1 -0
- package/build/components/picker/root.d.ts +13 -0
- package/build/components/picker/root.d.ts.map +1 -0
- package/build/components/picker/root.js +55 -0
- package/build/components/picker/root.js.map +1 -0
- package/build/components/picker/roving.d.ts +8 -0
- package/build/components/picker/roving.d.ts.map +1 -0
- package/build/components/picker/roving.js +62 -0
- package/build/components/picker/roving.js.map +1 -0
- package/build/components/picker/surface.d.ts +18 -0
- package/build/components/picker/surface.d.ts.map +1 -0
- package/build/components/picker/surface.js +36 -0
- package/build/components/picker/surface.js.map +1 -0
- package/build/components/picker/swatches/custom.d.ts +10 -0
- package/build/components/picker/swatches/custom.d.ts.map +1 -0
- package/build/components/picker/swatches/custom.js +65 -0
- package/build/components/picker/swatches/custom.js.map +1 -0
- package/build/components/picker/swatches.d.ts +16 -0
- package/build/components/picker/swatches.d.ts.map +1 -0
- package/build/components/picker/swatches.js +35 -0
- package/build/components/picker/swatches.js.map +1 -0
- package/build/components/picker/text.d.ts +5 -0
- package/build/components/picker/text.d.ts.map +1 -0
- package/build/components/picker/text.js +29 -0
- package/build/components/picker/text.js.map +1 -0
- package/build/components/picker/tile.d.ts +11 -0
- package/build/components/picker/tile.d.ts.map +1 -0
- package/build/components/picker/tile.js +19 -0
- package/build/components/picker/tile.js.map +1 -0
- package/build/components/picker/translate.d.ts +9 -0
- package/build/components/picker/translate.d.ts.map +1 -0
- package/build/components/picker/translate.js +13 -0
- package/build/components/picker/translate.js.map +1 -0
- package/build/components/picker/trigger.d.ts +12 -0
- package/build/components/picker/trigger.d.ts.map +1 -0
- package/build/components/picker/trigger.js +29 -0
- package/build/components/picker/trigger.js.map +1 -0
- package/build/components/picker/types.d.ts +114 -0
- package/build/components/picker/types.d.ts.map +1 -0
- package/build/components/picker/types.js +2 -0
- package/build/components/picker/types.js.map +1 -0
- package/build/components/picker/types.local.d.ts +143 -0
- package/build/components/picker/types.local.d.ts.map +1 -0
- package/build/components/picker/types.local.js +2 -0
- package/build/components/picker/types.local.js.map +1 -0
- package/build/picker/icons/consts.d.ts +9 -0
- package/build/picker/icons/consts.d.ts.map +1 -0
- package/build/picker/icons/consts.js +264 -0
- package/build/picker/icons/consts.js.map +1 -0
- package/build/picker/icons/types.d.ts +18 -0
- package/build/picker/icons/types.d.ts.map +1 -0
- package/build/picker/icons/types.js +2 -0
- package/build/picker/icons/types.js.map +1 -0
- package/build/picker/icons.d.ts +4 -0
- package/build/picker/icons.d.ts.map +1 -0
- package/build/picker/icons.js +54 -0
- package/build/picker/icons.js.map +1 -0
- package/build/picker/index.d.ts +11 -0
- package/build/picker/index.d.ts.map +1 -0
- package/build/picker/index.js +10 -0
- package/build/picker/index.js.map +1 -0
- package/build/picker/utils/color/types.d.ts +35 -0
- package/build/picker/utils/color/types.d.ts.map +1 -0
- package/build/picker/utils/color/types.js +2 -0
- package/build/picker/utils/color/types.js.map +1 -0
- package/build/picker/utils/color.d.ts +4 -0
- package/build/picker/utils/color.d.ts.map +1 -0
- package/build/picker/utils/color.js +96 -0
- package/build/picker/utils/color.js.map +1 -0
- package/build/picker/vocabulary/consts.d.ts +26 -0
- package/build/picker/vocabulary/consts.d.ts.map +1 -0
- package/build/picker/vocabulary/consts.js +336 -0
- package/build/picker/vocabulary/consts.js.map +1 -0
- package/build/picker/vocabulary/types.d.ts +67 -0
- package/build/picker/vocabulary/types.d.ts.map +1 -0
- package/build/picker/vocabulary/types.js +2 -0
- package/build/picker/vocabulary/types.js.map +1 -0
- package/build/picker/vocabulary.d.ts +11 -0
- package/build/picker/vocabulary.d.ts.map +1 -0
- package/build/picker/vocabulary.js +83 -0
- package/build/picker/vocabulary.js.map +1 -0
- package/package.json +37 -20
- package/src/@/components/ui/popover.tsx +47 -0
- package/src/components/picker/color-picker.tsx +15 -0
- package/src/components/picker/consts.local.ts +266 -0
- package/src/components/picker/dot.tsx +21 -0
- package/src/components/picker/grid.tsx +138 -0
- package/src/components/picker/i18n/be.json +60 -0
- package/src/components/picker/i18n/de.json +60 -0
- package/src/components/picker/i18n/en.json +60 -0
- package/src/components/picker/i18n/es.json +60 -0
- package/src/components/picker/i18n/fr.json +60 -0
- package/src/components/picker/i18n/pl.json +60 -0
- package/src/components/picker/i18n/ru.json +60 -0
- package/src/components/picker/i18n/uk.json +60 -0
- package/src/components/picker/i18n.ts +19 -0
- package/src/components/picker/icon-color-picker.tsx +25 -0
- package/src/components/picker/icon-picker.tsx +13 -0
- package/src/components/picker/index.ts +11 -0
- package/src/components/picker/panel.tsx +61 -0
- package/src/components/picker/root.tsx +81 -0
- package/src/components/picker/roving.ts +70 -0
- package/src/components/picker/surface.tsx +62 -0
- package/src/components/picker/swatches/custom.tsx +110 -0
- package/src/components/picker/swatches.tsx +67 -0
- package/src/components/picker/text.ts +46 -0
- package/src/components/picker/tile.tsx +35 -0
- package/src/components/picker/translate.ts +15 -0
- package/src/components/picker/trigger.tsx +54 -0
- package/src/components/picker/types.local.ts +154 -0
- package/src/components/picker/types.ts +125 -0
- package/src/picker/icons/consts.ts +309 -0
- package/src/picker/icons/types.ts +18 -0
- package/src/picker/icons.ts +70 -0
- package/src/picker/index.ts +11 -0
- package/src/picker/utils/color/types.ts +37 -0
- package/src/picker/utils/color.ts +119 -0
- package/src/picker/vocabulary/consts.ts +347 -0
- package/src/picker/vocabulary/types.ts +72 -0
- package/src/picker/vocabulary.ts +111 -0
- package/tests/context.ts +1 -1
- package/tests/harness/index.html +1 -0
- package/tests/harness/mount.tsx +13 -2
- package/tests/harness/picker.tsx +110 -0
- package/tests/picker-shots.spec.ts +174 -0
- package/tests/picker-vocabulary.spec.ts +217 -0
- package/tests/picker.spec.ts +333 -0
package/README.md
CHANGED
|
@@ -11,14 +11,14 @@ but never started.
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
bun add @owlmeans/web-panel@^0.1.18-rc.
|
|
14
|
+
bun add @owlmeans/web-panel@^0.1.18-rc.76
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Peer requirements (the consuming app provides these): `react`, `react-dom`,
|
|
18
18
|
`react-hook-form`, `ajv`, `tailwindcss@^4`, `lucide-react`, `clsx`,
|
|
19
19
|
`tailwind-merge`, `class-variance-authority`, plus the radix primitives
|
|
20
|
-
listed in `peerDependencies` (`alert-dialog`, `dialog`, `label`, `navigation-menu`, `
|
|
21
|
-
`separator`, `slot`). Also declare `ajv-formats` next to `ajv`: the form model imports it, but no dependency
|
|
20
|
+
listed in `peerDependencies` (`alert-dialog`, `dialog`, `label`, `navigation-menu`, `popover`,
|
|
21
|
+
`progress`, `separator`, `slot` — keep `dialog` and `popover` on the same Radix generation). Also declare `ajv-formats` next to `ajv`: the form model imports it, but no dependency
|
|
22
22
|
section of this manifest lists it.
|
|
23
23
|
|
|
24
24
|
## Concepts
|
|
@@ -38,8 +38,12 @@ section of this manifest lists it.
|
|
|
38
38
|
with tailwind-merge, never substituted.
|
|
39
39
|
- **Global overlays** — `PanelApp` renders its `children` and `SocketReloadDialog` beside the
|
|
40
40
|
router, so a dialog survives navigation.
|
|
41
|
-
- **`translate` props** — the navigation and
|
|
41
|
+
- **`translate` props** — the navigation, login and picker components take a
|
|
42
42
|
`(key, defaultValue) => string` resolver as a prop instead of reading an i18n provider implicitly.
|
|
43
|
+
- **Icon + colour picker** — `@owlmeans/web-panel/picker` is the standard way a person chooses an
|
|
44
|
+
icon and/or a colour (24 palette keys, ~250 curated lucide icons, an opt-in custom colour) and the
|
|
45
|
+
way a chosen mark is rendered (`IconTile`, `ColorDot`). A popover on wide screens, a bottom sheet
|
|
46
|
+
on phones; its data and colour helper are React-free under `./picker/vocabulary`.
|
|
43
47
|
|
|
44
48
|
## Usage
|
|
45
49
|
|
|
@@ -60,8 +64,8 @@ The components paint with these CSS variables, defined inside `@theme` in the ap
|
|
|
60
64
|
- `--animate-progress-indeterminate` + the `@keyframes progress-indeterminate`
|
|
61
65
|
rule for the `Progress` component's indeterminate mode
|
|
62
66
|
|
|
63
|
-
A working set is shipped at `src/@/globals.css` (for dev/test only). Toasts
|
|
64
|
-
`--popover`, `--popover-foreground` and `--border`.
|
|
67
|
+
A working set is shipped at `src/@/globals.css` (for dev/test only). Toasts and the picker's
|
|
68
|
+
surfaces additionally read `--popover`, `--popover-foreground` and `--border`.
|
|
65
69
|
|
|
66
70
|
Tailwind's scanner reads your CSS root plus its `@source` directives, and it excludes
|
|
67
71
|
`node_modules`. Classes that exist only inside this package's components — the whole navigation
|
|
@@ -316,6 +320,36 @@ export const ConnectionBadge: FC = () => {
|
|
|
316
320
|
The dialog's strings are the lib-tier `socket` namespace (`reload.title`, `reload.description`,
|
|
317
321
|
`reload.action`), shipped in seven languages.
|
|
318
322
|
|
|
323
|
+
### 6. Icon and colour picker
|
|
324
|
+
|
|
325
|
+
A person choosing a type's mark — an icon and a colour — gets one control; the stored values are a
|
|
326
|
+
palette key (or `#rrggbb` with `customColors`) and a kebab-case lucide name:
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
import { useState, type FC } from 'react'
|
|
330
|
+
import { IconColorPicker, IconTile, usePickerTranslate } from '@owlmeans/web-panel/picker'
|
|
331
|
+
import type { IconColorChange } from '@owlmeans/web-panel/picker'
|
|
332
|
+
|
|
333
|
+
export const TypeMarkField: FC<{ initial: IconColorChange, onSave: (mark: IconColorChange) => void }> =
|
|
334
|
+
({ initial, onSave }) => {
|
|
335
|
+
const translate = usePickerTranslate() // only under PanelApp / render()
|
|
336
|
+
const [mark, setMark] = useState(initial)
|
|
337
|
+
|
|
338
|
+
return <div className="flex items-center gap-3">
|
|
339
|
+
<IconColorPicker label="Mark" value={mark} onChange={setMark} translate={translate} />
|
|
340
|
+
<button type="button" onClick={() => onSave(mark)}>Save</button>
|
|
341
|
+
<IconTile icon={mark.icon} color={mark.color} size="sm" /> {/* how a list shows it */}
|
|
342
|
+
</div>
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
`ColorPicker` and `IconPicker` edit one half; `ColorSwatches` and `IconGrid` are the same grids
|
|
347
|
+
inline, for a dialog the app already owns. Stored marks render with `IconTile` / `ColorDot`, or with
|
|
348
|
+
`pickerColorHelper.styleOf(color)` in custom markup. From 768px up the picker opens as a popover
|
|
349
|
+
(modal, so it works inside an app's own Dialog or Sheet), below that as a bottom sheet with 44px
|
|
350
|
+
targets and a Done button. Without `translate` every string is English; the packaged bundle covers
|
|
351
|
+
eight languages.
|
|
352
|
+
|
|
319
353
|
## API
|
|
320
354
|
|
|
321
355
|
### Context and mounting
|
|
@@ -423,6 +457,37 @@ consumer's CSS puts dark tokens under `.dark` AND under
|
|
|
423
457
|
| `ConsentWidgetPresenceRecord`, `ConsentWidgetService`, `ConsentWidgetServiceAppend` | type | Service types |
|
|
424
458
|
| `useConsent`, `useConsentCategory`, `consentStore`, `openConsent`, `isConsented`, `readConsent`, `writeConsent`, `clearConsent`, `consentBootstrapScript`, `DEFAULT_CONSENT_CATEGORIES`, `CONSENT_KEY`, `CONSENT_ESSENTIAL`, `CONSENT_ANALYTICS`, `CONSENT_MARKETING` and the consent types | re-export | `@owlmeans/web-consent` |
|
|
425
459
|
|
|
460
|
+
### `@owlmeans/web-panel/picker`
|
|
461
|
+
|
|
462
|
+
Not re-exported by the root. Re-exports everything of `./picker/vocabulary` too.
|
|
463
|
+
|
|
464
|
+
| Symbol | Kind | Purpose |
|
|
465
|
+
|---|---|---|
|
|
466
|
+
| `IconColorPicker`, `IconColorPickerProps` | component, type | Icon + colour: `value?: { icon?, color? }`, `onChange({ icon?, color? })`, `colors?`, `icons?`, `customColors?`, `trigger?: 'button' \| 'tile'` |
|
|
467
|
+
| `ColorPicker`, `ColorPickerProps` | component, type | A colour: `value?`, `onChange(color)`, `colors?`, `customColors?`, `trigger?: 'button' \| 'dot'` |
|
|
468
|
+
| `IconPicker`, `IconPickerProps` | component, type | An icon: `value?`, `onChange(icon)`, `color?` (tint), `icons?`, `trigger?: 'button' \| 'tile'` |
|
|
469
|
+
| `PickerBaseProps` | type | Shared: `label?`, `placeholder?`, `disabled?`, `surface?: 'auto' \| 'popover' \| 'sheet'`, `translate?`, `className?`, `id?` |
|
|
470
|
+
| `ColorSwatches`, `IconGrid` (+ `…Props`) | component, type | The grids inline, for an app's own dialog or sheet |
|
|
471
|
+
| `IconTile`, `IconTileProps` | component, type | A stored mark: `icon?`, `color?`, `colors?`, `size?: 'xs' \| 'sm' \| 'md' \| 'lg'`, `variant?: 'tile' \| 'plain'`, `label?` |
|
|
472
|
+
| `ColorDot`, `ColorDotProps` | component, type | A stored colour as a dot in its ink: `color?`, `colors?`, `size?`, `label?` |
|
|
473
|
+
| `usePickerTranslate()`, `PickerTranslate` | hook, type | `(key, fallback) => string` over the lib-tier `picker` bundle — only under `PanelApp` / `render()` |
|
|
474
|
+
| `IconColorValue`, `IconColorChange` | type | The composite's value and its change (`undefined`, never `null`, for an unset half) |
|
|
475
|
+
| `PICKER_ICONS` | const | Catalogue name → statically imported lucide component |
|
|
476
|
+
| `pickerIconHelper` (`iconOf`, `has`, `search`, `byCategory`), `createPickerIconHelper`, `PickerIconHelper` | helper, type | Icon lookup with the `circle` fallback and catalogue search |
|
|
477
|
+
|
|
478
|
+
### `@owlmeans/web-panel/picker/vocabulary`
|
|
479
|
+
|
|
480
|
+
React-free and icon-free — safe on a server or in a seed.
|
|
481
|
+
|
|
482
|
+
| Symbol | Kind | Purpose |
|
|
483
|
+
|---|---|---|
|
|
484
|
+
| `PICKER_COLOR_KEYS`, `PickerColorKey` | const, type | The 24 keys in hue order: red … rose, maroon, brown, olive, navy, slate, stone, graphite |
|
|
485
|
+
| `PICKER_COLORS`, `PickerColor` | const, type | `{ key, swatch, ink, soft, inkDark?, softDark?, label? }` — every ink 4.5:1 on its ground and the page in both modes |
|
|
486
|
+
| `PICKER_FALLBACK_COLOR`, `PICKER_FALLBACK_ICON` | const | `'slate'`, `'circle'` |
|
|
487
|
+
| `PICKER_ICON_ENTRIES`, `PICKER_ICON_NAMES`, `PICKER_ICON_CATEGORIES` | const | The catalogue: `{ name, category, keywords }`, its names, its ten categories |
|
|
488
|
+
| `PickerIconEntry`, `PickerIconCategory`, `ResolvedPickerColor` | type | |
|
|
489
|
+
| `pickerColorHelper` (`isHex`, `normalizeHex`, `resolve`, `styleOf`, `hashKey`), `createPickerColorHelper`, `PickerColorHelper` | helper, type | Validate, normalize and resolve a stored colour (a hex gets contrast-safe inks); `styleOf` → the `--pick-*` custom properties the parts read |
|
|
490
|
+
|
|
426
491
|
### Differences from `@owlmeans/mui-panel`
|
|
427
492
|
|
|
428
493
|
The public names match the MUI implementation; these props and types differ:
|
|
@@ -478,6 +543,14 @@ The public names match the MUI implementation; these props and types differ:
|
|
|
478
543
|
- **Never import `@/…` from package code or vendor its primitives in the app.** The `@` alias
|
|
479
544
|
belongs to the consumer.
|
|
480
545
|
- **Every override of a packaged string covers all seven languages** (`SUPPORTED_LNGS`).
|
|
546
|
+
- **A person-chosen colour or icon goes through `./picker`.** Never a `Select` or radio group of
|
|
547
|
+
colour names, a hand-made swatch row, or a class built from the stored value
|
|
548
|
+
(`` `text-${color}-600` ``); store the key and the icon name, never the label.
|
|
549
|
+
- **Keep `@radix-ui/react-popover` and `@radix-ui/react-dialog` on one Radix generation.** They
|
|
550
|
+
share the dismissable-layer and focus-scope stacks; mixed, a picker inside a Dialog loses focus
|
|
551
|
+
to the dialog and its clicks count as outside.
|
|
552
|
+
- **`usePickerTranslate()` needs `PanelApp` / `render()`.** Without an i18n instance it throws;
|
|
553
|
+
the picker parts themselves render English with no `translate`.
|
|
481
554
|
|
|
482
555
|
## Related packages
|
|
483
556
|
|
|
@@ -490,6 +563,15 @@ The public names match the MUI implementation; these props and types differ:
|
|
|
490
563
|
- [`@owlmeans/web-router`](../web-router) — default OwlMeans routing plugin
|
|
491
564
|
- [`@owlmeans/mui-panel`](../mui-panel) — legacy Material UI implementation of the same surface
|
|
492
565
|
|
|
566
|
+
## Notes for coding agents
|
|
567
|
+
|
|
568
|
+
- Read the embedded `web-panel` skill first: its *Choosing a component* table maps every job to the
|
|
569
|
+
export, the import path and a correct one-liner, and lists the mistakes that recur in generated
|
|
570
|
+
code (private primitives, a missing `@source`, two `Toaster`s, `Form decorate` with an own submit).
|
|
571
|
+
- An icon or a colour a person chooses is edited with `@owlmeans/web-panel/picker`
|
|
572
|
+
(`IconColorPicker`, `ColorPicker`, `IconPicker`) and shown with `IconTile` / `ColorDot`; pass
|
|
573
|
+
`translate={usePickerTranslate()}` in an app rendered by `PanelApp`.
|
|
574
|
+
|
|
493
575
|
<!-- owlmeans:agent-guidance:start -->
|
|
494
576
|
## Agent guidance
|
|
495
577
|
|
|
@@ -498,7 +580,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
498
580
|
your project's skill store (`.agents/skills/`):
|
|
499
581
|
|
|
500
582
|
```sh
|
|
501
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
583
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.54
|
|
502
584
|
```
|
|
503
585
|
|
|
504
586
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/web-panel",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.76",
|
|
5
|
+
"generatedAt": "2026-10-16T18:05:19.013Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: web-panel
|
|
3
|
-
description: How to use @owlmeans/web-panel — base browser context factory (makeContext) with shadcn/Radix + Tailwind and the default OwlMeans router wired in,
|
|
3
|
+
description: How to use @owlmeans/web-panel — base browser context factory (makeContext) with shadcn/Radix + Tailwind and the default OwlMeans router wired in, the two-layer navigation shell (NavLayout/TopNav/SideNav/Footer), form/panel components, and the standard icon + colour picker (`./picker`: IconColorPicker, ColorPicker, IconPicker, IconTile, ColorDot). Auto-invoked when building a web app's makeContext, wiring its navigation or layout, importing web panel components, or letting a person choose (or showing) an icon or a colour.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,7 +8,54 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/web-panel
|
|
9
9
|
|
|
10
10
|
**Layer:** Web (React)
|
|
11
|
-
**Install:** `"@owlmeans/web-panel": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/web-panel": "^0.1.18-rc.76"` in `dependencies`
|
|
12
|
+
|
|
13
|
+
## Choosing a component
|
|
14
|
+
|
|
15
|
+
Pick the row for the job; the one-liner is the correct shape. Everything comes from the package
|
|
16
|
+
root unless the import column names a subpath.
|
|
17
|
+
|
|
18
|
+
| Job | Use | Import | Correct one-liner |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| The app's context | `makeContext` | root | `const context = makeContext<C, T>(cfg)` in `context.ts`, then `append*(context)` mixins |
|
|
21
|
+
| Mount the app | `render` (or `PanelApp` for a host that mounts itself) | root | `render(context)` |
|
|
22
|
+
| The application shell | `NavLayout` | root | `<NavLayout nav={navConfig} title="App" mobileMenu themeToggle>{children}</NavLayout>` |
|
|
23
|
+
| One piece of the shell | `TopNav` / `SideNav` / `MobileNav` / `Footer` / `ShellCredit` | root | `<Footer links={footerLinks} />` |
|
|
24
|
+
| Toasts | `Toaster` + `toast` from `sonner` | root | `<Toaster />` once, in the layout; `toast.success('Saved')` where the action ends |
|
|
25
|
+
| Light / dark switch | `ThemeToggle` / `useColorScheme`; head script from `./scheme` | root, `./scheme` | `<NavLayout themeToggle … />` |
|
|
26
|
+
| A link to a screen | `Link` | root | `<Link module={web.about} />` |
|
|
27
|
+
| A form | `Form`, `TextInput`, `SubmitButton`, `Button`, `ButtonSelector` | root | `<Form decorate validation={schema} onSubmit={save}><TextInput name="email" label /></Form>` |
|
|
28
|
+
| A panel, a heading, an error | `Block`, `Text`, `Status` | root | `<Status error={error} />` |
|
|
29
|
+
| An image upload | `ImageUploader` (react-dropzone options) | root | `<ImageUploader accept={{ 'image/*': [] }} onDrop={files => upload(files[0])} previewUrl={url} />` |
|
|
30
|
+
| "Connection lost" prompt | `SocketReloadDialog` (mounted by `PanelApp`) | root | `cfg.socket = { reloadDialog: true }` |
|
|
31
|
+
| The sign-in screen | `LoginScreen` / `LocalizedLoginScreen` / `appendLoginScreen` | root | `appendLoginScreen(context, { Logo })` |
|
|
32
|
+
| Cookie consent | `PanelCookieConsent`, `PanelConsentMenuWidget` | `./consent` | `<PanelCookieConsent />` as a `PanelApp` child |
|
|
33
|
+
| A person picks an icon AND a colour (a type's, a flow's, a label's mark) | `IconColorPicker` | `./picker` | `<IconColorPicker label="Mark" value={{ icon, color }} onChange={next => …} translate={usePickerTranslate()} />` |
|
|
34
|
+
| A person picks a colour only | `ColorPicker` | `./picker` | `<ColorPicker label="Colour" value={color} onChange={setColor} />` |
|
|
35
|
+
| A person picks an icon only | `IconPicker` | `./picker` | `<IconPicker label="Icon" value={icon} onChange={setIcon} color={color} />` |
|
|
36
|
+
| The same, inline in a dialog the app already owns | `ColorSwatches`, `IconGrid` | `./picker` | `<IconGrid value={icon} onChange={setIcon} color={color} />` |
|
|
37
|
+
| Show a chosen mark or colour (list, chip, header) | `IconTile`, `ColorDot` | `./picker` | `<IconTile icon={type.icon} color={type.tone} size="sm" />` |
|
|
38
|
+
| Palette, icon names, colour maths — no React | `PICKER_*`, `pickerColorHelper`, `pickerIconHelper` | `./picker/vocabulary` (`pickerIconHelper`, `PICKER_ICONS`: `./picker`) | `pickerColorHelper.styleOf(color)` |
|
|
39
|
+
| The current breakpoint | `useBreakPoint` / `useMapBreakpoint` | root | `useMapBreakpoint({ xs: 1, md: 2 }, 3)` |
|
|
40
|
+
|
|
41
|
+
**Common mistakes:**
|
|
42
|
+
|
|
43
|
+
- **Importing the package's private primitives.** `src/@/components/ui/*` (button, sheet, popover …)
|
|
44
|
+
and its `cn` are not exports; an app keeps its own shadcn components and never imports
|
|
45
|
+
`@owlmeans/web-panel/build/@/…` or expects `@/components/ui` to resolve to this package's copy.
|
|
46
|
+
- **A missing `@source`.** The app's Tailwind entry must scan this package's `src`
|
|
47
|
+
(`@source "../../../node_modules/@owlmeans/web-panel/src";`) or every class used only here — the
|
|
48
|
+
shell, the footer, the picker — silently never reaches the stylesheet.
|
|
49
|
+
- **Two `Toaster`s.** Mount it once, in the layout: two render every toast twice.
|
|
50
|
+
- **`Form decorate` plus an own submit button.** `decorate` already renders the `Card`, the root
|
|
51
|
+
error and a `SubmitButton` whenever `onSubmit` is given; without `decorate` there is no submit
|
|
52
|
+
button at all and the caller renders one.
|
|
53
|
+
- **A `Select`, radio group or hand-made swatch row for a colour or an icon a person chooses, or
|
|
54
|
+
`` `text-${color}-600` `` / `` `text-tone-${…}` `` built from a stored value.** A person-chosen colour
|
|
55
|
+
or icon is always edited with the `./picker` parts and rendered with `IconTile` / `ColorDot` (or
|
|
56
|
+
`pickerColorHelper.styleOf`); code-chosen tones (a status's meaning) stay the app's own classes.
|
|
57
|
+
- **`usePickerTranslate()` outside `PanelApp` / `render()`.** It needs the i18n instance and throws
|
|
58
|
+
without one; the picker parts themselves never read i18n (pass `translate`, or get English).
|
|
12
59
|
|
|
13
60
|
## Key Exports
|
|
14
61
|
|
|
@@ -47,6 +94,15 @@ user-invocable: false
|
|
|
47
94
|
- `./scheme` — the React-free colour-scheme half: `COLOR_SCHEME_KEY`, `COLOR_SCHEME_EVENT`,
|
|
48
95
|
`ColorSchemeChoice`, `colorSchemeHelper` (`readColorScheme`, `applyColorScheme`, `colorSchemeBootstrapScript`) — safe
|
|
49
96
|
to import from a Node build script
|
|
97
|
+
- `./picker` — the standard icon + colour picker and its parts (`IconColorPicker`, `ColorPicker`,
|
|
98
|
+
`IconPicker`, `ColorSwatches`, `IconGrid`, `IconTile`, `ColorDot`, `usePickerTranslate`), the icon
|
|
99
|
+
components (`PICKER_ICONS`, `pickerIconHelper`) and everything of `./picker/vocabulary` — see
|
|
100
|
+
*Subpath: `./picker`* below. Not re-exported by the root, so only a bundle importing it carries
|
|
101
|
+
the icon catalogue
|
|
102
|
+
- `./picker/vocabulary` — the React-free half: the 24-colour palette (`PICKER_COLORS`,
|
|
103
|
+
`PICKER_COLOR_KEYS`), the icon catalogue's names, categories and search words
|
|
104
|
+
(`PICKER_ICON_ENTRIES`, `PICKER_ICON_NAMES`, `PICKER_ICON_CATEGORIES`), the fallbacks and
|
|
105
|
+
`pickerColorHelper` — safe on a server, in a seed or a Node build script
|
|
50
106
|
|
|
51
107
|
## Usage
|
|
52
108
|
|
|
@@ -582,6 +638,148 @@ unregistered state resource threw inside render ("Resource consent-widget-presen
|
|
|
582
638
|
blanked the whole application. Pinned by `tests/consent.spec.ts` (`?consent=bare` / `?consent=menu`;
|
|
583
639
|
the configuration by `?consentCfg=window|bar`, `?modeProp=` and `?consentGeo=<CC>|fail`).
|
|
584
640
|
|
|
641
|
+
## Subpath: `./picker`
|
|
642
|
+
|
|
643
|
+
The standard editor and renderer of an icon and a colour **a person chooses** — a workcard type's
|
|
644
|
+
or a status flow's mark, a label, a category. One component family, so every application offers
|
|
645
|
+
the same 24 colours, the same curated icons and the same behaviour on a desktop and a phone.
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
import {
|
|
649
|
+
IconColorPicker, ColorPicker, IconPicker, ColorSwatches, IconGrid, IconTile, ColorDot, usePickerTranslate,
|
|
650
|
+
pickerColorHelper, pickerIconHelper, PICKER_COLORS, PICKER_COLOR_KEYS,
|
|
651
|
+
} from '@owlmeans/web-panel/picker'
|
|
652
|
+
// Server, seed, build script — the data and the colour helper without React or icons:
|
|
653
|
+
// import { pickerColorHelper, PICKER_COLOR_KEYS } from '@owlmeans/web-panel/picker/vocabulary'
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Which part
|
|
657
|
+
|
|
658
|
+
| Part | When |
|
|
659
|
+
|---|---|
|
|
660
|
+
| `IconColorPicker` | Both halves of a mark. One trigger (the tile, "Rocket · Indigo", a chevron — or `trigger="tile"` for the tile alone) opens swatches above a searchable, categorized icon grid tinted in the chosen colour. Stays open for the other half; Esc, a click outside or (sheet) Done closes it |
|
|
661
|
+
| `ColorPicker` | A colour alone (`trigger="button"` or `"dot"`). Closes on a swatch. `colors` takes an application palette — e.g. status tones |
|
|
662
|
+
| `IconPicker` | An icon alone, tinted in `color`. Closes on a pick |
|
|
663
|
+
| `ColorSwatches`, `IconGrid` | Inline, for a dialog or sheet the application already owns — no trigger, no surface of their own |
|
|
664
|
+
| `IconTile` | A stored mark shown: the icon in the colour's ink on its ground (`variant="tile"`), or the ink alone (`"plain"`); `size` `xs`/`sm`/`md`/`lg`; `label` makes it an image, else decorative |
|
|
665
|
+
| `ColorDot` | A stored colour as a dot in its ink (`size` `xs`/`sm`/`md`) |
|
|
666
|
+
| `usePickerTranslate()` | The `translate` for an app rendered by `PanelApp` / `render()` — the packaged bundle in the current language |
|
|
667
|
+
|
|
668
|
+
### Values
|
|
669
|
+
|
|
670
|
+
- **Colour**: a palette key — `red orange amber yellow lime green emerald teal cyan sky blue indigo
|
|
671
|
+
violet purple fuchsia pink rose maroon brown olive navy slate stone graphite` (`PICKER_COLOR_KEYS`,
|
|
672
|
+
hue order) — or, only with `customColors`, a lowercase `#rrggbb`. Never a label ("Indigo").
|
|
673
|
+
- **Icon**: a kebab-case lucide name from the catalogue (`PICKER_ICON_NAMES`, ~250 in ten categories,
|
|
674
|
+
a superset of the planning kits' icons). Never a component, never a label.
|
|
675
|
+
- `IconColorPicker` emits `onChange({ icon, color })` — both halves as they now stand; a half
|
|
676
|
+
never chosen stays `undefined`, never `null`. `value` tolerates `null`s and absent halves.
|
|
677
|
+
- An unknown stored value renders the fallback (`slate`, `circle`) and never throws, so a value
|
|
678
|
+
from an older palette or a typo never breaks a page.
|
|
679
|
+
- `customColors` (default `false`) adds a colour wheel (react-colorful) and a hex field: a full
|
|
680
|
+
`#rrggbb` commits while typing, `#rgb` / `abc` on Enter or blur, always normalized to lowercase six
|
|
681
|
+
digits; anything else marks the field `aria-invalid` and changes nothing. A custom colour's ink
|
|
682
|
+
and grounds are derived to keep 4.5:1 in both modes.
|
|
683
|
+
|
|
684
|
+
### Surfaces
|
|
685
|
+
|
|
686
|
+
`surface="auto"` (default) opens a popover from 768px up and a bottom sheet below — decided when
|
|
687
|
+
it OPENS, kept until it closes. `surface="popover" | "sheet"` forces one. The popover is modal, so
|
|
688
|
+
inside an application's own Dialog or Sheet the wheel scrolls it and focus stays in it; it keeps
|
|
689
|
+
12px off the edges and scrolls inside rather than growing past the viewport. The sheet has a grab
|
|
690
|
+
handle, a sticky header with the preview and a 44px Done button, `88dvh` at most and safe-area
|
|
691
|
+
padding. Below 768px and on coarse pointers every cell, chip, field and button is at least 44px;
|
|
692
|
+
the search field takes focus on open only for a fine pointer (no keyboard pops up on a phone).
|
|
693
|
+
Keyboard: arrows move in two dimensions through swatches and icons (one tab stop each), Home/End,
|
|
694
|
+
ArrowDown from the search into the grid and ArrowUp back, Enter/Space picks, Esc closes and focus
|
|
695
|
+
returns to the trigger. Every control is a `<button type="button">` with an `aria-label`, so a
|
|
696
|
+
pick never submits an enclosing form.
|
|
697
|
+
|
|
698
|
+
### Strings
|
|
699
|
+
|
|
700
|
+
The parts never read i18n implicitly — rendered without an i18n instance they show English. Pass
|
|
701
|
+
`translate={usePickerTranslate()}` in an app rendered by `PanelApp` / `render()`: chrome, colour
|
|
702
|
+
names and category names come from the lib-tier `picker` bundle in eight languages (en, pl, ru, be,
|
|
703
|
+
uk, es, de, fr); icon names stay English. An app overrides a string at the App tier in the `lib`
|
|
704
|
+
namespace (`i18nHelper.addI18nApp('de', 'picker', { colors: { teal: 'Türkis' } }, { ns: LIB_NAMESPACE })`).
|
|
705
|
+
Keys: `label`, `icon`, `color`, `placeholder.{both,icon,color}`, `nothing`, `done`, `search`,
|
|
706
|
+
`searchPlaceholder`, `categoriesLabel`, `all`, `results` (`{count}`), `empty` (`{query}`), `clear`,
|
|
707
|
+
`custom`, `hex`, `invalidHex`, `colors.<key>`, `categories.<category>`. `label` and `placeholder`
|
|
708
|
+
props override per instance. Only the 24 palette names translate: an application palette passed as
|
|
709
|
+
`colors` shows its `label`s as given, so translate them before passing them in.
|
|
710
|
+
|
|
711
|
+
### RIGHT and WRONG
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
import type { IconColorChange } from '@owlmeans/web-panel/picker'
|
|
715
|
+
|
|
716
|
+
// RIGHT — local state
|
|
717
|
+
const translate = usePickerTranslate()
|
|
718
|
+
const [mark, setMark] = useState<IconColorChange>({ icon: type.icon, color: type.tone })
|
|
719
|
+
<IconColorPicker label="Mark" value={mark} onChange={setMark} translate={translate} />
|
|
720
|
+
|
|
721
|
+
// RIGHT — react-hook-form: the field holds { icon, color }; the picker is the whole control
|
|
722
|
+
<Controller
|
|
723
|
+
name="mark" control={form.control}
|
|
724
|
+
render={({ field }) => <IconColorPicker
|
|
725
|
+
id="mark" label="Mark" value={field.value} onChange={field.onChange} disabled={field.disabled} translate={translate}
|
|
726
|
+
/>}
|
|
727
|
+
/>
|
|
728
|
+
// …and on save: { tone: values.mark.color, icon: values.mark.icon }
|
|
729
|
+
|
|
730
|
+
// WRONG — a Select of colour names, a hand-made swatch row, or a label stored instead of the key
|
|
731
|
+
<Select value={tone} onValueChange={setTone}>{PICKER_COLOR_KEYS.map(k => <SelectItem value={k}>{k}</SelectItem>)}</Select>
|
|
732
|
+
{['red', 'blue'].map(c => <button className={`bg-${c}-500`} onClick={() => setTone(c)} />)}
|
|
733
|
+
onChange={next => save({ tone: 'Indigo' })}
|
|
734
|
+
// WRONG — the picker hands over a value, not an event
|
|
735
|
+
<ColorPicker value={field.value} onChange={event => field.onChange(event.target.value)} />
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Rendering a stored mark
|
|
739
|
+
|
|
740
|
+
```tsx
|
|
741
|
+
<IconTile icon={type.icon} color={type.tone} size="sm" /> // list row, chip, header
|
|
742
|
+
<IconTile icon={flow.icon} color={flow.tone} variant="plain" /> // the ink alone, inline with text
|
|
743
|
+
<ColorDot color={label.color} /> // a dot
|
|
744
|
+
<span style={pickerColorHelper.styleOf(card.color)} className="text-(--pick-ink)">…</span> // custom markup
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
`pickerColorHelper.styleOf(value, colors?)` returns the custom properties `--pick-swatch`,
|
|
748
|
+
`--pick-ink`, `--pick-soft`, `--pick-ink-dark`, `--pick-soft-dark` (a plain string record — it goes
|
|
749
|
+
straight into `style`). The parts switch to the dark values themselves, through explicit
|
|
750
|
+
arbitrary variants on web-panel's scheme contract (`.dark` on `<html>`, or the system's dark
|
|
751
|
+
unless `.light`) — never through the app's `dark:` variant. A hand-written element using
|
|
752
|
+
`styleOf` reads `--pick-ink` / `--pick-ink-dark` itself. `pickerColorHelper.resolve(value)` gives
|
|
753
|
+
every field (and `custom: true` for a hex); `hashKey(seed)` gives a stable palette key for a record
|
|
754
|
+
that has none. Code-chosen tones (a status's meaning) stay the app's own classes; a colour a PERSON
|
|
755
|
+
chose always renders through these parts.
|
|
756
|
+
|
|
757
|
+
**DOM hooks** (stable, used by end-to-end suites): the trigger `data-picker-trigger`, the open
|
|
758
|
+
surface `data-picker-surface="popover|sheet"`, a swatch `data-picker-color="<key>"` (the custom
|
|
759
|
+
row `"custom"`, `data-selected` while a custom value is chosen), an icon cell
|
|
760
|
+
`data-picker-icon="<name>"`, a chip `data-picker-category`, the search field `data-picker-search`,
|
|
761
|
+
the hex field `data-picker-hex`, the sheet's Done `data-picker-done`; `IconTile` carries
|
|
762
|
+
`data-icon-tile`, `data-icon`, `data-color`, `ColorDot` `data-color-dot`. Picker parts never carry
|
|
763
|
+
`data-tone` or `data-slot="button"` — an application's own rules on those never reach them.
|
|
764
|
+
|
|
765
|
+
### Consumer setup
|
|
766
|
+
|
|
767
|
+
- `@radix-ui/react-popover` is a peer, like the other Radix primitives: keep it on the SAME Radix
|
|
768
|
+
generation as `@radix-ui/react-dialog` (update them together). The two share the dismissable-layer
|
|
769
|
+
and focus-scope stacks; a popover from another generation inside a Dialog is treated as an outside
|
|
770
|
+
click and loses focus to the dialog. `react-colorful` is a dependency of this package.
|
|
771
|
+
- The `@source` line for this package's `src` (see *Consumer setup* below) is what brings the
|
|
772
|
+
picker's classes — including its `[.dark_&]:` and `pointer-coarse:` variants — into the stylesheet.
|
|
773
|
+
- Tokens read: `--popover`, `--popover-foreground`, `--border`, `--input`, `--ring`, `--accent`,
|
|
774
|
+
`--accent-foreground`, `--primary`, `--primary-foreground`, `--muted-foreground`, `--foreground`,
|
|
775
|
+
`--destructive`.
|
|
776
|
+
|
|
777
|
+
Pinned by `tests/picker.spec.ts` (harness `/picker`: `?custom=1`, `?inSheet=1`, `?bare=1`,
|
|
778
|
+
`?surface=…`, `?compact=1`, `?empty=1`, `?inline=1`, `?dark=1`) and
|
|
779
|
+
`tests/picker-vocabulary.spec.ts` (palette contrast and OKLab distance, hex handling, catalogue ↔
|
|
780
|
+
components). `PICKER_SHOTS_DIR=<dir> bun test tests/picker-shots.spec.ts` writes every scenario's
|
|
781
|
+
screenshot at 1280 and 375, light and dark.
|
|
782
|
+
|
|
585
783
|
## Consumer setup — package boundary and Tailwind
|
|
586
784
|
|
|
587
785
|
`web-panel` ships its shadcn primitives and `cn` helper as private implementation files under its
|
|
@@ -591,8 +789,9 @@ fresh installation depend on unrelated files. `cn` is not exported: a consumer k
|
|
|
591
789
|
class-name helper and never vendors or imports this package's UI primitives.
|
|
592
790
|
|
|
593
791
|
Consumers still supply the package's peer dependencies: the Radix primitives (`alert-dialog`,
|
|
594
|
-
`dialog`, `label`, `navigation-menu`, `progress`, `separator`, `slot`
|
|
595
|
-
|
|
792
|
+
`dialog`, `label`, `navigation-menu`, `popover`, `progress`, `separator`, `slot` — `dialog` and
|
|
793
|
+
`popover` on the same Radix generation) plus React, Tailwind and the usual utility libraries. A
|
|
794
|
+
consumer may have its own shadcn `@` alias, but it is unrelated to this package.
|
|
596
795
|
|
|
597
796
|
Then point Tailwind at the installed package's **`src`** directory. Its oxide scanner reads the CSS root
|
|
598
797
|
plus `@source` directives only, and excludes `node_modules` — so classes that exist **only** inside
|
|
@@ -612,10 +811,11 @@ in a linked workspace, so it is the reliable scan target in both modes.
|
|
|
612
811
|
|
|
613
812
|
- `@owlmeans/web-client`, `@owlmeans/client-panel`, `@owlmeans/client-i18n`, `@owlmeans/web-router`
|
|
614
813
|
- `@owlmeans/client-socket` — `appendSocketStatus`, `useSocketStatus`, `useSocketRetry`, behind `SocketReloadDialog`
|
|
814
|
+
- `react-colorful` — the custom-colour wheel of `./picker` (`customColors`); `sonner` — toasts
|
|
615
815
|
- Peers (app-provided): `react`, `react-dom`, `react-hook-form`, `tailwindcss`, `tailwind-merge`,
|
|
616
|
-
`clsx`, `class-variance-authority`, `lucide-react
|
|
617
|
-
(`alert-dialog`, `dialog`, `label`,
|
|
618
|
-
no react-router.
|
|
816
|
+
`clsx`, `class-variance-authority`, `lucide-react` (`./picker` imports its ~250 catalogue icons
|
|
817
|
+
statically), `ajv`, and the `@radix-ui/react-*` primitives (`alert-dialog`, `dialog`, `label`,
|
|
818
|
+
`navigation-menu`, `popover`, `progress`, `separator`, `slot`). No MUI, no react-router.
|
|
619
819
|
- `ajv-formats` is imported at module scope by the form model but is declared in no dependency
|
|
620
820
|
section of the manifest, which lists `ajv` alone. An install that does not otherwise pull it in
|
|
621
821
|
fails at import time, so declare `ajv-formats` next to `ajv` in the consuming application.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
3
|
+
declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element;
|
|
5
|
+
declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): React.JSX.Element;
|
|
6
|
+
declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): React.JSX.Element;
|
|
7
|
+
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
|
8
|
+
//# sourceMappingURL=popover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../../src/@/components/ui/popover.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAI3D,iBAAS,OAAO,CAAC,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,qBAEpD;AAED,iBAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAEvD;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,KAAgB,EAChB,UAAc,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAevD;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,qBAEtD;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
|
+
function Popover({ ...props }) {
|
|
5
|
+
return _jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
6
|
+
}
|
|
7
|
+
function PopoverTrigger({ ...props }) {
|
|
8
|
+
return _jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
9
|
+
}
|
|
10
|
+
function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }) {
|
|
11
|
+
return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden', className), ...props }) }));
|
|
12
|
+
}
|
|
13
|
+
function PopoverAnchor({ ...props }) {
|
|
14
|
+
return _jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
15
|
+
}
|
|
16
|
+
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
|
17
|
+
//# sourceMappingURL=popover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover.js","sourceRoot":"","sources":["../../../../src/@/components/ui/popover.tsx"],"names":[],"mappings":";AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAE3D,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,SAAS,OAAO,CAAC,EACf,GAAG,KAAK,EAC2C;IACnD,OAAO,KAAC,gBAAgB,CAAC,IAAI,iBAAW,SAAS,KAAK,KAAK,GAAI,CAAA;AACjE,CAAC;AAED,SAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EAC8C;IACtD,OAAO,KAAC,gBAAgB,CAAC,OAAO,iBAAW,iBAAiB,KAAK,KAAK,GAAI,CAAA;AAC5E,CAAC;AAED,SAAS,cAAc,CAAC,EACtB,SAAS,EACT,KAAK,GAAG,QAAQ,EAChB,UAAU,GAAG,CAAC,EACd,GAAG,KAAK,EAC8C;IACtD,OAAO,CACL,KAAC,gBAAgB,CAAC,MAAM,cACtB,KAAC,gBAAgB,CAAC,OAAO,iBACb,iBAAiB,EAC3B,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,EAAE,CACX,geAAge,EAChe,SAAS,CACV,KACG,KAAK,GACT,GACsB,CAC3B,CAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EAC6C;IACrD,OAAO,KAAC,gBAAgB,CAAC,MAAM,iBAAW,gBAAgB,KAAK,KAAK,GAAI,CAAA;AAC1E,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { ColorPickerProps } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The colour half alone: a trigger opening the swatches (plus a colour wheel and a hex field with
|
|
5
|
+
* `customColors`). A swatch commits its key and closes; the wheel and the field commit as they
|
|
6
|
+
* change and keep it open. Pass `colors` for an application palette — a status palette, say.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ColorPicker: FC<ColorPickerProps>;
|
|
9
|
+
//# sourceMappingURL=color-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.d.ts","sourceRoot":"","sources":["../../../src/components/picker/color-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGlD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAK3C,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PickerRoot } from './root.js';
|
|
3
|
+
/**
|
|
4
|
+
* The colour half alone: a trigger opening the swatches (plus a colour wheel and a hex field with
|
|
5
|
+
* `customColors`). A swatch commits its key and closes; the wheel and the field commit as they
|
|
6
|
+
* change and keep it open. Pass `colors` for an application palette — a status palette, say.
|
|
7
|
+
*/
|
|
8
|
+
export const ColorPicker = ({ value, onChange, trigger = 'button', customColors = false, ...base }) => _jsx(PickerRoot, { ...base, mode: "color", trigger: trigger, customColors: customColors, closeOnPick: true, color: value, onColor: onChange, onIcon: () => undefined });
|
|
9
|
+
//# sourceMappingURL=color-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.js","sourceRoot":"","sources":["../../../src/components/picker/color-picker.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAyB,CAC/C,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,EACtE,EAAE,CAAC,KAAC,UAAU,OACV,IAAI,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,QAAC,KAAK,EAAE,KAAK,EAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,GAC1C,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { PickerDotSize, PickerTileSize } from './types.js';
|
|
3
|
+
import type { PickerLayout } from './types.local.js';
|
|
4
|
+
/** From this width up `surface="auto"` opens a popover; below it, a bottom sheet. */
|
|
5
|
+
export declare const POPOVER_QUERY = "(min-width: 768px)";
|
|
6
|
+
/** A mouse or trackpad — the search field may take focus on open without raising a keyboard. */
|
|
7
|
+
export declare const FINE_POINTER_QUERY = "(pointer: fine)";
|
|
8
|
+
/**
|
|
9
|
+
* The current mode's ink and ground, read from the five custom properties `styleOf` sets.
|
|
10
|
+
*
|
|
11
|
+
* Dark follows web-panel's colour-scheme contract — `.dark` on the document element, or the
|
|
12
|
+
* operating system's dark unless `.light` is there — through explicit arbitrary variants. Never the
|
|
13
|
+
* consumer's `dark:`: an application may define it any way it likes, or not at all. Every part that
|
|
14
|
+
* carries a colour's style puts this on the same element; children read `--pick-fg` / `--pick-bg`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const PICK_SCOPE: string;
|
|
17
|
+
/** A hairline inside a swatch, so a dark swatch keeps an edge on a dark surface and a pale one on a light. */
|
|
18
|
+
export declare const HAIRLINE: string;
|
|
19
|
+
export declare const TILE = "inline-flex shrink-0 items-center justify-center bg-(--pick-bg) text-(--pick-fg)";
|
|
20
|
+
export declare const TILE_SIZE: Record<PickerTileSize, string>;
|
|
21
|
+
export declare const PLAIN = "inline-flex shrink-0 items-center justify-center text-(--pick-fg)";
|
|
22
|
+
export declare const PLAIN_SIZE: Record<PickerTileSize, string>;
|
|
23
|
+
export declare const DOT = "inline-block shrink-0 rounded-full bg-(--pick-fg)";
|
|
24
|
+
export declare const DOT_SIZE: Record<PickerDotSize, string>;
|
|
25
|
+
export declare const TRIGGER_BUTTON: string;
|
|
26
|
+
export declare const TRIGGER_COMPACT: string;
|
|
27
|
+
export declare const TRIGGER_DOT = "rounded-full border border-input bg-transparent hover:bg-accent/60";
|
|
28
|
+
/** The empty tile of a trigger while nothing is chosen. */
|
|
29
|
+
export declare const TRIGGER_EMPTY: string;
|
|
30
|
+
export declare const CHEVRON: string;
|
|
31
|
+
export declare const POPOVER: string;
|
|
32
|
+
export declare const SHEET: string;
|
|
33
|
+
/** With an icon grid the surface keeps one height, so filtering never makes it jump. */
|
|
34
|
+
export declare const TALL: Record<'popover' | 'sheet', string>;
|
|
35
|
+
/** The trigger's swatch disc for a colour-only picker — the colour as it was picked. */
|
|
36
|
+
export declare const TRIGGER_DISC = "block size-4 shrink-0 rounded-full bg-(--pick-swatch)";
|
|
37
|
+
export declare const GRAB = "mx-auto mt-2 mb-1 h-1.5 w-10 shrink-0 rounded-full bg-muted-foreground/30";
|
|
38
|
+
export declare const HEADER: Record<'popover' | 'sheet', string>;
|
|
39
|
+
export declare const HEADER_TITLE = "truncate text-sm font-semibold leading-5";
|
|
40
|
+
export declare const HEADER_SUMMARY = "truncate text-xs leading-4 text-muted-foreground";
|
|
41
|
+
export declare const DONE: string;
|
|
42
|
+
export declare const BODY = "min-h-0 flex-1 overflow-y-auto overscroll-contain";
|
|
43
|
+
export declare const SECTION: Record<'popover' | 'sheet', string>;
|
|
44
|
+
export declare const SECTION_TITLE = "mb-2 text-xs font-medium text-muted-foreground";
|
|
45
|
+
export declare const SWATCHES: Record<PickerLayout, string>;
|
|
46
|
+
export declare const SWATCH: string;
|
|
47
|
+
export declare const SWATCH_DISC: string;
|
|
48
|
+
export declare const SWATCH_SELECTED = "ring-2 ring-foreground ring-offset-2 ring-offset-popover";
|
|
49
|
+
export declare const CUSTOM_ROW: string;
|
|
50
|
+
export declare const CUSTOM_DISC = "block size-5 shrink-0 rounded-full";
|
|
51
|
+
/** The colour wheel's mark while no custom colour is chosen. */
|
|
52
|
+
export declare const RAINBOW = "bg-[conic-gradient(from_180deg,#ef4444,#f59e0b,#eab308,#22c55e,#06b6d4,#3b82f6,#8b5cf6,#ec4899,#ef4444)]";
|
|
53
|
+
export declare const CUSTOM_PANEL = "mt-2 flex flex-col gap-2";
|
|
54
|
+
/** A full six-digit value — committed while typing; a three-digit one waits for Enter or blur. */
|
|
55
|
+
export declare const FULL_HEX: RegExp;
|
|
56
|
+
/** The wheel's colour while nothing custom is chosen yet — also the hex field's placeholder. */
|
|
57
|
+
export declare const CUSTOM_START = "#3b82f6";
|
|
58
|
+
/** react-colorful sizes itself with a stylesheet it injects; an inline size is the one that always wins. */
|
|
59
|
+
export declare const WHEEL_STYLE: CSSProperties;
|
|
60
|
+
export declare const FIELD: string;
|
|
61
|
+
export declare const HEX_FIELD = "font-mono";
|
|
62
|
+
export declare const FIELD_ERROR = "text-xs text-destructive";
|
|
63
|
+
/** The search field and the chips stay in view while the grid scrolls under them. */
|
|
64
|
+
export declare const ICON_TOOLS: Record<PickerLayout, string>;
|
|
65
|
+
export declare const SEARCH_WRAP = "relative";
|
|
66
|
+
export declare const SEARCH_ICON = "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground";
|
|
67
|
+
export declare const SEARCH = "pl-8 [&::-webkit-search-cancel-button]:cursor-pointer";
|
|
68
|
+
/** One scrolling row of category chips, running to the surface's edges rather than its padding. */
|
|
69
|
+
export declare const CHIPS: Record<PickerLayout, string>;
|
|
70
|
+
export declare const CHIP: string;
|
|
71
|
+
export declare const ICONS: Record<PickerLayout, string>;
|
|
72
|
+
export declare const ICON_CELL: string;
|
|
73
|
+
export declare const ICON_GRID_PAD: Record<PickerLayout, string>;
|
|
74
|
+
export declare const EMPTY = "flex flex-col items-center gap-2 px-4 py-8 text-center text-sm text-muted-foreground";
|
|
75
|
+
export declare const LINK_BUTTON: string;
|
|
76
|
+
//# sourceMappingURL=consts.local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../../src/components/picker/consts.local.ts"],"names":[],"mappings":"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"}
|