plass-ui 1.2.0 → 1.3.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 +78 -0
- package/dist/components/accordion/PlAccordion.js +1 -1
- package/dist/components/alert/PlAlert.js +1 -1
- package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
- package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
- package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
- package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
- package/dist/components/avatar/PlAvatar.js +1 -1
- package/dist/components/avatar-group/PlAvatarGroup.js +1 -1
- package/dist/components/back-top/PlBackTop.d.ts +55 -0
- package/dist/components/back-top/PlBackTop.js +1 -0
- package/dist/components/back-top/index.d.ts +2 -0
- package/dist/components/back-top/index.js +1 -0
- package/dist/components/badge/PlBadge.js +1 -1
- package/dist/components/blockquote/PlBlockquote.js +1 -1
- package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -1
- package/dist/components/box/PlBox.js +1 -1
- package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
- package/dist/components/button/PlButton.js +1 -1
- package/dist/components/calendar/PlCalendar.d.ts +104 -0
- package/dist/components/calendar/PlCalendar.js +1 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/calendar/index.js +1 -0
- package/dist/components/card/PlCard.js +1 -1
- package/dist/components/carousel/PlCarousel.js +1 -1
- package/dist/components/chat-bubble/PlChatBubble.js +1 -1
- package/dist/components/checkbox/PlCheckbox.js +1 -1
- package/dist/components/chip/PlChip.js +1 -1
- package/dist/components/collapsible/PlCollapsible.js +1 -1
- package/dist/components/color-picker/PlColorPicker.js +1 -1
- package/dist/components/combobox/PlCombobox.d.ts +11 -2
- package/dist/components/combobox/PlCombobox.js +1 -1
- package/dist/components/command-palette/PlCommandPalette.d.ts +1 -1
- package/dist/components/command-palette/PlCommandPalette.js +1 -1
- package/dist/components/confirm/PlConfirmProvider.d.ts +100 -0
- package/dist/components/confirm/PlConfirmProvider.js +1 -0
- package/dist/components/confirm/index.d.ts +2 -0
- package/dist/components/confirm/index.js +1 -0
- package/dist/components/container/PlContainer.js +1 -1
- package/dist/components/date-picker/PlDatePicker.d.ts +41 -2
- package/dist/components/date-picker/PlDatePicker.js +1 -1
- package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
- package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
- package/dist/components/divider/PlDivider.js +1 -1
- package/dist/components/drawer/PlDrawer.d.ts +1 -1
- package/dist/components/drawer/PlDrawer.js +1 -1
- package/dist/components/empty/PlEmpty.d.ts +47 -0
- package/dist/components/empty/PlEmpty.js +1 -0
- package/dist/components/empty/index.d.ts +2 -0
- package/dist/components/empty/index.js +1 -0
- package/dist/components/file-picker/PlFilePicker.js +1 -1
- package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
- package/dist/components/footer/PlFooter.js +1 -1
- package/dist/components/header/PlHeader.js +1 -1
- package/dist/components/highlight/PlHighlight.js +1 -1
- package/dist/components/hot-keys/PlHotKeys.js +1 -1
- package/dist/components/image/PlImage.d.ts +72 -0
- package/dist/components/image/PlImage.js +1 -0
- package/dist/components/image/index.d.ts +2 -0
- package/dist/components/image/index.js +1 -0
- package/dist/components/list/PlList.js +1 -1
- package/dist/components/menu/PlMenu.d.ts +2 -2
- package/dist/components/menu/PlMenu.js +1 -1
- package/dist/components/menubar/PlMenubar.js +1 -1
- package/dist/components/modal/PlModal.d.ts +1 -1
- package/dist/components/modal/PlModal.js +1 -1
- package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
- package/dist/components/number-field/PlNumberField.d.ts +11 -2
- package/dist/components/number-field/PlNumberField.js +1 -1
- package/dist/components/otp-field/PlOtpField.d.ts +10 -1
- package/dist/components/otp-field/PlOtpField.js +1 -1
- package/dist/components/overlay/PlOverlay.d.ts +1 -1
- package/dist/components/overlay/PlOverlay.js +1 -1
- package/dist/components/page-layout/PlPageLayout.js +1 -1
- package/dist/components/pagination/PlPagination.js +1 -1
- package/dist/components/panes/PlPanes.js +1 -1
- package/dist/components/pill/PlPill.js +1 -1
- package/dist/components/popconfirm/PlPopconfirm.d.ts +61 -0
- package/dist/components/popconfirm/PlPopconfirm.js +1 -0
- package/dist/components/popconfirm/index.d.ts +2 -0
- package/dist/components/popconfirm/index.js +1 -0
- package/dist/components/popover/PlPopover.d.ts +1 -1
- package/dist/components/popover/PlPopover.js +1 -1
- package/dist/components/progress-box/PlProgressBox.js +1 -1
- package/dist/components/progress-circular/PlProgressCircular.js +1 -1
- package/dist/components/progress-linear/PlProgressLinear.js +1 -1
- package/dist/components/radio-group/PlRadioGroup.js +1 -1
- package/dist/components/rating/PlRating.js +1 -1
- package/dist/components/scroll-zone/PlScrollZone.js +1 -1
- package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
- package/dist/components/select/PlSelect.d.ts +10 -1
- package/dist/components/select/PlSelect.js +1 -1
- package/dist/components/sidebar/PlSidebar.js +1 -1
- package/dist/components/skeleton/PlSkeleton.js +1 -1
- package/dist/components/slider/PlSlider.js +1 -1
- package/dist/components/spoiler/PlSpoiler.js +1 -1
- package/dist/components/stat/PlStat.d.ts +66 -0
- package/dist/components/stat/PlStat.js +1 -0
- package/dist/components/stat/index.d.ts +2 -0
- package/dist/components/stat/index.js +1 -0
- package/dist/components/stepper/PlStepper.d.ts +86 -0
- package/dist/components/stepper/PlStepper.js +1 -0
- package/dist/components/stepper/index.d.ts +2 -0
- package/dist/components/stepper/index.js +1 -0
- package/dist/components/switch/PlSwitch.js +1 -1
- package/dist/components/tabs/PlTabs.js +1 -1
- package/dist/components/text-field/PlTextField.d.ts +10 -1
- package/dist/components/text-field/PlTextField.js +1 -1
- package/dist/components/time-picker/PlTimePicker.js +1 -1
- package/dist/components/timeline/PlTimeline.d.ts +5 -8
- package/dist/components/timeline/PlTimeline.js +1 -1
- package/dist/components/toast/PlToast.d.ts +1 -1
- package/dist/components/toast/PlToast.js +1 -1
- package/dist/components/toggle/PlToggle.js +1 -1
- package/dist/components/toolbar/PlToolbar.js +1 -1
- package/dist/components/tooltip/PlTooltip.d.ts +1 -1
- package/dist/components/tooltip/PlTooltip.js +1 -1
- package/dist/components/transfer/PlTransfer.js +1 -1
- package/dist/components/tree/PlTree.d.ts +67 -0
- package/dist/components/tree/PlTree.js +1 -0
- package/dist/components/tree/index.d.ts +2 -0
- package/dist/components/tree/index.js +1 -0
- package/dist/components/visually-hidden/PlVisuallyHidden.d.ts +46 -0
- package/dist/components/visually-hidden/PlVisuallyHidden.js +1 -0
- package/dist/components/visually-hidden/index.d.ts +2 -0
- package/dist/components/visually-hidden/index.js +1 -0
- package/dist/css/back-top.css +2 -0
- package/dist/css/calendar.css +2 -0
- package/dist/css/confirm.css +2 -0
- package/dist/css/empty.css +2 -0
- package/dist/css/image.css +2 -0
- package/dist/css/popconfirm.css +2 -0
- package/dist/css/stat.css +2 -0
- package/dist/css/stepper.css +2 -0
- package/dist/css/tree.css +2 -0
- package/dist/css/visually-hidden.css +2 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/usePlBreakpoint.d.ts +38 -0
- package/dist/hooks/usePlBreakpoint.js +1 -0
- package/dist/hooks/usePlColorScheme.d.ts +66 -0
- package/dist/hooks/usePlColorScheme.js +1 -0
- package/dist/hooks/usePlHotKeys.d.ts +81 -0
- package/dist/hooks/usePlHotKeys.js +1 -0
- package/dist/hooks/usePlMediaQuery.d.ts +22 -0
- package/dist/hooks/usePlMediaQuery.js +1 -0
- package/dist/hooks/usePlReducedMotion.d.ts +22 -0
- package/dist/hooks/usePlReducedMotion.js +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +0 -1
- package/dist/internal/animate.js +1 -1
- package/dist/internal/calendar.d.ts +25 -3
- package/dist/internal/calendar.js +1 -1
- package/dist/internal/color-scheme.d.ts +23 -0
- package/dist/internal/color-scheme.js +1 -0
- package/dist/internal/date.d.ts +21 -0
- package/dist/internal/date.js +1 -1
- package/dist/internal/defaults.d.ts +69 -0
- package/dist/internal/defaults.js +1 -0
- package/dist/internal/direction.d.ts +4 -0
- package/dist/internal/direction.js +1 -0
- package/dist/internal/grid.d.ts +2 -0
- package/dist/internal/grid.js +1 -1
- package/dist/internal/keys.d.ts +93 -0
- package/dist/internal/keys.js +1 -0
- package/dist/internal/media.d.ts +26 -0
- package/dist/internal/media.js +1 -0
- package/dist/internal/page-layout.d.ts +6 -6
- package/dist/internal/page-layout.js +1 -1
- package/dist/internal/steps.d.ts +76 -0
- package/dist/internal/steps.js +1 -0
- package/dist/provider/PlColorSchemeScript.d.ts +40 -0
- package/dist/provider/PlColorSchemeScript.js +1 -0
- package/dist/provider/PlassProvider.d.ts +39 -0
- package/dist/provider/PlassProvider.js +1 -0
- package/dist/provider/index.d.ts +5 -0
- package/dist/provider/index.js +1 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +29 -1
- package/dist/tokens.css +29 -1
- package/dist/types.d.ts +17 -0
- package/package.json +17 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as
|
|
1
|
+
"use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as t from"react";import{useDefaults as r}from"../../internal/defaults.js";import{useRender as s}from"@base-ui/react/use-render";import{cx as a,hasContent as n,iconClasses as i,metaTextClasses as o,sheetBodyClasses as c,sheetTitleClasses as p,surfaceSlots as d,transitionClasses as m}from"../../internal/styles.js";import{bulletGapClasses as u,bulletSizeValues as f,bulletStatusClasses as x,connectorColorClasses as b,connectorStyleClasses as v,statusAt as h,titleStatusClasses as y}from"../../internal/steps.js";const N=/* @__PURE__ */t.createContext(null),g=/* @__PURE__ */t.createContext({index:0,last:!1}),z={default:{xs:"pb-5",sm:"pb-6",md:"pb-7",lg:"pb-8",xl:"pb-10"},compact:{xs:"pb-3",sm:"pb-3.5",md:"pb-4",lg:"pb-5",xl:"pb-6"}},j={default:{xs:"pe-5",sm:"pe-6",md:"pe-7",lg:"pe-8",xl:"pe-10"},compact:{xs:"pe-3",sm:"pe-3.5",md:"pe-4",lg:"pe-5",xl:"pe-6"}};export const PlTimelineItem=/* @__PURE__ */t.forwardRef(function PlTimelineItem({title:r,meta:s,bullet:w,status:P,color:C,connector:T="solid",className:_,children:I,...R},$){const k=t.useContext(N),{index:A,last:M}=t.useContext(g),q=k?.size??"md",B=k?.density??"default",D=k?.orientation??"vertical",E=C??k?.color??"primary",F=P??h(A,k?.active??null),G="horizontal"===D,H="none"!==T&&!M,J=e("span",{"aria-hidden":"true",className:a("relative z-10 flex shrink-0 items-center justify-center rounded-full","size-(--p-bullet) text-[calc(var(--p-bullet)*0.5)] leading-none font-semibold tabular-nums",x[F],m,i),children:w}),K=H?e("span",{"aria-hidden":"true",className:a("pointer-events-none absolute",G?"top-[calc(var(--p-bullet)/2_-_1px)] end-0 start-(--p-bullet) border-t-2":"top-(--p-bullet) bottom-0 start-[calc(var(--p-bullet)/2_-_1px)] border-s-2",v[T],b[F],m)}):null,L=l("div",{className:a("flex min-w-0 flex-col gap-0.5",G?"mt-2":""),children:[n(r)||n(s)?l("div",{className:"flex flex-wrap items-baseline gap-x-2",children:[n(r)?e("span",{className:a("font-semibold",p[q],y[F],m),children:r}):null,n(s)?e("span",{className:a("text-(--plass-muted-fg)",o[q]),children:s}):null]}):null,n(I)?e("div",{className:a("text-(--plass-muted-fg)",c[q]),children:I}):null]});return l("li",{ref:$,"aria-current":"current"===F?"step":void 0,"data-status":F,className:a("relative",G?a("flex min-w-0 flex-1 flex-col",M?"":j[B][q]):a("flex",u[q],M?"":z[B][q]),_),style:{"--p-bullet":f[q],...d(E,0),"--p-fill":`var(--plass-${E}-fill)`,"--p-on-solid":`var(--plass-${E}-on-solid)`},...R,children:[K,J,L]})});export const PlTimeline=/* @__PURE__ */t.forwardRef(function PlTimeline({active:l,size:n,color:i,density:o,orientation:c="vertical",render:p,className:m,style:u,children:f,...x},b){const v=r(),h=n??v.size??"md",y=i??v.color??"primary",z=o??v.density??"default",j=t.Children.toArray(f),w=j.length,P=t.useMemo(()=>({size:h,density:z,orientation:c,color:y,active:l??null}),[h,z,c,y,l]),C=s({render:p??e("ol",{}),ref:b,props:{role:"list",className:a("flex","horizontal"===c?"flex-row":"flex-col",m),style:{...d(y,0),...u},children:j.map((l,t)=>e(g.Provider,{value:{index:t,last:t===w-1},children:l},t)),...x}});return e(N.Provider,{value:P,children:C})});
|
|
@@ -129,4 +129,4 @@ export declare function usePlToast(): {
|
|
|
129
129
|
* swipe, the F6 focus hotkey, and the live region that makes a message which
|
|
130
130
|
* appeared out of nowhere reach a screen reader at all.
|
|
131
131
|
*/
|
|
132
|
-
export declare function PlToastProvider({ variant, size, color, density, position, timeout, limit, width, closeLabel, children }: PlToastProviderProps): React.JSX.Element;
|
|
132
|
+
export declare function PlToastProvider({ variant, size: sizeProp, color: colorProp, density: densityProp, position, timeout, limit, width, closeLabel, children }: PlToastProviderProps): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as t,jsxs as s}from"react/jsx-runtime";import*as e from"react";import{
|
|
1
|
+
"use client";import{jsx as t,jsxs as s}from"react/jsx-runtime";import*as e from"react";import{useDefaults as o}from"../../internal/defaults.js";import{Toast as a}from"@base-ui/react/toast";import{CloseIcon as i,severityIcon as r}from"../../internal/icons.js";import{controlSlots as n,focusRingClasses as l,glassClasses as c,hasContent as p,iconClasses as d,metaTextClasses as m,radiusClasses as u,sheetBodyClasses as f,sheetHeaderGapClasses as h,sheetPaddingXClasses as g,sheetPaddingYClasses as v,sheetSectionGapClasses as x,sheetTitleClasses as b}from"../../internal/styles.js";const y={"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"},w={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--plass-shadow-3),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[c,"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__ */[c,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" ")},j={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"};function toManagerOptions(t){const{color:s,variant:e,icon:o,className:a,style:i,actionLabel:r,onAction:n,...l}=t;return{...l,data:{color:s,variant:e,icon:o,className:a,style:i},actionProps:void 0===r?void 0:{children:r,onClick:n}}}export function usePlToast(){const t=a.useToastManager();return e.useMemo(()=>({add:s=>t.add(toManagerOptions(s)),close:s=>t.close(s),update:(s,e)=>t.update(s,toManagerOptions(e)),promise:(s,e)=>t.promise(s,{loading:toManagerOptions(e.loading),success:t=>toManagerOptions("function"==typeof e.success?e.success(t):e.success),error:t=>toManagerOptions("function"==typeof e.error?e.error(t):e.error)}),toasts:t.toasts}),[t])}function ToastItem({toast:e,variant:o,color:c,size:y,density:N,closeLabel:T,swipeDirection:M}){const z=e.data?.variant??o??"glass",O=e.data?.color??c,P=void 0===e.data?.icon?r(O):e.data.icon,k=j[z],$=p(e.title);return s(a.Root,{toast:e,swipeDirection:M,className:["pointer-events-auto flex w-full items-start",g[N??"default"][y],v[N??"default"][y],u[y],x[y],f[y],w[z],d,"[transition:opacity_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0","data-[limited]:hidden",l,"[outline:none]",e.data?.className??""].filter(Boolean).join(" "),style:{...n(O,3,z),...e.data?.style},children:[p(P)?t("span",{className:`flex h-[1lh] shrink-0 items-center ${k}`,children:P}):null,s("div",{className:`flex min-w-0 flex-1 flex-col ${h[y]}`,children:[t(a.Title,{className:`plass-title font-semibold ${b[y]} ${k}`}),t(a.Description,{className:$&&"solid"!==z?"text-(--plass-muted-fg)":""})]}),t(a.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",l,m[y]].join(" ")}),t("span",{className:"flex h-[1lh] shrink-0 items-center",children:t(a.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",l].join(" "),children:t(i,{})})})]})}function ToastViewport(s){const{toasts:e}=a.useToastManager(),{position:o,width:i,...r}=s,n=[o.startsWith("top")?"up":"down","left","right"];return t(a.Portal,{children:t(a.Viewport,{className:["plass-portal pointer-events-none fixed inset-x-0 z-(--plass-z-portal) flex flex-col gap-2 p-4",y[o]].join(" "),children:e.map(s=>t("div",{className:"w-full",style:{maxWidth:"number"==typeof i?`${i}px`:i},children:t(ToastItem,{toast:s,swipeDirection:n,...r})},s.id))})})}export function PlToastProvider({variant:e="glass",size:i,color:r,density:n,position:l="bottom-end",timeout:c=5e3,limit:p=3,width:d=380,closeLabel:m="Close",children:u}){const f=o(),h=i??f.size??"md",g=r??f.color??"primary",v=n??f.density??"default";return s(a.Provider,{timeout:c,limit:p,children:[u,t(ToastViewport,{position:l,variant:e,size:h,color:g,density:v,width:d,closeLabel:m})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsxs as s}from"react/jsx-runtime";import*as e from"react";import{
|
|
1
|
+
"use client";import{jsxs as s}from"react/jsx-runtime";import*as e from"react";import{useDefaults as o}from"../../internal/defaults.js";import{Toggle as r}from"@base-ui/react/toggle";import{ButtonGroupContext as l}from"../../internal/button-group.js";import{controlHeightClasses as a,controlSlots as t,controlSquareClasses as i,controlTextClasses as p,disabledClasses as n,focusRingClasses as v,gapClasses as g,glassClasses as d,hasContent as h,iconClasses as x,paddingXClasses as c,radiusClasses as f,transitionClasses as m}from"../../internal/styles.js";const b={xs:`${a.xs} ${g.xs} ${f.xs} ${p.xs}`,sm:`${a.sm} ${g.sm} ${f.sm} ${p.sm}`,md:`${a.md} ${g.md} ${f.md} ${p.md}`,lg:`${a.lg} ${g.lg} ${f.lg} ${p.lg}`,xl:`${a.xl} ${g.xl} ${f.xl} ${p.xl}`},$={xs:`${i.xs} px-0`,sm:`${i.sm} px-0`,md:`${i.md} px-0`,lg:`${i.lg} px-0`,xl:`${i.xl} px-0`},u=/* @__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]",m,v,x].join(" "),w={solid:/* @__PURE__ */[d,"text-(--plass-muted-fg) bg-(--plass-glass-hover)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[d,"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"},j={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)"},y={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[d,"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)"},P={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:a,size:i,color:p,density:v,elevation:g,pressed:d,defaultPressed:x,onPressedChange:f,value:m,startIcon:T,endIcon:k,fullWidth:z=!1,disabled:C,className:E,style:I,children:M,onPointerMove:N,...B},R){const W=o(),X=e.useContext(l),Y=a??X?.variant??"glass",q=i??X?.size??W.size??"md",A=p??X?.color??W.color??"primary",D=v??X?.density??W.density??"default",F=g??X?.elevation??0,G=C??X?.disabled??!1,H=!h(M);return s(r,{ref:R,value:m,pressed:d,defaultPressed:x,onPressedChange:s=>f?.(s),disabled:G,className:s=>[u,b[q],H?$[q]:c[D][q],G?n[Y]:s.pressed?`${y[Y]} ${P[Y]}`:`${w[Y]} ${j[Y]}`,G?"":"plass-glow cursor-pointer",z?"w-full":"",E??""].filter(Boolean).join(" "),style:{...t(A,F,Y),...I},onPointerMove:s=>{const e=s.currentTarget;e.style.setProperty("--p-mx",`${s.nativeEvent.offsetX}px`),e.style.setProperty("--p-my",`${s.nativeEvent.offsetY}px`),N?.(s)},...B,children:[T,M,k]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as s from"react";import{
|
|
1
|
+
"use client";import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as s from"react";import{useDefaults as i}from"../../internal/defaults.js";import{useRender as o}from"@base-ui/react/use-render";import{cx as a,hasContent as l,radiusClasses as n,sheetPaddingXClasses as d,sheetPaddingYClasses as c,sheetRestClasses as m,sheetSectionGapClasses as p,surfaceSlots as f,transitionClasses as b}from"../../internal/styles.js";const x=m,u={static:{top:"",bottom:""},sticky:{top:"sticky top-0 z-20",bottom:"sticky bottom-0 z-20"},fixed:{top:"fixed inset-x-0 top-0 z-30",bottom:"fixed inset-x-0 bottom-0 z-30"}},v={top:"border-b [border-color:var(--plass-divider)]",bottom:"border-t [border-color:var(--plass-divider)]"};export const PlToolbar=/* @__PURE__ */s.forwardRef(function PlToolbar({variant:s="glass",size:m,color:y,density:h,elevation:w=0,position:z="static",side:g="top",divider:j=!1,start:k,end:N,render:P,className:T,style:F,children:R,...q},A){const B=i(),C=m??B.size??"md",D=y??B.color??"primary",E=h??B.density??"default",G=a("flex w-full min-w-0 items-center",d[E][C],c[E][C],p[C],"static"===z?n[C]:"",x[s],j?v[g]:"",u[z][g],b,T);return o({render:P??e("div",{}),ref:A,props:{className:G,style:{...f(D,w),...F},children:r(t,{children:[l(k)?e("div",{className:"flex min-w-0 shrink-0 items-center gap-2",children:k}):null,e("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:R}),l(N)?e("div",{className:"flex min-w-0 shrink-0 items-center gap-2",children:N}):null]}),...q}})});
|
|
@@ -89,4 +89,4 @@ export type PlTooltipProviderProps = React.ComponentProps<typeof BaseUITooltip.P
|
|
|
89
89
|
* this component wires both, and drops the reference while it is closed rather
|
|
90
90
|
* than pointing at an element that is not in the document.
|
|
91
91
|
*/
|
|
92
|
-
export declare function PlTooltip({ content, children, size, color, density, side, align, sideOffset, delay, closeDelay, arrow, open, defaultOpen, onOpenChange, disabled, className, style, ...props }: PlTooltipProps): React.JSX.Element;
|
|
92
|
+
export declare function PlTooltip({ content, children, size: sizeProp, color: colorProp, density: densityProp, side, align, sideOffset, delay, closeDelay, arrow, open, defaultOpen, onOpenChange, disabled, className, style, ...props }: PlTooltipProps): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as s,jsxs as a}from"react/jsx-runtime";import*as e from"react";import{
|
|
1
|
+
"use client";import{jsx as s,jsxs as a}from"react/jsx-runtime";import*as e from"react";import{useDefaults as t}from"../../internal/defaults.js";import{Tooltip as o}from"@base-ui/react/tooltip";import{glassClasses as l,metaTextClasses as i,paddingXClasses as r,radiusClasses as n,surfaceSlots as d}from"../../internal/styles.js";export const PlTooltipProvider=o.Provider;const p=/* @__PURE__ */[l,"max-w-64 border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]","[outline:none]","[transition:opacity_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0","data-[instant]:[transition-duration:0ms]"].join(" "),c={xs:"py-0.5",sm:"py-0.5",md:"py-1",lg:"py-1.5",xl:"py-2"},m={xs:6,sm:7,md:8,lg:9,xl:10};export function PlTooltip({content:l,children:g,size:f,color:h,density:y,side:u="top",align:x="center",sideOffset:b=6,delay:v,closeDelay:j,arrow:w=!0,open:P,defaultOpen:z,onOpenChange:O,disabled:N=!1,className:T,style:B,...C}){const D=t(),L=f??D.size??"sm",M=h??D.color??"secondary",_=y??D.density??"default",k=m[L],A=e.useId(),[I,R]=e.useState(z??!1),S=P??I;return a(o.Root,{open:P,defaultOpen:z,onOpenChange:s=>{R(s),O?.(s)},children:[s(o.Trigger,{render:g,delay:v,closeDelay:j,disabled:N,"aria-describedby":S?A:void 0}),s(o.Portal,{children:s(o.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",side:u,align:x,sideOffset:b,children:a(o.Popup,{id:A,role:"tooltip",className:[p,n[L],r[_][L],c[L],i[L],T??""].filter(Boolean).join(" "),style:{...d(M,3),...B},...C,children:[w?s(o.Arrow,{className:["data-[side=top]:bottom-[-1px]","data-[side=bottom]:top-[-1px] data-[side=bottom]:rotate-180","data-[side=left]:right-[-1px] data-[side=left]:-rotate-90","data-[side=right]:left-[-1px] data-[side=right]:rotate-90"].join(" "),children:a("svg",{width:k,height:k/2,viewBox:"0 0 10 5","aria-hidden":"true",className:"block",children:[s("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-line)"}),s("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-press)",transform:"translate(0 -1)"})]})}):null,l]})})})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as a from"react";import{
|
|
1
|
+
"use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as a from"react";import{useDefaults as t}from"../../internal/defaults.js";import{PlCheckbox as s}from"../checkbox/PlCheckbox.js";import{PlIconButton as r}from"../icon-button/PlIconButton.js";import{PlTextField as i}from"../text-field/PlTextField.js";import{ArrowRightIcon as n}from"../../internal/icons.js";import{searchText as o}from"../../internal/search.js";import{cx as c,fieldRestClasses as d,hasContent as h,metaTextClasses as m,paddingXClasses as u,radiusClasses as b,surfaceSlots as f,toLength as v}from"../../internal/styles.js";const p={xs:"py-1",sm:"py-1.5",md:"py-2",lg:"py-2.5",xl:"py-3"},g={xs:"py-0.5",sm:"py-1",md:"py-1",lg:"py-1.5",xl:"py-2"};function Panel({title:a,rows:t,ticked:r,onTick:n,onTickAll:o,search:h,onSearch:v,searchable:y,disabled:x,height:k,emptyLabel:w,searchLabel:S,selectAllLabel:L,style:N}){const{variant:j,size:T,color:z,density:A}=N,C=t.filter(e=>!e.disabled),P=C.filter(e=>r.has(e.value)),M=C.length>0&&P.length===C.length,V=P.length>0&&!M,_=u[A][T];return l("div",{className:c("flex min-w-0 flex-col overflow-hidden",d[j],b[T]),style:f(z,0),children:[l("div",{className:c("flex items-center gap-2 border-b [border-color:var(--plass-divider)]",_,p[T]),children:[e(s,{size:T,color:z,checked:M,indeterminate:V,disabled:x||0===C.length,"aria-label":L,onCheckedChange:e=>o(!0===e)}),e("span",{className:c("min-w-0 flex-1 truncate font-medium",m[T]),children:a}),l("span",{className:c("shrink-0 tabular-nums text-(--plass-muted-fg)",m[T]),children:[P.length,"/",t.length]})]}),y?e("div",{className:c(_,p[T]),children:e(i,{size:T,color:z,density:A,fullWidth:!0,variant:"ghost",disabled:x,placeholder:S,"aria-label":S,value:h,onChange:e=>v(e.target.value)})}):null,e("div",{className:"min-h-0 flex-1 overflow-y-auto overscroll-contain",style:void 0===k?void 0:{height:k},children:e("div",{className:c("flex flex-col",_,p[T]),children:0===t.length?e("span",{className:c("text-(--plass-muted-fg)",m[T],g[T]),children:w}):t.map(l=>e(s,{size:T,color:z,className:g[T],label:l.label,checked:r.has(l.value),disabled:x||l.disabled,onCheckedChange:e=>n(l.value,!0===e)},l.value))})})]})}function narrow(e,l){const a=o(l);return""===a?e:e.filter(e=>"string"!=typeof e.label||o(e.label).includes(a))}export const PlTransfer=/* @__PURE__ */a.forwardRef(function PlTransfer({items:s,value:i,defaultValue:o,onValueChange:d,sourceLabel:m="Available",targetLabel:u="Selected",searchable:b=!1,searchLabel:f="Search",emptyLabel:p="Nothing here",selectAllLabel:g="Select all",toTargetLabel:y="Move to selected",toSourceLabel:x="Move to available",height:k=220,disabled:w=!1,variant:S="glass",size:L,color:N,density:j,className:T,...z},A){const C=t(),P=L??C.size??"md",M=N??C.color??"primary",V=j??C.density??"default",[_,B]=a.useState(o??[]),F=i??_,[I,R]=a.useState(()=>new Set),[W,q]=a.useState(""),[D,E]=a.useState(""),G=a.useMemo(()=>new Set(F),[F]),H=a.useMemo(()=>s.filter(e=>!G.has(e.value)),[s,G]),J=a.useMemo(()=>s.filter(e=>G.has(e.value)),[s,G]),tick=(e,l)=>{R(a=>{const t=new Set(a);return l?t.add(e):t.delete(e),t})},tickAll=(e,l)=>{R(a=>{const t=new Set(a);for(const a of e)a.disabled||(l?t.add(a.value):t.delete(a.value));return t})},move=(e,l)=>{const a=e.filter(e=>!e.disabled&&I.has(e.value));if(0===a.length)return;const t=new Set(a.map(e=>e.value)),r=l?s.filter(e=>G.has(e.value)||t.has(e.value)).map(e=>e.value):F.filter(e=>!t.has(e));R(e=>new Set([...e].filter(e=>!t.has(e)))),(e=>{void 0===i&&B(e),d?.(e)})(r)},K=narrow(H,W),O=narrow(J,D),Q=K.some(e=>!e.disabled&&I.has(e.value)),U=O.some(e=>!e.disabled&&I.has(e.value)),X=v(k),Y={variant:S,size:P,color:M,density:V},Z="ghost"===S?"ghost":"glass";return l("div",{ref:A,className:c("grid w-full items-center gap-3","[grid-template-columns:minmax(0,1fr)_auto_minmax(0,1fr)]",T),...z,children:[e(Panel,{title:h(m)?m:"Available",rows:K,ticked:I,onTick:tick,onTickAll:e=>tickAll(K,e),search:W,onSearch:q,searchable:b,disabled:w,height:X,emptyLabel:p,searchLabel:f,selectAllLabel:g,style:Y}),l("div",{className:"flex flex-col gap-2",children:[e(r,{size:P,color:M,variant:Z,label:y,disabled:w||!Q,onClick:()=>move(K,!0),icon:e(n,{})}),e(r,{size:P,color:M,variant:Z,label:x,disabled:w||!U,onClick:()=>move(O,!1),icon:e("span",{className:"flex rotate-180",children:e(n,{})})})]}),e(Panel,{title:h(u)?u:"Selected",rows:O,ticked:I,onTick:tick,onTickAll:e=>tickAll(O,e),search:D,onSearch:E,searchable:b,disabled:w,height:X,emptyLabel:p,searchLabel:f,selectAllLabel:g,style:Y})]})});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PlassColor, PlassDensity, PlassSize } from '../../types.js';
|
|
3
|
+
/** One node. A branch is a node with `children`; a leaf is one without. */
|
|
4
|
+
export interface PlTreeNode {
|
|
5
|
+
/** What identifies it. Unique across the whole tree. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** What the row says. */
|
|
8
|
+
label: React.ReactNode;
|
|
9
|
+
/** A glyph before the label. */
|
|
10
|
+
icon?: React.ReactNode;
|
|
11
|
+
/** Its own children. An **empty array is a branch with nothing in it**, which
|
|
12
|
+
* is not the same as a leaf: the first opens and shows nothing, the second
|
|
13
|
+
* has no twisty at all. `undefined` is the leaf. */
|
|
14
|
+
children?: readonly PlTreeNode[];
|
|
15
|
+
/** In the tree but not selectable, and not a stop for the arrow keys. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** How many rows a click can leave selected. */
|
|
19
|
+
export type PlTreeSelection = 'none' | 'single' | 'multiple';
|
|
20
|
+
export interface PlTreeProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
|
21
|
+
/** The whole tree, as data. */
|
|
22
|
+
items: readonly PlTreeNode[];
|
|
23
|
+
/** The ids of the branches that are open. Use with `onExpandedChange` to control them. */
|
|
24
|
+
expanded?: readonly string[];
|
|
25
|
+
/** The branches that start open, for an uncontrolled tree. */
|
|
26
|
+
defaultExpanded?: readonly string[];
|
|
27
|
+
onExpandedChange?: (expanded: string[]) => void;
|
|
28
|
+
/** The ids of the selected rows. Use with `onSelectedChange` to control them. */
|
|
29
|
+
selected?: readonly string[];
|
|
30
|
+
/** What starts selected, for an uncontrolled tree. */
|
|
31
|
+
defaultSelected?: readonly string[];
|
|
32
|
+
onSelectedChange?: (selected: string[]) => void;
|
|
33
|
+
/**
|
|
34
|
+
* How many rows a click can leave selected.
|
|
35
|
+
*
|
|
36
|
+
* `single` by default. `none` makes the tree a browser rather than a
|
|
37
|
+
* chooser — every row still expands, and a click reports through
|
|
38
|
+
* `onItemClick` without anything staying lit.
|
|
39
|
+
* @default 'single'
|
|
40
|
+
*/
|
|
41
|
+
selection?: PlTreeSelection;
|
|
42
|
+
/** Called when a row is clicked, selectable or not. */
|
|
43
|
+
onItemClick?: (node: PlTreeNode) => void;
|
|
44
|
+
/** @default 'md' */
|
|
45
|
+
size?: PlassSize;
|
|
46
|
+
/** @default 'primary' */
|
|
47
|
+
color?: PlassColor;
|
|
48
|
+
/** @default 'default' */
|
|
49
|
+
density?: PlassDensity;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A hierarchy, opened one branch at a time.
|
|
53
|
+
*
|
|
54
|
+
* It takes its nodes as **data** rather than as children, which is the opposite
|
|
55
|
+
* of what most of this library does and is the right way round here for one
|
|
56
|
+
* reason: a tree is recursive, and recursion written in JSX is a component
|
|
57
|
+
* every caller has to write for themselves. `PlTable` takes its columns the
|
|
58
|
+
* same way and for the same reason.
|
|
59
|
+
*
|
|
60
|
+
* The keyboard is the ARIA tree pattern and it is most of what makes this a
|
|
61
|
+
* tree rather than a nested list: **one tab stop** for the whole thing, the up
|
|
62
|
+
* and down arrows walking the rows that are actually visible, and the left and
|
|
63
|
+
* right arrows opening a branch, stepping into it, and going back out to the
|
|
64
|
+
* parent. A tree where Tab walked four hundred rows would be one nobody reaches
|
|
65
|
+
* the end of.
|
|
66
|
+
*/
|
|
67
|
+
export declare const PlTree: React.ForwardRefExoticComponent<PlTreeProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as i}from"react/jsx-runtime";import*as t from"react";import{useDefaults as l}from"../../internal/defaults.js";import{ChevronIcon as n}from"../../internal/icons.js";import{controlTextLeadingClasses as d,cx as s,focusRingClasses as r,gapClasses as a,iconClasses as o,radiusClasses as c,surfaceSlots as m,transitionClasses as p}from"../../internal/styles.js";const f={xs:14,sm:16,md:20,lg:24,xl:28},u={default:{xs:"py-1",sm:"py-1",md:"py-1.5",lg:"py-2",xl:"py-2.5"},compact:{xs:"py-0.5",sm:"py-0.5",md:"py-1",lg:"py-1",xl:"py-1.5"}};function visibleRows(e,i,t=1,l=[]){for(const n of e)l.push({node:n,level:t}),n.children&&i.has(n.id)&&visibleRows(n.children,i,t+1,l);return l}export const PlTree=/* @__PURE__ */t.forwardRef(function PlTree({items:h,expanded:v,defaultExpanded:x,onExpandedChange:b,selected:y,defaultSelected:g,onSelectedChange:w,selection:k="single",onItemClick:D,size:S,color:j,density:I,className:N,style:E,...R},A){const C=l(),M=S??C.size??"md",z=j??C.color??"primary",F=I??C.density??"default",[P,T]=t.useState(x??[]),$=v??P,B=t.useMemo(()=>new Set($),[$]),[H,K]=t.useState(g??[]),L=y??H,U=t.useMemo(()=>new Set(L),[L]),q=t.useMemo(()=>visibleRows(h,B),[h,B]),[G,J]=t.useState(null),O=q.filter(e=>!e.node.disabled),Q=G&&O.some(e=>e.node.id===G)?G:O[0]?.node.id??null,toggle=(e,i)=>{var t;t=i??!B.has(e)?[...$.filter(i=>i!==e),e]:$.filter(i=>i!==e),void 0===v&&T(t),b?.(t)},select=e=>{if("none"===k)return;const i="multiple"===k?U.has(e.id)?L.filter(i=>i!==e.id):[...L,e.id]:[e.id];void 0===y&&K(i),w?.(i)},V=t.useId(),rowId=e=>`${V}-${e}`,focusRow=e=>{J(e),document.getElementById(rowId(e))?.focus()},renderRow=({node:l,level:m})=>{const h=void 0!==l.children,v=B.has(l.id),x=U.has(l.id);return i(t.Fragment,{children:[i("div",{id:rowId(l.id),role:"treeitem","aria-level":m,"aria-expanded":h?v:void 0,"aria-selected":"none"===k?void 0:x,"aria-disabled":l.disabled||void 0,tabIndex:l.disabled?void 0:Q===l.id?0:-1,onFocus:()=>J(l.id),onKeyDown:e=>{l.disabled||((e,i,t)=>{const l=O.findIndex(e=>e.node.id===i.id),n=void 0!==i.children,d=B.has(i.id);switch(e.key){case"ArrowDown":e.preventDefault(),O[l+1]&&focusRow(O[l+1].node.id);break;case"ArrowUp":e.preventDefault(),O[l-1]&&focusRow(O[l-1].node.id);break;case"ArrowRight":e.preventDefault(),n&&!d?toggle(i.id,!0):n&&O[l+1]&&focusRow(O[l+1].node.id);break;case"ArrowLeft":if(e.preventDefault(),n&&d){toggle(i.id,!1);break}for(let e=l-1;e>=0;e-=1)if(O[e].level<t){focusRow(O[e].node.id);break}break;case"Home":e.preventDefault(),O[0]&&focusRow(O[0].node.id);break;case"End":e.preventDefault(),O.length&&focusRow(O[O.length-1].node.id);break;case"Enter":case" ":e.preventDefault(),n&&toggle(i.id),select(i),D?.(i)}})(e,l,m)},onClick:()=>{l.disabled||(h&&toggle(l.id),select(l),D?.(l))},className:s("flex cursor-pointer items-center select-none",a[M],u[F][M],d[M],c[M],r,p,o,l.disabled?"cursor-not-allowed opacity-50":x?"bg-(--p-soft) text-(--p-accent) font-medium":"text-(--plass-fg) hover:bg-(--p-soft)"),style:{paddingInlineStart:(m-1)*f[M]+6+"px"},children:[e("span",{"aria-hidden":"true",className:s("flex shrink-0 items-center text-(--plass-muted-fg)",p,h?"":"invisible",v?"rotate-0":"-rotate-90 rtl:rotate-90"),children:e(n,{})}),l.icon?e("span",{className:"flex shrink-0 items-center",children:l.icon}):null,e("span",{className:"truncate",children:l.label})]}),h&&v&&l.children.length>0?e("div",{role:"group",children:l.children.map(e=>renderRow({node:e,level:m+1}))}):null]},l.id)};return e("div",{ref:A,role:"tree","aria-multiselectable":"multiple"===k||void 0,className:s("flex flex-col",N),style:{...m(z,0),...E},...R,children:h.map(e=>renderRow({node:e,level:1}))})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{PlTree}from"./PlTree.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
export interface PlVisuallyHiddenProps extends React.ComponentPropsWithoutRef<'span'> {
|
|
4
|
+
/**
|
|
5
|
+
* Brings the content back into the page while anything inside it has the
|
|
6
|
+
* focus, and clips it again as soon as the focus leaves.
|
|
7
|
+
*
|
|
8
|
+
* Off by default, because the ordinary use of this component is a name that
|
|
9
|
+
* is never meant to be seen. The exception is the one element that *must*
|
|
10
|
+
* appear when it is reached — a skip link — and there is no way for a caller
|
|
11
|
+
* to add it from the outside: the clip is `position: absolute`, so revealing
|
|
12
|
+
* it means putting the element back in the flow, which a `className` cannot
|
|
13
|
+
* do without also fighting the class it is trying to override.
|
|
14
|
+
*
|
|
15
|
+
* `:focus-within` rather than `:focus`, because the thing being tabbed to is
|
|
16
|
+
* almost always a link *inside* the box rather than the box itself — and
|
|
17
|
+
* `:focus-within` matches the element when it holds the focus too, so the
|
|
18
|
+
* narrower case is covered by the wider one.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
focusable?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Renders something other than a `<span>`: `render={<div />}`,
|
|
24
|
+
* `render={<h2 />}`. Base UI's own escape hatch.
|
|
25
|
+
*/
|
|
26
|
+
render?: useRender.RenderProp;
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Content for a screen reader and for nobody else.
|
|
31
|
+
*
|
|
32
|
+
* It is not a styling escape hatch and it is not `display: none`. The two
|
|
33
|
+
* obvious ways to hide something — `hidden` and `opacity: 0` — are both wrong
|
|
34
|
+
* in the same place: the first takes the text off the accessibility tree along
|
|
35
|
+
* with the screen, which is the one thing this component exists to avoid, and
|
|
36
|
+
* the second leaves a clickable ghost the size of the words. A one-pixel
|
|
37
|
+
* clipped box is the only form that is absent to a sighted reader and present
|
|
38
|
+
* to every other kind.
|
|
39
|
+
*
|
|
40
|
+
* What it is for is the sentence a control cannot say out loud — the word
|
|
41
|
+
* "Close" on a button that draws an ✕, the unit after a number, the change of
|
|
42
|
+
* context on a link that says "read more". The library already reaches for this
|
|
43
|
+
* inside a dozen components; this is the same rule, spelled once, for the
|
|
44
|
+
* caller's own markup.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PlVisuallyHidden: React.ForwardRefExoticComponent<PlVisuallyHiddenProps & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import*as i from"react";import{useRender as r}from"@base-ui/react/use-render";import{cx as s,srOnlyClasses as n}from"../../internal/styles.js";const o=/* @__PURE__ */["focus-within:static focus-within:size-auto","focus-within:overflow-visible focus-within:whitespace-normal","focus-within:[clip-path:none]"].join(" ");export const PlVisuallyHidden=/* @__PURE__ */i.forwardRef(function PlVisuallyHidden({focusable:i=!1,render:t,className:a,children:c,...l},f){return r({render:t??e("span",{}),ref:f,props:{className:s(n,i?o:"",a),children:c,...l}})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{PlVisuallyHidden}from"./PlVisuallyHidden.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { usePlBreakpoint, usePlBreakpointValue } from './usePlBreakpoint.js';
|
|
2
|
+
export { usePlColorScheme } from './usePlColorScheme.js';
|
|
3
|
+
export type { PlColorScheme, PlColorSchemeOptions, PlColorSchemeResult, PlResolvedColorScheme } from './usePlColorScheme.js';
|
|
4
|
+
export { usePlHotKeys } from './usePlHotKeys.js';
|
|
5
|
+
export type { PlHotKeysOptions, PlHotKeysTarget } from './usePlHotKeys.js';
|
|
6
|
+
export { usePlMediaQuery } from './usePlMediaQuery.js';
|
|
7
|
+
export { usePlReducedMotion } from './usePlReducedMotion.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{usePlBreakpoint,usePlBreakpointValue}from"./usePlBreakpoint.js";export{usePlColorScheme}from"./usePlColorScheme.js";export{usePlHotKeys}from"./usePlHotKeys.js";export{usePlMediaQuery}from"./usePlMediaQuery.js";export{usePlReducedMotion}from"./usePlReducedMotion.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { PlassBreakpoint, PlassResponsive } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Which rung of the breakpoint ladder the window is on.
|
|
4
|
+
*
|
|
5
|
+
* Four queries rather than one `innerWidth` read, and deliberately: a width
|
|
6
|
+
* measured in JavaScript is a number that has to be compared against a `rem`,
|
|
7
|
+
* and a `rem` is whatever the reader has set their font size to. `matchMedia`
|
|
8
|
+
* asks the same engine the stylesheet asks, so a component that switches at
|
|
9
|
+
* `md` here switches with the `md:` utilities beside it rather than a few
|
|
10
|
+
* pixels away from them.
|
|
11
|
+
*
|
|
12
|
+
* **`xs` is the server's answer**, and the first one a browser renders. See
|
|
13
|
+
* `usePlMediaQuery` for what follows from that.
|
|
14
|
+
*/
|
|
15
|
+
export declare function usePlBreakpoint(): PlassBreakpoint;
|
|
16
|
+
/**
|
|
17
|
+
* A `PlassResponsive` value, resolved for the width the window is at.
|
|
18
|
+
*
|
|
19
|
+
* The same shape and the same rule as `PlGrid`'s own props: a bare value
|
|
20
|
+
* applies everywhere, and a map applies each entry **from its own breakpoint
|
|
21
|
+
* up**, so `{ xs: 1, md: 3 }` is `1` on a phone and `3` from 48rem. An entry
|
|
22
|
+
* cascades to the rungs above it, which is what keeps a responsive value to the
|
|
23
|
+
* breakpoints it actually names.
|
|
24
|
+
*
|
|
25
|
+
* It exists because there is a class of decision CSS cannot make — how many
|
|
26
|
+
* items to fetch, which of two components to mount, how many characters to
|
|
27
|
+
* truncate at — and writing it out by hand means repeating the ladder in
|
|
28
|
+
* numbers a stylesheet will later disagree with.
|
|
29
|
+
*
|
|
30
|
+
* `undefined` when the map named no rung at or below the current one:
|
|
31
|
+
* `{ lg: 3 }` on a phone is not `3`, and guessing a value the caller did not
|
|
32
|
+
* write would be worse than saying so.
|
|
33
|
+
*
|
|
34
|
+
* An object is read as a **map**, exactly as it is in a responsive prop — so a
|
|
35
|
+
* value that is itself an object has to be wrapped in a map to be passed
|
|
36
|
+
* through: `{ xs: { … } }`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function usePlBreakpointValue<T>(value: PlassResponsive<T>): T | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{breakpointMap as e,breakpoints as t}from"../internal/grid.js";import{useMediaQuery as r}from"../internal/media.js";export function usePlBreakpoint(){const e=r("(width >= 40rem)"),t=r("(width >= 48rem)"),i=r("(width >= 64rem)");return r("(width >= 80rem)")?"xl":i?"lg":t?"md":e?"sm":"xs"}export function usePlBreakpointValue(r){const i=usePlBreakpoint(),n=e(r);for(let e=t.indexOf(i);e>=0;e-=1){const r=n[t[e]];if(void 0!==r)return r}}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type PlColorScheme, type PlResolvedColorScheme } from '../internal/color-scheme.js';
|
|
2
|
+
export type { PlColorScheme, PlResolvedColorScheme };
|
|
3
|
+
export interface PlColorSchemeOptions {
|
|
4
|
+
/**
|
|
5
|
+
* What to use when nothing has been stored.
|
|
6
|
+
*
|
|
7
|
+
* `system` — follow the platform — and it should stay `system`: a library
|
|
8
|
+
* that pinned a page to light on first visit would be overruling a preference
|
|
9
|
+
* the reader has already expressed to their operating system.
|
|
10
|
+
* @default 'system'
|
|
11
|
+
*/
|
|
12
|
+
defaultScheme?: PlColorScheme;
|
|
13
|
+
/**
|
|
14
|
+
* Where the choice is kept, in `localStorage`.
|
|
15
|
+
*
|
|
16
|
+
* Change it to scope the choice to one app on a shared origin. There is no
|
|
17
|
+
* way to turn storage off, because a toggle whose answer does not survive a
|
|
18
|
+
* reload is a toggle that looks broken.
|
|
19
|
+
* @default 'plass-color-scheme'
|
|
20
|
+
*/
|
|
21
|
+
storageKey?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PlColorSchemeResult {
|
|
24
|
+
/** What the reader chose. `system` is the absence of a choice. */
|
|
25
|
+
scheme: PlColorScheme;
|
|
26
|
+
/** What the page is painted in, once `system` has been resolved. */
|
|
27
|
+
resolved: PlResolvedColorScheme;
|
|
28
|
+
/** Chooses one. Written to `<html>` and to storage, and every other caller of this hook hears about it. */
|
|
29
|
+
setScheme: (next: PlColorScheme) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Light ⇄ dark, from whatever is currently *painted*.
|
|
32
|
+
*
|
|
33
|
+
* So the first press on a system-dark page gives light, which is what a
|
|
34
|
+
* reader pressing a toggle means. It leaves `system` behind, deliberately:
|
|
35
|
+
* they have now expressed a preference of their own.
|
|
36
|
+
*/
|
|
37
|
+
toggle: () => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The dark mode toggle, and what it takes to make one that does not flash.
|
|
41
|
+
*
|
|
42
|
+
* The library's tokens already answer to `.dark` / `[data-theme]` on any
|
|
43
|
+
* ancestor and to `prefers-color-scheme` when neither is there, so a page that
|
|
44
|
+
* only ever follows the platform needs nothing at all — this is for the app that
|
|
45
|
+
* offers a **choice**, which needs three things the CSS cannot do on its own:
|
|
46
|
+
* somewhere to keep it, something to write it onto `<html>`, and a way to paint
|
|
47
|
+
* it before the first frame.
|
|
48
|
+
*
|
|
49
|
+
* The third one is not this hook. React runs after the document has been
|
|
50
|
+
* parsed, so a scheme applied from an effect is applied one paint too late and
|
|
51
|
+
* the reader sees a white flash. [`PlColorSchemeScript`](./PlColorSchemeScript)
|
|
52
|
+
* is the answer to that and belongs in `<head>`.
|
|
53
|
+
*
|
|
54
|
+
* ```tsx
|
|
55
|
+
* const { resolved, toggle } = usePlColorScheme();
|
|
56
|
+
*
|
|
57
|
+
* <PlIconButton label="Switch theme" icon={resolved === 'dark' ? <Sun /> : <Moon />} onClick={toggle} />
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* **`storageKey` and `defaultScheme` are read once**, when the first component
|
|
61
|
+
* using that key mounts, and are ignored on every call after it. That is what
|
|
62
|
+
* makes two toggles on one page agree with each other — they share one store —
|
|
63
|
+
* and it means these two are decisions to make where the app is set up rather
|
|
64
|
+
* than props to compute. Changing them at runtime does nothing.
|
|
65
|
+
*/
|
|
66
|
+
export declare function usePlColorScheme(options?: PlColorSchemeOptions): PlColorSchemeResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import*as e from"react";import{DEFAULT_STORAGE_KEY as t,applyColorScheme as r,darkQuery as s,useColorSchemeStore as o}from"../internal/color-scheme.js";import{useMediaQuery as m}from"../internal/media.js";export function usePlColorScheme(c={}){const{defaultScheme:l="system",storageKey:a=t}=c,[i,n]=o(a,l),f=m(s),h="system"===i?f?"dark":"light":i;e.useEffect(()=>{r(i)},[i]);const u=e.useCallback(()=>{n("dark"===h?"light":"dark")},[h,n]);return{scheme:i,resolved:h,setScheme:n,toggle:u}}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PlassHotKeys } from '../types.js';
|
|
3
|
+
/** Anything a listener can be attached to, plus the ref a React caller holds. */
|
|
4
|
+
export type PlHotKeysTarget = Window | Document | HTMLElement | React.RefObject<HTMLElement | null> | null;
|
|
5
|
+
export interface PlHotKeysOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Whether the chords are bound at all. `false` removes the listener rather
|
|
8
|
+
* than making the handlers no-ops, so a shortcut that is off does not consume
|
|
9
|
+
* the key from whatever else wanted it.
|
|
10
|
+
* @default true
|
|
11
|
+
*/
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* What the listener is attached to.
|
|
15
|
+
*
|
|
16
|
+
* `window` is the default and is what a global shortcut means. A ref, an
|
|
17
|
+
* element or `document` scopes the binding to a region — but note that a
|
|
18
|
+
* `keydown` only reaches an element that contains the focus, so scoping to a
|
|
19
|
+
* panel nobody has tabbed into binds nothing.
|
|
20
|
+
* @default window
|
|
21
|
+
*/
|
|
22
|
+
target?: PlHotKeysTarget;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a chord is answered while the focus is in a text field.
|
|
25
|
+
*
|
|
26
|
+
* Off by default, and this is the decision the hook exists to get right: a
|
|
27
|
+
* global `/` that jumps to search must not eat the slash out of a URL
|
|
28
|
+
* somebody is typing into a form.
|
|
29
|
+
*
|
|
30
|
+
* It is narrower than it sounds, and only two kinds of chord are ever held
|
|
31
|
+
* back. A chord carrying **`Mod`, `Ctrl`, `Meta` or `Alt` is answered either
|
|
32
|
+
* way**, because none of those can appear in a field's value — so the
|
|
33
|
+
* ordinary `Mod+K` needs nothing set here. Shift does not count as one:
|
|
34
|
+
* `Shift+A` is how a capital A is typed. And a key that **does nothing in a
|
|
35
|
+
* field** is answered either way too: `Escape` is the one that matters, since
|
|
36
|
+
* a panel that closes on Escape has to close from inside its own form.
|
|
37
|
+
*
|
|
38
|
+
* What is left is exactly the case this is for: a printable character, or one
|
|
39
|
+
* of the keys that edits or moves through text, pressed while the focus is in
|
|
40
|
+
* a field. Turn it on for a chord that belongs to the field the reader is in.
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
whileTyping?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Binds keyboard chords outside any one control.
|
|
47
|
+
*
|
|
48
|
+
* The map is the same `PlassHotKeys` a field's `hotKeys` prop takes and the
|
|
49
|
+
* chords are spelled the way `PlHotKeys` draws them, which is the whole point:
|
|
50
|
+
* a shortcut that is **displayed** on a key cap and a shortcut that is **bound**
|
|
51
|
+
* are one string rather than two that drift. `Mod` is Command on a Mac and
|
|
52
|
+
* Control everywhere else.
|
|
53
|
+
*
|
|
54
|
+
* `PlCommandPalette` is the hook's first caller — it has bound its own opener
|
|
55
|
+
* this way since it existed, with a private copy of the matcher — and an
|
|
56
|
+
* application's own shortcuts are the reason it is public.
|
|
57
|
+
*
|
|
58
|
+
* Three rules it shares with the `hotKeys` prop:
|
|
59
|
+
*
|
|
60
|
+
* - **A modifier is checked in both directions.** `Enter` does not fire on
|
|
61
|
+
* `Shift+Enter`, and `Mod+K` does not fire on `Mod+Shift+K`.
|
|
62
|
+
* - **A chord that matches is consumed** — `preventDefault()`, so the browser's
|
|
63
|
+
* own `Mod+K` search bar does not also open. Read from the other end, an
|
|
64
|
+
* event that is **already** consumed is left alone: a field's own `hotKeys`
|
|
65
|
+
* map wins over a page's.
|
|
66
|
+
* - **These are chords rather than letters.** A single unmodified key is
|
|
67
|
+
* allowed and is sometimes right (`?` for help), but it is the case
|
|
68
|
+
* `whileTyping` is about.
|
|
69
|
+
*
|
|
70
|
+
* The handlers are read fresh on every keystroke, so an inline object literal
|
|
71
|
+
* costs nothing and a handler closing over current state is never stale. What
|
|
72
|
+
* rebinds the listener is the **set of chords** changing, not the map's
|
|
73
|
+
* identity.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* usePlHotKeys({
|
|
77
|
+
* 'Mod+K': () => setPaletteOpen(true),
|
|
78
|
+
* 'Mod+S': save
|
|
79
|
+
* });
|
|
80
|
+
*/
|
|
81
|
+
export declare function usePlHotKeys(hotKeys: PlassHotKeys | undefined, options?: PlHotKeysOptions): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import*as e from"react";import{editsText as n,hasHardModifier as t,isTypingTarget as r,matchesHotKey as o}from"../internal/keys.js";export function usePlHotKeys(i,u={}){const{enabled:s=!0,target:f,whileTyping:c=!1}=u,l=e.useRef(i);e.useEffect(()=>{l.current=i});const d=Object.keys(i??{}).join("\n");e.useEffect(()=>{const e=function resolve(e){return void 0===e?"undefined"==typeof window?null:window:null===e?null:"current"in e?e.current:e}(f);if(!s||!e||""===d)return;const i=d.split("\n"),onKeyDown=e=>{const u=e;if(!u.defaultPrevented)for(const e of i)if(o(u,e)){if(!c&&!t(e)&&n(u.key)&&r(u.target))return;return u.preventDefault(),void l.current?.[e]?.()}};return e.addEventListener("keydown",onKeyDown),()=>e.removeEventListener("keydown",onKeyDown)},[d,f,s,c])}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the window matches a CSS media query, as a boolean that re-renders
|
|
3
|
+
* when the answer changes.
|
|
4
|
+
*
|
|
5
|
+
* The library has always had this — it is how a `PlSidebar` knows it has become
|
|
6
|
+
* a drawer and how a `PlAnimate*` finds out that the reader asked for less
|
|
7
|
+
* motion — and it is public now because the alternative in application code is
|
|
8
|
+
* a `useState`, an effect and a listener that is nearly always subscribed one
|
|
9
|
+
* render too late.
|
|
10
|
+
*
|
|
11
|
+
* **The first answer in a browser is the server's answer.** There is no window
|
|
12
|
+
* to measure while the HTML is being generated, so this returns `false` on the
|
|
13
|
+
* server and through the hydrating render, and the real answer arrives in the
|
|
14
|
+
* render after that. Anything that has to be right in the *first* frame belongs
|
|
15
|
+
* in CSS — a Tailwind variant, or the `--plass-*` token that variant sets — and
|
|
16
|
+
* this hook is for the decisions CSS cannot make, like whether a component
|
|
17
|
+
* exists at all.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const coarse = usePlMediaQuery('(pointer: coarse)');
|
|
21
|
+
*/
|
|
22
|
+
export declare function usePlMediaQuery(query: string): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{useMediaQuery as e}from"../internal/media.js";export function usePlMediaQuery(r){return e(r)}
|