plass-ui 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +169 -0
- package/README.md +14 -15
- package/dist/components/accordion/PlAccordion.d.ts +14 -0
- package/dist/components/accordion/PlAccordion.js +1 -1
- package/dist/components/avatar/PlAvatar.js +1 -1
- package/dist/components/avatar-group/PlAvatarGroup.d.ts +47 -0
- package/dist/components/avatar-group/PlAvatarGroup.js +1 -0
- package/dist/components/avatar-group/index.d.ts +2 -0
- package/dist/components/avatar-group/index.js +1 -0
- package/dist/components/checkbox/PlCheckbox.js +1 -1
- package/dist/components/color-picker/PlColorPicker.d.ts +88 -0
- package/dist/components/color-picker/PlColorPicker.js +1 -0
- package/dist/components/color-picker/index.d.ts +2 -0
- package/dist/components/color-picker/index.js +1 -0
- package/dist/components/combobox/PlCombobox.js +1 -1
- package/dist/components/command-palette/PlCommandPalette.d.ts +83 -0
- package/dist/components/command-palette/PlCommandPalette.js +1 -0
- package/dist/components/command-palette/index.d.ts +2 -0
- package/dist/components/command-palette/index.js +1 -0
- package/dist/components/divider/PlDivider.js +1 -1
- package/dist/components/drawer/PlDrawer.js +1 -1
- package/dist/components/fieldset/PlFieldset.d.ts +35 -0
- package/dist/components/fieldset/PlFieldset.js +1 -0
- package/dist/components/fieldset/index.d.ts +2 -0
- package/dist/components/fieldset/index.js +1 -0
- package/dist/components/footer/PlFooter.d.ts +90 -0
- package/dist/components/footer/PlFooter.js +1 -0
- package/dist/components/footer/index.d.ts +2 -0
- package/dist/components/footer/index.js +1 -0
- package/dist/components/form/PlForm.d.ts +61 -0
- package/dist/components/form/PlForm.js +1 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +1 -0
- package/dist/components/header/PlHeader.d.ts +124 -0
- package/dist/components/header/PlHeader.js +1 -0
- package/dist/components/header/index.d.ts +2 -0
- package/dist/components/header/index.js +1 -0
- package/dist/components/menu/PlMenu.js +1 -1
- package/dist/components/menubar/PlMenubar.d.ts +56 -0
- package/dist/components/menubar/PlMenubar.js +1 -0
- package/dist/components/menubar/index.d.ts +2 -0
- package/dist/components/menubar/index.js +1 -0
- package/dist/components/modal/PlModal.js +1 -1
- package/dist/components/navigation-menu/PlNavigationMenu.d.ts +99 -0
- package/dist/components/navigation-menu/PlNavigationMenu.js +1 -0
- package/dist/components/navigation-menu/index.d.ts +2 -0
- package/dist/components/navigation-menu/index.js +1 -0
- package/dist/components/number-field/PlNumberField.js +1 -1
- package/dist/components/otp-field/PlOtpField.js +1 -1
- package/dist/components/overlay/PlOverlay.js +1 -1
- package/dist/components/page-layout/PlPageLayout.d.ts +139 -0
- package/dist/components/page-layout/PlPageLayout.js +1 -0
- package/dist/components/page-layout/index.d.ts +2 -0
- package/dist/components/page-layout/index.js +1 -0
- package/dist/components/pagination/PlPagination.d.ts +23 -0
- package/dist/components/pagination/PlPagination.js +1 -1
- package/dist/components/popover/PlPopover.js +1 -1
- package/dist/components/radio-group/PlRadioGroup.js +1 -1
- package/dist/components/scroll-zone/PlScrollZone.d.ts +35 -15
- package/dist/components/scroll-zone/PlScrollZone.js +1 -1
- package/dist/components/select/PlSelect.js +1 -1
- package/dist/components/sidebar/PlSidebar.d.ts +141 -0
- package/dist/components/sidebar/PlSidebar.js +1 -0
- package/dist/components/sidebar/PlSidebarTrigger.d.ts +34 -0
- package/dist/components/sidebar/PlSidebarTrigger.js +1 -0
- package/dist/components/sidebar/index.d.ts +4 -0
- package/dist/components/sidebar/index.js +1 -0
- package/dist/components/switch/PlSwitch.js +1 -1
- package/dist/components/table/PlTable.js +1 -1
- package/dist/components/text-field/PlTextField.js +1 -1
- package/dist/components/text-link/PlTextLink.d.ts +25 -2
- package/dist/components/text-link/PlTextLink.js +1 -1
- package/dist/components/toast/PlToast.js +1 -1
- package/dist/components/toggle/PlToggle.d.ts +55 -0
- package/dist/components/toggle/PlToggle.js +1 -0
- package/dist/components/toggle/PlToggleGroup.d.ts +48 -0
- package/dist/components/toggle/PlToggleGroup.js +1 -0
- package/dist/components/toggle/index.d.ts +4 -0
- package/dist/components/toggle/index.js +1 -0
- package/dist/components/tooltip/PlTooltip.js +1 -1
- package/dist/components/transfer/PlTransfer.d.ts +55 -0
- package/dist/components/transfer/PlTransfer.js +1 -0
- package/dist/components/transfer/index.d.ts +2 -0
- package/dist/components/transfer/index.js +1 -0
- package/dist/css/avatar-group.css +2 -0
- package/dist/css/color-picker.css +2 -0
- package/dist/css/command-palette.css +2 -0
- package/dist/css/fieldset.css +2 -0
- package/dist/css/footer.css +2 -0
- package/dist/css/form.css +2 -0
- package/dist/css/header.css +2 -0
- package/dist/css/menubar.css +2 -0
- package/dist/css/navigation-menu.css +2 -0
- package/dist/css/page-layout.css +2 -0
- package/dist/css/sidebar.css +2 -0
- package/dist/css/toggle.css +2 -0
- package/dist/css/transfer.css +2 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1 -1
- package/dist/internal/avatar-group.d.ts +25 -0
- package/dist/internal/avatar-group.js +2 -0
- package/dist/internal/color.d.ts +109 -0
- package/dist/internal/color.js +1 -0
- package/dist/internal/link.d.ts +18 -0
- package/dist/internal/link.js +1 -0
- package/dist/internal/page-layout.d.ts +140 -0
- package/dist/internal/page-layout.js +1 -0
- package/dist/internal/picker.js +1 -1
- package/dist/internal/search.d.ts +31 -0
- package/dist/internal/search.js +1 -0
- package/dist/internal/styles.d.ts +9 -0
- package/dist/internal/styles.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +26 -0
- package/dist/tokens.css +26 -0
- package/package.json +3 -3
|
@@ -28,19 +28,21 @@ export type PlScrollZoneMode = 'item' | 'page' | 'hold';
|
|
|
28
28
|
/**
|
|
29
29
|
* Where the scroll buttons sit, which is also where the strip ends.
|
|
30
30
|
*
|
|
31
|
+
* - `inline` — beside the strip, in the layout. The default: the scroller stops
|
|
32
|
+
* where the button starts, so an item is *cut off* at the button's edge
|
|
33
|
+
* rather than sliding beneath it, nothing is ever half-hidden behind a
|
|
34
|
+
* control, and the button is legible over the page rather than over whatever
|
|
35
|
+
* it landed on.
|
|
31
36
|
* - `overlay` — over the ends of the strip, which keeps every pixel of the box
|
|
32
|
-
* for content and lets an item pass under a button.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* button starts, so an item is *cut off* at the button's edge rather than
|
|
36
|
-
* sliding beneath it: nothing is ever half-hidden behind a control, and the
|
|
37
|
-
* button is legible over the page rather than over whatever it landed on.
|
|
37
|
+
* for content and lets an item pass under a button. What a shelf of pictures
|
|
38
|
+
* wants, where the strip reaching the edge of its box is worth more than
|
|
39
|
+
* seeing the whole of the item a button came to rest on.
|
|
38
40
|
*
|
|
39
41
|
* The lane an `inline` button sits in is kept even while that button has
|
|
40
42
|
* nowhere to go, or the strip would resize under the pointer every time it
|
|
41
43
|
* reached an end.
|
|
42
44
|
*/
|
|
43
|
-
export type PlScrollZoneButtonPlacement = '
|
|
45
|
+
export type PlScrollZoneButtonPlacement = 'inline' | 'overlay';
|
|
44
46
|
export interface PlScrollZoneProps extends PlassStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
|
45
47
|
/**
|
|
46
48
|
* Which way the children run, and therefore which way the zone scrolls.
|
|
@@ -63,10 +65,10 @@ export interface PlScrollZoneProps extends PlassStyleProps, Omit<React.Component
|
|
|
63
65
|
/** When the scroll buttons are drawn. @default 'auto' */
|
|
64
66
|
buttons?: PlScrollZoneButtons;
|
|
65
67
|
/**
|
|
66
|
-
* Whether the buttons sit
|
|
67
|
-
* reach for when
|
|
68
|
-
*
|
|
69
|
-
* @default '
|
|
68
|
+
* Whether the buttons sit beside the strip or over it. `overlay` is what to
|
|
69
|
+
* reach for when the strip reaching the edge of its box is worth more than
|
|
70
|
+
* seeing the whole of the item a button came to rest on.
|
|
71
|
+
* @default 'inline'
|
|
70
72
|
*/
|
|
71
73
|
buttonPlacement?: PlScrollZoneButtonPlacement;
|
|
72
74
|
/** What pressing one does. @default 'item' */
|
|
@@ -89,6 +91,23 @@ export interface PlScrollZoneProps extends PlassStyleProps, Omit<React.Component
|
|
|
89
91
|
* @default true
|
|
90
92
|
*/
|
|
91
93
|
drag?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Turns a vertical wheel over a horizontal strip into scrolling along it.
|
|
96
|
+
*
|
|
97
|
+
* A mouse has one wheel and it points the wrong way for a strip that runs
|
|
98
|
+
* across the box. What a browser does with it there is its own business,
|
|
99
|
+
* which is the problem: it makes the answer depend on which browser the
|
|
100
|
+
* reader happens to be in. The pointer being on the strip is them saying
|
|
101
|
+
* which of the two things under it they meant to move.
|
|
102
|
+
*
|
|
103
|
+
* Only the vertical half of a gesture, and only while the strip has somewhere
|
|
104
|
+
* to go. A trackpad's two fingers, a tilt wheel and Shift held down already
|
|
105
|
+
* scroll it sideways and are left alone; and the moment it reaches an end the
|
|
106
|
+
* wheel goes back to the page, so a reader on their way down a long page is
|
|
107
|
+
* held up by one shelf rather than caught in it.
|
|
108
|
+
* @default true
|
|
109
|
+
*/
|
|
110
|
+
wheel?: boolean;
|
|
92
111
|
/** Shows the native scrollbar. @default false */
|
|
93
112
|
scrollbar?: boolean;
|
|
94
113
|
/** What the scrollable region is called — "Categories", "Recent files". */
|
|
@@ -110,10 +129,11 @@ export interface PlScrollZoneProps extends PlassStyleProps, Omit<React.Component
|
|
|
110
129
|
*
|
|
111
130
|
* The mechanism is an ordinary scroll container, and everything the component
|
|
112
131
|
* offers is a way of driving one. Swiping on a phone, two-finger dragging on a
|
|
113
|
-
* trackpad, the
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
132
|
+
* trackpad, the arrow keys and the scrollbar are the browser's own and are
|
|
133
|
+
* never intercepted; what is added on top is a pair of buttons for the pointer
|
|
134
|
+
* that has neither a wheel nor a finger, a mouse drag for the strip that reads
|
|
135
|
+
* as something to pull rather than something to page, and the vertical wheel a
|
|
136
|
+
* horizontal strip would otherwise have no use for.
|
|
117
137
|
*
|
|
118
138
|
* Nothing is transformed. A translated track would have to argue for an
|
|
119
139
|
* exception to the house rule; a scroll offset does not, and it is also what
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{PlIconButton as r}from"../icon-button/PlIconButton.js";import{spacingValue as o}from"../../internal/grid.js";import{ChevronIcon as s}from"../../internal/icons.js";import{cx as
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{PlIconButton as r}from"../icon-button/PlIconButton.js";import{spacingValue as o}from"../../internal/grid.js";import{ChevronIcon as s}from"../../internal/icons.js";import{cx as l}from"../../internal/styles.js";const i={xs:"p-1",sm:"p-1.5",md:"p-2",lg:"p-3",xl:"p-4"},a={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-3",xl:"gap-4"};export const PlScrollZone=/* @__PURE__ */n.forwardRef(function PlScrollZone({orientation:c="horizontal",lines:u=1,spacing:d=2,buttons:f="auto",buttonPlacement:p="inline",mode:m="item",step:v=1,speed:b=900,snap:w=!1,drag:g=!0,wheel:h=!0,scrollbar:y=!1,variant:x="glass",size:E="md",color:L="primary",density:k="default",label:M,previousLabel:C="Previous",nextLabel:P="Next",className:D,style:R,children:A,...B},N){const T="horizontal"===c,j=Math.max(1,Math.round(u)),z=Math.max(1,Math.round(v)),S=n.useRef(null),W=n.useRef(null),[Y,_]=n.useState({back:!1,forward:!1}),H=n.useCallback(()=>{const e=S.current;if(!e)return;const t=T?e.clientWidth:e.clientHeight,n=T?e.scrollWidth:e.scrollHeight,r=Math.abs(T?e.scrollLeft:e.scrollTop);_(e=>{const o=r>1,s=n-t-r>1;return e.back===o&&e.forward===s?e:{back:o,forward:s}})},[T]);n.useEffect(()=>{const e=S.current,t=W.current;if(!e)return;if(H(),"undefined"==typeof ResizeObserver)return;const n=new ResizeObserver(H);return n.observe(e),t&&n.observe(t),()=>n.disconnect()},[H]);const F=n.useCallback(()=>{const e=S.current;return e&&T&&"rtl"===getComputedStyle(e).direction?-1:1},[T]),I=n.useCallback((e,t)=>{const n=S.current;if(!n)return;const r=t?function scrollBehavior(){return"undefined"!=typeof window&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"}():"auto";n.scrollBy(T?{left:e,behavior:r}:{top:e,behavior:r})},[T]);n.useEffect(()=>{const e=S.current;if(!e||!h||!T)return;const onWheel=t=>{if(Math.abs(t.deltaY)<=Math.abs(t.deltaX))return;const n=t.deltaMode===t.DOM_DELTA_LINE?16*t.deltaY:t.deltaMode===t.DOM_DELTA_PAGE?t.deltaY*e.clientWidth:t.deltaY,r=Math.abs(e.scrollLeft);(n>0?e.scrollWidth-e.clientWidth-r>1:r>1)&&(t.preventDefault(),I(n*F(),!1))};return e.addEventListener("wheel",onWheel,{passive:!1}),()=>e.removeEventListener("wheel",onWheel)},[F,T,I,h]);const O=n.useCallback(()=>{const e=S.current,t=W.current;if(!e||!t)return[];const n=T&&"rtl"===getComputedStyle(e).direction,r=T?n?"right":"left":"top",o=n?-1:1,s=e.getBoundingClientRect()[r],l=[];for(const e of Array.from(t.children)){const t=Math.round((e.getBoundingClientRect()[r]-s)*o);l.includes(t)||l.push(t)}return l.sort((e,t)=>e-t)},[T]),X=n.useCallback((e,t=m)=>{const n=S.current;if(!n)return;const r=F(),o=T?n.clientWidth:n.clientHeight;if("page"===t)return void I(o*(e?1:-1)*r,!0);const s=O(),l=s.filter(e=>e>1),i=s.filter(e=>e<-1),a=e?l[z-1]:i[i.length-z];I(void 0!==a?a*r:o*(e?1:-1)*r,!0)},[F,T,O,z,m,I]),$=n.useRef(null);n.useEffect(()=>()=>$.current?.(),[]);const q=n.useCallback((e,t)=>{if($.current)return;const n=F(),r=performance.now();let o=r,s=0;const tick=t=>{const r=t-o;o=t,I(b*r/1e3*(e?1:-1)*n,!1),s=requestAnimationFrame(tick)};s=requestAnimationFrame(tick);const release=()=>{cancelAnimationFrame(s),$.current=null,window.removeEventListener(t,release),window.removeEventListener("pointercancel",release),window.removeEventListener("blur",release),performance.now()-r<140&&X(e,"item")};$.current=release,window.addEventListener(t,release),window.addEventListener("pointercancel",release),window.addEventListener("blur",release)},[X,F,I,b]),Z=n.useRef(null);function pressHandlers(e){return"hold"!==m?{onClick:()=>X(e)}:{onPointerDown:t=>{0===t.button&&q(e,"pointerup")},onKeyDown:t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),q(e,"keyup"))}}}n.useEffect(()=>()=>Z.current?.(),[]);const G="none"!==f&&("always"===f||Y.back||Y.forward),K="inline"===p;function scrollButton(t){const n=t?Y.forward:Y.back;if("auto"===f&&!n&&!K)return e("span",{});const o="auto"===f&&!n,i=e(r,{variant:x,size:E,color:L,density:k,elevation:1,label:t?P:C,disabled:!n,className:"pointer-events-auto",icon:e("span",{className:l("flex items-center",T?t?"-rotate-90 rtl:rotate-90":"rotate-90 rtl:-rotate-90":t?"":"rotate-180"),children:e(s,{})}),...pressHandlers(t)});return K?e("span",{className:l("flex shrink-0 items-center justify-center",o?"invisible":""),inert:o,children:i}):i}return t("div",{ref:N,className:l("relative flex min-w-0",K&&T?"flex-row items-stretch":"flex-col",K?a[E]:"",D),style:{"--p-ring":`var(--plass-${L}-ring)`,...R},...B,children:[G&&K?scrollButton(!1):null,e("div",{ref:S,tabIndex:0,role:M?"group":void 0,"aria-label":M,className:l("min-h-0 min-w-0 grow",T?"overflow-x-auto overflow-y-hidden":"overflow-y-auto overflow-x-hidden",w?T?"snap-x snap-mandatory":"snap-y snap-mandatory":"",y?"":"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",g&&(Y.back||Y.forward)?"cursor-grab data-[dragging]:cursor-grabbing":"","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:[outline-offset:-2px]"),onScroll:H,onPointerDown:function beginDrag(e){if(!g||"touch"===e.pointerType||0!==e.button)return;Z.current?.();const t=e.currentTarget,n=e.clientX,r=e.clientY,o=t.scrollLeft,s=t.scrollTop;let l=!1;const i=document.body.style.getPropertyValue("-webkit-user-select"),move=e=>{const i=e.clientX-n,a=e.clientY-r;if(!l){if(Math.abs(T?i:a)<4)return;l=!0,t.setPointerCapture(e.pointerId),t.dataset.dragging="true",document.body.style.setProperty("-webkit-user-select","none")}T?t.scrollLeft=o-i:t.scrollTop=s-a},release=()=>{Z.current=null,t.removeEventListener("pointermove",move),t.removeEventListener("pointerup",end),t.removeEventListener("pointercancel",release),delete t.dataset.dragging,i?document.body.style.setProperty("-webkit-user-select",i):document.body.style.removeProperty("-webkit-user-select")},end=()=>{const e=l;if(release(),!e)return;const swallow=e=>{e.stopPropagation(),e.preventDefault()};t.addEventListener("click",swallow,{capture:!0,once:!0}),window.setTimeout(()=>t.removeEventListener("click",swallow,!0),0)};Z.current=release,t.addEventListener("pointermove",move),t.addEventListener("pointerup",end),t.addEventListener("pointercancel",release)},children:e("div",{ref:W,className:l(w?"[&>*]:snap-start":""),style:{display:"grid",gap:o(d),gridAutoFlow:T?"column":"row",...T?{width:"max-content",gridTemplateRows:`repeat(${j}, auto)`,gridAutoColumns:"max-content"}:{gridTemplateColumns:`repeat(${j}, minmax(0, 1fr))`,gridAutoRows:"max-content"}},children:A})}),G&&K?scrollButton(!0):null,G&&!K?t("div",{className:l("pointer-events-none absolute inset-0 flex justify-between",T?"items-center":"flex-col items-center",i[E]),children:[scrollButton(!1),scrollButton(!0)]}):null]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Select as t}from"@base-ui/react/select";import{Field as s}from"@base-ui/react/field";import{CheckIcon as r,ChevronIcon as i}from"../../internal/icons.js";import{WidthSizer as n}from"../../internal/sizer.js";import{controlHeightClasses as o,controlTextLeadingClasses as c,disabledClasses as d,fieldReadOnlyClasses as m,fieldRestClasses as
|
|
1
|
+
"use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Select as t}from"@base-ui/react/select";import{Field as s}from"@base-ui/react/field";import{CheckIcon as r,ChevronIcon as i}from"../../internal/icons.js";import{WidthSizer as n}from"../../internal/sizer.js";import{controlHeightClasses as o,controlTextLeadingClasses as c,disabledClasses as d,fieldReadOnlyClasses as m,fieldRestClasses as p,focusWithinRingClasses as u,gapClasses as h,glassClasses as f,hasContent as g,iconClasses as x,metaTextClasses as v,paddingXClasses as b,radiusClasses as N,stackGapClasses as j,surfaceSlots as w,transitionClasses as y}from"../../internal/styles.js";const I=/* @__PURE__ */["group relative flex w-full cursor-pointer items-center select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",y,u,x].join(" "),S=/* @__PURE__ */[f,"max-h-[min(20rem,var(--available-height))] overflow-y-auto overscroll-contain","min-w-[var(--anchor-width)] border bg-(--plass-glass-press) p-1","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]","[outline:none]"].join(" "),$=/* @__PURE__ */["relative flex cursor-pointer items-center gap-2 select-none","rounded-(--plass-radius-xs) py-1.5 pe-2 ps-7",y,"data-[highlighted]:bg-(--p-soft-hover) data-[highlighted]:text-(--p-accent)","data-[selected]:font-semibold data-[selected]:text-(--p-accent)","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50","[outline:none]"].join(" ");export const PlSelect=/* @__PURE__ */l.forwardRef(function PlSelect({variant:u="glass",size:f="md",color:x="primary",density:y="default",elevation:z=0,items:P,value:V,defaultValue:k,onValueChange:O,placeholder:R,label:T,description:q,error:C,invalid:M,startIcon:W,fullWidth:_=!1,disabled:B=!1,readOnly:D=!1,required:E=!1,name:L,id:A,className:F,style:G,...H},J){const K=g(C),Q=M??K,U=Q?"danger":x,X=l.useMemo(()=>P.map(e=>({label:e.label??String(e.value),value:e.value})),[P]),Y=l.useMemo(()=>[...P.map(e=>e.label??String(e.value)),...g(R)?[R]:[]],[P,R]);return a(s.Root,{disabled:B,invalid:Q,className:["flex-col align-top",j[f],_?"flex w-full":"inline-flex",F??""].filter(Boolean).join(" "),style:{...w(U,z),...G},...H,children:[T?e(s.Label,{className:[v[f],"font-semibold",B?"text-(--plass-muted-fg)":"text-(--plass-fg)"].join(" "),children:T}):null,a(t.Root,{id:A,name:L,items:X,value:V,defaultValue:k,onValueChange:e=>O?.(e),disabled:B,readOnly:D,required:E,children:[a(t.Trigger,{ref:J,className:[I,o[f],c[f],N[f],h[f],b[y][f],B?d[u]:D?`${m[u]} cursor-default`:p[u]].join(" "),children:[W?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:W}):null,a("span",{className:"flex min-w-0 flex-1 flex-col",children:[e(t.Value,{className:["w-full truncate text-start","data-[placeholder]:text-(--plass-muted-fg)"].join(" "),placeholder:R}),e(n,{samples:Y})]}),e(t.Icon,{className:["flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]","data-[popup-open]:rotate-180"].join(" "),children:e(i,{})})]}),e(t.Portal,{children:e(t.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",sideOffset:6,alignItemWithTrigger:!1,children:e(t.Popup,{className:`${S} ${N[f]} ${c[f]}`,style:w(U,3),children:P.map(l=>a(t.Item,{value:l.value,disabled:l.disabled,className:$,children:[e(t.ItemIndicator,{className:"absolute start-1.5 flex size-4 items-center justify-center",children:e(r,{})}),e(t.ItemText,{className:"truncate",children:l.label??String(l.value)})]},String(l.value)))})})})]}),q?e(s.Description,{className:`${v[f]} text-(--plass-muted-fg)`,children:q}):null,e(s.Error,K?{match:!0,className:`${v[f]} text-(--p-accent)`,children:C}:{className:`${v[f]} text-(--p-accent)`})]})});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PlPageLayoutCollapse, PlassSidebarSide } from '../../internal/page-layout.js';
|
|
3
|
+
import type { PlassColor, PlassDensity, PlassElevation, PlassSize, PlassVariant } from '../../types.js';
|
|
4
|
+
export type { PlassSidebarSide } from '../../internal/page-layout.js';
|
|
5
|
+
export interface PlSidebarProps extends Omit<React.ComponentPropsWithoutRef<'aside'>, 'color' | 'title'> {
|
|
6
|
+
/**
|
|
7
|
+
* Which end of the band it takes. Logical rather than physical — `start` is
|
|
8
|
+
* the left of an English page and the right of an Arabic one — because a
|
|
9
|
+
* navigation rail is beside the text it belongs to in every writing
|
|
10
|
+
* direction.
|
|
11
|
+
*
|
|
12
|
+
* Inside a `PlPageLayout` this is already decided by which slot the sidebar
|
|
13
|
+
* was handed to, and setting it again is only a way of disagreeing with the
|
|
14
|
+
* layout.
|
|
15
|
+
* @default 'start'
|
|
16
|
+
*/
|
|
17
|
+
side?: PlassSidebarSide;
|
|
18
|
+
/**
|
|
19
|
+
* How wide the column is — a number in pixels or any CSS length. Left out, it
|
|
20
|
+
* is the width `size` implies.
|
|
21
|
+
*
|
|
22
|
+
* With `resizable` it is only the width the sidebar *starts* at: dragging
|
|
23
|
+
* writes over it, and the caller hears about it through `onResize`.
|
|
24
|
+
*/
|
|
25
|
+
width?: number | string;
|
|
26
|
+
/** How narrow it may be dragged. @default 160 */
|
|
27
|
+
minWidth?: number | string;
|
|
28
|
+
/** And how wide. @default 480 */
|
|
29
|
+
maxWidth?: number | string;
|
|
30
|
+
/**
|
|
31
|
+
* Lets the reader drag the inner edge to change the column's width.
|
|
32
|
+
*
|
|
33
|
+
* Off by default. A sidebar that can be resized is a sidebar whose width is
|
|
34
|
+
* the reader's to remember, which means a caller who turns this on usually
|
|
35
|
+
* also wants to store what `onResizeEnd` reports.
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
resizable?: boolean;
|
|
39
|
+
/** Fires with the width in pixels while the edge is being dragged. */
|
|
40
|
+
onResize?: (width: number) => void;
|
|
41
|
+
/** Fires once, with the same number, when it is let go. */
|
|
42
|
+
onResizeEnd?: (width: number) => void;
|
|
43
|
+
/**
|
|
44
|
+
* The window width below which the sidebar stops being a column and becomes a
|
|
45
|
+
* drawer that is opened — with a `PlSidebarTrigger` somewhere on the page as
|
|
46
|
+
* the way to open it. `none` keeps it a column at every width.
|
|
47
|
+
*
|
|
48
|
+
* Defaults to the `PlPageLayout`'s own `collapseBelow`, and to `none` outside
|
|
49
|
+
* one: a sidebar that collapsed with nothing on the page able to bring it
|
|
50
|
+
* back would be a sidebar the reader has lost.
|
|
51
|
+
*/
|
|
52
|
+
collapseBelow?: PlPageLayoutCollapse;
|
|
53
|
+
/**
|
|
54
|
+
* Whether the drawer is open. Only meaningful once the sidebar has collapsed;
|
|
55
|
+
* a column is not opened, it is there.
|
|
56
|
+
*
|
|
57
|
+
* Inside a `PlPageLayout` the layout owns this — it is what a trigger
|
|
58
|
+
* anywhere on the page talks to — so control it there rather than here.
|
|
59
|
+
* `onOpenChange` still fires either way.
|
|
60
|
+
*/
|
|
61
|
+
open?: boolean;
|
|
62
|
+
/** Which state it starts in, for an uncontrolled standalone sidebar. @default false */
|
|
63
|
+
defaultOpen?: boolean;
|
|
64
|
+
onOpenChange?: (open: boolean) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the column holds its place while the page scrolls past it.
|
|
67
|
+
*
|
|
68
|
+
* On by default, and it costs nothing when it is not needed: with the page
|
|
69
|
+
* scrolling it becomes a `sticky` column as tall as what is left of the
|
|
70
|
+
* window under the header, and with only the content scrolling it is already
|
|
71
|
+
* as tall as the layout and this changes nothing.
|
|
72
|
+
* @default true
|
|
73
|
+
*/
|
|
74
|
+
sticky?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* The heading, drawn only while the sidebar is a drawer. A column has the
|
|
77
|
+
* page around it to say what it is; a panel that has covered the page does
|
|
78
|
+
* not.
|
|
79
|
+
*/
|
|
80
|
+
title?: React.ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* What the sheet is made of, said the way a **container** says it: the panel
|
|
83
|
+
* is never dyed, because what is on it arrives with colours of its own.
|
|
84
|
+
* @default 'glass'
|
|
85
|
+
*/
|
|
86
|
+
variant?: PlassVariant;
|
|
87
|
+
/** The panel's scale — its default width and the air around its content. @default 'md' */
|
|
88
|
+
size?: PlassSize;
|
|
89
|
+
/** @default 'primary' */
|
|
90
|
+
color?: PlassColor;
|
|
91
|
+
/** @default 'default' */
|
|
92
|
+
density?: PlassDensity;
|
|
93
|
+
/** Drop shadow depth. `0` — the default — is flat. @default 0 */
|
|
94
|
+
elevation?: PlassElevation;
|
|
95
|
+
/**
|
|
96
|
+
* Draws a hairline down the inner edge — the one facing the content. The
|
|
97
|
+
* outer edge is against the window, where there is nothing on the other side
|
|
98
|
+
* to be separated from.
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
divider?: boolean;
|
|
102
|
+
/** The gutter and the air above and below the content. @default true */
|
|
103
|
+
padded?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The name the region is announced by. Every `<aside>` on a page should have
|
|
106
|
+
* one, and a page with two sidebars *must*, or a screen reader offers two
|
|
107
|
+
* regions called "complementary".
|
|
108
|
+
* @default 'Sidebar'
|
|
109
|
+
*/
|
|
110
|
+
label?: string;
|
|
111
|
+
/** What the drawer's close button says, once the sidebar has collapsed. @default 'Close sidebar' */
|
|
112
|
+
closeLabel?: string;
|
|
113
|
+
/** What the drag handle is announced as. @default 'Resize sidebar' */
|
|
114
|
+
resizeLabel?: string;
|
|
115
|
+
/** Everything in it: a nav, a filter panel, a table of contents. */
|
|
116
|
+
children?: React.ReactNode;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A column beside the page's content, and a drawer once the window is too
|
|
120
|
+
* narrow to hold one.
|
|
121
|
+
*
|
|
122
|
+
* Two presentations of one panel, exactly as `PlDrawer` is: above
|
|
123
|
+
* `collapseBelow` it is an `<aside>` in the layout that the content is laid out
|
|
124
|
+
* around, and below it the same children are a drawer over a scrim with a focus
|
|
125
|
+
* trap, an Escape and a way back to the trigger. They are one component because
|
|
126
|
+
* they are one thing — a caller should not have to swap components at a
|
|
127
|
+
* breakpoint — and because the children only exist once either way, so nothing
|
|
128
|
+
* inside is rendered twice into the document for a screen reader to read twice.
|
|
129
|
+
*
|
|
130
|
+
* Which of the two is showing is a media query, and it is answered in CSS for
|
|
131
|
+
* the first paint and in JavaScript from then on. That split is deliberate: the
|
|
132
|
+
* markup a server sends is the column, so a narrow screen would draw a full
|
|
133
|
+
* width sidebar and throw it away a moment later — the class that hides it
|
|
134
|
+
* below the breakpoint is what stops that, and `matchMedia` is what decides,
|
|
135
|
+
* once there is a window to ask, that the drawer should exist at all.
|
|
136
|
+
*
|
|
137
|
+
* A real `<aside>`, which is the `complementary` landmark: the region a screen
|
|
138
|
+
* reader offers as "related to the page but not the page", and what a search
|
|
139
|
+
* engine reads as navigation chrome rather than as the article.
|
|
140
|
+
*/
|
|
141
|
+
export declare const PlSidebar: React.ForwardRefExoticComponent<PlSidebarProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{PlDrawer as n}from"../drawer/PlDrawer.js";import{drawerSide as o,expandedOnlyClasses as s,PlPageLayoutContext as i,PlassSidebarSideContext as a,useCollapsed as l}from"../../internal/page-layout.js";import{cx as d,sheetPaddingXClasses as c,sheetPaddingYClasses as u,sheetRestClasses as p,surfaceSlots as m,toLength as f,transitionClasses as y}from"../../internal/styles.js";const b={xs:"11rem",sm:"13rem",md:"16rem",lg:"18rem",xl:"21rem"},v=p;function toPixels(e,t){if(null==e)return t;if("number"==typeof e)return e;const r=/^\s*(-?[\d.]+)\s*(px|rem|em|%)\s*$/.exec(e);if(!r)return t;const n=Number(r[1]);if(Number.isNaN(n))return t;switch(r[2]){case"px":return n;case"%":return"undefined"==typeof window?t:window.innerWidth*n/100;default:return n*parseFloat(("undefined"==typeof document?"":getComputedStyle(document.documentElement).fontSize)||"16")}}export const PlSidebar=/* @__PURE__ */r.forwardRef(function PlSidebar({side:p,width:g,minWidth:w=160,maxWidth:h=480,resizable:x=!1,onResize:P,onResizeEnd:C,collapseBelow:k,open:z,defaultOpen:L=!1,onOpenChange:R,sticky:E=!0,title:N,variant:S="glass",size:j="md",color:B="primary",density:D="default",elevation:O=0,divider:A=!0,padded:M=!0,label:W="Sidebar",closeLabel:I="Close sidebar",resizeLabel:T="Resize sidebar",className:X,style:$,children:_,...F},K){const V=r.useContext(i),q=r.useContext(a),G=p??q??"start",H=k??(V.present?V.collapseBelow:"none"),J=l(H),[Q,U]=r.useState(L),Y=void 0!==z,Z=Y?z:V.present?V.open[G]:Q,ee=f(g)??b[j],te=r.useRef(null),re=r.useCallback(e=>{te.current=e,"function"==typeof K?K(e):K&&(K.current=e)},[K]),ne=r.useRef(null);r.useEffect(()=>()=>ne.current?.(),[]);const applyWidth=e=>{const t=te.current;if(!t)return e;const r=Math.min(toPixels(h,480),Math.max(toPixels(w,160),Math.round(e)));return t.style.setProperty("--p-sidebar-w",`${r}px`),r};return J?e(n,{side:o(G),mode:"overlay",open:Z,onOpenChange:e=>{Y||(V.present?V.setOpen(G,e):U(e)),R?.(e)},title:N,size:j,color:B,density:D,closeLabel:I,extent:void 0===g?void 0:ee,"aria-label":N?void 0:W,className:X,style:$,children:_}):t("aside",{ref:re,"aria-label":W,className:d("relative flex min-w-0 shrink-0 flex-col","w-(--p-sidebar-w)",v[S],A?d("start"===G?"border-e":"border-s","[border-color:var(--plass-divider)]"):"","content"===V.scroll?"h-full":E?d("self-start","sticky [top:var(--p-layout-header,0px)]","[height:calc(100dvh-var(--p-layout-header,0px)-var(--p-layout-footer,0px))]"):"",s[H],y,X),style:{...m(B,O),"--p-sidebar-w":ee,...$},...F,children:[e("div",{className:d("min-h-0 flex-1 overflow-y-auto overscroll-contain",M?d(c[D][j],u[D][j]):""),children:_}),x?e("div",{role:"separator","aria-orientation":"vertical","aria-label":T,tabIndex:0,className:d("absolute inset-y-0 z-1 w-2 cursor-col-resize","start"===G?"end-0 -me-1":"start-0 -ms-1","bg-transparent hover:bg-(--p-soft) data-[dragging]:bg-(--p-soft)",y,"[outline:none] focus-visible:[outline:2px_solid_var(--p-ring)]","focus-visible:[outline-offset:0px]"),onPointerDown:e=>{const t=te.current;if(!t||0!==e.button)return;const r=e.currentTarget;r.setPointerCapture(e.pointerId),r.dataset.dragging="true";const n=document.body.style.getPropertyValue("-webkit-user-select");document.body.style.setProperty("-webkit-user-select","none");const o=e.clientX,s=t.getBoundingClientRect().width,i="rtl"===getComputedStyle(t).direction,a="start"===G===i?-1:1;let l=s;const move=e=>{l=applyWidth(s+(e.clientX-o)*a),P?.(l)},release=()=>{ne.current=null,r.removeEventListener("pointermove",move),r.removeEventListener("pointerup",end),r.removeEventListener("pointercancel",end),delete r.dataset.dragging,n?document.body.style.setProperty("-webkit-user-select",n):document.body.style.removeProperty("-webkit-user-select")},end=()=>{release(),C?.(l)};ne.current=release,r.addEventListener("pointermove",move),r.addEventListener("pointerup",end),r.addEventListener("pointercancel",end)},onKeyDown:e=>{if("ArrowLeft"!==e.key&&"ArrowRight"!==e.key)return;e.preventDefault();const t="rtl"===getComputedStyle(e.currentTarget).direction,r="start"===G===t?-1:1;(e=>{const t=te.current;if(!t)return;const r=applyWidth(t.getBoundingClientRect().width+e);P?.(r),C?.(r)})(("ArrowRight"===e.key?16:-16)*r)}}):null]})});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type PlIconButtonProps } from '../icon-button/PlIconButton.js';
|
|
3
|
+
import type { PlPageLayoutCollapse, PlassSidebarSide } from '../../internal/page-layout.js';
|
|
4
|
+
export interface PlSidebarTriggerProps extends Omit<PlIconButtonProps, 'icon' | 'label'> {
|
|
5
|
+
/** Which of the layout's two sidebars it opens. @default 'start' */
|
|
6
|
+
side?: PlassSidebarSide;
|
|
7
|
+
/**
|
|
8
|
+
* The width below which the button appears — the same one the sidebar
|
|
9
|
+
* collapses at, since the button exists exactly while the sidebar does not.
|
|
10
|
+
* Inherited from the `PlPageLayout`, which is where it should be set.
|
|
11
|
+
*/
|
|
12
|
+
collapseBelow?: PlPageLayoutCollapse;
|
|
13
|
+
/** The glyph. A hamburger, drawn here, unless something else is given. */
|
|
14
|
+
icon?: React.ReactNode;
|
|
15
|
+
/** What it does, in words. @default 'Open sidebar' / 'Close sidebar' */
|
|
16
|
+
label?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The button that brings back a `PlSidebar` the window has become too narrow to
|
|
20
|
+
* hold.
|
|
21
|
+
*
|
|
22
|
+
* It is drawn only while that is true, and the "while" is a media query rather
|
|
23
|
+
* than a piece of state: the button carries a class that hides it at and above
|
|
24
|
+
* the breakpoint. That matters more than it looks — a trigger whose presence
|
|
25
|
+
* depended on `matchMedia` would be absent from the markup a server sends and
|
|
26
|
+
* would pop into the header a moment after the page arrived, on every phone,
|
|
27
|
+
* every time.
|
|
28
|
+
*
|
|
29
|
+
* Put it in a `PlHeader`'s `brand` slot, ahead of the logo, which is where
|
|
30
|
+
* thirty years of hamburgers have taught readers to look for it. It has to be
|
|
31
|
+
* inside a `PlPageLayout` to have something to open; outside one there is no
|
|
32
|
+
* sidebar it could be talking about, and it renders nothing.
|
|
33
|
+
*/
|
|
34
|
+
export declare const PlSidebarTrigger: React.ForwardRefExoticComponent<PlSidebarTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{PlIconButton as n}from"../icon-button/PlIconButton.js";import{collapsedOnlyClasses as o,PlPageLayoutContext as t}from"../../internal/page-layout.js";import{cx as i}from"../../internal/styles.js";function MenuIcon(){return e("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":"true",children:e("path",{d:"M4 7h16M4 12h16M4 17h16",strokeLinecap:"round"})})}export const PlSidebarTrigger=/* @__PURE__ */r.forwardRef(function PlSidebarTrigger({side:a="start",collapseBelow:s,icon:l,label:c,variant:u="ghost",className:p,onClick:d,...m},f){const h=r.useContext(t);if(!h.present)return null;const b=s??h.collapseBelow,g=h.open[a];return e(n,{ref:f,variant:u,icon:l??e(MenuIcon,{}),label:c??(g?"Close sidebar":"Open sidebar"),"aria-expanded":g,className:i(o[b],p),onClick:e=>{h.setOpen(a,!g),d?.(e)},...m})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{PlSidebar}from"./PlSidebar.js";export{PlSidebarTrigger}from"./PlSidebarTrigger.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as a,jsxs as e,Fragment as t}from"react/jsx-runtime";import*as l from"react";import{Switch as r}from"@base-ui/react/switch";import{Field as s}from"@base-ui/react/field";import{controlSlots as i,focusRingClasses as c,hasContent as n,metaTextClasses as o,tickRowTextClasses as d}from"../../internal/styles.js";const h={xs:"h-3.5 w-6",sm:"h-4 w-7",md:"h-5 w-9",lg:"h-6 w-11",xl:"h-7 w-13"},m={xs:"data-[checked]:left-[calc(100%-0.75rem)]",sm:"data-[checked]:left-[calc(100%-0.875rem)]",md:"data-[checked]:left-[calc(100%-1.125rem)]",lg:"data-[checked]:left-[calc(100%-1.375rem)]",xl:"data-[checked]:left-[calc(100%-1.625rem)]"},p=/* @__PURE__ */["relative inline-flex shrink-0 rounded-full","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","[transition-property:background-color,background-image,box-shadow,filter]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]",c].join(" "),f=/* @__PURE__ */["cursor-pointer bg-(--plass-track)","hover:brightness-[0.97] dark:hover:brightness-110","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:[box-shadow:var(--p-lift)] data-[checked]:hover:brightness-105"].join(" "),u=/* @__PURE__ */["cursor-default bg-(--plass-track) saturate-[0.55]","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:shadow-none"].join(" "),g=/* @__PURE__ */["cursor-not-allowed bg-(--plass-track)","opacity-50 saturate-[0.35] shadow-none","data-[checked]:[background-image:var(--p-fill)]"].join(" "),b=/* @__PURE__ */["absolute inset-y-0.5 left-0.5 aspect-square rounded-full bg-white","[box-shadow:0_1px_2px_rgb(20_40_90/0.25)]","[transition:left_var(--plass-duration)_var(--plass-ease)]"].join(" ");export const PlSwitch=/* @__PURE__ */l.forwardRef(function PlSwitch({size:l="md",color:c="primary",label:x,description:k,error:w,invalid:v,labelPlacement:j="end",disabled:N=!1,readOnly:y=!1,className:_,style:$,...P},R){const S=n(w),B=v??S,O=B?"danger":c,q=a("span",{className:"flex h-[1lh] shrink-0 items-center",children:a(r.Root,{ref:R,className:[p,h[l],N?g:y?u:f].join(" "),disabled:N,readOnly:y,...P,children:a(r.Thumb,{className:`${b} ${m[l]}`})})}),z=x||k?e("span",{className:["flex min-w-0 flex-col gap-0.5","start"===j?"flex-1":""].filter(Boolean).join(" "),children:[x?a(s.Label,{className:N?"text-(--plass-muted-fg)":"cursor-pointer text-(--plass-fg)",children:x}):null,k?a(s.Description,{className:`${o[l]} text-(--plass-muted-fg)`,children:k}):null]}):null;return e(s.Root,{disabled:N,invalid:B,className:["inline-flex flex-col gap-1 align-top",_??""].filter(Boolean).join(" "),style:{...i(O,0,"solid"),...$},children:[a("div",{className:`flex items-start gap-2.5 ${d[l]}`,children:e(t,"start"===j?{children:[z,q]}:{children:[q,z]})}),
|
|
1
|
+
"use client";import{jsx as a,jsxs as e,Fragment as t}from"react/jsx-runtime";import*as l from"react";import{Switch as r}from"@base-ui/react/switch";import{Field as s}from"@base-ui/react/field";import{controlSlots as i,focusRingClasses as c,hasContent as n,metaTextClasses as o,tickRowTextClasses as d}from"../../internal/styles.js";const h={xs:"h-3.5 w-6",sm:"h-4 w-7",md:"h-5 w-9",lg:"h-6 w-11",xl:"h-7 w-13"},m={xs:"data-[checked]:left-[calc(100%-0.75rem)]",sm:"data-[checked]:left-[calc(100%-0.875rem)]",md:"data-[checked]:left-[calc(100%-1.125rem)]",lg:"data-[checked]:left-[calc(100%-1.375rem)]",xl:"data-[checked]:left-[calc(100%-1.625rem)]"},p=/* @__PURE__ */["relative inline-flex shrink-0 rounded-full","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","[transition-property:background-color,background-image,box-shadow,filter]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]",c].join(" "),f=/* @__PURE__ */["cursor-pointer bg-(--plass-track)","hover:brightness-[0.97] dark:hover:brightness-110","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:[box-shadow:var(--p-lift)] data-[checked]:hover:brightness-105"].join(" "),u=/* @__PURE__ */["cursor-default bg-(--plass-track) saturate-[0.55]","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:shadow-none"].join(" "),g=/* @__PURE__ */["cursor-not-allowed bg-(--plass-track)","opacity-50 saturate-[0.35] shadow-none","data-[checked]:[background-image:var(--p-fill)]"].join(" "),b=/* @__PURE__ */["absolute inset-y-0.5 left-0.5 aspect-square rounded-full bg-white","[box-shadow:0_1px_2px_rgb(20_40_90/0.25)]","[transition:left_var(--plass-duration)_var(--plass-ease)]"].join(" ");export const PlSwitch=/* @__PURE__ */l.forwardRef(function PlSwitch({size:l="md",color:c="primary",label:x,description:k,error:w,invalid:v,labelPlacement:j="end",disabled:N=!1,readOnly:y=!1,className:_,style:$,...P},R){const S=n(w),B=v??S,O=B?"danger":c,q=a("span",{className:"flex h-[1lh] shrink-0 items-center",children:a(r.Root,{ref:R,className:[p,h[l],N?g:y?u:f].join(" "),disabled:N,readOnly:y,...P,children:a(r.Thumb,{className:`${b} ${m[l]}`})})}),z=x||k?e("span",{className:["flex min-w-0 flex-col gap-0.5","start"===j?"flex-1":""].filter(Boolean).join(" "),children:[x?a(s.Label,{className:N?"text-(--plass-muted-fg)":"cursor-pointer text-(--plass-fg)",children:x}):null,k?a(s.Description,{className:`${o[l]} text-(--plass-muted-fg)`,children:k}):null]}):null;return e(s.Root,{disabled:N,invalid:B,className:["inline-flex flex-col gap-1 align-top",_??""].filter(Boolean).join(" "),style:{...i(O,0,"solid"),...$},children:[a("div",{className:`flex items-start gap-2.5 ${d[l]}`,children:e(t,"start"===j?{children:[z,q]}:{children:[q,z]})}),a(s.Error,S?{match:!0,className:`${o[l]} text-(--p-accent)`,children:w}:{className:`${o[l]} text-(--p-accent)`})]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{controlTextLeadingClasses as a,focusRingInsetClasses as t,metaTextClasses as l,paddingXValues as s,radiusClasses as o,sheetRestClasses as n,srOnlyClasses as i,surfaceSlots as d}from"../../internal/styles.js";const c={default:{xs:"0.375rem",sm:"0.5rem",md:"0.75rem",lg:"0.875rem",xl:"1rem"},compact:{xs:"0.125rem",sm:"0.25rem",md:"0.4375rem",lg:"0.5625rem",xl:"0.6875rem"}},p={display:"table",width:"100%",margin:0,borderCollapse:"collapse",borderSpacing:0},m=/* @__PURE__ */["[--p-row:transparent]","[transition:background-color_var(--plass-duration)_var(--plass-ease)]"].join(" "),g=/* @__PURE__ */["cursor-pointer [outline:none]",t].join(" "),h="1px solid var(--plass-divider)";export function PlTable({variant:t="glass",size:v="md",color:y="primary",density:u="default",elevation:x=0,columns:f,rows:b,getRowKey:w,caption:k,empty:N="No data",striped:j=!1,hoverable:B=!1,stickyHeader:$=!1,maxHeight:A,onRowClick:C,className:H,style:S,...T}){const z=s[u][v],D=c[u][v],K=Boolean(C),R=B||K,_=void 0!==A,E={padding:`${D} ${z}`,border:0,background:"none"},I={...E,...$?{boxShadow:"inset 0 -1px 0 var(--plass-border)"}:{borderBottom:"1px solid var(--plass-border)"},...$?{background:"linear-gradient(var(--plass-glass-press), var(--plass-glass-press)), linear-gradient(var(--plass-surface), var(--plass-surface))"}:null},bodyCellStyle=e=>0===e?E:{...E,borderTop:h};return r("div",{className:["overflow-hidden",o[v],n[t],H??""].filter(Boolean).join(" "),style:{...d(y,x),...S},...T,children:[k?e("div",{"aria-hidden":"true",className:`${l[v]} font-semibold text-(--plass-muted-fg)`,style:{...E,borderBottom:h,textAlign:"start"},children:k}):null,e("div",{className:["overflow-x-auto",_?"overflow-y-auto overscroll-contain":""].filter(Boolean).join(" "),style:_?{maxHeight:A}:void 0,children:r("table",{className:`text-start ${a[v]} text-(--plass-fg)`,style:p,children:[k?e("caption",{className:i,children:k}):null,e("colgroup",{children:f.map(r=>e("col",{style:void 0===r.width?void 0:{width:"number"==typeof r.width?`${r.width}px`:r.width}},r.key))}),e("thead",{children:e("tr",{children:f.map(r=>e("th",{scope:"col",className:["font-semibold whitespace-nowrap text-(--plass-muted-fg)",$?"sticky top-0 z-10":""].filter(Boolean).join(" "),style:{...I,textAlign:r.align??"start"},children:r.header??r.key},r.key))})}),e("tbody",{children:0===b.length?e("tr",{className:m,children:e("td",{colSpan:f.length,className:"text-(--plass-muted-fg)",style:{...E,padding:`2rem ${z}`,textAlign:"center"},children:N})}):b.map((r,a)=>e("tr",{className:[m,j&&a%2==1?"[--p-row:var(--plass-stripe)]":"",R?"hover:[--p-row:var(--p-soft)]":"",K?g:""].filter(Boolean).join(" "),style:{backgroundColor:"var(--p-row)"},tabIndex:K?0:void 0,onClick:C?()=>C(r,a):void 0,onKeyDown:C?e=>{e.target===e.currentTarget&&("Enter"!==e.key&&" "!==e.key||(e.preventDefault(),C(r,a)))}:void 0,children:f.map(t=>e("td",{style:{...bodyCellStyle(a),textAlign:t.align??"start"},children:t.render?t.render(r,a):r[t.key]},t.key))},w?w(r,a):a))})]})})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Field as n}from"@base-ui/react/field";import{Input as s}from"@base-ui/react/input";import{Spinner as
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Field as n}from"@base-ui/react/field";import{Input as s}from"@base-ui/react/input";import{Spinner as i}from"../../internal/icons.js";import{controlHeightClasses as r,controlTextLeadingClasses as a,disabledClasses as o,fieldReadOnlyClasses as c,fieldRestClasses as m,focusWithinRingClasses as d,gapClasses as p,hasContent as x,iconClasses as u,metaTextClasses as f,paddingXClasses as h,radiusClasses as g,stackGapClasses as $,surfaceSlots as y,transitionClasses as b}from"../../internal/styles.js";const j={xs:`${p.xs} ${g.xs} ${a.xs}`,sm:`${p.sm} ${g.sm} ${a.sm}`,md:`${p.md} ${g.md} ${a.md}`,lg:`${p.lg} ${g.lg} ${a.lg}`,xl:`${p.xl} ${g.xl} ${a.xl}`},N={xs:"min-h-6 py-[3px]",sm:"min-h-8 py-[6px]",md:"min-h-10 py-[9px]",lg:"min-h-12 py-[11px]",xl:"min-h-14 py-[13px]"},v={none:"resize-none",vertical:"resize-y",horizontal:"resize-x",both:"resize"},w=/* @__PURE__ */["group relative flex w-full cursor-text","[-webkit-tap-highlight-color:transparent]",b,d,u].join(" "),z=m,k=c;export const PlTextField=/* @__PURE__ */l.forwardRef(function PlTextField({variant:a="glass",size:c="md",color:m="primary",density:d="default",elevation:p=0,multiline:u=!1,rows:g=3,resize:b="vertical",label:D,description:P,error:R,invalid:T,startIcon:B,endIcon:F,loading:I=!1,fullWidth:O=!1,readOnly:C=!1,disabled:E=!1,type:L="text",className:W,style:q,...A},G){const H=x(R),J=T??H,K=J?"danger":m,M=l.useRef(null),Q=l.useCallback(e=>{M.current=e,"function"==typeof G?G(e):G&&(G.current=e)},[G]),S=[w,j[c],u?`${N[c]} items-start`:`${r[c]} items-center`,h[d][c],E?o[a]:C?k[a]:z[a]].filter(Boolean).join(" "),U=["min-w-0 flex-1 bg-transparent [font:inherit] text-inherit","[outline:none]","placeholder:text-(--plass-muted-fg)","caret-(--p-accent) selection:bg-(--p-soft-press)","disabled:cursor-not-allowed",u?`block ${v[b]}`:"self-stretch"].join(" "),V="inline-flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg) transition-[color] duration-(--plass-duration) group-focus-within:text-(--p-accent)";return t(n.Root,{disabled:E,invalid:J,className:["flex-col align-top",$[c],O?"flex w-full":"inline-flex",W??""].filter(Boolean).join(" "),style:{...y(K,p),...q},children:[D?e(n.Label,{className:[f[c],"font-semibold",E?"text-(--plass-muted-fg)":"text-(--plass-fg)"].join(" "),children:D}):null,t("span",{className:S,onPointerDown:e=>{e.target!==e.currentTarget||E||(e.preventDefault(),M.current?.focus())},children:[B?e("span",{className:V,children:B}):null,e(s,{ref:Q,className:U,disabled:E,readOnly:C,"aria-busy":I||void 0,"data-loading":I||void 0,...u?{render:e("textarea",{rows:g})}:{type:L},...A}),I?e("span",{className:V,children:e(i,{})}):F?e("span",{className:V,children:F}):null]}),P?e(n.Description,{className:[f[c],"text-(--plass-muted-fg)"].join(" "),children:P}):null,e(n.Error,H?{match:!0,className:[f[c],"text-(--p-accent)"].join(" "),children:R}:{className:[f[c],"text-(--p-accent)"].join(" ")})]})});
|
|
@@ -48,8 +48,22 @@ export interface PlTextLinkProps extends Omit<React.ComponentPropsWithoutRef<'a'
|
|
|
48
48
|
* of your own replaces the glyph.
|
|
49
49
|
*
|
|
50
50
|
* Left out, it follows `newTab`.
|
|
51
|
+
*
|
|
52
|
+
* It is `icon` rather than `endIcon`, and the difference from every other
|
|
53
|
+
* component's is the reason: this one is about the link's *destination*, and
|
|
54
|
+
* it has an opinion — a link that takes over the window says so unless it is
|
|
55
|
+
* told not to. An `endIcon` elsewhere is a node and nothing else.
|
|
51
56
|
*/
|
|
52
57
|
icon?: React.ReactNode | boolean;
|
|
58
|
+
/**
|
|
59
|
+
* A mark before the label — a favicon, a file type, a lock.
|
|
60
|
+
*
|
|
61
|
+
* A plain node with no opinion, unlike `icon` above: nothing is drawn here
|
|
62
|
+
* unless something is put here. It rides on the label at the same size,
|
|
63
|
+
* separated by the same quarter-em, so a link with one in front of it still
|
|
64
|
+
* sits inside a sentence.
|
|
65
|
+
*/
|
|
66
|
+
startIcon?: React.ReactNode;
|
|
53
67
|
/**
|
|
54
68
|
* What a screen reader hears after the label on a `newTab` link. Never drawn.
|
|
55
69
|
* @default '(opens in a new tab)'
|
|
@@ -57,8 +71,17 @@ export interface PlTextLinkProps extends Omit<React.ComponentPropsWithoutRef<'a'
|
|
|
57
71
|
newTabLabel?: string;
|
|
58
72
|
/**
|
|
59
73
|
* Renders something other than an `<a>` — the `Link` a router brings, most of
|
|
60
|
-
* the time.
|
|
61
|
-
*
|
|
74
|
+
* the time.
|
|
75
|
+
*
|
|
76
|
+
* **An `href` on what comes back wins.** A router's `Link` does not pass its
|
|
77
|
+
* address through; it *resolves* one — a locale prefix, a base path, a typed
|
|
78
|
+
* route — and hands the anchor the result. So when the element carries an
|
|
79
|
+
* `href` of its own, this component's is not merged over it, and the router
|
|
80
|
+
* keeps what it worked out. Written the other way round, every localised link
|
|
81
|
+
* in an app silently lost its prefix.
|
|
82
|
+
*
|
|
83
|
+
* The element having none is the ordinary case (`render={<a />}`), and there
|
|
84
|
+
* the `href` above is used.
|
|
62
85
|
*/
|
|
63
86
|
render?: useRender.RenderProp;
|
|
64
87
|
/** The label. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as n,Fragment as e,jsxs as r}from"react/jsx-runtime";import*as s from"react";import{useRender as i}from"@base-ui/react/use-render";import{ExternalLinkIcon as l,LinkIcon as
|
|
1
|
+
"use client";import{jsx as n,Fragment as e,jsxs as r}from"react/jsx-runtime";import*as s from"react";import{useRender as i}from"@base-ui/react/use-render";import{ExternalLinkIcon as l,LinkIcon as a}from"../../internal/icons.js";import{controlTextLeadingClasses as o,focusRingClasses as t,srOnlyClasses as c}from"../../internal/styles.js";import{safeRel as p}from"../../internal/link.js";const m={always:"[&.plass-link]:underline",hover:"[&.plass-link]:no-underline [&.plass-link]:hover:underline",none:"[&.plass-link]:no-underline"},d=/* @__PURE__ */["plass-link","cursor-pointer","[&_svg]:pointer-events-none [&_svg]:inline [&_svg]:size-[0.95em] [&_svg]:shrink-0",/* @__PURE__ */["[transition-property:color,text-decoration-color]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]"].join(" "),t,"focus-visible:rounded-[0.25rem]"].join(" ");export const PlTextLink=/* @__PURE__ */s.forwardRef(function PlTextLink({href:t,underline:u="always",color:f,size:v,newTab:h=!1,icon:k,startIcon:x,newTabLabel:b="(opens in a new tab)",render:g,className:j,style:y,children:w,..._},N){const T=k??h,L=!0===T?n(h?l:a,{}):T,z=[d,v?o[v]:"",m[u],f?"[&.plass-link]:text-(--p-accent)":"[&.plass-link]:text-inherit",j??""].filter(Boolean).join(" "),C={"--p-underline":"color-mix(in oklab, currentColor 45%, transparent)","--p-underline-hover":"currentColor","--p-ring":`var(--plass-${f??"primary"}-ring)`,...f?{"--p-accent":`var(--plass-${f}-accent)`}:null},P=s.isValidElement(g)&&void 0!==g.props.href,{rel:$,...B}=_,E=p(h?"_blank":void 0,$);return i({render:g??n("a",{}),ref:N,props:{...P?null:{href:t},target:h?"_blank":void 0,className:z,style:{...C,...y},children:r(e,{children:[x?n("span",{className:"me-[0.25em]",children:x}):null,w,L?n("span",{className:"ms-[0.25em]",children:L}):null,h?r(e,{children:[" ",n("span",{className:c,children:b})]}):null]}),...B,rel:E}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as s from"react";import{Toast as o}from"@base-ui/react/toast";import{CloseIcon as a,severityIcon as i}from"../../internal/icons.js";import{controlSlots as r,focusRingClasses as n,glassClasses as l,hasContent as c,iconClasses as p,metaTextClasses as d,radiusClasses as m,sheetBodyClasses as u,sheetHeaderGapClasses as f,sheetPaddingXClasses as h,sheetPaddingYClasses as g,sheetSectionGapClasses as v,sheetTitleClasses as x}from"../../internal/styles.js";const b={"top-start":"top-0 items-start","top-center":"top-0 items-center","top-end":"top-0 items-end","bottom-start":"bottom-0 flex-col-reverse items-start","bottom-center":"bottom-0 flex-col-reverse items-center","bottom-end":"bottom-0 flex-col-reverse items-end"},y={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--plass-shadow-3),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[l,"border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--p-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" "),ghost:/* @__PURE__ */[l,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" ")},w={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"};function toManagerOptions(t){const{color:e,variant:s,icon:o,actionLabel:a,onAction:i,...r}=t;return{...r,data:{color:e,variant:s,icon:o},actionProps:void 0===a?void 0:{children:a,onClick:i}}}export function usePlToast(){const t=o.useToastManager();return s.useMemo(()=>({add:e=>t.add(toManagerOptions(e)),close:e=>t.close(e),update:(e,s)=>t.update(e,toManagerOptions(s)),promise:(e,s)=>t.promise(e,{loading:toManagerOptions(s.loading),success:t=>toManagerOptions("function"==typeof s.success?s.success(t):s.success),error:t=>toManagerOptions("function"==typeof s.error?s.error(t):s.error)}),toasts:t.toasts}),[t])}function ToastItem({toast:s,variant:l,color:b,size:j,density:N,closeLabel:T,swipeDirection:M}){const
|
|
1
|
+
"use client";import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as s from"react";import{Toast as o}from"@base-ui/react/toast";import{CloseIcon as a,severityIcon as i}from"../../internal/icons.js";import{controlSlots as r,focusRingClasses as n,glassClasses as l,hasContent as c,iconClasses as p,metaTextClasses as d,radiusClasses as m,sheetBodyClasses as u,sheetHeaderGapClasses as f,sheetPaddingXClasses as h,sheetPaddingYClasses as g,sheetSectionGapClasses as v,sheetTitleClasses as x}from"../../internal/styles.js";const b={"top-start":"top-0 items-start","top-center":"top-0 items-center","top-end":"top-0 items-end","bottom-start":"bottom-0 flex-col-reverse items-start","bottom-center":"bottom-0 flex-col-reverse items-center","bottom-end":"bottom-0 flex-col-reverse items-end"},y={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--plass-shadow-3),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[l,"border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--p-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" "),ghost:/* @__PURE__ */[l,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" ")},w={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"};function toManagerOptions(t){const{color:e,variant:s,icon:o,actionLabel:a,onAction:i,...r}=t;return{...r,data:{color:e,variant:s,icon:o},actionProps:void 0===a?void 0:{children:a,onClick:i}}}export function usePlToast(){const t=o.useToastManager();return s.useMemo(()=>({add:e=>t.add(toManagerOptions(e)),close:e=>t.close(e),update:(e,s)=>t.update(e,toManagerOptions(s)),promise:(e,s)=>t.promise(e,{loading:toManagerOptions(s.loading),success:t=>toManagerOptions("function"==typeof s.success?s.success(t):s.success),error:t=>toManagerOptions("function"==typeof s.error?s.error(t):s.error)}),toasts:t.toasts}),[t])}function ToastItem({toast:s,variant:l,color:b,size:j,density:N,closeLabel:T,swipeDirection:M}){const z=s.data?.variant??l??"glass",O=s.data?.color??b,P=void 0===s.data?.icon?i(O):s.data.icon,k=w[z],$=c(s.title);return e(o.Root,{toast:s,swipeDirection:M,className:["pointer-events-auto flex w-full items-start",h[N??"default"][j],g[N??"default"][j],m[j],v[j],u[j],y[z],p,"[transition:opacity_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0","data-[limited]:hidden",n,"[outline:none]"].filter(Boolean).join(" "),style:r(O,3,z),children:[c(P)?t("span",{className:`flex h-[1lh] shrink-0 items-center ${k}`,children:P}):null,e("div",{className:`flex min-w-0 flex-1 flex-col ${f[j]}`,children:[t(o.Title,{className:`plass-title font-semibold ${x[j]} ${k}`}),t(o.Description,{className:$&&"solid"!==z?"text-(--plass-muted-fg)":""})]}),t(o.Action,{className:["flex h-[1lh] shrink-0 cursor-pointer items-center rounded-full px-2","font-medium underline-offset-2",k||"text-(--p-on-solid)","hover:underline",n,d[j]].join(" ")}),t("span",{className:"flex h-[1lh] shrink-0 items-center",children:t(o.Close,{"aria-label":T,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",n].join(" "),children:t(a,{})})})]})}function ToastViewport(e){const{toasts:s}=o.useToastManager(),{position:a,width:i,...r}=e,n=[a.startsWith("top")?"up":"down","left","right"];return t(o.Portal,{children:t(o.Viewport,{className:["plass-portal pointer-events-none fixed inset-x-0 z-(--plass-z-portal) flex flex-col gap-2 p-4",b[a]].join(" "),children:s.map(e=>t("div",{className:"w-full",style:{maxWidth:"number"==typeof i?`${i}px`:i},children:t(ToastItem,{toast:e,swipeDirection:n,...r})},e.id))})})}export function PlToastProvider({variant:s="glass",size:a="md",color:i="primary",density:r="default",position:n="bottom-end",timeout:l=5e3,limit:c=3,width:p=380,closeLabel:d="Close",children:m}){return e(o.Provider,{timeout:l,limit:c,children:[m,t(ToastViewport,{position:n,variant:s,size:a,color:i,density:r,width:p,closeLabel:d})]})}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PlassElevation, PlassStyleProps, PlassVariant } from '../../types.js';
|
|
3
|
+
export interface PlToggleProps extends PlassStyleProps, Omit<React.ComponentPropsWithoutRef<'button'>, 'color' | 'value'> {
|
|
4
|
+
/**
|
|
5
|
+
* What the key is made of while it is **off**. On is always the colour family
|
|
6
|
+
* asserting itself, whichever material was asked for.
|
|
7
|
+
*
|
|
8
|
+
* - `solid` — the densest clear glass, which fills with the family's gradient
|
|
9
|
+
* when it goes on. The loudest, for a toggle a screen is steered by.
|
|
10
|
+
* - `glass` — the canonical sheet with a hairline round it. The default.
|
|
11
|
+
* - `ghost` — nothing at all until the pointer arrives or it goes on. What a
|
|
12
|
+
* toolbar wants.
|
|
13
|
+
* @default 'glass'
|
|
14
|
+
*/
|
|
15
|
+
variant?: PlassVariant;
|
|
16
|
+
/** Whether it is on. Use with `onPressedChange` for a controlled toggle. */
|
|
17
|
+
pressed?: boolean;
|
|
18
|
+
/** Whether it starts on, for an uncontrolled one. @default false */
|
|
19
|
+
defaultPressed?: boolean;
|
|
20
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
21
|
+
/** Identifies the toggle inside a `PlToggleGroup`. */
|
|
22
|
+
value?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Drop shadow depth. `0` — the default, and one below a `PlButton`'s — is
|
|
25
|
+
* flat: a toggle is a state rather than an action, and a state does not float
|
|
26
|
+
* off the page waiting to be taken.
|
|
27
|
+
* @default 0
|
|
28
|
+
*/
|
|
29
|
+
elevation?: PlassElevation;
|
|
30
|
+
/** Content placed before the label. Sized in `em`, so it tracks the label. */
|
|
31
|
+
startIcon?: React.ReactNode;
|
|
32
|
+
/** Content placed after the label. */
|
|
33
|
+
endIcon?: React.ReactNode;
|
|
34
|
+
/** Stretches to the width of the container. */
|
|
35
|
+
fullWidth?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The label. Left out, the toggle goes square around whatever icon it was
|
|
38
|
+
* given — which is what a toolbar toggle is. An icon-only toggle still needs
|
|
39
|
+
* an `aria-label`.
|
|
40
|
+
*/
|
|
41
|
+
children?: React.ReactNode;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A button that stays down.
|
|
45
|
+
*
|
|
46
|
+
* The difference from a `PlSwitch` is what the press *is*: a switch changes a
|
|
47
|
+
* setting and the change is the point; a toggle changes the state of the thing
|
|
48
|
+
* beside it — bold on the selected words, the grid on the canvas, the filter on
|
|
49
|
+
* the list. The difference from a `PlCheckbox` is that this one is a control
|
|
50
|
+
* rather than an answer, so it never goes in a form.
|
|
51
|
+
*
|
|
52
|
+
* Base UI's Toggle owns `aria-pressed` and the controlled/uncontrolled pair.
|
|
53
|
+
* What is left here is the surface, and the rule that off is neutral.
|
|
54
|
+
*/
|
|
55
|
+
export declare const PlToggle: React.ForwardRefExoticComponent<PlToggleProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsxs as s}from"react/jsx-runtime";import*as e from"react";import{Toggle as o}from"@base-ui/react/toggle";import{ButtonGroupContext as a}from"../../internal/button-group.js";import{controlHeightClasses as l,controlSlots as r,controlSquareClasses as t,controlTextClasses as p,disabledClasses as i,focusRingClasses as n,gapClasses as v,glassClasses as g,hasContent as d,iconClasses as h,paddingXClasses as x,radiusClasses as c,transitionClasses as f}from"../../internal/styles.js";const b={xs:`${l.xs} ${v.xs} ${c.xs} ${p.xs}`,sm:`${l.sm} ${v.sm} ${c.sm} ${p.sm}`,md:`${l.md} ${v.md} ${c.md} ${p.md}`,lg:`${l.lg} ${v.lg} ${c.lg} ${p.lg}`,xl:`${l.xl} ${v.xl} ${c.xl} ${p.xl}`},m={xs:`${t.xs} px-0`,sm:`${t.sm} px-0`,md:`${t.md} px-0`,lg:`${t.lg} px-0`,xl:`${t.xl} px-0`},$=/* @__PURE__ */["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-semibold leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",f,n,h].join(" "),u={solid:/* @__PURE__ */[g,"text-(--plass-muted-fg) bg-(--plass-glass-hover)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[g,"border text-(--plass-muted-fg) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-muted-fg) bg-transparent"},w={solid:/* @__PURE__ */["hover:bg-(--plass-glass-press) hover:text-(--plass-fg)","hover:[box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)]","active:[box-shadow:var(--p-elev-press),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */["hover:bg-(--plass-glass-hover) hover:text-(--plass-fg) hover:[border-color:var(--p-line)]","hover:[box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)]","active:bg-(--plass-glass-press)","active:[box-shadow:var(--p-elev-press),var(--plass-gloss-glass)]"].join(" "),ghost:"hover:bg-(--p-soft) hover:text-(--plass-fg) active:bg-(--p-soft-hover)"},j={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[g,"border text-(--p-accent) bg-(--p-soft)","[border-color:var(--p-line-hover)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-(--p-soft)"},y={solid:/* @__PURE__ */["hover:brightness-105 hover:[box-shadow:var(--p-elev-hover),var(--p-lift-hover)]","active:brightness-95 active:[box-shadow:var(--p-elev-press),var(--p-lift-press)]"].join(" "),glass:"hover:bg-(--p-soft-hover) active:bg-(--p-soft-press)",ghost:"hover:bg-(--p-soft-hover) active:bg-(--p-soft-press)"};export const PlToggle=/* @__PURE__ */e.forwardRef(function PlToggle({variant:l,size:t,color:p,density:n,elevation:v,pressed:g,defaultPressed:h,onPressedChange:c,value:f,startIcon:P,endIcon:T,fullWidth:k=!1,disabled:C,className:z,style:E,children:I,onPointerMove:M,...N},B){const R=e.useContext(a),W=l??R?.variant??"glass",X=t??R?.size??"md",Y=p??R?.color??"primary",q=n??R?.density??"default",A=v??R?.elevation??0,D=C??R?.disabled??!1,F=!d(I);return s(o,{ref:B,value:f,pressed:g,defaultPressed:h,onPressedChange:s=>c?.(s),disabled:D,className:s=>[$,b[X],F?m[X]:x[q][X],D?i[W]:s.pressed?`${j[W]} ${y[W]}`:`${u[W]} ${w[W]}`,D?"":"plass-glow cursor-pointer",k?"w-full":"",z??""].filter(Boolean).join(" "),style:{...r(Y,A,W),...E},onPointerMove:s=>{const e=s.currentTarget;e.style.setProperty("--p-mx",`${s.nativeEvent.offsetX}px`),e.style.setProperty("--p-my",`${s.nativeEvent.offsetY}px`),M?.(s)},...N,children:[P,I,T]})});
|