@fungi.computer/caps 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1125 -2
- package/dist/blocks/app-bar.d.ts +43 -0
- package/dist/blocks/app-bar.js +244 -0
- package/dist/blocks/app-status-bar.d.ts +93 -0
- package/dist/blocks/app-status-bar.js +42 -0
- package/dist/blocks/async-state.d.ts +21 -0
- package/dist/blocks/async-state.js +8 -0
- package/dist/blocks/card-grid.d.ts +11 -0
- package/dist/blocks/card-grid.js +21 -0
- package/dist/blocks/command-menu.d.ts +26 -0
- package/dist/blocks/command-menu.js +70 -0
- package/dist/blocks/composer.d.ts +23 -0
- package/dist/blocks/composer.js +13 -0
- package/dist/blocks/empty-state.d.ts +59 -0
- package/dist/blocks/empty-state.js +35 -0
- package/dist/blocks/faq-chat.d.ts +62 -0
- package/dist/blocks/faq-chat.js +77 -0
- package/dist/blocks/game-share-card.d.ts +17 -0
- package/dist/blocks/game-share-card.js +9 -0
- package/dist/blocks/launcher-grid.d.ts +50 -0
- package/dist/blocks/launcher-grid.js +11 -0
- package/dist/blocks/listing-detail.d.ts +23 -0
- package/dist/blocks/listing-detail.js +12 -0
- package/dist/blocks/loading-state.d.ts +5 -0
- package/dist/blocks/loading-state.js +8 -0
- package/dist/blocks/mosaic.d.ts +29 -0
- package/dist/blocks/mosaic.js +19 -0
- package/dist/blocks/permission-grid.d.ts +45 -0
- package/dist/blocks/permission-grid.js +14 -0
- package/dist/blocks/pricing-card.d.ts +53 -0
- package/dist/blocks/pricing-card.js +12 -0
- package/dist/blocks/release-tag.d.ts +20 -0
- package/dist/blocks/release-tag.js +10 -0
- package/dist/blocks/resource-select.d.ts +22 -0
- package/dist/blocks/resource-select.js +16 -0
- package/dist/blocks/result-state.d.ts +15 -0
- package/dist/blocks/result-state.js +8 -0
- package/dist/blocks/section-card.d.ts +31 -0
- package/dist/blocks/section-card.js +7 -0
- package/dist/blocks/section-heading.d.ts +13 -0
- package/dist/blocks/section-heading.js +11 -0
- package/dist/blocks/spec-sheet.d.ts +125 -0
- package/dist/blocks/spec-sheet.js +47 -0
- package/dist/blocks/status-tray.d.ts +83 -0
- package/dist/blocks/status-tray.js +79 -0
- package/dist/blocks/upload-queue.d.ts +48 -0
- package/dist/blocks/upload-queue.js +24 -0
- package/dist/components/action-row.d.ts +16 -0
- package/dist/components/action-row.js +11 -0
- package/dist/components/activity-line.d.ts +33 -0
- package/dist/components/activity-line.js +69 -0
- package/dist/components/alert.d.ts +17 -0
- package/dist/components/alert.js +17 -0
- package/dist/components/badge.d.ts +19 -0
- package/dist/components/badge.js +24 -0
- package/dist/components/button.d.ts +55 -0
- package/dist/components/button.js +230 -0
- package/dist/components/card.d.ts +61 -0
- package/dist/components/card.js +48 -0
- package/dist/components/chat-bubble.d.ts +34 -0
- package/dist/components/chat-bubble.js +10 -0
- package/dist/components/checkbox-bead.d.ts +6 -0
- package/dist/components/checkbox-bead.js +67 -0
- package/dist/components/checkbox.d.ts +21 -0
- package/dist/components/checkbox.js +46 -0
- package/dist/components/code-input.d.ts +35 -0
- package/dist/components/code-input.js +126 -0
- package/dist/components/combobox.d.ts +86 -0
- package/dist/components/combobox.js +218 -0
- package/dist/components/confirm-action.d.ts +23 -0
- package/dist/components/confirm-action.js +64 -0
- package/dist/components/copy-field.d.ts +53 -0
- package/dist/components/copy-field.js +49 -0
- package/dist/components/count-badge.d.ts +15 -0
- package/dist/components/count-badge.js +9 -0
- package/dist/components/cover-pattern.d.ts +19 -0
- package/dist/components/cover-pattern.js +74 -0
- package/dist/components/data-list.d.ts +25 -0
- package/dist/components/data-list.js +16 -0
- package/dist/components/dialog.d.ts +39 -0
- package/dist/components/dialog.js +73 -0
- package/dist/components/diff-view.d.ts +14 -0
- package/dist/components/diff-view.js +13 -0
- package/dist/components/disclosure.d.ts +29 -0
- package/dist/components/disclosure.js +19 -0
- package/dist/components/dropdown-menu.d.ts +49 -0
- package/dist/components/dropdown-menu.js +98 -0
- package/dist/components/field-guide.d.ts +41 -0
- package/dist/components/field-guide.js +18 -0
- package/dist/components/field.d.ts +164 -0
- package/dist/components/field.js +228 -0
- package/dist/components/game-feedback.d.ts +84 -0
- package/dist/components/game-feedback.js +48 -0
- package/dist/components/game-hud.d.ts +126 -0
- package/dist/components/game-hud.js +136 -0
- package/dist/components/generation-frame.d.ts +36 -0
- package/dist/components/generation-frame.js +97 -0
- package/dist/components/gooey.d.ts +32 -0
- package/dist/components/gooey.js +25 -0
- package/dist/components/hold-button.d.ts +26 -0
- package/dist/components/hold-button.js +115 -0
- package/dist/components/icon-button.d.ts +24 -0
- package/dist/components/icon-button.js +18 -0
- package/dist/components/icon-checkbox.d.ts +20 -0
- package/dist/components/icon-checkbox.js +9 -0
- package/dist/components/icon-choice-mark.d.ts +6 -0
- package/dist/components/icon-choice-mark.js +5 -0
- package/dist/components/icon-lamp.d.ts +42 -0
- package/dist/components/icon-lamp.js +15 -0
- package/dist/components/icon-radio.d.ts +16 -0
- package/dist/components/icon-radio.js +9 -0
- package/dist/components/inline-code.d.ts +3 -0
- package/dist/components/inline-code.js +7 -0
- package/dist/components/input-group.d.ts +9 -0
- package/dist/components/input-group.js +15 -0
- package/dist/components/input.d.ts +15 -0
- package/dist/components/input.js +15 -0
- package/dist/components/item-grid.d.ts +110 -0
- package/dist/components/item-grid.js +136 -0
- package/dist/components/keycap.d.ts +80 -0
- package/dist/components/keycap.js +18 -0
- package/dist/components/label.d.ts +13 -0
- package/dist/components/label.js +7 -0
- package/dist/components/listbox.d.ts +50 -0
- package/dist/components/listbox.js +134 -0
- package/dist/components/loader-blobs.d.ts +5 -0
- package/dist/components/loader-blobs.js +128 -0
- package/dist/components/loader.d.ts +21 -0
- package/dist/components/loader.js +25 -0
- package/dist/components/markdown.d.ts +23 -0
- package/dist/components/markdown.js +70 -0
- package/dist/components/minimap-labels.d.ts +39 -0
- package/dist/components/minimap-labels.js +113 -0
- package/dist/components/monogram.d.ts +32 -0
- package/dist/components/monogram.js +24 -0
- package/dist/components/motion-visibility.d.ts +2 -0
- package/dist/components/motion-visibility.js +25 -0
- package/dist/components/navigation-rail.d.ts +11 -0
- package/dist/components/navigation-rail.js +55 -0
- package/dist/components/overlay-root.d.ts +16 -0
- package/dist/components/overlay-root.js +24 -0
- package/dist/components/pixel-number.d.ts +50 -0
- package/dist/components/pixel-number.js +113 -0
- package/dist/components/popover.d.ts +31 -0
- package/dist/components/popover.js +24 -0
- package/dist/components/presence.d.ts +59 -0
- package/dist/components/presence.js +232 -0
- package/dist/components/price-tag.d.ts +11 -0
- package/dist/components/price-tag.js +6 -0
- package/dist/components/progress.d.ts +25 -0
- package/dist/components/progress.js +24 -0
- package/dist/components/prose.d.ts +14 -0
- package/dist/components/prose.js +10 -0
- package/dist/components/quota-meter.d.ts +24 -0
- package/dist/components/quota-meter.js +11 -0
- package/dist/components/radio-bead.d.ts +4 -0
- package/dist/components/radio-bead.js +53 -0
- package/dist/components/radio-group.d.ts +54 -0
- package/dist/components/radio-group.js +64 -0
- package/dist/components/resize-handle.d.ts +23 -0
- package/dist/components/resize-handle.js +31 -0
- package/dist/components/rough-drawing.d.ts +42 -0
- package/dist/components/rough-drawing.js +231 -0
- package/dist/components/rough.d.ts +68 -0
- package/dist/components/rough.js +33 -0
- package/dist/components/scroll-area.d.ts +12 -0
- package/dist/components/scroll-area.js +96 -0
- package/dist/components/scroll-motion.d.ts +12 -0
- package/dist/components/scroll-motion.js +31 -0
- package/dist/components/scroll-to-bottom-blob-state.d.ts +40 -0
- package/dist/components/scroll-to-bottom-blob-state.js +109 -0
- package/dist/components/scroll-to-bottom-blob.d.ts +16 -0
- package/dist/components/scroll-to-bottom-blob.js +174 -0
- package/dist/components/select.d.ts +9 -0
- package/dist/components/select.js +12 -0
- package/dist/components/selectable.d.ts +13 -0
- package/dist/components/selectable.js +45 -0
- package/dist/components/send-action.d.ts +33 -0
- package/dist/components/send-action.js +96 -0
- package/dist/components/separator.d.ts +11 -0
- package/dist/components/separator.js +7 -0
- package/dist/components/skeleton.d.ts +5 -0
- package/dist/components/skeleton.js +7 -0
- package/dist/components/slider.d.ts +18 -0
- package/dist/components/slider.js +31 -0
- package/dist/components/stat.d.ts +17 -0
- package/dist/components/stat.js +7 -0
- package/dist/components/status-bead.d.ts +9 -0
- package/dist/components/status-bead.js +107 -0
- package/dist/components/status-mark.d.ts +12 -0
- package/dist/components/status-mark.js +177 -0
- package/dist/components/status.d.ts +38 -0
- package/dist/components/status.js +28 -0
- package/dist/components/store-card.d.ts +21 -0
- package/dist/components/store-card.js +10 -0
- package/dist/components/surface.d.ts +89 -0
- package/dist/components/surface.js +31 -0
- package/dist/components/switch-bead.d.ts +4 -0
- package/dist/components/switch-bead.js +62 -0
- package/dist/components/switch.d.ts +11 -0
- package/dist/components/switch.js +36 -0
- package/dist/components/tabs.d.ts +55 -0
- package/dist/components/tabs.js +81 -0
- package/dist/components/technonomicon.d.ts +192 -0
- package/dist/components/technonomicon.js +121 -0
- package/dist/components/textarea.d.ts +9 -0
- package/dist/components/textarea.js +11 -0
- package/dist/components/toaster.d.ts +4 -0
- package/dist/components/toaster.js +13 -0
- package/dist/components/tool-call-chip.d.ts +22 -0
- package/dist/components/tool-call-chip.js +100 -0
- package/dist/components/tooltip.d.ts +41 -0
- package/dist/components/tooltip.js +169 -0
- package/dist/components/trading-card.d.ts +60 -0
- package/dist/components/trading-card.js +13 -0
- package/dist/components/undo-action.d.ts +52 -0
- package/dist/components/undo-action.js +100 -0
- package/dist/components/undo-toast.d.ts +21 -0
- package/dist/components/undo-toast.js +58 -0
- package/dist/components/visually-hidden.d.ts +9 -0
- package/dist/components/visually-hidden.js +11 -0
- package/dist/components/window.d.ts +65 -0
- package/dist/components/window.js +31 -0
- package/dist/components/wizard.d.ts +17 -0
- package/dist/components/wizard.js +19 -0
- package/dist/enhance/cigarette-card.d.ts +8 -0
- package/dist/enhance/cigarette-card.js +33 -0
- package/dist/enhance/sketch.d.ts +16 -0
- package/dist/enhance/sketch.js +130 -0
- package/dist/form-error.d.ts +7 -0
- package/dist/form-error.js +14 -0
- package/dist/form-fields.d.ts +15 -0
- package/dist/form-fields.js +250 -0
- package/dist/form-schema.d.ts +166 -0
- package/dist/form-schema.js +398 -0
- package/dist/form.d.ts +30 -0
- package/dist/form.js +20 -0
- package/dist/lib/cn.d.ts +8 -0
- package/dist/lib/cn.js +12 -0
- package/dist/lib/format-money.d.ts +2 -0
- package/dist/lib/format-money.js +22 -0
- package/dist/lib/glide.d.ts +12 -0
- package/dist/lib/glide.js +143 -0
- package/dist/lib/ime.d.ts +3 -0
- package/dist/lib/ime.js +8 -0
- package/dist/lib/motion-spring.d.ts +27 -0
- package/dist/lib/motion-spring.js +36 -0
- package/dist/lib/motion.d.ts +51 -0
- package/dist/lib/motion.js +161 -0
- package/dist/lib/reorder-motion.d.ts +13 -0
- package/dist/lib/reorder-motion.js +201 -0
- package/dist/lib/seed-hash.d.ts +6 -0
- package/dist/lib/seed-hash.js +13 -0
- package/dist/lib/tanstack-highlight.d.ts +4 -0
- package/dist/lib/tanstack-highlight.js +41 -0
- package/dist/schema-form.d.ts +120 -0
- package/dist/schema-form.js +129 -0
- package/dist/styles.css +18814 -0
- package/docs/api/README.md +134 -0
- package/docs/api/blocks/app-bar.md +227 -0
- package/docs/api/blocks/app-status-bar.md +257 -0
- package/docs/api/blocks/async-state.md +53 -0
- package/docs/api/blocks/card-grid.md +31 -0
- package/docs/api/blocks/command-menu.md +89 -0
- package/docs/api/blocks/composer.md +40 -0
- package/docs/api/blocks/empty-state.md +97 -0
- package/docs/api/blocks/faq-chat.md +147 -0
- package/docs/api/blocks/game-share-card.md +40 -0
- package/docs/api/blocks/launcher-grid.md +86 -0
- package/docs/api/blocks/listing-detail.md +51 -0
- package/docs/api/blocks/loading-state.md +21 -0
- package/docs/api/blocks/mosaic.md +94 -0
- package/docs/api/blocks/permission-grid.md +79 -0
- package/docs/api/blocks/pricing-card.md +90 -0
- package/docs/api/blocks/release-tag.md +62 -0
- package/docs/api/blocks/resource-select.md +126 -0
- package/docs/api/blocks/result-state.md +42 -0
- package/docs/api/blocks/section-card.md +42 -0
- package/docs/api/blocks/section-heading.md +61 -0
- package/docs/api/blocks/spec-sheet.md +400 -0
- package/docs/api/blocks/status-tray.md +141 -0
- package/docs/api/blocks/upload-queue.md +110 -0
- package/docs/api/components/action-row.md +51 -0
- package/docs/api/components/activity-line.md +103 -0
- package/docs/api/components/alert.md +60 -0
- package/docs/api/components/badge.md +77 -0
- package/docs/api/components/button.md +94 -0
- package/docs/api/components/card.md +165 -0
- package/docs/api/components/chat-bubble.md +66 -0
- package/docs/api/components/checkbox-bead.md +20 -0
- package/docs/api/components/checkbox.md +42 -0
- package/docs/api/components/code-input.md +61 -0
- package/docs/api/components/combobox.md +303 -0
- package/docs/api/components/confirm-action.md +58 -0
- package/docs/api/components/copy-field.md +106 -0
- package/docs/api/components/count-badge.md +39 -0
- package/docs/api/components/cover-pattern.md +43 -0
- package/docs/api/components/data-list.md +80 -0
- package/docs/api/components/dialog.md +235 -0
- package/docs/api/components/diff-view.md +59 -0
- package/docs/api/components/disclosure.md +71 -0
- package/docs/api/components/dropdown-menu.md +269 -0
- package/docs/api/components/field-guide.md +174 -0
- package/docs/api/components/field.md +252 -0
- package/docs/api/components/game-feedback.md +157 -0
- package/docs/api/components/game-hud.md +359 -0
- package/docs/api/components/generation-frame.md +59 -0
- package/docs/api/components/hold-button.md +44 -0
- package/docs/api/components/icon-button.md +56 -0
- package/docs/api/components/icon-checkbox.md +42 -0
- package/docs/api/components/icon-choice-mark.md +31 -0
- package/docs/api/components/icon-lamp.md +92 -0
- package/docs/api/components/icon-radio.md +42 -0
- package/docs/api/components/inline-code.md +21 -0
- package/docs/api/components/input-group.md +53 -0
- package/docs/api/components/input.md +54 -0
- package/docs/api/components/item-grid.md +262 -0
- package/docs/api/components/keycap.md +102 -0
- package/docs/api/components/label.md +40 -0
- package/docs/api/components/listbox.md +131 -0
- package/docs/api/components/loader-blobs.md +9 -0
- package/docs/api/components/loader.md +51 -0
- package/docs/api/components/markdown.md +91 -0
- package/docs/api/components/minimap-labels.md +84 -0
- package/docs/api/components/monogram.md +96 -0
- package/docs/api/components/motion-visibility.md +9 -0
- package/docs/api/components/navigation-rail.md +37 -0
- package/docs/api/components/overlay-root.md +92 -0
- package/docs/api/components/pixel-number.md +120 -0
- package/docs/api/components/popover.md +80 -0
- package/docs/api/components/presence.md +106 -0
- package/docs/api/components/price-tag.md +48 -0
- package/docs/api/components/progress.md +90 -0
- package/docs/api/components/prose.md +48 -0
- package/docs/api/components/quota-meter.md +47 -0
- package/docs/api/components/radio-bead.md +9 -0
- package/docs/api/components/radio-group.md +126 -0
- package/docs/api/components/resize-handle.md +46 -0
- package/docs/api/components/rough-drawing.md +122 -0
- package/docs/api/components/rough.md +66 -0
- package/docs/api/components/scroll-area.md +22 -0
- package/docs/api/components/scroll-motion.md +9 -0
- package/docs/api/components/scroll-to-bottom-blob-state.md +162 -0
- package/docs/api/components/scroll-to-bottom-blob.md +73 -0
- package/docs/api/components/select.md +39 -0
- package/docs/api/components/send-action.md +58 -0
- package/docs/api/components/separator.md +38 -0
- package/docs/api/components/skeleton.md +31 -0
- package/docs/api/components/slider.md +70 -0
- package/docs/api/components/stat.md +42 -0
- package/docs/api/components/status-bead.md +19 -0
- package/docs/api/components/status-mark.md +19 -0
- package/docs/api/components/status.md +105 -0
- package/docs/api/components/store-card.md +53 -0
- package/docs/api/components/surface.md +161 -0
- package/docs/api/components/switch-bead.md +9 -0
- package/docs/api/components/switch.md +40 -0
- package/docs/api/components/tabs.md +138 -0
- package/docs/api/components/technonomicon.md +773 -0
- package/docs/api/components/textarea.md +40 -0
- package/docs/api/components/toaster.md +29 -0
- package/docs/api/components/tool-call-chip.md +68 -0
- package/docs/api/components/tooltip.md +113 -0
- package/docs/api/components/trading-card.md +95 -0
- package/docs/api/components/undo-action.md +117 -0
- package/docs/api/components/undo-toast.md +49 -0
- package/docs/api/components/visually-hidden.md +37 -0
- package/docs/api/components/window.md +291 -0
- package/docs/api/components/wizard.md +65 -0
- package/docs/api/enhance/cigarette-card.md +52 -0
- package/docs/api/enhance/sketch.md +42 -0
- package/docs/api/form.md +1623 -0
- package/docs/api/lib/cn.md +46 -0
- package/docs/api/lib/format-money.md +30 -0
- package/docs/api/lib/glide.md +36 -0
- package/docs/api/lib/ime.md +29 -0
- package/docs/api/lib/motion-spring.md +91 -0
- package/docs/api/lib/motion.md +212 -0
- package/docs/api/lib/reorder-motion.md +46 -0
- package/docs/api/lib/seed-hash.md +31 -0
- package/docs/api/lib/tanstack-highlight.md +40 -0
- package/package.json +597 -3
- package/src/app-status-bar.css +158 -0
- package/src/fonts.css +1 -0
- package/src/status-tray.css +282 -0
- package/src/styles.css +10177 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "./dialog.js";
|
|
5
|
+
import { Field, FieldError, Form, FormFooter } from "./field.js";
|
|
6
|
+
import { HoldButton } from "./hold-button.js";
|
|
7
|
+
import { Input } from "./input.js";
|
|
8
|
+
/**
|
|
9
|
+
* Confirms once per gesture, owns pending/result feedback, and keeps failed
|
|
10
|
+
* confirmations available for retry. Type mode closes on success and restores
|
|
11
|
+
* focus through Dialog. A pending action cannot be dismissed or cancelled.
|
|
12
|
+
*/
|
|
13
|
+
export function ConfirmAction({ label, confirmLabel, onConfirm, error, mode, phrase, }) {
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
const [typed, setTyped] = useState("");
|
|
16
|
+
const [state, setState] = useState("idle");
|
|
17
|
+
const pending = useRef(false);
|
|
18
|
+
const input = useRef(null);
|
|
19
|
+
const busy = state === "busy";
|
|
20
|
+
const matches = mode === "hold" || (phrase.length > 0 && typed === phrase);
|
|
21
|
+
const message = busy
|
|
22
|
+
? undefined
|
|
23
|
+
: error !== undefined && error !== ""
|
|
24
|
+
? error
|
|
25
|
+
: state instanceof Error
|
|
26
|
+
? state.message
|
|
27
|
+
: undefined;
|
|
28
|
+
const result = message ? "failed" : state === "done" ? "done" : undefined;
|
|
29
|
+
async function confirm() {
|
|
30
|
+
if (pending.current || !matches)
|
|
31
|
+
return;
|
|
32
|
+
pending.current = true;
|
|
33
|
+
setState("busy");
|
|
34
|
+
try {
|
|
35
|
+
await onConfirm();
|
|
36
|
+
setState("done");
|
|
37
|
+
setOpen(false);
|
|
38
|
+
setTyped("");
|
|
39
|
+
}
|
|
40
|
+
catch (cause) {
|
|
41
|
+
setState(new Error("Could not confirm the action. Try again.", { cause }));
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
pending.current = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (mode === "hold") {
|
|
48
|
+
return (_jsxs("div", { className: "grid gap-sm", children: [_jsx(HoldButton, { variant: "destructive", loading: busy, result: result, holdHint: confirmLabel, onConfirm: () => void confirm(), children: label }), _jsx(FieldError, { children: message })] }));
|
|
49
|
+
}
|
|
50
|
+
return (_jsxs(Dialog, { open: open, onOpenChange: (next, details) => {
|
|
51
|
+
if (pending.current) {
|
|
52
|
+
details.cancel();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setOpen(next);
|
|
56
|
+
setTyped("");
|
|
57
|
+
setState("idle");
|
|
58
|
+
}, children: [_jsx(DialogTrigger, { render: _jsx(Button, { variant: "destructive" }), children: label }), _jsx(DialogContent, { initialFocus: input, children: _jsxs(Form, { busy: busy, onSubmit: (event) => {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
void confirm();
|
|
61
|
+
}, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: label }), _jsx(DialogDescription, { children: "Type the phrase exactly to confirm." })] }), _jsx(Field, { label: `Type ${phrase} to confirm`, children: _jsx(Input, { ref: input, autoComplete: "off", autoCapitalize: "none", spellCheck: false, value: typed, onChange: (event) => {
|
|
62
|
+
setTyped(event.currentTarget.value);
|
|
63
|
+
} }) }), _jsxs(FormFooter, { error: message, children: [_jsx(DialogClose, { render: _jsx(Button, { variant: "ghost" }), disabled: busy, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "destructive", disabled: !matches, loading: busy, result: result, children: confirmLabel })] })] }) })] }));
|
|
64
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type HTMLAttributes } from "react";
|
|
2
|
+
/** The colour role of one run of text in a block's code. */
|
|
3
|
+
export type CopyFieldTokenKind = "text" | "tag" | "attribute" | "string";
|
|
4
|
+
/** One run of a block's code; the runs, joined, are the copied value. */
|
|
5
|
+
export type CopyFieldToken = {
|
|
6
|
+
kind: CopyFieldTokenKind;
|
|
7
|
+
text: string;
|
|
8
|
+
};
|
|
9
|
+
/** Props accepted by CopyField. */
|
|
10
|
+
export type CopyFieldProps = {
|
|
11
|
+
/** Copy action text; the code presentations default to "Copy". */
|
|
12
|
+
label?: string;
|
|
13
|
+
} & ({
|
|
14
|
+
value: string;
|
|
15
|
+
/** Absent: show the value as wrapped code beside its copy action. */
|
|
16
|
+
fieldLabel?: undefined;
|
|
17
|
+
displayValue?: undefined;
|
|
18
|
+
layout?: "inline";
|
|
19
|
+
title?: undefined;
|
|
20
|
+
tokens?: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
value: string;
|
|
23
|
+
/** Visible label of a read-only input that holds the value. */
|
|
24
|
+
fieldLabel: string;
|
|
25
|
+
/** Readable text shown in the input instead of the copied value. */
|
|
26
|
+
displayValue?: string;
|
|
27
|
+
layout?: "inline";
|
|
28
|
+
title?: undefined;
|
|
29
|
+
tokens?: undefined;
|
|
30
|
+
} | ({
|
|
31
|
+
/**
|
|
32
|
+
* `block`: a titled code panel for a snippet someone pastes elsewhere.
|
|
33
|
+
* Lines keep their breaks and scroll inside the panel, never the page.
|
|
34
|
+
*/
|
|
35
|
+
layout: "block";
|
|
36
|
+
fieldLabel?: undefined;
|
|
37
|
+
displayValue?: undefined;
|
|
38
|
+
/** Short caption in the panel's header, such as the language. */
|
|
39
|
+
title?: string;
|
|
40
|
+
} & ({
|
|
41
|
+
value: string;
|
|
42
|
+
tokens?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
/** Coloured runs of the code; joined, they are what is copied. */
|
|
45
|
+
tokens: readonly CopyFieldToken[];
|
|
46
|
+
value?: undefined;
|
|
47
|
+
}))) & Omit<HTMLAttributes<HTMLElement>, "children" | "title">;
|
|
48
|
+
/**
|
|
49
|
+
* A value with an explicit copy action and visible outcome: wrapped code by
|
|
50
|
+
* default, a labelled read-only input when `fieldLabel` is given, or a titled
|
|
51
|
+
* code panel with `layout="block"`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function CopyField({ value, label, fieldLabel, displayValue, layout, title, tokens, className, ...props }: CopyFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Check, Copy } from "lucide-react";
|
|
3
|
+
import { useId, useState } from "react";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
import { Input } from "./input.js";
|
|
7
|
+
import { InputGroup } from "./input-group.js";
|
|
8
|
+
import { Label } from "./label.js";
|
|
9
|
+
import { VisuallyHidden } from "./visually-hidden.js";
|
|
10
|
+
/** Key each run by where it starts in the value, which is stable and unique. */
|
|
11
|
+
function tokenRuns(tokens) {
|
|
12
|
+
let offset = 0;
|
|
13
|
+
return tokens.map((token) => {
|
|
14
|
+
const run = { ...token, offset };
|
|
15
|
+
offset += token.text.length;
|
|
16
|
+
return run;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A value with an explicit copy action and visible outcome: wrapped code by
|
|
21
|
+
* default, a labelled read-only input when `fieldLabel` is given, or a titled
|
|
22
|
+
* code panel with `layout="block"`.
|
|
23
|
+
*/
|
|
24
|
+
export function CopyField({ value, label, fieldLabel, displayValue, layout, title, tokens, className, ...props }) {
|
|
25
|
+
const id = useId();
|
|
26
|
+
const [state, setState] = useState({ kind: "ready" });
|
|
27
|
+
const copied = tokens ? tokens.map((token) => token.text).join("") : value;
|
|
28
|
+
const copy = async () => {
|
|
29
|
+
setState(await navigator.clipboard.writeText(copied).then(() => ({ kind: "copied" }), (cause) => ({ kind: "failed", cause })));
|
|
30
|
+
};
|
|
31
|
+
if (fieldLabel !== undefined)
|
|
32
|
+
return (_jsxs("div", { ...props, className: cn("caps-copy-field-input", className), children: [_jsx(Label, { htmlFor: id, children: fieldLabel }), _jsxs(InputGroup, { children: [_jsx(Input, { className: "caps-copy-field-control", "aria-label": fieldLabel, id: id, onFocus: (event) => {
|
|
33
|
+
event.currentTarget.select();
|
|
34
|
+
}, readOnly: true, value: displayValue ?? copied }), _jsx(Button, { onClick: () => void copy(), size: "sm", variant: "outline", children: state.kind === "copied" ? "Copied" : (label ?? "Copy") })] }), state.kind === "failed" ? (_jsx("span", { role: "status", children: "Could not copy. Select the text to copy it." })) : null] }));
|
|
35
|
+
const text = state.kind === "copied"
|
|
36
|
+
? "Copied"
|
|
37
|
+
: state.kind === "failed"
|
|
38
|
+
? "Copy failed"
|
|
39
|
+
: (label ?? "Copy");
|
|
40
|
+
if (layout === "block")
|
|
41
|
+
return (_jsxs("figure", { ...props, className: cn("caps-copy-field-block", className), "data-state": state.kind, children: [_jsxs("figcaption", { className: "caps-copy-field-header", children: [_jsx("span", { className: "caps-copy-field-title", children: title }), _jsxs(Button, { onClick: () => void copy(), size: "sm", variant: state.kind === "copied" ? "ghost" : "outline", children: [state.kind === "copied" ? (_jsx(Check, { "aria-hidden": "true", size: 15 })) : (_jsx(Copy, { "aria-hidden": "true", size: 15 })), text] }), _jsx(VisuallyHidden, { role: "status", children: state.kind === "copied"
|
|
42
|
+
? "Copied to the clipboard"
|
|
43
|
+
: state.kind === "failed"
|
|
44
|
+
? "Could not copy. Select the code to copy it."
|
|
45
|
+
: "" })] }), _jsx("pre", { className: "caps-copy-field-code", tabIndex: 0, children: _jsx("code", { children: tokens
|
|
46
|
+
? tokenRuns(tokens).map((run) => (_jsx("span", { className: "caps-copy-field-token", "data-kind": run.kind, children: run.text }, run.offset)))
|
|
47
|
+
: copied }) })] }));
|
|
48
|
+
return (_jsxs("div", { ...props, className: cn("caps-copy-field", className), children: [_jsx("code", { className: "caps-copy-field-value", children: copied }), _jsxs(Button, { "aria-label": `${text}: ${copied}`, onClick: () => void copy(), size: "sm", variant: "outline", children: [state.kind === "copied" ? _jsx(Check, { size: 15 }) : _jsx(Copy, { size: 15 }), text] })] }));
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
+
/** Props accepted by CountBadge. */
|
|
3
|
+
export type CountBadgeProps = {
|
|
4
|
+
count: ReactNode;
|
|
5
|
+
/** Semantic count emphasis; warnings call attention to items needing action. */
|
|
6
|
+
tone?: "neutral" | "warning";
|
|
7
|
+
label?: ReactNode;
|
|
8
|
+
} & HTMLAttributes<HTMLSpanElement>;
|
|
9
|
+
/** A badge displaying a caller-provided count and label. */
|
|
10
|
+
export declare const CountBadge: import("react").ForwardRefExoticComponent<{
|
|
11
|
+
count: ReactNode;
|
|
12
|
+
/** Semantic count emphasis; warnings call attention to items needing action. */
|
|
13
|
+
tone?: "neutral" | "warning";
|
|
14
|
+
label?: ReactNode;
|
|
15
|
+
} & HTMLAttributes<HTMLSpanElement> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
/** A badge displaying a caller-provided count and label. */
|
|
5
|
+
export const CountBadge = forwardRef(function CountBadge({ className, count, label, tone = "neutral", ...props }, ref) {
|
|
6
|
+
return (_jsxs("span", { ...props, className: cn("inline-flex items-center gap-xs", className), ref: ref, children: [_jsx("span", { className: tone === "warning"
|
|
7
|
+
? "badge badge-warning badge-sm tabular-nums caps-numeric"
|
|
8
|
+
: "badge badge-neutral badge-sm tabular-nums caps-numeric", children: count }), label !== undefined ? (_jsx("span", { className: "text-sm text-base-content", children: label })) : null] }));
|
|
9
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SVGAttributes } from "react";
|
|
2
|
+
/** Props accepted by CoverPattern. */
|
|
3
|
+
export type CoverPatternProps = {
|
|
4
|
+
/** Stable identity that picks the garden; the same seed draws the same one. */
|
|
5
|
+
seed: string;
|
|
6
|
+
/** Names the pattern for assistive technology; without it the pattern is decorative. */
|
|
7
|
+
label?: string;
|
|
8
|
+
} & Omit<SVGAttributes<SVGSVGElement>, "children" | "role" | "aria-label">;
|
|
9
|
+
/**
|
|
10
|
+
* A garden of mushrooms over a thread of mycelium: the stand-in for a cover
|
|
11
|
+
* that has no picture yet. It fills its box, holds no text, and takes every
|
|
12
|
+
* color from the theme.
|
|
13
|
+
*/
|
|
14
|
+
export declare const CoverPattern: import("react").ForwardRefExoticComponent<{
|
|
15
|
+
/** Stable identity that picks the garden; the same seed draws the same one. */
|
|
16
|
+
seed: string;
|
|
17
|
+
/** Names the pattern for assistive technology; without it the pattern is decorative. */
|
|
18
|
+
label?: string;
|
|
19
|
+
} & Omit<SVGAttributes<SVGSVGElement>, "role" | "aria-label" | "children"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { seedHash } from "../lib/seed-hash.js";
|
|
5
|
+
/** Theme tones a mushroom cap may take; the current Stipe theme supplies each color. */
|
|
6
|
+
const capTones = [
|
|
7
|
+
"primary",
|
|
8
|
+
"secondary",
|
|
9
|
+
"accent",
|
|
10
|
+
"info",
|
|
11
|
+
"warning",
|
|
12
|
+
"error",
|
|
13
|
+
];
|
|
14
|
+
/** A small seeded generator, so one seed always draws one garden. */
|
|
15
|
+
function sequence(seed) {
|
|
16
|
+
let state = seedHash(seed) || 1;
|
|
17
|
+
return () => {
|
|
18
|
+
state = (state + 0x6d2b79f5) | 0;
|
|
19
|
+
let mixed = Math.imul(state ^ (state >>> 15), 1 | state);
|
|
20
|
+
mixed = (mixed + Math.imul(mixed ^ (mixed >>> 7), 61 | mixed)) ^ mixed;
|
|
21
|
+
return ((mixed ^ (mixed >>> 14)) >>> 0) / 4294967296;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const number = (value) => value.toFixed(1);
|
|
25
|
+
/**
|
|
26
|
+
* A garden of mushrooms over a thread of mycelium: the stand-in for a cover
|
|
27
|
+
* that has no picture yet. It fills its box, holds no text, and takes every
|
|
28
|
+
* color from the theme.
|
|
29
|
+
*/
|
|
30
|
+
export const CoverPattern = forwardRef(function CoverPattern({ seed, label, className, ...props }, ref) {
|
|
31
|
+
const next = sequence(seed);
|
|
32
|
+
const count = 5 + Math.floor(next() * 2);
|
|
33
|
+
const mushrooms = Array.from({ length: count }, (_, index) => {
|
|
34
|
+
const size = 11 + next() * 11;
|
|
35
|
+
return {
|
|
36
|
+
x: 14 + (index * 132) / (count - 1) + (next() - 0.5) * 12,
|
|
37
|
+
base: 74 + next() * 20,
|
|
38
|
+
size,
|
|
39
|
+
tone: capTones[Math.floor(next() * capTones.length)] ?? "primary",
|
|
40
|
+
spots: 2 + Math.floor(next() * 2),
|
|
41
|
+
lean: (next() - 0.5) * 0.5,
|
|
42
|
+
};
|
|
43
|
+
}).sort((a, b) => a.base - b.base);
|
|
44
|
+
const threads = Array.from({ length: 4 }, () => {
|
|
45
|
+
const y = 80 + next() * 16;
|
|
46
|
+
return `M-4 ${number(y)} C40 ${number(y - 8 + next() * 16)} 100 ${number(y - 8 + next() * 16)} 164 ${number(y - 6 + next() * 12)}`;
|
|
47
|
+
});
|
|
48
|
+
const spores = Array.from({ length: 9 }, () => ({
|
|
49
|
+
x: next() * 160,
|
|
50
|
+
y: 6 + next() * 50,
|
|
51
|
+
r: 0.7 + next() * 1.3,
|
|
52
|
+
}));
|
|
53
|
+
return (_jsxs("svg", { ...props, "aria-hidden": label ? undefined : true, "aria-label": label, className: cn("caps-cover-pattern", className), focusable: "false", preserveAspectRatio: "xMidYMid slice", ref: ref, role: label ? "img" : undefined, viewBox: "0 0 160 100", children: [_jsx("rect", { width: "160", height: "100", style: {
|
|
54
|
+
fill: "color-mix(in oklab, var(--color-base-300) 88%, var(--color-secondary))",
|
|
55
|
+
} }), _jsx("circle", { cx: number(110 + next() * 34), cy: number(20 + next() * 8), r: "9", style: {
|
|
56
|
+
fill: "color-mix(in oklab, var(--color-warning) 45%, var(--color-base-300))",
|
|
57
|
+
} }), _jsx("path", { d: "M0 74 Q36 62 76 70 T160 66 V100 H0 Z", style: {
|
|
58
|
+
fill: "color-mix(in oklab, var(--color-success) 30%, var(--color-base-300))",
|
|
59
|
+
} }), threads.map((path) => (_jsx("path", { d: path, fill: "none", strokeLinecap: "round", strokeWidth: "0.6", style: {
|
|
60
|
+
stroke: "color-mix(in oklab, var(--color-base-content) 22%, transparent)",
|
|
61
|
+
} }, path))), spores.map((spore) => (_jsx("circle", { cx: number(spore.x), cy: number(spore.y), r: number(spore.r), style: {
|
|
62
|
+
fill: "color-mix(in oklab, var(--color-base-content) 28%, transparent)",
|
|
63
|
+
} }, `${number(spore.x)}-${number(spore.y)}`))), mushrooms.map((mushroom) => {
|
|
64
|
+
const stemWidth = mushroom.size * 0.55;
|
|
65
|
+
const stemHeight = mushroom.size * 0.95;
|
|
66
|
+
const capBase = mushroom.base - stemHeight;
|
|
67
|
+
return (_jsxs("g", { transform: `rotate(${number(mushroom.lean * 20)} ${number(mushroom.x)} ${number(mushroom.base)})`, children: [_jsx("rect", { x: number(mushroom.x - stemWidth / 2), y: number(capBase - 1), width: number(stemWidth), height: number(stemHeight + 1), rx: number(stemWidth / 2), style: {
|
|
68
|
+
fill: "color-mix(in oklab, var(--color-base-100) 92%, var(--color-warning))",
|
|
69
|
+
} }), _jsx("path", { d: `M${number(mushroom.x - mushroom.size)} ${number(capBase)} A${number(mushroom.size)} ${number(mushroom.size * 0.85)} 0 0 1 ${number(mushroom.x + mushroom.size)} ${number(capBase)} Z`, style: { fill: `var(--color-${mushroom.tone})` } }), Array.from({ length: mushroom.spots }, (_, spot) => (_jsx("circle", { cx: number(mushroom.x +
|
|
70
|
+
(spot - (mushroom.spots - 1) / 2) * mushroom.size * 0.62), cy: number(capBase - mushroom.size * (spot % 2 === 0 ? 0.42 : 0.22)), r: number(mushroom.size * 0.16), style: {
|
|
71
|
+
fill: "color-mix(in oklab, var(--color-base-100) 90%, transparent)",
|
|
72
|
+
} }, spot)))] }, `${number(mushroom.x)}-${number(mushroom.base)}`));
|
|
73
|
+
})] }));
|
|
74
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type HTMLAttributes, type LiHTMLAttributes, type ReactNode } from "react";
|
|
2
|
+
/** Props accepted by DataList. */
|
|
3
|
+
export type DataListProps = HTMLAttributes<HTMLUListElement> & {
|
|
4
|
+
density?: "regular" | "compact";
|
|
5
|
+
};
|
|
6
|
+
/** A list wrapper for caller-provided rows. */
|
|
7
|
+
export declare const DataList: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLUListElement> & {
|
|
8
|
+
density?: "regular" | "compact";
|
|
9
|
+
} & import("react").RefAttributes<HTMLUListElement>>;
|
|
10
|
+
/** A list row for a caller-provided label and value. */
|
|
11
|
+
export declare const DataRow: import("react").ForwardRefExoticComponent<LiHTMLAttributes<HTMLLIElement> & import("react").RefAttributes<HTMLLIElement>>;
|
|
12
|
+
/** Props accepted by DataListHeading. */
|
|
13
|
+
export type DataListHeadingProps = HTMLAttributes<HTMLHeadingElement> & {
|
|
14
|
+
/** Heading level; the host keeps its document outline. */
|
|
15
|
+
level?: 2 | 3;
|
|
16
|
+
/** Optional trailing count or status, such as a Badge. */
|
|
17
|
+
aside?: ReactNode;
|
|
18
|
+
};
|
|
19
|
+
/** A quiet small-caps section label that groups the rows below it. */
|
|
20
|
+
export declare const DataListHeading: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLHeadingElement> & {
|
|
21
|
+
/** Heading level; the host keeps its document outline. */
|
|
22
|
+
level?: 2 | 3;
|
|
23
|
+
/** Optional trailing count or status, such as a Badge. */
|
|
24
|
+
aside?: ReactNode;
|
|
25
|
+
} & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, } from "react";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
/** A list wrapper for caller-provided rows. */
|
|
5
|
+
export const DataList = forwardRef(function DataList({ className, density = "regular", ...props }, ref) {
|
|
6
|
+
return (_jsx("ul", { ...props, className: cn("list", density === "compact" && "list-sm", className), ref: ref }));
|
|
7
|
+
});
|
|
8
|
+
/** A list row for a caller-provided label and value. */
|
|
9
|
+
export const DataRow = forwardRef(function DataRow({ className, ...props }, ref) {
|
|
10
|
+
return _jsx("li", { ...props, className: cn("list-row", className), ref: ref });
|
|
11
|
+
});
|
|
12
|
+
/** A quiet small-caps section label that groups the rows below it. */
|
|
13
|
+
export const DataListHeading = forwardRef(function DataListHeading({ aside, children, className, level = 2, ...props }, ref) {
|
|
14
|
+
const Heading = level === 3 ? "h3" : "h2";
|
|
15
|
+
return (_jsxs(Heading, { ...props, className: cn("caps-data-list-heading", className), ref: ref, children: [_jsx("span", { children: children }), aside !== undefined ? (_jsx("span", { className: "caps-data-list-heading-aside", children: aside })) : null] }));
|
|
16
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Dialog as BaseDialog } from "@base-ui/react/dialog";
|
|
2
|
+
import { type HTMLAttributes } from "react";
|
|
3
|
+
/** Details supplied to a Dialog open-change callback. */
|
|
4
|
+
export type DialogChangeDetails = BaseDialog.Root.ChangeEventDetails;
|
|
5
|
+
/** Supported DialogChangeReason values. */
|
|
6
|
+
export type DialogChangeReason = BaseDialog.Root.ChangeEventReason;
|
|
7
|
+
/** Supported DialogInteractionOwner values. */
|
|
8
|
+
export type DialogInteractionOwner = "host" | "local";
|
|
9
|
+
/** Props accepted by Dialog. */
|
|
10
|
+
export type DialogProps<Payload = unknown> = BaseDialog.Root.Props<Payload> & {
|
|
11
|
+
interactionOwner?: DialogInteractionOwner;
|
|
12
|
+
};
|
|
13
|
+
/** A dialog controller with explicit controlled or uncontrolled open state. */
|
|
14
|
+
export declare function Dialog<Payload = unknown>({ children, interactionOwner, modal, onOpenChange, ...props }: DialogProps<Payload>): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
/** The trigger control for a Dialog. */
|
|
16
|
+
export declare const DialogTrigger: import("react").ForwardRefExoticComponent<Omit<BaseDialog.Trigger.Props<unknown>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
17
|
+
/** Shell dialog destination, with Base UI container and mount lifetime overrides. */
|
|
18
|
+
export declare const DialogPortal: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogPortalProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
|
+
/** The styled backdrop for a composed Dialog. */
|
|
20
|
+
export declare const DialogBackdrop: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogBackdropProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
21
|
+
/** The styled popup with Base UI composition and caller-controlled focus targets. */
|
|
22
|
+
export declare const DialogPopup: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogPopupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
23
|
+
/** Props accepted by DialogContent. */
|
|
24
|
+
export type DialogContentProps = BaseDialog.Popup.Props & Pick<BaseDialog.Portal.Props, "container" | "keepMounted">;
|
|
25
|
+
/**
|
|
26
|
+
* The default portal, backdrop and popup composition for a Dialog.
|
|
27
|
+
* Keeps child state across closes. Like Base UI, only full modal mode has a backdrop.
|
|
28
|
+
*/
|
|
29
|
+
export declare const DialogContent: import("react").ForwardRefExoticComponent<Omit<DialogContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
30
|
+
/** A footer layout for caller-provided Dialog actions. */
|
|
31
|
+
export declare function DialogFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
/** A header layout for caller-provided Dialog content. */
|
|
33
|
+
export declare function DialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
/** The accessible title for a Dialog. */
|
|
35
|
+
export declare const DialogTitle: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogTitleProps, "ref"> & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
36
|
+
/** The accessible description for a Dialog. */
|
|
37
|
+
export declare const DialogDescription: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogDescriptionProps, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
|
|
38
|
+
/** A control that requests a Dialog to close. */
|
|
39
|
+
export declare const DialogClose: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react/dialog").DialogCloseProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Dialog as BaseDialog } from "@base-ui/react/dialog";
|
|
3
|
+
import { createContext, forwardRef, useContext, } from "react";
|
|
4
|
+
import { cn, resolveClassName } from "../lib/cn.js";
|
|
5
|
+
import { useOverlayRoot } from "./overlay-root.js";
|
|
6
|
+
const DialogContext = createContext(null);
|
|
7
|
+
/** A dialog controller with explicit controlled or uncontrolled open state. */
|
|
8
|
+
export function Dialog({ children, interactionOwner = "local", modal = true, onOpenChange, ...props }) {
|
|
9
|
+
return (_jsx(DialogContext.Provider, { value: { interactionOwner, modal }, children: _jsx(BaseDialog.Root, { ...props, modal: modal, onOpenChange: (next, details) => {
|
|
10
|
+
if (interactionOwner === "host" &&
|
|
11
|
+
!next &&
|
|
12
|
+
details.reason === "escape-key") {
|
|
13
|
+
details.cancel();
|
|
14
|
+
details.allowPropagation();
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
onOpenChange?.(next, details);
|
|
18
|
+
}, children: children }) }));
|
|
19
|
+
}
|
|
20
|
+
function useDialogContext() {
|
|
21
|
+
const context = useContext(DialogContext);
|
|
22
|
+
if (!context)
|
|
23
|
+
throw new Error("Dialog parts must be used inside <Dialog>");
|
|
24
|
+
return context;
|
|
25
|
+
}
|
|
26
|
+
/** The trigger control for a Dialog. */
|
|
27
|
+
export const DialogTrigger = forwardRef(function DialogTrigger({ className, type = "button", ...props }, ref) {
|
|
28
|
+
return (_jsx(BaseDialog.Trigger, { ...props, className: (state) => cn("btn", resolveClassName(className, state)), ref: ref, type: type }));
|
|
29
|
+
});
|
|
30
|
+
/** Shell dialog destination, with Base UI container and mount lifetime overrides. */
|
|
31
|
+
export const DialogPortal = forwardRef(function DialogPortal({ container, ...props }, ref) {
|
|
32
|
+
const root = useOverlayRoot("dialog");
|
|
33
|
+
if (container == null && root === null)
|
|
34
|
+
return null;
|
|
35
|
+
return (_jsx(BaseDialog.Portal, { ...props, container: container ?? root, ref: ref }));
|
|
36
|
+
});
|
|
37
|
+
/** The styled backdrop for a composed Dialog. */
|
|
38
|
+
export const DialogBackdrop = forwardRef(function DialogBackdrop({ className, ...props }, ref) {
|
|
39
|
+
return (_jsx(BaseDialog.Backdrop, { ...props, ref: ref, className: (state) => cn("caps-dialog-backdrop fixed inset-0 bg-black/40", resolveClassName(className, state)) }));
|
|
40
|
+
});
|
|
41
|
+
/** The styled popup with Base UI composition and caller-controlled focus targets. */
|
|
42
|
+
export const DialogPopup = forwardRef(function DialogPopup({ className, finalFocus, ...props }, ref) {
|
|
43
|
+
const dialog = useDialogContext();
|
|
44
|
+
return (_jsx(BaseDialog.Popup, { ...props, className: (state) => cn("caps-dialog-popup max-h-screen w-11/12 max-w-(--container-lg) overflow-y-auto overscroll-contain rounded-box bg-base-100 p-lg text-base-content shadow-xl", resolveClassName(className, state)), finalFocus: dialog.interactionOwner === "host" ? false : (finalFocus ?? true), ref: ref }));
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* The default portal, backdrop and popup composition for a Dialog.
|
|
48
|
+
* Keeps child state across closes. Like Base UI, only full modal mode has a backdrop.
|
|
49
|
+
*/
|
|
50
|
+
export const DialogContent = forwardRef(function DialogContent({ container, keepMounted = true, className, ...props }, ref) {
|
|
51
|
+
const { modal } = useDialogContext();
|
|
52
|
+
return (_jsxs(DialogPortal, { container: container, keepMounted: keepMounted, children: [modal === true ? _jsx(DialogBackdrop, {}) : null, _jsx(DialogPopup, { ...props, className: (state) => cn("fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2", resolveClassName(className, state)), ref: ref })] }));
|
|
53
|
+
});
|
|
54
|
+
/** A footer layout for caller-provided Dialog actions. */
|
|
55
|
+
export function DialogFooter({ className, ...props }) {
|
|
56
|
+
return (_jsx("div", { ...props, className: cn("flex justify-end gap-sm", className) }));
|
|
57
|
+
}
|
|
58
|
+
/** A header layout for caller-provided Dialog content. */
|
|
59
|
+
export function DialogHeader({ className, ...props }) {
|
|
60
|
+
return _jsx("div", { ...props, className: cn("flex flex-col gap-sm", className) });
|
|
61
|
+
}
|
|
62
|
+
/** The accessible title for a Dialog. */
|
|
63
|
+
export const DialogTitle = forwardRef(function DialogTitle({ className, ...props }, ref) {
|
|
64
|
+
return (_jsx(BaseDialog.Title, { ...props, className: (state) => cn("text-lg font-semibold", resolveClassName(className, state)), ref: ref }));
|
|
65
|
+
});
|
|
66
|
+
/** The accessible description for a Dialog. */
|
|
67
|
+
export const DialogDescription = forwardRef(function DialogDescription({ className, ...props }, ref) {
|
|
68
|
+
return (_jsx(BaseDialog.Description, { ...props, className: (state) => cn("text-sm text-base-content", resolveClassName(className, state)), ref: ref }));
|
|
69
|
+
});
|
|
70
|
+
/** A control that requests a Dialog to close. */
|
|
71
|
+
export const DialogClose = forwardRef(function DialogClose({ className, type = "button", ...props }, ref) {
|
|
72
|
+
return (_jsx(BaseDialog.Close, { ...props, className: (state) => cn("btn btn-ghost", resolveClassName(className, state)), ref: ref, type: type }));
|
|
73
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
/** One presentational diff line; the caller owns parsing. */
|
|
3
|
+
export type DiffViewLine = Readonly<{
|
|
4
|
+
kind: "add" | "context" | "file" | "hunk" | "remove";
|
|
5
|
+
text: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Props accepted by DiffView. */
|
|
8
|
+
export type DiffViewProps = {
|
|
9
|
+
lines: readonly DiffViewLine[];
|
|
10
|
+
/** Lines the caller omitted, shown as a trailing note. */
|
|
11
|
+
hiddenLines?: number;
|
|
12
|
+
} & Omit<HTMLAttributes<HTMLPreElement>, "children">;
|
|
13
|
+
/** A compact monospace diff with add/remove/hunk/file line tones. */
|
|
14
|
+
export declare function DiffView({ lines, hiddenLines, className, ...props }: DiffViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
const markers = {
|
|
4
|
+
add: "+",
|
|
5
|
+
context: " ",
|
|
6
|
+
file: "",
|
|
7
|
+
hunk: "@@",
|
|
8
|
+
remove: "-",
|
|
9
|
+
};
|
|
10
|
+
/** A compact monospace diff with add/remove/hunk/file line tones. */
|
|
11
|
+
export function DiffView({ lines, hiddenLines = 0, className, ...props }) {
|
|
12
|
+
return (_jsxs("pre", { ...props, className: cn("caps-diff", className), children: [lines.map((line, index) => (_jsxs("span", { className: "caps-diff-line", "data-kind": line.kind, children: [_jsx("span", { "aria-hidden": "true", className: "caps-diff-marker", children: markers[line.kind] }), line.text, "\n"] }, `${String(index)}:${line.kind}`))), hiddenLines > 0 ? (_jsxs("span", { className: "caps-diff-line", "data-kind": "more", children: ["\u2026 ", String(hiddenLines), " more lines"] })) : null] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Semantic tone of the disclosure header. */
|
|
3
|
+
export type DisclosureTone = "neutral" | "error";
|
|
4
|
+
/** Density: `group` for a summary header, `row` for a compact nested row. */
|
|
5
|
+
export type DisclosureSize = "group" | "row";
|
|
6
|
+
/** Props accepted by Disclosure. */
|
|
7
|
+
export type DisclosureProps = Readonly<{
|
|
8
|
+
/** Controlled open state; the caller owns persistence. */
|
|
9
|
+
open: boolean;
|
|
10
|
+
/** Called with the requested open state. */
|
|
11
|
+
onOpenChange: (open: boolean) => void;
|
|
12
|
+
/** One-line header content. */
|
|
13
|
+
summary: ReactNode;
|
|
14
|
+
/** Optional leading visual, such as a status bead or icon. */
|
|
15
|
+
leading?: ReactNode;
|
|
16
|
+
/** Optional trailing metadata, such as a duration. */
|
|
17
|
+
trailing?: ReactNode;
|
|
18
|
+
/** Panel content, mounted only while open. */
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
tone?: DisclosureTone;
|
|
21
|
+
size?: DisclosureSize;
|
|
22
|
+
className?: string;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* A controlled one-line disclosure over Base UI Collapsible. The header is a
|
|
26
|
+
* native button carrying `aria-expanded` and `aria-controls`, so Enter and
|
|
27
|
+
* Space toggle it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function Disclosure({ open, onOpenChange, summary, leading, trailing, children, tone, size, className, }: DisclosureProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Collapsible } from "@base-ui/react/collapsible";
|
|
3
|
+
import { ChevronRight } from "lucide-react";
|
|
4
|
+
import { cn, cva } from "../lib/cn.js";
|
|
5
|
+
const disclosureVariants = cva("caps-disclosure", {
|
|
6
|
+
variants: {
|
|
7
|
+
tone: { neutral: "", error: "caps-disclosure-error" },
|
|
8
|
+
size: { group: "caps-disclosure-group", row: "caps-disclosure-row" },
|
|
9
|
+
},
|
|
10
|
+
defaultVariants: { tone: "neutral", size: "group" },
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* A controlled one-line disclosure over Base UI Collapsible. The header is a
|
|
14
|
+
* native button carrying `aria-expanded` and `aria-controls`, so Enter and
|
|
15
|
+
* Space toggle it.
|
|
16
|
+
*/
|
|
17
|
+
export function Disclosure({ open, onOpenChange, summary, leading, trailing, children, tone, size, className, }) {
|
|
18
|
+
return (_jsxs(Collapsible.Root, { className: cn(disclosureVariants({ tone, size }), className), onOpenChange: onOpenChange, open: open, children: [_jsxs(Collapsible.Trigger, { className: "caps-disclosure-trigger", children: [leading === undefined ? null : (_jsx("span", { className: "caps-disclosure-leading", children: leading })), _jsx("span", { className: "caps-disclosure-summary", children: summary }), trailing === undefined ? null : (_jsx("span", { className: "caps-disclosure-trailing", children: trailing })), _jsx(ChevronRight, { "aria-hidden": "true", className: "caps-disclosure-chevron", size: 12 })] }), _jsx(Collapsible.Panel, { className: "caps-disclosure-panel", children: children })] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/** Details supplied to a DropdownMenu open-change callback. */
|
|
4
|
+
export type DropdownMenuChangeDetails = BaseMenu.Root.ChangeEventDetails;
|
|
5
|
+
/** Supported DropdownMenuChangeReason values. */
|
|
6
|
+
export type DropdownMenuChangeReason = BaseMenu.Root.ChangeEventReason;
|
|
7
|
+
/** Supported DropdownMenuInteractionOwner values. */
|
|
8
|
+
export type DropdownMenuInteractionOwner = "host" | "local";
|
|
9
|
+
/** Props accepted by DropdownMenu. */
|
|
10
|
+
export type DropdownMenuProps<Payload = unknown> = BaseMenu.Root.Props<Payload> & {
|
|
11
|
+
interactionOwner?: DropdownMenuInteractionOwner;
|
|
12
|
+
};
|
|
13
|
+
/** A menu controller with explicit controlled or uncontrolled open state. */
|
|
14
|
+
export declare function DropdownMenu<Payload = unknown>({ actionsRef: suppliedActionsRef, children, interactionOwner, onOpenChange, ...props }: DropdownMenuProps<Payload>): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
/** Access the nearest DropdownMenu close operation. */
|
|
16
|
+
export declare function useDropdownMenu(): {
|
|
17
|
+
/** Close the nearest menu, if it is mounted. */
|
|
18
|
+
close: () => void | undefined;
|
|
19
|
+
};
|
|
20
|
+
/** The trigger control for a DropdownMenu. */
|
|
21
|
+
export declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<Omit<BaseMenu.Trigger.Props<unknown>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
22
|
+
/** Shell popover destination, with Base UI container and mount lifetime overrides. */
|
|
23
|
+
export declare const DropdownMenuPortal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/menu").MenuPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
24
|
+
/** Base UI owns placement; a shell's popover root supplies its collision boundary. */
|
|
25
|
+
export declare const DropdownMenuPositioner: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/menu").MenuPositionerProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
/** The styled popup for caller-composed menu placement and portal ownership. */
|
|
27
|
+
export declare const DropdownMenuPopup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/menu").MenuPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
/** Props accepted by DropdownMenuContent. */
|
|
29
|
+
export type DropdownMenuContentProps = BaseMenu.Popup.Props & Pick<BaseMenu.Portal.Props, "container" | "keepMounted"> & Pick<BaseMenu.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">;
|
|
30
|
+
/** The positioned content region for a DropdownMenu. */
|
|
31
|
+
export declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuContentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
32
|
+
/** Props accepted by DropdownMenuItem. */
|
|
33
|
+
export type DropdownMenuItemProps = Omit<BaseMenu.Item.Props, "onSelect"> & {
|
|
34
|
+
/** Called when this item is selected. */
|
|
35
|
+
onSelect?: (event: React.SyntheticEvent<HTMLDivElement>) => void;
|
|
36
|
+
variant?: "default" | "destructive";
|
|
37
|
+
};
|
|
38
|
+
/** An actionable item in a DropdownMenu. */
|
|
39
|
+
export declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuItemProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
40
|
+
/** Props accepted by DropdownMenuCheckboxItem. */
|
|
41
|
+
export type DropdownMenuCheckboxItemProps = Omit<BaseMenu.CheckboxItem.Props, "onSelect"> & Pick<DropdownMenuItemProps, "onSelect">;
|
|
42
|
+
/** A checkable item in a DropdownMenu. */
|
|
43
|
+
export declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<DropdownMenuCheckboxItemProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
44
|
+
/** A visual separator in a DropdownMenu. */
|
|
45
|
+
export declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
46
|
+
/** A named set of related items; pair it with a DropdownMenuLabel. */
|
|
47
|
+
export declare const DropdownMenuGroup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/menu").MenuGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
48
|
+
/** The visible name of a DropdownMenuGroup, announced with its items. */
|
|
49
|
+
export declare const DropdownMenuLabel: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/menu").MenuGroupLabelProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|