@particle-academy/react-fancy 5.53.1 → 5.54.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/CHANGELOG.md +100 -0
- package/dist/PdfViewer.types-BEk2Jq6p.d.ts +97 -0
- package/dist/PdfViewer.types-DyoUBa2g.d.cts +97 -0
- package/dist/button.cjs +4 -4
- package/dist/button.js +2 -2
- package/dist/chat-drawer.cjs +3 -3
- package/dist/chat-drawer.js +2 -2
- package/dist/chunk-2O5UXH5R.cjs +191 -0
- package/dist/chunk-2O5UXH5R.cjs.map +1 -0
- package/dist/{chunk-26JZ47BJ.js → chunk-45JO5BEZ.js} +17 -11
- package/dist/chunk-45JO5BEZ.js.map +1 -0
- package/dist/{chunk-TFKG5FSG.cjs → chunk-4I4Y5MZO.cjs} +4 -4
- package/dist/{chunk-TFKG5FSG.cjs.map → chunk-4I4Y5MZO.cjs.map} +1 -1
- package/dist/{chunk-2KFHSFFY.cjs → chunk-6GKR5OAW.cjs} +4 -4
- package/dist/{chunk-2KFHSFFY.cjs.map → chunk-6GKR5OAW.cjs.map} +1 -1
- package/dist/chunk-7MDHCYEB.cjs +414 -0
- package/dist/chunk-7MDHCYEB.cjs.map +1 -0
- package/dist/{chunk-X7H75WVP.cjs → chunk-BJKKW77L.cjs} +17 -8
- package/dist/chunk-BJKKW77L.cjs.map +1 -0
- package/dist/chunk-DXZCKDYS.js +189 -0
- package/dist/chunk-DXZCKDYS.js.map +1 -0
- package/dist/{chunk-EJ6P7K4G.js → chunk-EULOJOTU.js} +3 -3
- package/dist/{chunk-EJ6P7K4G.js.map → chunk-EULOJOTU.js.map} +1 -1
- package/dist/chunk-I27K6NLX.cjs +15 -0
- package/dist/chunk-I27K6NLX.cjs.map +1 -0
- package/dist/{chunk-N7ABDCQ6.cjs → chunk-I2TBENUQ.cjs} +11 -11
- package/dist/{chunk-N7ABDCQ6.cjs.map → chunk-I2TBENUQ.cjs.map} +1 -1
- package/dist/{chunk-IVRYSSM7.js → chunk-J3A4Z2P7.js} +2 -2
- package/dist/chunk-J3A4Z2P7.js.map +1 -0
- package/dist/{chunk-EEFWVFKO.js → chunk-KUJ5XRBD.js} +7 -4
- package/dist/chunk-KUJ5XRBD.js.map +1 -0
- package/dist/chunk-MORXQ5UM.js +412 -0
- package/dist/chunk-MORXQ5UM.js.map +1 -0
- package/dist/{chunk-D4QOV56U.js → chunk-MTTRPPHH.js} +3 -3
- package/dist/{chunk-D4QOV56U.js.map → chunk-MTTRPPHH.js.map} +1 -1
- package/dist/{chunk-QKFOJKVE.cjs → chunk-MXWR3T3N.cjs} +2 -2
- package/dist/chunk-MXWR3T3N.cjs.map +1 -0
- package/dist/{chunk-G4M3MCJO.cjs → chunk-ONHT2PDW.cjs} +4 -4
- package/dist/{chunk-G4M3MCJO.cjs.map → chunk-ONHT2PDW.cjs.map} +1 -1
- package/dist/{chunk-2MUGEPRD.js → chunk-REKY2CM6.js} +5 -5
- package/dist/{chunk-2MUGEPRD.js.map → chunk-REKY2CM6.js.map} +1 -1
- package/dist/{chunk-E4TRDGSU.cjs → chunk-SLCR7A6W.cjs} +4 -4
- package/dist/{chunk-E4TRDGSU.cjs.map → chunk-SLCR7A6W.cjs.map} +1 -1
- package/dist/chunk-SV5BW3IA.js +13 -0
- package/dist/chunk-SV5BW3IA.js.map +1 -0
- package/dist/{chunk-OC5OUZSD.js → chunk-TBXZ3NGR.js} +4 -4
- package/dist/{chunk-OC5OUZSD.js.map → chunk-TBXZ3NGR.js.map} +1 -1
- package/dist/{chunk-VP7MT7LH.cjs → chunk-TCW72JBU.cjs} +17 -17
- package/dist/{chunk-VP7MT7LH.cjs.map → chunk-TCW72JBU.cjs.map} +1 -1
- package/dist/{chunk-CF5KRDN4.js → chunk-TGBLDJ72.js} +18 -9
- package/dist/chunk-TGBLDJ72.js.map +1 -0
- package/dist/{chunk-QFC736WY.js → chunk-WE5WGVVX.js} +3 -3
- package/dist/{chunk-QFC736WY.js.map → chunk-WE5WGVVX.js.map} +1 -1
- package/dist/{chunk-YVTFODCJ.cjs → chunk-WUG646R4.cjs} +6 -3
- package/dist/chunk-WUG646R4.cjs.map +1 -0
- package/dist/{chunk-CAMQ5B3V.cjs → chunk-XOXA3QZR.cjs} +21 -15
- package/dist/chunk-XOXA3QZR.cjs.map +1 -0
- package/dist/{chunk-Y6LL3B5P.js → chunk-ZFU4FY3Q.js} +3 -3
- package/dist/{chunk-Y6LL3B5P.js.map → chunk-ZFU4FY3Q.js.map} +1 -1
- package/dist/icon.cjs +7 -7
- package/dist/icon.js +1 -1
- package/dist/{index-AesVUjQE.d.cts → index-Bd4br4sF.d.cts} +1 -1
- package/dist/{index-D3wJ8hrZ.d.ts → index-Bwrc9ktU.d.ts} +1 -1
- package/dist/index.cjs +45 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +5 -4
- package/dist/inputs.js +3 -2
- package/dist/json-editor.cjs +15 -15
- package/dist/json-editor.js +4 -4
- package/dist/magic-wand.cjs +4 -4
- package/dist/magic-wand.js +3 -3
- package/dist/media-viewer.cjs +3 -3
- package/dist/media-viewer.d.cts +2 -2
- package/dist/media-viewer.d.ts +2 -2
- package/dist/media-viewer.js +2 -2
- package/dist/multi-switch.cjs +3 -2
- package/dist/multi-switch.js +2 -1
- package/dist/pdf-viewer.cjs +2 -2
- package/dist/pdf-viewer.d.cts +13 -1
- package/dist/pdf-viewer.d.ts +13 -1
- package/dist/pdf-viewer.js +1 -1
- package/dist/prompt-input.cjs +6 -5
- package/dist/prompt-input.js +5 -4
- package/dist/reason-tag.cjs +4 -4
- package/dist/reason-tag.js +3 -3
- package/dist/switch.cjs +2 -2
- package/dist/switch.js +1 -1
- package/dist/tooltip.cjs +3 -2
- package/dist/tooltip.js +2 -1
- package/docs/PdfViewer.md +106 -4
- package/package.json +1 -1
- package/dist/PdfViewer.types-Bgn9EmZT.d.cts +0 -22
- package/dist/PdfViewer.types-xnPpdjJa.d.ts +0 -22
- package/dist/chunk-26JZ47BJ.js.map +0 -1
- package/dist/chunk-CAMQ5B3V.cjs.map +0 -1
- package/dist/chunk-CF5KRDN4.js.map +0 -1
- package/dist/chunk-EEFWVFKO.js.map +0 -1
- package/dist/chunk-HRH5BIYG.js +0 -56
- package/dist/chunk-HRH5BIYG.js.map +0 -1
- package/dist/chunk-IVRYSSM7.js.map +0 -1
- package/dist/chunk-QKFOJKVE.cjs.map +0 -1
- package/dist/chunk-RVBTDXPD.cjs +0 -169
- package/dist/chunk-RVBTDXPD.cjs.map +0 -1
- package/dist/chunk-VQXXX6DK.js +0 -167
- package/dist/chunk-VQXXX6DK.js.map +0 -1
- package/dist/chunk-X7H75WVP.cjs.map +0 -1
- package/dist/chunk-XM3W5ETT.cjs +0 -58
- package/dist/chunk-XM3W5ETT.cjs.map +0 -1
- package/dist/chunk-YVTFODCJ.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,106 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [5.54.1] - 2026-10-21
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A `Button` narrower than its label now wraps the label inside itself.**
|
|
19
|
+
The showcase's own "Constrained width" example (104px columns, captioned
|
|
20
|
+
"multi-word labels stack left-aligned, icon stays put") had its labels
|
|
21
|
+
spilling past the buttons and over each other: the label carried
|
|
22
|
+
`whitespace-nowrap`, so text 92-116px wide had nowhere to go in a 54px slot.
|
|
23
|
+
It now wraps, left-aligned, with the icon staying put beside it; words are
|
|
24
|
+
never split. An unconstrained button is unchanged -- measured in Chrome, every
|
|
25
|
+
width and height in the probe row is identical to 5.54.0.
|
|
26
|
+
- **Want one line with an ellipsis instead?** `labelClassName="truncate"`.
|
|
27
|
+
The label has `min-w-0` and no white-space class of its own, so `truncate`
|
|
28
|
+
wins uncontested inside a button whose width you set (`w-full` in a narrow
|
|
29
|
+
column, `w-24`, `max-w-[120px]`, ...).
|
|
30
|
+
- **What to DO:** nothing, unless you relied on a squeezed button keeping its
|
|
31
|
+
label on one line (a flex row narrower than its buttons, a "send →" label
|
|
32
|
+
whose arrow is part of the text). 4.4.1 made that the default; it is now
|
|
33
|
+
opt-in: add `labelClassName="whitespace-nowrap"` to that button, or
|
|
34
|
+
`shrink-0` so the row cannot squeeze it.
|
|
35
|
+
- **`Switch` honours `labelHidden`.** It was ignored, so the label was always
|
|
36
|
+
drawn. It is now visually hidden (`sr-only`) and still names the control, as
|
|
37
|
+
on Input, Field, DatePicker and CheckboxGroup.
|
|
38
|
+
- **`aria-*` on a `Switch` now names the switch, not its wrapper.** Rest props
|
|
39
|
+
were spread on the wrapping `<div>`, so `aria-label` / `aria-labelledby`
|
|
40
|
+
labelled a div and left the `role="switch"` button unnamed. The split: every
|
|
41
|
+
`aria-*` prop goes on the button; everything else -- `className`, `style`,
|
|
42
|
+
`data-*`, event handlers -- stays on the wrapper exactly as before. (In
|
|
43
|
+
`mode="view"`, where there is no button, `aria-*` stays on the wrapper.)
|
|
44
|
+
- **`Switch`'s unchecked track reads the `border` token** (`--fancy-border` /
|
|
45
|
+
`--fancy-border-dark`) instead of hard-coded zinc. Set nothing and nothing
|
|
46
|
+
changes: the fallbacks are today's `zinc-200` / `zinc-600` (the dark one is
|
|
47
|
+
one step lighter than the role's `zinc-700` default, so a track still reads
|
|
48
|
+
against a dark surface; listed as a deliberate exception in the token test).
|
|
49
|
+
- **A `MultiSwitch` directly inside a `Tooltip` lost its selected thumb.**
|
|
50
|
+
Two halves, both fixed. `Tooltip` cloned its child with its own `ref` and
|
|
51
|
+
`onMouseEnter` / `onMouseLeave` / `onFocus` / `onBlur`, REPLACING the child's;
|
|
52
|
+
they are now composed, so a child's own ref and handlers keep working. And in
|
|
53
|
+
React 19 a ref reaches a function component as a plain prop, so the
|
|
54
|
+
Tooltip's ref arrived in `MultiSwitch`'s rest props and replaced the ref its
|
|
55
|
+
thumb is measured from; `MultiSwitch` now feeds both. A `ref` you put on a
|
|
56
|
+
`MultiSwitch` yourself reaches its radiogroup too. If you wrapped the switch
|
|
57
|
+
in a `<span>` to work around this, the wrapper can go.
|
|
58
|
+
- The same report said the switch also lost its `className`. It does not:
|
|
59
|
+
the class is in the DOM and paints in light mode, directly inside a Tooltip
|
|
60
|
+
or not. In DARK mode a bare `border-green-500` loses to the component's own
|
|
61
|
+
`dark:border-*`, with or without a Tooltip -- add `dark:border-green-500`.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- Docs only: `icon-config.ts`'s comments now say `<Icon name="github-logo" />`
|
|
66
|
+
resolves the brand mark. fancy-brand-icons 0.4.0 registers every mark as
|
|
67
|
+
`<brand>-logo`, so a bare `github` is Lucide's icon.
|
|
68
|
+
|
|
69
|
+
## [5.54.0] - 2026-10-21
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- **`PdfViewer` page-image mode (`pages`), with an access `policy` and a
|
|
74
|
+
`watermark`** (react-fancy#36). For showing a PDF without handing over the
|
|
75
|
+
file: your app renders the PDF to page images on its server, behind its own
|
|
76
|
+
auth, and the viewer only displays them.
|
|
77
|
+
- `pages={{ count, url: (page, scale) => string, aspectRatio? }}`. The page
|
|
78
|
+
images are the **only** requests the viewer makes. It never fetches or
|
|
79
|
+
references the PDF, and `src` is ignored in this mode even if passed.
|
|
80
|
+
`scale` is zoom x devicePixelRatio, rounded up to 1, 1.5, 2, 3 or 4.
|
|
81
|
+
- Its own toolbar: previous / next page, zoom out / reset / in, fit width,
|
|
82
|
+
fit page. With `frame`, full screen comes from the `FauxClient` frame.
|
|
83
|
+
Pages near the viewport get images; the rest are sized placeholders.
|
|
84
|
+
- Controlled `page` / `onPageChange` and `zoom` / `onZoomChange`, with stable
|
|
85
|
+
`data-react-fancy-pdf-viewer-*` handles on each page and button.
|
|
86
|
+
- **No search**: page images have no text to search. That is the cost of
|
|
87
|
+
not sending the PDF.
|
|
88
|
+
- `policy={{ download?, print?, copy?, screenshot? }}`, all allowed by default.
|
|
89
|
+
**Every flag is a deterrent, not a guarantee.** The real protection is that
|
|
90
|
+
the PDF never reaches the browser:
|
|
91
|
+
- `download: false`: no context menu on the pages and the images are not
|
|
92
|
+
draggable. Page images can still be captured (devtools, cache, screen).
|
|
93
|
+
- `print: false`: print CSS blanks the viewer, and Ctrl/Cmd+P is
|
|
94
|
+
intercepted while focus is inside it.
|
|
95
|
+
- `copy: false`: user selection off (there is no text layer anyway).
|
|
96
|
+
- `screenshot: "deter"`: the pages blur while the tab is hidden or the
|
|
97
|
+
window loses focus, and for 1.5 s after PrintScreen (which also tries to
|
|
98
|
+
clear the clipboard, best effort). **A web page cannot prevent
|
|
99
|
+
screenshots.**
|
|
100
|
+
- `watermark={{ text, opacity?, angle?, density? }}`: a tiled overlay on every
|
|
101
|
+
page, `pointer-events: none`. **It can be removed with devtools.** If it
|
|
102
|
+
must hold, burn it into the images on your server; `url(page, scale)` is
|
|
103
|
+
where to ask for that.
|
|
104
|
+
- `policy` and `watermark` apply only in page-image mode. The native-plugin
|
|
105
|
+
mode (`src`) is unchanged and cannot be restricted.
|
|
106
|
+
- New types: `PdfPageSource`, `PdfViewerPolicy`, `PdfViewerWatermark`.
|
|
107
|
+
- `MediaViewer` (`pdfProps`) and fancy-code's `FileViewer`
|
|
108
|
+
(`mediaProps.pdfProps`) already forward these untouched, so neither needed a
|
|
109
|
+
change.
|
|
110
|
+
- **What to do:** nothing unless you want it. `src` is now optional in the
|
|
111
|
+
types, since page-image mode does not need one; every existing call compiles
|
|
112
|
+
and renders as before. No new dependencies.
|
|
113
|
+
|
|
14
114
|
## [5.53.1] - 2026-10-21
|
|
15
115
|
|
|
16
116
|
### Fixed
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { F as FauxClientProps } from './FauxClient.types-Dtk9aRs6.js';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Pages the APP rendered to images, behind its own auth. With this the viewer
|
|
6
|
+
* never fetches or references the PDF: these URLs are its only requests.
|
|
7
|
+
*/
|
|
8
|
+
interface PdfPageSource {
|
|
9
|
+
/** Number of pages. */
|
|
10
|
+
count: number;
|
|
11
|
+
/**
|
|
12
|
+
* The image URL for a page (1-based). `scale` is a resolution hint, the zoom
|
|
13
|
+
* times the device pixel ratio rounded UP to one of 1, 1.5, 2, 3 or 4, so a
|
|
14
|
+
* page is fetched at a handful of sizes rather than one per zoom click.
|
|
15
|
+
* Render scale 1 at whatever width reads sharply at fit-width in your layout.
|
|
16
|
+
* This is also the place to burn a watermark in on the server.
|
|
17
|
+
*/
|
|
18
|
+
url: (page: number, scale: number) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Page width / height, used to size a page before its image arrives (each
|
|
21
|
+
* page switches to its image's real ratio once loaded). Default A4 portrait,
|
|
22
|
+
* `1 / Math.SQRT2`.
|
|
23
|
+
*/
|
|
24
|
+
aspectRatio?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* What a viewer of the page images may do. Every flag defaults to allowed.
|
|
28
|
+
* These are DETERRENTS: a web page cannot stop a determined viewer, and a page
|
|
29
|
+
* image that reached the screen can always be captured. Real control is the
|
|
30
|
+
* app never serving the PDF, which page-image mode makes possible.
|
|
31
|
+
*/
|
|
32
|
+
interface PdfViewerPolicy {
|
|
33
|
+
/** `false`: no context menu ("Save image as") and no dragging the images out. */
|
|
34
|
+
download?: boolean;
|
|
35
|
+
/** `false`: print CSS blanks the viewer, and Ctrl/Cmd+P is swallowed while focus is inside it. */
|
|
36
|
+
print?: boolean;
|
|
37
|
+
/** `false`: user selection is off. (Page images have no text layer anyway.) */
|
|
38
|
+
copy?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* `"deter"`: the pages blur while the tab is hidden or the window has lost
|
|
41
|
+
* focus, and briefly after a PrintScreen key. It CANNOT prevent a screenshot.
|
|
42
|
+
* Default `"allow"`.
|
|
43
|
+
*/
|
|
44
|
+
screenshot?: "allow" | "deter";
|
|
45
|
+
}
|
|
46
|
+
/** A tiled text overlay drawn over every page, in the browser. */
|
|
47
|
+
interface PdfViewerWatermark {
|
|
48
|
+
text: string;
|
|
49
|
+
/** 0-1. Default 0.15. */
|
|
50
|
+
opacity?: number;
|
|
51
|
+
/** Degrees. Default -30. */
|
|
52
|
+
angle?: number;
|
|
53
|
+
/** Repeats per area; 2 tiles twice as tightly. Default 1. */
|
|
54
|
+
density?: number;
|
|
55
|
+
}
|
|
56
|
+
interface PdfViewerProps {
|
|
57
|
+
/**
|
|
58
|
+
* Show the PDF in react-fancy's `FauxClient` frame with a full-screen button,
|
|
59
|
+
* revealed on hover. Zoom stays on the browser's own PDF toolbar (with
|
|
60
|
+
* `pages`, on the viewer's toolbar). Default `false`.
|
|
61
|
+
*/
|
|
62
|
+
frame?: boolean;
|
|
63
|
+
/** Passed to the frame (`variant`, `onFullscreenChange`, …). */
|
|
64
|
+
frameProps?: Partial<FauxClientProps>;
|
|
65
|
+
/**
|
|
66
|
+
* PDF source — an `http(s):`, `data:`, or `blob:` URL — shown in the
|
|
67
|
+
* browser's native PDF plugin. Ignored, and never referenced, when `pages` is set.
|
|
68
|
+
*/
|
|
69
|
+
src?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Page-image mode: show server-rendered page images instead of embedding the
|
|
72
|
+
* PDF. `policy` and `watermark` apply only in this mode.
|
|
73
|
+
*/
|
|
74
|
+
pages?: PdfPageSource;
|
|
75
|
+
/** The current page (1-based), controlled. */
|
|
76
|
+
page?: number;
|
|
77
|
+
/** Starting page when uncontrolled. Default 1. */
|
|
78
|
+
defaultPage?: number;
|
|
79
|
+
onPageChange?: (page: number) => void;
|
|
80
|
+
/** Zoom, 1 = fit width, controlled (page-image mode). */
|
|
81
|
+
zoom?: number;
|
|
82
|
+
/** Default 1. */
|
|
83
|
+
defaultZoom?: number;
|
|
84
|
+
onZoomChange?: (zoom: number) => void;
|
|
85
|
+
/** What the viewer may do with the pages (page-image mode). Default: everything allowed. */
|
|
86
|
+
policy?: PdfViewerPolicy;
|
|
87
|
+
/** A tiled overlay over every page (page-image mode). Removable with devtools; burn it in server-side when it must hold. */
|
|
88
|
+
watermark?: PdfViewerWatermark;
|
|
89
|
+
/** Accessible title for the document (default `"PDF document"`). */
|
|
90
|
+
title?: string;
|
|
91
|
+
/** Additional CSS classes for the container. */
|
|
92
|
+
className?: string;
|
|
93
|
+
/** Inline styles for the container (e.g. a fixed height). */
|
|
94
|
+
style?: CSSProperties;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type { PdfPageSource as P, PdfViewerPolicy as a, PdfViewerProps as b, PdfViewerWatermark as c };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { F as FauxClientProps } from './FauxClient.types-Dtk9aRs6.cjs';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Pages the APP rendered to images, behind its own auth. With this the viewer
|
|
6
|
+
* never fetches or references the PDF: these URLs are its only requests.
|
|
7
|
+
*/
|
|
8
|
+
interface PdfPageSource {
|
|
9
|
+
/** Number of pages. */
|
|
10
|
+
count: number;
|
|
11
|
+
/**
|
|
12
|
+
* The image URL for a page (1-based). `scale` is a resolution hint, the zoom
|
|
13
|
+
* times the device pixel ratio rounded UP to one of 1, 1.5, 2, 3 or 4, so a
|
|
14
|
+
* page is fetched at a handful of sizes rather than one per zoom click.
|
|
15
|
+
* Render scale 1 at whatever width reads sharply at fit-width in your layout.
|
|
16
|
+
* This is also the place to burn a watermark in on the server.
|
|
17
|
+
*/
|
|
18
|
+
url: (page: number, scale: number) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Page width / height, used to size a page before its image arrives (each
|
|
21
|
+
* page switches to its image's real ratio once loaded). Default A4 portrait,
|
|
22
|
+
* `1 / Math.SQRT2`.
|
|
23
|
+
*/
|
|
24
|
+
aspectRatio?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* What a viewer of the page images may do. Every flag defaults to allowed.
|
|
28
|
+
* These are DETERRENTS: a web page cannot stop a determined viewer, and a page
|
|
29
|
+
* image that reached the screen can always be captured. Real control is the
|
|
30
|
+
* app never serving the PDF, which page-image mode makes possible.
|
|
31
|
+
*/
|
|
32
|
+
interface PdfViewerPolicy {
|
|
33
|
+
/** `false`: no context menu ("Save image as") and no dragging the images out. */
|
|
34
|
+
download?: boolean;
|
|
35
|
+
/** `false`: print CSS blanks the viewer, and Ctrl/Cmd+P is swallowed while focus is inside it. */
|
|
36
|
+
print?: boolean;
|
|
37
|
+
/** `false`: user selection is off. (Page images have no text layer anyway.) */
|
|
38
|
+
copy?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* `"deter"`: the pages blur while the tab is hidden or the window has lost
|
|
41
|
+
* focus, and briefly after a PrintScreen key. It CANNOT prevent a screenshot.
|
|
42
|
+
* Default `"allow"`.
|
|
43
|
+
*/
|
|
44
|
+
screenshot?: "allow" | "deter";
|
|
45
|
+
}
|
|
46
|
+
/** A tiled text overlay drawn over every page, in the browser. */
|
|
47
|
+
interface PdfViewerWatermark {
|
|
48
|
+
text: string;
|
|
49
|
+
/** 0-1. Default 0.15. */
|
|
50
|
+
opacity?: number;
|
|
51
|
+
/** Degrees. Default -30. */
|
|
52
|
+
angle?: number;
|
|
53
|
+
/** Repeats per area; 2 tiles twice as tightly. Default 1. */
|
|
54
|
+
density?: number;
|
|
55
|
+
}
|
|
56
|
+
interface PdfViewerProps {
|
|
57
|
+
/**
|
|
58
|
+
* Show the PDF in react-fancy's `FauxClient` frame with a full-screen button,
|
|
59
|
+
* revealed on hover. Zoom stays on the browser's own PDF toolbar (with
|
|
60
|
+
* `pages`, on the viewer's toolbar). Default `false`.
|
|
61
|
+
*/
|
|
62
|
+
frame?: boolean;
|
|
63
|
+
/** Passed to the frame (`variant`, `onFullscreenChange`, …). */
|
|
64
|
+
frameProps?: Partial<FauxClientProps>;
|
|
65
|
+
/**
|
|
66
|
+
* PDF source — an `http(s):`, `data:`, or `blob:` URL — shown in the
|
|
67
|
+
* browser's native PDF plugin. Ignored, and never referenced, when `pages` is set.
|
|
68
|
+
*/
|
|
69
|
+
src?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Page-image mode: show server-rendered page images instead of embedding the
|
|
72
|
+
* PDF. `policy` and `watermark` apply only in this mode.
|
|
73
|
+
*/
|
|
74
|
+
pages?: PdfPageSource;
|
|
75
|
+
/** The current page (1-based), controlled. */
|
|
76
|
+
page?: number;
|
|
77
|
+
/** Starting page when uncontrolled. Default 1. */
|
|
78
|
+
defaultPage?: number;
|
|
79
|
+
onPageChange?: (page: number) => void;
|
|
80
|
+
/** Zoom, 1 = fit width, controlled (page-image mode). */
|
|
81
|
+
zoom?: number;
|
|
82
|
+
/** Default 1. */
|
|
83
|
+
defaultZoom?: number;
|
|
84
|
+
onZoomChange?: (zoom: number) => void;
|
|
85
|
+
/** What the viewer may do with the pages (page-image mode). Default: everything allowed. */
|
|
86
|
+
policy?: PdfViewerPolicy;
|
|
87
|
+
/** A tiled overlay over every page (page-image mode). Removable with devtools; burn it in server-side when it must hold. */
|
|
88
|
+
watermark?: PdfViewerWatermark;
|
|
89
|
+
/** Accessible title for the document (default `"PDF document"`). */
|
|
90
|
+
title?: string;
|
|
91
|
+
/** Additional CSS classes for the container. */
|
|
92
|
+
className?: string;
|
|
93
|
+
/** Inline styles for the container (e.g. a fixed height). */
|
|
94
|
+
style?: CSSProperties;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type { PdfPageSource as P, PdfViewerPolicy as a, PdfViewerProps as b, PdfViewerWatermark as c };
|
package/dist/button.cjs
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('./chunk-M5MUGSON.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkXOXA3QZR_cjs = require('./chunk-XOXA3QZR.cjs');
|
|
5
5
|
require('./chunk-X2FC7ODX.cjs');
|
|
6
6
|
require('./chunk-XCZZVRBY.cjs');
|
|
7
|
-
require('./chunk-
|
|
7
|
+
require('./chunk-MXWR3T3N.cjs');
|
|
8
8
|
require('./chunk-ZU5Q77OT.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
Object.defineProperty(exports, "Action", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkXOXA3QZR_cjs.Action; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "Button", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkXOXA3QZR_cjs.Button; }
|
|
19
19
|
});
|
|
20
20
|
//# sourceMappingURL=button.cjs.map
|
|
21
21
|
//# sourceMappingURL=button.cjs.map
|
package/dist/button.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import './chunk-LQ4ICCN2.js';
|
|
2
|
-
export { Action, Button } from './chunk-
|
|
2
|
+
export { Action, Button } from './chunk-45JO5BEZ.js';
|
|
3
3
|
import './chunk-6TBRBN7H.js';
|
|
4
4
|
import './chunk-45BBNJQD.js';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-J3A4Z2P7.js';
|
|
6
6
|
import './chunk-MMW2JGKZ.js';
|
|
7
7
|
//# sourceMappingURL=button.js.map
|
|
8
8
|
//# sourceMappingURL=button.js.map
|
package/dist/chat-drawer.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkONHT2PDW_cjs = require('./chunk-ONHT2PDW.cjs');
|
|
4
4
|
require('./chunk-AIA5UNQ5.cjs');
|
|
5
|
-
require('./chunk-
|
|
5
|
+
require('./chunk-MXWR3T3N.cjs');
|
|
6
6
|
require('./chunk-ZU5Q77OT.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "ChatDrawer", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkONHT2PDW_cjs.ChatDrawer; }
|
|
13
13
|
});
|
|
14
14
|
//# sourceMappingURL=chat-drawer.cjs.map
|
|
15
15
|
//# sourceMappingURL=chat-drawer.cjs.map
|
package/dist/chat-drawer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { ChatDrawer } from './chunk-
|
|
1
|
+
export { ChatDrawer } from './chunk-WE5WGVVX.js';
|
|
2
2
|
import './chunk-TJ66S5K6.js';
|
|
3
|
-
import './chunk-
|
|
3
|
+
import './chunk-J3A4Z2P7.js';
|
|
4
4
|
import './chunk-MMW2JGKZ.js';
|
|
5
5
|
//# sourceMappingURL=chat-drawer.js.map
|
|
6
6
|
//# sourceMappingURL=chat-drawer.js.map
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkO3F6DYWR_cjs = require('./chunk-O3F6DYWR.cjs');
|
|
4
|
+
var chunkKJ22KE56_cjs = require('./chunk-KJ22KE56.cjs');
|
|
5
|
+
var chunkL3V3BYVS_cjs = require('./chunk-L3V3BYVS.cjs');
|
|
6
|
+
var chunkSNHU2AI4_cjs = require('./chunk-SNHU2AI4.cjs');
|
|
7
|
+
var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
|
|
8
|
+
var react = require('react');
|
|
9
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
+
|
|
11
|
+
// src/components/inputs/Switch/Switch.colors.ts
|
|
12
|
+
var switchTrack = {
|
|
13
|
+
// The host's colour, from CSS variables -- no dark: variant, because a
|
|
14
|
+
// host that themes per mode scopes the variables themselves.
|
|
15
|
+
brand: "bg-brand",
|
|
16
|
+
slate: "bg-slate-500",
|
|
17
|
+
gray: "bg-gray-500",
|
|
18
|
+
zinc: "bg-zinc-500",
|
|
19
|
+
neutral: "bg-neutral-500",
|
|
20
|
+
stone: "bg-stone-500",
|
|
21
|
+
red: "bg-red-500",
|
|
22
|
+
orange: "bg-orange-500",
|
|
23
|
+
amber: "bg-amber-500",
|
|
24
|
+
yellow: "bg-yellow-500",
|
|
25
|
+
lime: "bg-lime-500",
|
|
26
|
+
green: "bg-green-500",
|
|
27
|
+
emerald: "bg-emerald-500",
|
|
28
|
+
teal: "bg-teal-500",
|
|
29
|
+
cyan: "bg-cyan-500",
|
|
30
|
+
sky: "bg-sky-500",
|
|
31
|
+
blue: "bg-blue-500",
|
|
32
|
+
indigo: "bg-indigo-500",
|
|
33
|
+
violet: "bg-violet-500",
|
|
34
|
+
purple: "bg-purple-500",
|
|
35
|
+
fuchsia: "bg-fuchsia-500",
|
|
36
|
+
pink: "bg-pink-500",
|
|
37
|
+
rose: "bg-rose-500"
|
|
38
|
+
};
|
|
39
|
+
var Switch = react.forwardRef(
|
|
40
|
+
({
|
|
41
|
+
size = "md",
|
|
42
|
+
dirty,
|
|
43
|
+
error,
|
|
44
|
+
label,
|
|
45
|
+
labelHidden,
|
|
46
|
+
description,
|
|
47
|
+
required,
|
|
48
|
+
disabled,
|
|
49
|
+
className,
|
|
50
|
+
id,
|
|
51
|
+
name,
|
|
52
|
+
checked: controlledChecked,
|
|
53
|
+
defaultChecked = false,
|
|
54
|
+
onCheckedChange,
|
|
55
|
+
color = "blue",
|
|
56
|
+
mode,
|
|
57
|
+
...rest
|
|
58
|
+
}, ref) => {
|
|
59
|
+
const wrapperProps = {};
|
|
60
|
+
const controlAria = {};
|
|
61
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
62
|
+
if (key.startsWith("aria-")) controlAria[key] = value;
|
|
63
|
+
else wrapperProps[key] = value;
|
|
64
|
+
}
|
|
65
|
+
const autoId = react.useId();
|
|
66
|
+
const switchId = id ?? autoId;
|
|
67
|
+
const resolvedMode = chunkL3V3BYVS_cjs.useFieldMode(mode);
|
|
68
|
+
const { showControl, interactive, enterEdit, exitEdit } = chunkKJ22KE56_cjs.useInlineEdit(resolvedMode, disabled);
|
|
69
|
+
const [checked, setChecked] = chunkSNHU2AI4_cjs.useControllableState(
|
|
70
|
+
controlledChecked,
|
|
71
|
+
defaultChecked,
|
|
72
|
+
onCheckedChange
|
|
73
|
+
);
|
|
74
|
+
const trackSizes = {
|
|
75
|
+
xs: "h-3.5 w-6",
|
|
76
|
+
sm: "h-4 w-7",
|
|
77
|
+
md: "h-5 w-9",
|
|
78
|
+
lg: "h-6 w-11",
|
|
79
|
+
xl: "h-7 w-[52px]"
|
|
80
|
+
}[size];
|
|
81
|
+
const knobSizes = {
|
|
82
|
+
xs: "h-2.5 w-2.5",
|
|
83
|
+
sm: "h-3 w-3",
|
|
84
|
+
md: "h-4 w-4",
|
|
85
|
+
lg: "h-5 w-5",
|
|
86
|
+
xl: "h-6 w-6"
|
|
87
|
+
}[size];
|
|
88
|
+
const translateOn = {
|
|
89
|
+
xs: "translate-x-2.5",
|
|
90
|
+
sm: "translate-x-3",
|
|
91
|
+
md: "translate-x-4",
|
|
92
|
+
lg: "translate-x-5",
|
|
93
|
+
xl: "translate-x-6"
|
|
94
|
+
}[size];
|
|
95
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
96
|
+
"div",
|
|
97
|
+
{
|
|
98
|
+
...wrapperProps,
|
|
99
|
+
...showControl ? void 0 : controlAria,
|
|
100
|
+
"data-react-fancy-switch": "",
|
|
101
|
+
className: chunkZU5Q77OT_cjs.cn("flex items-start gap-2", className),
|
|
102
|
+
children: [
|
|
103
|
+
!showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
104
|
+
"span",
|
|
105
|
+
{
|
|
106
|
+
"data-react-fancy-display": "",
|
|
107
|
+
"data-mode": "view",
|
|
108
|
+
role: interactive ? "button" : void 0,
|
|
109
|
+
tabIndex: interactive ? 0 : void 0,
|
|
110
|
+
title: interactive ? "Click to edit" : void 0,
|
|
111
|
+
onClick: interactive ? enterEdit : void 0,
|
|
112
|
+
onKeyDown: interactive ? (e) => {
|
|
113
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
114
|
+
e.preventDefault();
|
|
115
|
+
enterEdit();
|
|
116
|
+
}
|
|
117
|
+
} : void 0,
|
|
118
|
+
className: chunkZU5Q77OT_cjs.cn(
|
|
119
|
+
"text-sm font-medium text-zinc-700 dark:text-zinc-200",
|
|
120
|
+
interactive && "cursor-pointer rounded-md outline-none transition-colors hover:text-zinc-900 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:text-white"
|
|
121
|
+
),
|
|
122
|
+
children: checked ? "On" : "Off"
|
|
123
|
+
}
|
|
124
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
125
|
+
"button",
|
|
126
|
+
{
|
|
127
|
+
...controlAria,
|
|
128
|
+
ref,
|
|
129
|
+
id: switchId,
|
|
130
|
+
type: "button",
|
|
131
|
+
role: "switch",
|
|
132
|
+
"aria-checked": checked,
|
|
133
|
+
disabled,
|
|
134
|
+
autoFocus: interactive,
|
|
135
|
+
onBlur: () => {
|
|
136
|
+
if (interactive) exitEdit();
|
|
137
|
+
},
|
|
138
|
+
onClick: () => setChecked(!checked),
|
|
139
|
+
className: chunkZU5Q77OT_cjs.cn(
|
|
140
|
+
"relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
141
|
+
trackSizes,
|
|
142
|
+
// The unchecked track is the `border` role ("tracks"). The dark
|
|
143
|
+
// fallback stays zinc-600, today's colour, not the role's zinc-700
|
|
144
|
+
// default — set nothing, see no change.
|
|
145
|
+
checked ? switchTrack[color] : "bg-[color:var(--fancy-border,var(--color-zinc-200))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-600))]",
|
|
146
|
+
chunkO3F6DYWR_cjs.dirtyRingClasses(dirty),
|
|
147
|
+
error && "ring-2 ring-red-500/50"
|
|
148
|
+
),
|
|
149
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
150
|
+
"span",
|
|
151
|
+
{
|
|
152
|
+
className: chunkZU5Q77OT_cjs.cn(
|
|
153
|
+
"pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform",
|
|
154
|
+
knobSizes,
|
|
155
|
+
checked ? translateOn : "translate-x-0"
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
name && /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: checked ? "1" : "0" }),
|
|
162
|
+
(label || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
163
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
164
|
+
"label",
|
|
165
|
+
{
|
|
166
|
+
htmlFor: switchId,
|
|
167
|
+
className: chunkZU5Q77OT_cjs.cn(
|
|
168
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
169
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
170
|
+
// Not drawn, still the accessible name (it labels the button).
|
|
171
|
+
labelHidden && "sr-only"
|
|
172
|
+
),
|
|
173
|
+
children: [
|
|
174
|
+
label,
|
|
175
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-red-500", children: "*" })
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]", children: description }),
|
|
180
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-red-500", children: error })
|
|
181
|
+
] })
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
Switch.displayName = "Switch";
|
|
188
|
+
|
|
189
|
+
exports.Switch = Switch;
|
|
190
|
+
//# sourceMappingURL=chunk-2O5UXH5R.cjs.map
|
|
191
|
+
//# sourceMappingURL=chunk-2O5UXH5R.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/inputs/Switch/Switch.colors.ts","../src/components/inputs/Switch/Switch.tsx"],"names":["forwardRef","useId","useFieldMode","useInlineEdit","useControllableState","jsxs","cn","jsx","dirtyRingClasses"],"mappings":"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","file":"chunk-2O5UXH5R.cjs","sourcesContent":["// AUTO-GENERATED by scripts/gen-switch-colors — do not edit by hand.\n// Literal Tailwind class strings for every color in the v4 palette so the\n// scanner can detect them in the published dist (template-built names are\n// invisible to Tailwind's JIT). Regenerate after changing the palette.\nimport type { Color } from \"../../../utils/types\";\n\nexport const switchTrack: Record<Color, string> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: \"bg-brand\",\n slate: \"bg-slate-500\",\n gray: \"bg-gray-500\",\n zinc: \"bg-zinc-500\",\n neutral: \"bg-neutral-500\",\n stone: \"bg-stone-500\",\n red: \"bg-red-500\",\n orange: \"bg-orange-500\",\n amber: \"bg-amber-500\",\n yellow: \"bg-yellow-500\",\n lime: \"bg-lime-500\",\n green: \"bg-green-500\",\n emerald: \"bg-emerald-500\",\n teal: \"bg-teal-500\",\n cyan: \"bg-cyan-500\",\n sky: \"bg-sky-500\",\n blue: \"bg-blue-500\",\n indigo: \"bg-indigo-500\",\n violet: \"bg-violet-500\",\n purple: \"bg-purple-500\",\n fuchsia: \"bg-fuchsia-500\",\n pink: \"bg-pink-500\",\n rose: \"bg-rose-500\",\n};\n","import { forwardRef, useId } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport { dirtyRingClasses } from \"../inputs.utils\";\nimport type { SwitchProps } from \"./Switch.types\";\nimport { switchTrack } from \"./Switch.colors\";\n\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n name,\n checked: controlledChecked,\n defaultChecked = false,\n onCheckedChange,\n color = \"blue\",\n mode,\n ...rest\n },\n ref,\n ) => {\n // `aria-*` names and describes the CONTROL, so it goes on the role=\"switch\"\n // button; everything else (className, style, data-*, handlers) stays on the\n // wrapper, where it has always gone. On the wrapper, an `aria-label` named a\n // div and left the switch itself unnamed.\n const wrapperProps: Record<string, unknown> = {};\n const controlAria: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rest)) {\n if (key.startsWith(\"aria-\")) controlAria[key] = value;\n else wrapperProps[key] = value;\n }\n\n const autoId = useId();\n const switchId = id ?? autoId;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [checked, setChecked] = useControllableState(\n controlledChecked,\n defaultChecked,\n onCheckedChange,\n );\n\n const trackSizes = {\n xs: \"h-3.5 w-6\",\n sm: \"h-4 w-7\",\n md: \"h-5 w-9\",\n lg: \"h-6 w-11\",\n xl: \"h-7 w-[52px]\",\n }[size];\n\n const knobSizes = {\n xs: \"h-2.5 w-2.5\",\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-5 w-5\",\n xl: \"h-6 w-6\",\n }[size];\n\n const translateOn = {\n xs: \"translate-x-2.5\",\n sm: \"translate-x-3\",\n md: \"translate-x-4\",\n lg: \"translate-x-5\",\n xl: \"translate-x-6\",\n }[size];\n\n return (\n <div\n {...wrapperProps}\n // View mode has no switch to name, so its aria-* stay on the wrapper.\n {...(showControl ? undefined : controlAria)}\n data-react-fancy-switch=\"\" className={cn(\"flex items-start gap-2\", className)}>\n {!showControl ? (\n <span\n data-react-fancy-display=\"\"\n data-mode=\"view\"\n role={interactive ? \"button\" : undefined}\n tabIndex={interactive ? 0 : undefined}\n title={interactive ? \"Click to edit\" : undefined}\n onClick={interactive ? enterEdit : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n enterEdit();\n }\n }\n : undefined\n }\n className={cn(\n \"text-sm font-medium text-zinc-700 dark:text-zinc-200\",\n interactive &&\n \"cursor-pointer rounded-md outline-none transition-colors hover:text-zinc-900 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:text-white\",\n )}\n >\n {checked ? \"On\" : \"Off\"}\n </span>\n ) : (\n <button\n {...controlAria}\n ref={ref}\n id={switchId}\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n autoFocus={interactive}\n onBlur={() => {\n if (interactive) exitEdit();\n }}\n onClick={() => setChecked(!checked)}\n className={cn(\n \"relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n trackSizes,\n // The unchecked track is the `border` role (\"tracks\"). The dark\n // fallback stays zinc-600, today's colour, not the role's zinc-700\n // default — set nothing, see no change.\n checked\n ? switchTrack[color]\n : \"bg-[color:var(--fancy-border,var(--color-zinc-200))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-600))]\",\n dirtyRingClasses(dirty),\n error && \"ring-2 ring-red-500/50\",\n )}\n >\n <span\n className={cn(\n \"pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform\",\n knobSizes,\n checked ? translateOn : \"translate-x-0\",\n )}\n />\n </button>\n )}\n {name && (\n <input type=\"hidden\" name={name} value={checked ? \"1\" : \"0\"} />\n )}\n {(label || description) && (\n <div className=\"flex flex-col\">\n {label && (\n <label\n htmlFor={switchId}\n className={cn(\n \"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100\",\n disabled && \"cursor-not-allowed opacity-50\",\n // Not drawn, still the accessible name (it labels the button).\n labelHidden && \"sr-only\",\n )}\n >\n {label}\n {required && <span className=\"ml-0.5 text-red-500\">*</span>}\n </label>\n )}\n {description && (\n <span className=\"text-xs text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\">\n {description}\n </span>\n )}\n {error && <span className=\"text-xs text-red-500\">{error}</span>}\n </div>\n )}\n </div>\n );\n },\n);\n\nSwitch.displayName = \"Switch\";\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sanitizeHref } from './chunk-6TBRBN7H.js';
|
|
2
2
|
import { resolve } from './chunk-45BBNJQD.js';
|
|
3
|
-
import { Icon } from './chunk-
|
|
3
|
+
import { Icon } from './chunk-J3A4Z2P7.js';
|
|
4
4
|
import { cn } from './chunk-MMW2JGKZ.js';
|
|
5
5
|
import { forwardRef } from 'react';
|
|
6
6
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
@@ -344,14 +344,20 @@ var Button = forwardRef(
|
|
|
344
344
|
{
|
|
345
345
|
"data-react-fancy-button-label": "",
|
|
346
346
|
className: cn(
|
|
347
|
-
// A button
|
|
348
|
-
//
|
|
349
|
-
//
|
|
350
|
-
//
|
|
351
|
-
// the
|
|
352
|
-
//
|
|
353
|
-
// the
|
|
354
|
-
|
|
347
|
+
// A button narrower than its label WRAPS the label inside itself
|
|
348
|
+
// (left-aligned, via the button's `text-left`); the icon is its own
|
|
349
|
+
// shrink-0 flex item, so it stays put beside the text. `min-w-0`
|
|
350
|
+
// lets the span shrink below its text. Words are never split
|
|
351
|
+
// (measured: in the showcase's 104px column `break-words` turned
|
|
352
|
+
// "customer" into "custome/r"). Unconstrained, nothing wraps and
|
|
353
|
+
// the button looks as it always did.
|
|
354
|
+
//
|
|
355
|
+
// No white-space class here, on purpose: `labelClassName="truncate"`
|
|
356
|
+
// must win uncontested to give one line with an ellipsis, and a
|
|
357
|
+
// `whitespace-normal` would fight its nowrap in the cascade.
|
|
358
|
+
// (5.54.0 and earlier forced `whitespace-nowrap`, so a constrained
|
|
359
|
+
// label spilled out of the button and over its neighbours.)
|
|
360
|
+
"min-w-0",
|
|
355
361
|
// `responsive` collapses to icon-only when squeezed, while keeping
|
|
356
362
|
// the label readable to screen readers.
|
|
357
363
|
responsive && "sr-only sm:not-sr-only",
|
|
@@ -453,5 +459,5 @@ Button.displayName = "Button";
|
|
|
453
459
|
var Action = Button;
|
|
454
460
|
|
|
455
461
|
export { Action, Button };
|
|
456
|
-
//# sourceMappingURL=chunk-
|
|
457
|
-
//# sourceMappingURL=chunk-
|
|
462
|
+
//# sourceMappingURL=chunk-45JO5BEZ.js.map
|
|
463
|
+
//# sourceMappingURL=chunk-45JO5BEZ.js.map
|