plass-ui 1.6.0 → 1.7.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.
Files changed (165) hide show
  1. package/CHANGELOG.md +276 -0
  2. package/README.md +3 -1
  3. package/dist/components/accordion/PlAccordion.d.ts +13 -0
  4. package/dist/components/accordion/PlAccordion.js +1 -1
  5. package/dist/components/accordion/index.d.ts +1 -1
  6. package/dist/components/alert/PlAlert.js +1 -1
  7. package/dist/components/animate-headline/PlAnimateHeadline.d.ts +10 -1
  8. package/dist/components/animate-marquee/PlAnimateMarquee.d.ts +8 -1
  9. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  10. package/dist/components/app-logo/PlAppLogo.js +1 -1
  11. package/dist/components/area-chart/PlAreaChart.d.ts +35 -6
  12. package/dist/components/area-chart/PlAreaChart.js +1 -1
  13. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  14. package/dist/components/avatar/PlAvatar.js +1 -1
  15. package/dist/components/back-top/PlBackTop.d.ts +5 -5
  16. package/dist/components/back-top/PlBackTop.js +1 -1
  17. package/dist/components/badge/PlBadge.js +1 -1
  18. package/dist/components/bar-chart/PlBarChart.d.ts +54 -2
  19. package/dist/components/bar-chart/PlBarChart.js +1 -1
  20. package/dist/components/blockquote/PlBlockquote.d.ts +2 -2
  21. package/dist/components/blockquote/PlBlockquote.js +1 -1
  22. package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -1
  23. package/dist/components/button/PlButton.d.ts +7 -0
  24. package/dist/components/button/PlButton.js +1 -1
  25. package/dist/components/calendar/PlCalendar.js +1 -1
  26. package/dist/components/card/PlCard.d.ts +7 -4
  27. package/dist/components/carousel/PlCarousel.d.ts +14 -4
  28. package/dist/components/carousel/PlCarousel.js +1 -1
  29. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  30. package/dist/components/checkbox/PlCheckbox.js +1 -1
  31. package/dist/components/chip/PlChip.d.ts +2 -1
  32. package/dist/components/chip/PlChip.js +1 -1
  33. package/dist/components/collapsible/PlCollapsible.d.ts +11 -0
  34. package/dist/components/collapsible/PlCollapsible.js +1 -1
  35. package/dist/components/color-picker/PlColorPicker.d.ts +3 -1
  36. package/dist/components/color-picker/PlColorPicker.js +1 -1
  37. package/dist/components/combobox/PlCombobox.d.ts +11 -5
  38. package/dist/components/combobox/PlCombobox.js +1 -1
  39. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  40. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  41. package/dist/components/data-table/PlDataTable.d.ts +13 -2
  42. package/dist/components/data-table/PlDataTable.js +1 -1
  43. package/dist/components/drawer/PlDrawer.js +1 -1
  44. package/dist/components/fieldset/PlFieldset.js +1 -1
  45. package/dist/components/file-picker/PlFilePicker.d.ts +3 -1
  46. package/dist/components/file-picker/PlFilePicker.js +1 -1
  47. package/dist/components/floating-action-button/PlFloatingActionButton.d.ts +5 -0
  48. package/dist/components/floating-action-button/PlFloatingActionButton.js +1 -1
  49. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  50. package/dist/components/footer/PlFooter.d.ts +3 -1
  51. package/dist/components/gallery/PlGallery.js +1 -1
  52. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  53. package/dist/components/header/PlHeader.d.ts +4 -2
  54. package/dist/components/header/PlHeader.js +1 -1
  55. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  56. package/dist/components/hover-card/PlHoverCard.js +1 -1
  57. package/dist/components/how-to-steps/PlHowToSteps.js +1 -1
  58. package/dist/components/image/PlImage.js +1 -1
  59. package/dist/components/line-chart/PlLineChart.d.ts +32 -6
  60. package/dist/components/line-chart/PlLineChart.js +1 -1
  61. package/dist/components/menu/PlMenu.js +1 -1
  62. package/dist/components/mockup/PlMockup.d.ts +5 -0
  63. package/dist/components/mockup/PlMockup.js +1 -1
  64. package/dist/components/modal/PlModal.js +1 -1
  65. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +4 -3
  66. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  67. package/dist/components/number-field/PlNumberField.d.ts +7 -5
  68. package/dist/components/number-field/PlNumberField.js +1 -1
  69. package/dist/components/otp-field/PlOtpField.js +1 -1
  70. package/dist/components/overlay/PlOverlay.js +1 -1
  71. package/dist/components/page-layout/PlPageLayout.d.ts +14 -3
  72. package/dist/components/page-layout/PlPageLayout.js +1 -1
  73. package/dist/components/pagination/PlPagination.js +1 -1
  74. package/dist/components/panes/PlPanes.js +1 -1
  75. package/dist/components/pie-chart/PlPieChart.d.ts +26 -1
  76. package/dist/components/pie-chart/PlPieChart.js +1 -1
  77. package/dist/components/pill/PlPill.js +1 -1
  78. package/dist/components/popconfirm/PlPopconfirm.d.ts +8 -1
  79. package/dist/components/popconfirm/PlPopconfirm.js +1 -1
  80. package/dist/components/popover/PlPopover.js +1 -1
  81. package/dist/components/progress-box/PlProgressBox.js +1 -1
  82. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  83. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  84. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  85. package/dist/components/rating/PlRating.js +1 -1
  86. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  87. package/dist/components/scroll-area/PlScrollArea.js +1 -1
  88. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  89. package/dist/components/select/PlSelect.d.ts +4 -1
  90. package/dist/components/select/PlSelect.js +1 -1
  91. package/dist/components/sidebar/PlSidebar.js +1 -1
  92. package/dist/components/slider/PlSlider.js +1 -1
  93. package/dist/components/sparkline/PlSparkline.js +1 -1
  94. package/dist/components/stepper/PlStepper.js +1 -1
  95. package/dist/components/switch/PlSwitch.js +1 -1
  96. package/dist/components/table/PlTable.d.ts +11 -1
  97. package/dist/components/table/PlTable.js +1 -1
  98. package/dist/components/tabs/PlTabs.d.ts +18 -1
  99. package/dist/components/tabs/PlTabs.js +1 -1
  100. package/dist/components/text-field/PlTextField.d.ts +6 -8
  101. package/dist/components/text-field/PlTextField.js +1 -1
  102. package/dist/components/text-link/PlTextLink.js +1 -1
  103. package/dist/components/timeline-chart/PlTimelineChart.js +1 -1
  104. package/dist/components/toast/PlToast.js +1 -1
  105. package/dist/components/toggle/PlToggle.js +1 -1
  106. package/dist/components/tooltip/PlTooltip.d.ts +4 -0
  107. package/dist/components/tooltip/PlTooltip.js +1 -1
  108. package/dist/components/tour/PlTour.js +1 -1
  109. package/dist/components/transfer/PlTransfer.d.ts +5 -2
  110. package/dist/components/transfer/PlTransfer.js +1 -1
  111. package/dist/components/tree/PlTree.js +1 -1
  112. package/dist/components/window-pane/PlWindowPane.d.ts +13 -3
  113. package/dist/components/window-pane/PlWindowPane.js +1 -1
  114. package/dist/internal/animate.js +1 -1
  115. package/dist/internal/bottom-bar.d.ts +29 -0
  116. package/dist/internal/bottom-bar.js +1 -0
  117. package/dist/internal/calendar.js +1 -1
  118. package/dist/internal/chart-frame.d.ts +88 -10
  119. package/dist/internal/chart-frame.js +1 -1
  120. package/dist/internal/chart-line.d.ts +11 -6
  121. package/dist/internal/chart-line.js +1 -1
  122. package/dist/internal/chart.d.ts +149 -1
  123. package/dist/internal/chart.js +1 -1
  124. package/dist/internal/defaults.d.ts +2 -2
  125. package/dist/internal/focusable.d.ts +10 -0
  126. package/dist/internal/focusable.js +1 -1
  127. package/dist/internal/form.d.ts +29 -0
  128. package/dist/internal/form.js +1 -1
  129. package/dist/internal/glow.d.ts +32 -1
  130. package/dist/internal/glow.js +1 -1
  131. package/dist/internal/icons.d.ts +24 -0
  132. package/dist/internal/icons.js +1 -1
  133. package/dist/internal/labels.d.ts +22 -0
  134. package/dist/internal/labels.js +1 -1
  135. package/dist/internal/loading.d.ts +13 -0
  136. package/dist/internal/loading.js +1 -0
  137. package/dist/internal/mockup.js +1 -1
  138. package/dist/internal/notch.d.ts +57 -3
  139. package/dist/internal/notch.js +1 -1
  140. package/dist/internal/picker.d.ts +8 -2
  141. package/dist/internal/picker.js +1 -1
  142. package/dist/internal/progress.d.ts +17 -6
  143. package/dist/internal/progress.js +1 -1
  144. package/dist/internal/sizer.d.ts +12 -11
  145. package/dist/internal/sizer.js +1 -1
  146. package/dist/internal/steps.d.ts +0 -15
  147. package/dist/internal/steps.js +1 -1
  148. package/dist/internal/styles.d.ts +114 -8
  149. package/dist/internal/styles.js +1 -1
  150. package/dist/internal/table-scroll.d.ts +42 -0
  151. package/dist/internal/table-scroll.js +1 -0
  152. package/dist/internal/table.js +1 -1
  153. package/dist/internal/text.d.ts +8 -5
  154. package/dist/internal/window.js +1 -1
  155. package/dist/locales/de.js +1 -1
  156. package/dist/locales/es.js +1 -1
  157. package/dist/locales/fr.js +1 -1
  158. package/dist/locales/ja.js +1 -1
  159. package/dist/locales/ko.js +1 -1
  160. package/dist/locales/zh-Hans.js +1 -1
  161. package/dist/styles.css +1 -1
  162. package/dist/tailwind.css +406 -42
  163. package/dist/tokens.css +406 -42
  164. package/dist/types.d.ts +217 -13
  165. package/package.json +1 -1
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import * as React from 'react';
16
16
  import type { CartesianContext } from './chart-frame.js';
17
- import type { PlassChartCurve, PlassChartValueLabels } from '../types.js';
17
+ import type { PlassChartCurve, PlassChartLabelColor, PlassChartNulls, PlassChartValueLabels } from '../types.js';
18
18
  /** Whether a point gets a dot on it. */
19
19
  export type ChartMarkers = 'none' | 'auto' | 'all';
20
20
  export interface LineSeriesProps {
@@ -26,12 +26,17 @@ export interface LineSeriesProps {
26
26
  stacked: boolean;
27
27
  markers: ChartMarkers;
28
28
  valueLabels: PlassChartValueLabels;
29
+ /** What colour those labels are written in. */
30
+ valueLabelColor: PlassChartLabelColor;
29
31
  /**
30
- * Bridges a gap instead of breaking at it. Off by default, and it should
31
- * stay off unless the caller knows the gap is an artefact of collection
32
- * rather than a month where nothing happened.
32
+ * What a gap does to the line.
33
+ *
34
+ * Only `connect` reaches this far. `gap` is what the path builder does when
35
+ * it is handed the `null`s, and `zero` was settled before the frame was ever
36
+ * given the data — see `zeroNulls`, which is why a zeroed gap moves the axis
37
+ * and fills the table row as well as the line.
33
38
  */
34
- connectNulls: boolean;
39
+ nulls: PlassChartNulls;
35
40
  /**
36
41
  * Fades the line from a paler step of its own hue at the old end to the full
37
42
  * colour at the new one. One hue throughout — a stroke that changes hue along
@@ -41,4 +46,4 @@ export interface LineSeriesProps {
41
46
  /** Unique per chart instance, so two charts' gradient defs cannot collide. */
42
47
  idPrefix: string;
43
48
  }
44
- export declare function LineSeries({ context, curve, filled, stacked, markers, valueLabels, connectNulls, gradient, idPrefix }: LineSeriesProps): React.JSX.Element;
49
+ export declare function LineSeries({ context, curve, filled, stacked, markers, valueLabels, valueLabelColor, nulls, gradient, idPrefix }: LineSeriesProps): React.JSX.Element;
@@ -1 +1 @@
1
- import{jsx as l,jsxs as e}from"react/jsx-runtime";import{areaPath as r,chartFontSizes as t,dimmedByHover as o,labelledPoints as a,linePath as n,lineDash as s,lineWidths as i,markerRadii as c,markGap as u}from"./chart.js";import{markTransitionClasses as f}from"./chart-frame.js";export function LineSeries({context:p,curve:d,filled:m,stacked:x,markers:h,valueLabels:k,connectNulls:v,gradient:$,idPrefix:y}){const{values:b,visible:g,colors:j,dashed:C,hovered:L,activeIndex:N,plot:W,point:z,zeroPx:B,size:E,format:G}=p,P=i[E],S=c[E],w=g.indexOf(!0),A=[],D=[];return b.forEach((l,e)=>{const r=l.map((l,e)=>D[e]??0);A.push(r),x&&g[e]&&l.forEach((l,e)=>{D[e]=(D[e]??0)+(l.value??0)})}),e("g",{children:[e("defs",{children:[$?j.map((r,t)=>e("linearGradient",{id:`${y}-stroke-${t}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 45%, transparent)`}),l("stop",{offset:"100%",stopColor:r})]},`stroke-${t}`)):null,m&&!x?j.map((r,t)=>e("linearGradient",{id:`${y}-fill-${t}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 28%, transparent)`}),l("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${r} 2%, transparent)`})]},`fill-${t}`)):null]}),b.map((i,c)=>{if(!g[c])return null;const p=j[c],b=o(L,c,g),D=i.map((l,e)=>{if(null===l.value)return null;const r=x?A[c][e]+l.value:l.value;return z(e,r)}),I=v?D.filter(Boolean):D,O=i.map((l,e)=>null===l.value?null:x?z(e,A[c][e]):{x:z(e,l.value).x,y:B}),q=m&&x,F=a(i,k);return e("g",{opacity:b?.28:1,className:f,children:[m?l("path",{d:r(I,v?O.filter(Boolean):O,d),fill:x?`color-mix(in oklab, ${p} 70%, transparent)`:`url(#${y}-fill-${c})`,stroke:"none"}):null,q&&c!==w?l("path",{d:n(v?O.filter(Boolean):O,d),fill:"none",stroke:"var(--plass-chart-gap)",strokeWidth:u}):null,q?null:l("path",{d:n(I,d),fill:"none",stroke:$?`url(#${y}-stroke-${c})`:p,strokeWidth:P,strokeDasharray:C[c]?s:void 0,strokeLinecap:"round",strokeLinejoin:"round"}),D.map((e,r)=>e&&("all"===h||"auto"===h&&i.length<=14||r===N)?l("circle",{cx:e.x,cy:e.y,r:r===N?S+1:S,fill:i[r].color??p,stroke:"var(--plass-chart-gap)",strokeWidth:u,className:f},r):null),"none"===k?null:D.map((e,r)=>{const o=i[r].value;return e&&null!==o&&F(r)?l("text",{x:e.x,y:e.y-S-5,textAnchor:e.x>W.left+W.width-24?"end":e.x<W.left+24?"start":"middle",fontSize:t[E],fontWeight:500,fill:"var(--plass-fg)",className:"tabular-nums",children:i[r].label??G(o)},`label-${r}`):null})]},c)})]})}
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{areaPath as l,chartFontSizes as a,dimmedByHover as o,labelledPoints as n,linePath as s,lineDash as i,lineWidths as c,markerRadii as u,markGap as m}from"./chart.js";import{markTransitionClasses as p}from"./chart-frame.js";import{usePrefersReducedMotion as d}from"./media.js";export function LineSeries({context:f,curve:h,filled:x,stacked:k,markers:y,valueLabels:g,valueLabelColor:v,nulls:$,gradient:b,idPrefix:S}){const{values:j,visible:w,colors:N,dashed:C,hovered:L,activeIndex:W,plot:z,point:B,zeroPx:E,size:G,format:M}=f,O=c[G],P=u[G],T=w.indexOf(!0),U=[],A=[];j.forEach((e,t)=>{const r=e.map((e,t)=>A[t]??0);U.push(r),k&&w[t]&&e.forEach((e,t)=>{A[t]=(A[t]??0)+(e.value??0)})});const D=d(),I=j.map((e,t)=>o(L,t,w)),[q,F]=r.useState(()=>new Set),[H,J]=r.useState(I);(I.length!==H.length||I.some((e,t)=>e!==H[t]))&&(J(I),F(e=>new Set(I.flatMap((t,r)=>t||D||!w[r]||!0!==H[r]&&!e.has(r)?[]:[r]))));const K=j.map((e,t)=>{if(!w[t])return null;const r=e.map((e,r)=>{if(null===e.value)return null;const l=k?U[t][r]+e.value:e.value;return B(r,l)}),l=r.flatMap((t,r)=>t&&("all"===y||"auto"===y&&e.length<=14||r===W)?[{...t,category:r,r:r===W?P+1:P}]:[]);return{color:N[t],dimmed:I[t],tops:r,marks:l,cut:(I[t]||q.has(t))&&l.length>0}});return t("g",{children:[t("defs",{children:[b?N.map((r,l)=>t("linearGradient",{id:`${S}-stroke-${l}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[e("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 45%, transparent)`}),e("stop",{offset:"100%",stopColor:r})]},`stroke-${l}`)):null,x&&!k?N.map((r,l)=>t("linearGradient",{id:`${S}-fill-${l}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[e("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 28%, transparent)`}),e("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${r} 2%, transparent)`})]},`fill-${l}`)):null,K.map((r,l)=>r?.cut?t("mask",{id:`${S}-cut-${l}`,maskUnits:"userSpaceOnUse",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[e("rect",{x:"-50%",y:"-50%",width:"200%",height:"200%",fill:"white"}),r.marks.map(t=>e("circle",{cx:t.x,cy:t.y,r:t.r+m/2,fill:"black",className:p},t.category))]},`cut-${l}`):null)]}),j.map((r,a)=>{const o=K[a];if(!o)return null;const{color:n,tops:c}=o,u="connect"===$,d=u?c.filter(Boolean):c,f=r.map((e,t)=>null===e.value?null:k?B(t,U[a][t]):{x:B(t,e.value).x,y:E}),y=x&&k;return t("g",{opacity:o.dimmed?.28:1,mask:o.cut?`url(#${S}-cut-${a})`:void 0,className:p,onTransitionEnd:q.has(a)?e=>{e.target===e.currentTarget&&"opacity"===e.propertyName&&F(e=>new Set([...e].filter(e=>e!==a)))}:void 0,children:[x?e("path",{d:l(d,u?f.filter(Boolean):f,h),fill:k?`color-mix(in oklab, ${n} 70%, transparent)`:`url(#${S}-fill-${a})`,stroke:"none"}):null,y&&a!==T?e("path",{d:s(u?f.filter(Boolean):f,h),fill:"none",stroke:"var(--plass-chart-gap)",strokeWidth:m}):null,y?null:e("path",{d:s(d,h),fill:"none",stroke:b?`url(#${S}-stroke-${a})`:n,strokeWidth:O,strokeDasharray:C[a]?i:void 0,strokeLinecap:"round",strokeLinejoin:"round"})]},a)}),K.map((t,r)=>t&&t.marks.length>0?e("g",{opacity:t.dimmed?.28:1,className:p,children:t.marks.map(l=>e("circle",{cx:l.x,cy:l.y,r:l.r,fill:j[r][l.category].color??t.color,stroke:"var(--plass-chart-gap)",strokeWidth:m,className:p},l.category))},r):null),"none"===g?null:K.map((t,r)=>{if(!t)return null;const l=j[r],o=n(l,g);return e("g",{opacity:t.dimmed?.28:1,className:p,children:t.tops.map((r,n)=>{const s=l[n].value;return r&&null!==s&&o(n)?e("text",{x:r.x,y:r.y-P-5,textAnchor:r.x>z.left+z.width-24?"end":r.x<z.left+24?"start":"middle",fontSize:a[G],fontWeight:600,fill:"ink"===v?"var(--plass-fg)":l[n].color??t.color,className:"tabular-nums",children:l[n].label??M(s)},n):null})},r)})]})}
@@ -16,7 +16,7 @@
16
16
  * makes.
17
17
  */
18
18
  import type * as React from 'react';
19
- import type { PlassChartCategory, PlassChartDatum, PlassChartSeries, PlassChartValueLabels, PlassDensity, PlassSize } from '../types.js';
19
+ import type { PlassChartCategory, PlassChartDatum, PlassChartSeries, PlassChartSort, PlassChartValueLabels, PlassDensity, PlassSize } from '../types.js';
20
20
  /**
21
21
  * How tall a plot is when nobody said, in pixels.
22
22
  *
@@ -130,6 +130,56 @@ export interface ChartValue {
130
130
  export declare function toValue(datum: PlassChartDatum): ChartValue;
131
131
  /** Every series unpacked, in the order it was given. */
132
132
  export declare function toValues(series: readonly PlassChartSeries[]): ChartValue[][];
133
+ /**
134
+ * The categories put in order of size, and the tail of them folded into one.
135
+ *
136
+ * Both are changes to the **data** rather than to the drawing, which is the
137
+ * same rule `zeroNulls` and `stackToFull` follow and for the same reason: the
138
+ * axis, the tooltip, the legend and the table under the chart all read the
139
+ * series they were given, so a category that has been folded away has to be
140
+ * folded away for all of them at once. A painter that reordered the bars would
141
+ * leave the axis naming the old order.
142
+ *
143
+ * ## What "size" means with more than one series
144
+ *
145
+ * The total across every series at that category, and every series' magnitude
146
+ * rather than its signed value — a category whose two series are +50 and −50 is
147
+ * a hundred units of chart, not nothing. `hidden` is not consulted: the order
148
+ * is a property of the data, and a chart whose columns rearranged themselves
149
+ * when a legend entry was clicked is one a reader cannot use.
150
+ *
151
+ * ## The tail
152
+ *
153
+ * `max` keeps the largest that many and sums the rest into one category, which
154
+ * is the answer to a chart of ninety countries: a bar too short to see is a bar
155
+ * that is costing width without saying anything, and eighty of them is a chart
156
+ * of nothing but noise. What is folded is decided by size and never by the
157
+ * order asked for, so `ascending` shows the small ones it kept rather than
158
+ * keeping the small ones. "Other" is always last, wherever the sort would
159
+ * otherwise have put it: it is not a category, it is what is left.
160
+ */
161
+ export declare function rankCategories(series: readonly PlassChartSeries[], categories: readonly PlassChartCategory[] | undefined, options: {
162
+ sort?: PlassChartSort;
163
+ max?: number;
164
+ other: string;
165
+ }): {
166
+ series: readonly PlassChartSeries[];
167
+ categories: readonly PlassChartCategory[] | undefined;
168
+ };
169
+ /**
170
+ * Every gap in every series read as a zero, for `nulls="zero"`.
171
+ *
172
+ * Done to the **data**, before the frame ever sees it, and that is the whole
173
+ * reason it is a function here rather than a branch in the painter. A zero is a
174
+ * value: it has to move the scale, appear in the tooltip, and be in the row a
175
+ * screen reader is handed. Substituted inside the drawing code it would be none
176
+ * of those — the line would touch a baseline the axis did not admit existed,
177
+ * and the table under it would still say the month was missing.
178
+ *
179
+ * A point that carried a label or a colour of its own keeps them, because it is
180
+ * the same point with a number read into it.
181
+ */
182
+ export declare function zeroNulls(series: readonly PlassChartSeries[]): PlassChartSeries[];
133
183
  /**
134
184
  * Which points of a series get a value label, decided once for the whole
135
185
  * series.
@@ -260,6 +310,43 @@ export declare function valueScale(extent: {
260
310
  /** Keeps zero in range. Off for a line chart told an explicit `min`. */
261
311
  includeZero?: boolean;
262
312
  }): ValueScale;
313
+ /**
314
+ * A value axis whose steps are **multiplications** rather than additions.
315
+ *
316
+ * The one scale in the library that changes what a distance on the plot means.
317
+ * On a linear axis the same length is the same number of units wherever it is;
318
+ * here it is the same *ratio* — the gap from 10 to 100 is the gap from 100 to
319
+ * 1,000 — which is the only way a series that runs from 3 to 3,000,000 can be
320
+ * drawn with the small end still legible. It is also the reason a log axis has
321
+ * to be labelled as one: a reader who takes it for linear reads every shape on
322
+ * it wrong, and nothing in the picture says which it is.
323
+ *
324
+ * ## Zero, and everything under it
325
+ *
326
+ * There is no such place. A logarithm has no value at zero and none at all
327
+ * below it, so an axis whose data reaches either cannot simply be stretched to
328
+ * hold them. What happens instead is stated rather than hidden: the axis floors
329
+ * at the smallest **positive** power of ten the data needs, or three decades
330
+ * under the top when the data offers no positive value to floor at, and a zero
331
+ * or a negative is drawn on that floor. It is on the baseline because that is
332
+ * where the axis ends, not because the chart worked out that it belongs there.
333
+ *
334
+ * ## The ticks
335
+ *
336
+ * Powers of ten, because those are the numbers a reader can multiply in their
337
+ * head. Over a short span — two decades or fewer, where whole decades would
338
+ * leave an axis with three labels on it — each decade also gets its 2 and its
339
+ * 5, which is the same 1-2-5 family `niceStep` picks from and for the same
340
+ * reason. Over a long one the decades are thinned by stride instead.
341
+ */
342
+ export declare function logScale(extent: {
343
+ min: number;
344
+ max: number;
345
+ } | null, options?: {
346
+ min?: number;
347
+ max?: number;
348
+ tickCount?: number;
349
+ }): ValueScale;
263
350
  /** The units a time axis is allowed to step in. */
264
351
  export type TimeUnit = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
265
352
  /** A value scale whose numbers are instants, and the unit its ticks step in. */
@@ -390,6 +477,67 @@ export declare function fitCategoryLabels(texts: string[], options: {
390
477
  fontSize: number;
391
478
  ticks: boolean;
392
479
  }): string[];
480
+ /**
481
+ * A caller's tick angle as the axis uses it: degrees, and never past a quarter
482
+ * turn either way.
483
+ *
484
+ * Past 90° a label is upside down, which is not a label. `-45` is the one to
485
+ * reach for — it reads at a glance, where a quarter turn has to be tilted the
486
+ * head for — and the sign is which way the text leans: negative runs it up
487
+ * towards the right, the way every chart that has ever done this draws it.
488
+ */
489
+ export declare function tickAngleOf(angle: number | 'auto' | undefined): number;
490
+ /**
491
+ * The angle `auto` settles on, which is a diagonal or nothing at all.
492
+ *
493
+ * The question it answers is the one a caller would otherwise answer by
494
+ * looking: *would any of these names be cut?* If none of them would, upright is
495
+ * the best an axis can do — it is the one angle that reads without the head
496
+ * moving — and turning them would be spending the plot's height on a problem
497
+ * the chart does not have. As soon as one name is wider than its slot, cutting
498
+ * is the alternative, and a diagonal beats a cut at every width.
499
+ *
500
+ * It is deliberately not a *continuous* answer. An angle worked out to fit the
501
+ * longest name exactly would be a different angle on every chart on a
502
+ * dashboard, and would change under the reader as a window is dragged; -45° is
503
+ * the one every chart that does this has settled on, and holding it still is
504
+ * worth more than the pixels a bespoke angle would save.
505
+ */
506
+ export declare function autoTickAngle(texts: readonly string[], options: {
507
+ slot: number;
508
+ fontSize: number;
509
+ }): number;
510
+ /** How deep a band of labels turned by `angle` is, away from the axis. */
511
+ export declare function tiltedDepth(widest: number, angle: number, fontSize: number): number;
512
+ /**
513
+ * And how far off its own tick it reaches, along the axis.
514
+ *
515
+ * What the two ends of the axis have to keep clear, so the first and the last
516
+ * name are not cut off at the edge of the drawing.
517
+ */
518
+ export declare function tiltedStep(width: number, angle: number, fontSize: number): number;
519
+ /**
520
+ * The least room two turned labels can sit in along the axis without touching.
521
+ *
522
+ * And **not** `tiltedStep`, which is the mistake this is here to avoid. Two
523
+ * labels turned by the same angle are parallel, so what has to clear between
524
+ * them is not their length but the distance *across* them — which is the step
525
+ * along the axis times the sine of the angle. Read the other way round, that is
526
+ * the step one line of text needs, and it is why a turned axis fits so many
527
+ * more labels than an upright one: at a quarter turn the answer is one line of
528
+ * text, whatever the names happen to say.
529
+ */
530
+ export declare function tiltedPitch(angle: number, fontSize: number): number;
531
+ /**
532
+ * How long a turned label may be before it is cut, given the depth the axis is
533
+ * willing to spend on its band.
534
+ *
535
+ * A turned label is not confined to its slot any more, so nothing else stops a
536
+ * forty-character name taking half the drawing. The depth is what is rationed,
537
+ * and this reads the length back out of it. The floor on the sine is what keeps
538
+ * a barely-turned label from being handed a budget of several thousand pixels.
539
+ */
540
+ export declare function tiltedRoom(depth: number, angle: number, fontSize: number): number;
393
541
  /** The plot's box inside the chart, once the axes have taken their bands. */
394
542
  export interface PlotBox {
395
543
  left: number;
@@ -1 +1 @@
1
- import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const lineDash="6 4";export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--plass-chart-1)","var(--plass-chart-2)","var(--plass-chart-3)","var(--plass-chart-4)","var(--plass-chart-5)","var(--plass-chart-6)","var(--plass-chart-7)","var(--plass-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--plass-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function dimmedByHover(t,e,n){return null!==t&&t!==e&&!0===n[t]}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function labelledPoints(t,e){if("none"===e)return()=>!1;if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let n=t.length-1;n>=0;n--)if(null!==t[n].value){e=n;break}return t=>t===e}let n=1/0,r=-1/0;for(const e of t)null!==e.value&&(n=Math.min(n,e.value),r=Math.max(r,e.value));return e=>{const o=t[e].value;return null!==o&&(o===n||o===r)}}export function stackToFull(t,e){const n=toValues(t),r=[];for(const t of n)t.forEach((t,e)=>{r[e]=(r[e]??0)+Math.abs(t.value??0)});return t.map((t,o)=>({...t,data:n[o].map((t,n)=>{if(null===t.value)return null;const o=r[n];return{x:t.x,y:0===o?0:t.value/o*100,color:t.color,label:t.label??e(t.value)}})}))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoriesAreDates(t,e){return(e?.some(t=>t instanceof Date)??!1)||t.some(t=>t.some(t=>t.x instanceof Date))}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function niceStep(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:r=!0}=e;let o=e.min??(t?t.min:0),a=e.max??(t?t.max:1);if(r&&void 0===e.min&&(o=Math.min(o,0)),r&&void 0===e.max&&(a=Math.max(a,0)),a===o){const t=Math.abs(a)>0?.5*Math.abs(a):1,n=void 0===e.min,r=void 0===e.max;!n&&r||(o-=t),!r&&n||(a+=t)}const i=void 0!==e.min&&void 0!==e.max?function dividingStep(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let r=niceStep(t/Math.max(1,e)),o=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<o&&(o=l,r=u)}return r}(a-o,n):niceStep((a-o)/Math.max(1,n)),u=void 0!==e.min?o:Math.floor(o/i)*i,s=void 0!==e.max?a:Math.ceil(a/i)*i,c=s-u||1,l=[];for(let t=u;t<=s+1e-9*i;t+=i)l.push(Number(t.toFixed(12)));return{min:u,max:s,ticks:l,fraction:t=>(t-u)/c}}const r=1e3,o=6e4,a=36e5,i=24*a,u=[{unit:"second",count:1,size:r},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:o},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:a},{unit:"hour",count:3,size:3*a},{unit:"hour",count:6,size:6*a},{unit:"hour",count:12,size:12*a},{unit:"day",count:1,size:i},{unit:"day",count:2,size:2*i},{unit:"week",count:1,size:7*i},{unit:"week",count:2,size:14*i},{unit:"month",count:1,size:30*i},{unit:"quarter",count:1,size:91*i},{unit:"month",count:6,size:182*i},{unit:"year",count:1,size:365*i}];function floorTime(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/o)*o:Math.floor(t/r)*r}function addTime(t,e,n){const a=new Date(t);if("year"===e)a.setFullYear(a.getFullYear()+n);else if("quarter"===e)a.setMonth(a.getMonth()+3*n);else if("month"===e)a.setMonth(a.getMonth()+n);else if("week"===e)a.setDate(a.getDate()+7*n);else if("day"===e)a.setDate(a.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?o:r);a.setHours(a.getHours()+n)}return a.getTime()}const s={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};export function timeScale(t,e={}){const{tickCount:n=6}=e;let r=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),o=e.max??t?.max??r+i;o<=r&&(r-=i/2,o+=i/2);const a=o-r;let c=u[0],l=1/0;for(const t of u){const e=Math.abs(a/t.size-n);e<l&&(l=e,c=t)}const h=c.unit,m="year"===h?Math.max(1,Math.round(niceStep(a/n/(365*i)))):c.count;let f=e.min??function alignTime(t,e,n){let r=floorTime(t,s[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=addTime(r,e,n);if(o>t)return r;r=o}return r}(r,h,m);const $=[];let x=f;for(let t=0;t<500&&($.push(x),!(x>o));t++)x=addTime(x,h,m);let p=e.max??$[$.length-1];p<=f&&(f-=i/2,p+=i/2);const M=p-f;return{min:f,max:p,ticks:$.filter(t=>t>=f&&t<=p),unit:h,step:m,fraction:t=>(t-f)/M}}function timeParts(t,e,n=!1){if("second"===t||"minute"===t||"hour"===t){const r="second"===t?{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}:{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if(!n)return r;const o={month:"short",day:"numeric",...r};return e?{...o,year:"numeric"}:o}if("year"===t)return{year:"numeric"};const r="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...r,year:"numeric"}:r}export function timeNeedsDate(t,e){return!("second"!==e&&"minute"!==e&&"hour"!==e||t.length<2||floorTime(t[0],"day")===floorTime(t[t.length-1]-1,"day"))}export function formatTimeValue(e,n,r,o=!1){return t(r,timeParts(n,!0,o)).format(new Date(e))}export function formatTimeTicks(e,n,r){const o=new Set(e.map(t=>new Date(t).getFullYear())).size>1,a=timeNeedsDate(e,n);return e.map((e,i)=>t(r,timeParts(n,o||0===i,a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function fitCategoryLabels(t,e){const{horizontal:n,slot:r,fontSize:o,ticks:a}=e;return a||!n&&r-6<2.4*o?t:t.map(t=>truncate(t,n?150:r-6,o))}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const flush=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function monotonePath(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?flush():r.push(e);return flush(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const flush=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(flush(e),o=e+1);return flush(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const arc=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${arc(i,-i)}H${t+n-i}${arc(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${arc(-i,i)}H${t+i}${arc(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${arc(i,i)}V${e+r-i}${arc(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${arc(-i,-i)}V${e+i}${arc(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const c={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*c[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t)return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`;const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function ringPath(t,e,n,r,o){const point=r=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(o-r)>=360){const t=r+180;return`M${point(r)}A${n} ${n} 0 1 1 ${point(t)}A${n} ${n} 0 1 1 ${point(r)}`}const a=Math.abs(o-r)>180?1:0;return`M${point(r)}A${n} ${n} 0 ${a} 1 ${point(o)}`}export function arcPath(t,e,n,r,o,a){const point=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}ZM${point(r,o)}A${r} ${r} 0 1 0 ${point(r,t)}A${r} ${r} 0 1 0 ${point(r,o)}Z`:`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}Z`}const i=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}Z`:`M${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}L${point(r,a)}A${r} ${r} 0 ${i} 0 ${point(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const worst=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},place=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||worst([...h,t])<=worst(h)||place(),h.push(t);return h.length>0&&place(),i}const l={month:"short",day:"numeric"},h={notation:"compact",maximumFractionDigits:1},m={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,l).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,h).format(t):e(n,m).format(t)}export function writeChartValue(t,n,r){return n?e(r,n).format(t):compactNumber(t,r)}
1
+ import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const lineDash="6 4";export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--plass-chart-1)","var(--plass-chart-2)","var(--plass-chart-3)","var(--plass-chart-4)","var(--plass-chart-5)","var(--plass-chart-6)","var(--plass-chart-7)","var(--plass-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--plass-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function dimmedByHover(t,e,n){return null!==t&&t!==e&&!0===n[t]}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function rankCategories(t,e,n){const{sort:o="none",max:r,other:a}=n,i=categoryCount(t),u=void 0!==r&&r>0&&i>r;if(!u&&("none"===o||0===i))return{series:t,categories:e};const s=toValues(t),size=t=>s.reduce((e,n)=>e+Math.abs(n[t]?.value??0),0),c=Array.from({length:i},(t,e)=>e),l=u?[...c].sort((t,e)=>size(e)-size(t)).slice(0,r).sort((t,e)=>t-e):c,h=u?c.filter(t=>!l.includes(t)):[],m="none"===o?l:[...l].sort((t,e)=>"ascending"===o?size(t)-size(e):size(e)-size(t));return{series:t.map((t,e)=>{const n=s[e],o=m.map(e=>t.data[e]??null);if(h.length>0){const t=h.filter(t=>null!==n[t]?.value),e=t.reduce((t,e)=>t+(n[e]?.value??0),0);o.push(0===t.length?{y:null,x:a}:{y:e,x:a})}return{...t,data:o}}),categories:e?[...m.map(t=>e[t]??t),...h.length>0?[a]:[]]:void 0}}export function zeroNulls(t){return t.map(t=>({...t,data:t.data.map(t=>null==t?0:"number"==typeof t?Number.isFinite(t)?t:0:null!==t.y&&void 0!==t.y&&Number.isFinite(t.y)?t:{...t,y:0})}))}export function labelledPoints(t,e){if("none"===e)return()=>!1;if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let n=t.length-1;n>=0;n--)if(null!==t[n].value){e=n;break}return t=>t===e}let n=1/0,o=-1/0;for(const e of t)null!==e.value&&(n=Math.min(n,e.value),o=Math.max(o,e.value));return e=>{const r=t[e].value;return null!==r&&(r===n||r===o)}}export function stackToFull(t,e){const n=toValues(t),o=[];for(const t of n)t.forEach((t,e)=>{o[e]=(o[e]??0)+Math.abs(t.value??0)});return t.map((t,r)=>({...t,data:n[r].map((t,n)=>{if(null===t.value)return null;const r=o[n];return{x:t.x,y:0===r?0:t.value/r*100,color:t.color,label:t.label??e(t.value)}})}))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoriesAreDates(t,e){return(e?.some(t=>t instanceof Date)??!1)||t.some(t=>t.some(t=>t.x instanceof Date))}export function categoryExtent(t,e){let n=1/0,o=-1/0,r=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(r=!0,n=Math.min(n,i),o=Math.max(o,i))})}),r?{min:n,max:o}:null}export function bubbleRadius(t,e,n,o){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(o,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:o}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,o=-1/0,r=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(r=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),o=Math.max(o,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(r=!0,n=Math.min(n,t),o=Math.max(o,t));return r?{min:n,max:o}:null}function niceStep(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:o=!0}=e;let r=e.min??(t?t.min:0),a=e.max??(t?t.max:1);if(o&&void 0===e.min&&(r=Math.min(r,0)),o&&void 0===e.max&&(a=Math.max(a,0)),a===r){const t=Math.abs(a)>0?.5*Math.abs(a):1,n=void 0===e.min,o=void 0===e.max;!n&&o||(r-=t),!o&&n||(a+=t)}const i=void 0!==e.min&&void 0!==e.max?function dividingStep(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let o=niceStep(t/Math.max(1,e)),r=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<r&&(r=l,o=u)}return o}(a-r,n):niceStep((a-r)/Math.max(1,n)),u=void 0!==e.min?r:Math.floor(r/i)*i,s=void 0!==e.max?a:Math.ceil(a/i)*i,c=s-u||1,l=[];for(let t=u;t<=s+1e-9*i;t+=i)l.push(Number(t.toFixed(12)));return{min:u,max:s,ticks:l,fraction:t=>(t-u)/c}}export function logScale(t,e={}){const{tickCount:n=5}=e,o=Math.max(e.max??(t?t.max:1),1e-12),r=e.min??(t?t.min:o/1e3),a=r>0?r:o/1e3,i=Math.floor(Math.log10(a)),u=Math.ceil(Math.log10(o)),s=10**i,c=10**Math.max(u,i+1),l=Math.log10(c)-Math.log10(s),h=[];if(l<=2){for(let t=i;t<=Math.log10(c)+1e-9;t+=1)for(const e of[1,2,5]){const n=e*10**t;n>=s-1e-12&&n<=c+1e-12&&h.push(Number(n.toPrecision(12)))}h[h.length-1]!==c&&h.push(c)}else{const t=Math.max(1,Math.round(l/Math.max(1,n-1)));for(let e=i;e<=Math.log10(c)+1e-9;e+=t)h.push(Number((10**e).toPrecision(12)));h[h.length-1]!==c&&h.push(c)}return{min:s,max:c,ticks:h,fraction:t=>(Math.log10(Math.min(c,Math.max(s,t)))-Math.log10(s))/(l||1)}}const o=1e3,r=6e4,a=36e5,i=24*a,u=[{unit:"second",count:1,size:o},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:r},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:a},{unit:"hour",count:3,size:3*a},{unit:"hour",count:6,size:6*a},{unit:"hour",count:12,size:12*a},{unit:"day",count:1,size:i},{unit:"day",count:2,size:2*i},{unit:"week",count:1,size:7*i},{unit:"week",count:2,size:14*i},{unit:"month",count:1,size:30*i},{unit:"quarter",count:1,size:91*i},{unit:"month",count:6,size:182*i},{unit:"year",count:1,size:365*i}];function floorTime(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/r)*r:Math.floor(t/o)*o}function addTime(t,e,n){const a=new Date(t);if("year"===e)a.setFullYear(a.getFullYear()+n);else if("quarter"===e)a.setMonth(a.getMonth()+3*n);else if("month"===e)a.setMonth(a.getMonth()+n);else if("week"===e)a.setDate(a.getDate()+7*n);else if("day"===e)a.setDate(a.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?r:o);a.setHours(a.getHours()+n)}return a.getTime()}const s={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};export function timeScale(t,e={}){const{tickCount:n=6}=e;let o=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),r=e.max??t?.max??o+i;r<=o&&(o-=i/2,r+=i/2);const a=r-o;let c=u[0],l=1/0;for(const t of u){const e=Math.abs(a/t.size-n);e<l&&(l=e,c=t)}const h=c.unit,m="year"===h?Math.max(1,Math.round(niceStep(a/n/(365*i)))):c.count;let f=e.min??function alignTime(t,e,n){let o=floorTime(t,s[e]);if("year"===e&&n>1){const t=new Date(o).getFullYear();o=new Date(t-(t%n+n)%n,0,1).getTime()}for(let r=0;r<500;r++){const r=addTime(o,e,n);if(r>t)return o;o=r}return o}(o,h,m);const x=[];let $=f;for(let t=0;t<500&&(x.push($),!($>r));t++)$=addTime($,h,m);let M=e.max??x[x.length-1];M<=f&&(f-=i/2,M+=i/2);const p=M-f;return{min:f,max:M,ticks:x.filter(t=>t>=f&&t<=M),unit:h,step:m,fraction:t=>(t-f)/p}}function timeParts(t,e,n=!1){if("second"===t||"minute"===t||"hour"===t){const o="second"===t?{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}:{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if(!n)return o;const r={month:"short",day:"numeric",...o};return e?{...r,year:"numeric"}:r}if("year"===t)return{year:"numeric"};const o="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...o,year:"numeric"}:o}export function timeNeedsDate(t,e){return!("second"!==e&&"minute"!==e&&"hour"!==e||t.length<2||floorTime(t[0],"day")===floorTime(t[t.length-1]-1,"day"))}export function formatTimeValue(e,n,o,r=!1){return t(o,timeParts(n,!0,r)).format(new Date(e))}export function formatTimeTicks(e,n,o){const r=new Set(e.map(t=>new Date(t).getFullYear())).size>1,a=timeNeedsDate(e,n);return e.map((e,i)=>t(o,timeParts(n,r||0===i,a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const o=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/o))}export function showsTick(t,e,n,o){return t%n===0||o&&t===e-1}export function fitsLast(t,e,n,o){const r=(t-1)%e;return r>0&&r*n>=o+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const o=e-textWidth("…",n);let r="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>o)break;a=t,r+=e}return r.length>0?`${r.trimEnd()}…`:"…"}export function fitCategoryLabels(t,e){const{horizontal:n,slot:o,fontSize:r,ticks:a}=e;return a||!n&&o-6<2.4*r?t:t.map(t=>truncate(t,n?150:o-6,r))}export function tickAngleOf(t){return void 0!==t&&"auto"!==t&&Number.isFinite(t)?Math.max(-90,Math.min(90,t)):0}export function autoTickAngle(t,e){const n=e.slot-6;return t.some(t=>textWidth(t,e.fontSize)>n)?-45:0}export function tiltedDepth(t,e,n){const o=Math.abs(e)*Math.PI/180;return Math.abs(Math.sin(o))*t+Math.abs(Math.cos(o))*n}export function tiltedStep(t,e,n){const o=Math.abs(e)*Math.PI/180;return Math.abs(Math.cos(o))*t+Math.abs(Math.sin(o))*n}export function tiltedPitch(t,e){const n=Math.abs(t)*Math.PI/180;return 1.35*e/Math.max(Math.abs(Math.sin(n)),.09)}export function tiltedRoom(t,e,n){const o=Math.abs(e)*Math.PI/180;return Math.max(3*n,(t-Math.abs(Math.cos(o))*n)/Math.max(Math.abs(Math.sin(o)),.09))}export function bandScale(t,e,n){const o=t>0?e/t:e;return{step:o,band:o*n,centre:t=>o*(t+.5)}}export function linePath(t,e){const n=[];let o=[];const flush=()=>{if(0!==o.length){if(1===o.length)n.push(`M${o[0].x} ${o[0].y}h0`);else if("step"===e){n.push(`M${o[0].x} ${o[0].y}`);for(let t=1;t<o.length;t++){const e=(o[t-1].x+o[t].x)/2;n.push(`H${e}V${o[t].y}H${o[t].x}`)}}else if("smooth"===e)n.push(`M${o[0].x} ${o[0].y}`),n.push(function monotonePath(t){const e=t.length,n=[];for(let o=0;o<e-1;o++){const e=t[o+1].x-t[o].x;n.push(0===e?0:(t[o+1].y-t[o].y)/e)}const o=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],r=n[t];o.push(e*r<=0?0:2*e*r/(e+r))}o.push(n[e-2]??0);const r=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;r.push(`C${t[n].x+e} ${t[n].y+o[n]*e} ${t[n+1].x-e} ${t[n+1].y-o[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return r.join("")}(o));else{n.push(`M${o[0].x} ${o[0].y}`);for(let t=1;t<o.length;t++)n.push(`L${o[t].x} ${o[t].y}`)}o=[]}};for(const e of t)null===e?flush():o.push(e);return flush(),n.join("")}export function areaPath(t,e,n){const o=[];let r=0;const flush=a=>{const i=t.slice(r,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(r,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");o.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(flush(e),r=e+1);return flush(t.length),o.join("")}export function barPath(t,e,n,o,r,a){const i=Math.max(0,Math.min(r,n/2,o/2));if(0===i||n<=0||o<=0)return`M${t} ${e}h${n}v${o}h${-n}Z`;const arc=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+o}V${e+i}${arc(i,-i)}H${t+n-i}${arc(i,i)}V${e+o}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+o-i}${arc(-i,i)}H${t+i}${arc(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${arc(i,i)}V${e+o-i}${arc(-i,i)}H${t}Z`:`M${t+n} ${e+o}H${t+i}${arc(-i,-i)}V${e+i}${arc(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const c={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,o){const r=Math.max(0,o)*c[t];if(0===r)return"";if("circle"===t)return`M${e-r} ${n}a${r} ${r} 0 1 0 ${2*r} 0a${r} ${r} 0 1 0 ${2*-r} 0Z`;if("square"===t)return`M${e-r} ${n-r}h${2*r}v${2*r}h${2*-r}Z`;if("diamond"===t)return`M${e} ${n-r}L${e+r} ${n}L${e} ${n+r}L${e-r} ${n}Z`;if("triangle"===t)return`M${[0,120,240].map(t=>{const o=(t-90)*Math.PI/180;return`${e+r*Math.cos(o)} ${n+r*Math.sin(o)}`}).join("L")}Z`;const a=r/3;return`M${e-a} ${n-r}h${2*a}v${r-a}h${r-a}v${2*a}h${-(r-a)}v${r-a}h${2*-a}v${-(r-a)}h${-(r-a)}v${2*-a}h${r-a}Z`}export function ringPath(t,e,n,o,r){const point=o=>{const r=(o-90)*Math.PI/180;return`${t+n*Math.cos(r)} ${e+n*Math.sin(r)}`};if(Math.abs(r-o)>=360){const t=o+180;return`M${point(o)}A${n} ${n} 0 1 1 ${point(t)}A${n} ${n} 0 1 1 ${point(o)}`}const a=Math.abs(r-o)>180?1:0;return`M${point(o)}A${n} ${n} 0 ${a} 1 ${point(r)}`}export function arcPath(t,e,n,o,r,a){const point=(n,o)=>{const r=(o-90)*Math.PI/180;return`${t+n*Math.cos(r)} ${e+n*Math.sin(r)}`};if(Math.abs(a-r)>=360){const t=r+180;return o>0?`M${point(n,r)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,r)}ZM${point(o,r)}A${o} ${o} 0 1 0 ${point(o,t)}A${o} ${o} 0 1 0 ${point(o,r)}Z`:`M${point(n,r)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,r)}Z`}const i=Math.abs(a-r)>180?1:0;return o<=0?`M${t} ${e}L${point(n,r)}A${n} ${n} 0 ${i} 1 ${point(n,a)}Z`:`M${point(n,r)}A${n} ${n} 0 ${i} 1 ${point(n,a)}L${point(o,a)}A${o} ${o} 0 ${i} 0 ${point(o,r)}Z`}export const rampSteps=5;export function rampStep(t,e,n,o,r=0){if("diverging"===o){const o=Math.max(Math.abs(n-r),Math.abs(r-e));if(!(o>0))return 2;const a=(t-r)/o;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const o=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(o>0)||e<=0||n<=0)return[];const r=e*n/o,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*r})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const worst=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const o=t[0].area,r=t[t.length-1].area;return Math.max(e*e*o/(n*n),n*n/(e*e*r))},place=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,o=c>=l;let r=0;for(const t of h){const e=n>0?t.area/n:0;i.push(o?{index:t.index,x:u,y:s+r,width:n,height:e}:{index:t.index,x:u+r,y:s,width:e,height:n}),r+=e}o?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||worst([...h,t])<=worst(h)||place(),h.push(t);return h.length>0&&place(),i}const l={month:"short",day:"numeric"},h={notation:"compact",maximumFractionDigits:1},m={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,l).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,h).format(t):e(n,m).format(t)}export function writeChartValue(t,n,o){return n?e(o,n).format(t):compactNumber(t,o)}
@@ -41,8 +41,8 @@ export interface PlassDefaults {
41
41
  /** How tightly they pack their content. */
42
42
  density?: PlassDensity;
43
43
  /**
44
- * Where a labelled control puts its label — above the box, or in the box's
45
- * top edge.
44
+ * Where a labelled control puts its label — above the box, in the box's top
45
+ * edge, or inside the box until it is focused or filled.
46
46
  *
47
47
  * Here for the same reason `density` is: a product whose forms notch their
48
48
  * labels notches all of them, and the decision is the application's rather
@@ -6,3 +6,13 @@
6
6
  * it to the top of the document.
7
7
  */
8
8
  export declare function focusablesIn(root: ParentNode): HTMLElement[];
9
+ /**
10
+ * Whether a press on `target`, inside a field's `shell`, is one the browser
11
+ * should be left to answer: a press on the field's own `control`, where it
12
+ * places the caret or starts a selection, or on something in the shell that
13
+ * takes a press of its own, a button or a link in an adornment.
14
+ *
15
+ * Anything else in the shell, its padding or a drawn adornment, is part of the
16
+ * field, and a press there keeps the focus in the control.
17
+ */
18
+ export declare function ownsPress(target: EventTarget | null, shell: Element, control: Element | null): boolean;
@@ -1 +1 @@
1
- export function focusablesIn(e){return Array.from(e.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(e=>!e.closest("[inert]"))}
1
+ export function focusablesIn(t){return Array.from(t.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(t=>!t.closest("[inert]"))}export function ownsPress(t,e,n){if(!(t instanceof Element))return!0;if(null!==n&&n.contains(t))return!0;const o=t.closest('a[href], button, input, select, textarea, [tabindex], [role="button"]');return null!==o&&o!==e&&e.contains(o)}
@@ -24,6 +24,35 @@ export declare const FormReportContext: React.Context<FormReport | null>;
24
24
  * for as long as `enabled` holds. Outside a `PlForm` it does nothing.
25
25
  */
26
26
  export declare function useFormReport(name: string | undefined, read: () => unknown, enabled?: boolean): void;
27
+ /**
28
+ * Whether a `PlFieldset` around the caller is disabled, the nearest one or any
29
+ * further out.
30
+ *
31
+ * Base UI hands a disabled fieldset to every `Field` inside it through a
32
+ * context of its own, and the browser disables a native control inside a
33
+ * `<fieldset disabled>`. Neither reaches the look, which a shell draws from its
34
+ * own `disabled`, nor a control that is neither in a `Field` nor native, such
35
+ * as a slider's track or a segmented button's segments. `PlFieldset` hands the
36
+ * answer Base UI gives its fields down through this as well, and a control
37
+ * counts it in wherever it reads its own `disabled`.
38
+ */
39
+ export declare const FieldsetDisabledContext: React.Context<boolean>;
40
+ /**
41
+ * Whether a surface around the caller is already drawn at a disabled control's
42
+ * fade, the half opacity and the drained colour of `disabledClasses`.
43
+ *
44
+ * A control disabled together with that surface draws the look of a disabled
45
+ * control without the fade, which would draw it at a quarter. A disabled
46
+ * `multiple` `PlCombobox` hands it to its chips, and a `PlChip` disabled
47
+ * anywhere else still fades on its own. The Flutter build hands the same answer
48
+ * down through `PlassFadedScope`.
49
+ */
50
+ export declare const FadedContext: React.Context<boolean>;
51
+ /**
52
+ * A control's `disabled`, with a disabled `PlFieldset` around it counted in, so
53
+ * a control in one draws itself exactly as it would with `disabled` of its own.
54
+ */
55
+ export declare function useDisabled(disabled: boolean | undefined): boolean;
27
56
  /**
28
57
  * Whether `element` is inside a disabled `<fieldset>`, re-rendering when a
29
58
  * fieldset around it turns `disabled` on or off.
@@ -1 +1 @@
1
- import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{Field as o}from"@base-ui/react/field";export const FormReportContext=/* @__PURE__ */n.createContext(null);export function useFormReport(e,t,r=!0){const o=n.useContext(FormReportContext),s=n.useRef(t);n.useEffect(()=>{s.current=t}),n.useEffect(()=>{if(!o||!e||!r)return;const entry=()=>s.current();return o.set(e,entry),()=>{o.get(e)===entry&&o.delete(e)}},[o,e,r])}function fieldsetsAround(e){const t=[];for(let r=e.parentElement?.closest("fieldset");r;r=r.parentElement?.closest("fieldset"))t.push(r);return t}export function useFieldsetDisabled(e){const t=n.useCallback(t=>{if(!e)return()=>{};const r=new MutationObserver(t);return fieldsetsAround(e).forEach(e=>r.observe(e,{attributes:!0,attributeFilter:["disabled"]})),()=>r.disconnect()},[e]);return n.useSyncExternalStore(t,()=>null!==e&&fieldsetsAround(e).some(t=>t.disabled&&!t.querySelector(":scope > legend")?.contains(e)),()=>!1)}export function leaveFormControl(e){e?.dispatchEvent(new FocusEvent("focusout",{bubbles:!0}))}export const FormControl=/* @__PURE__ */n.forwardRef(function FormControl({name:n,value:s,required:u,disabled:i,standIn:a},l){const c=Array.isArray(s),d=c?s.length>0&&s.every(e=>""!==e):""!==s;return useFormReport(n,()=>[...s],c&&!i),r(t,{children:[e(o.Control,{ref:l,name:n,value:c?d?s.join("\n"):"":s,required:u,disabled:i,tabIndex:-1,"aria-hidden":"true",autoComplete:"off",className:"pointer-events-none absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onFocus:()=>a()?.focus(),render:c?t=>e("input",{...t,name:void 0}):void 0}),c&&n?s.map((t,r)=>e("input",{type:"hidden",name:n,value:t,disabled:i},r)):null]})});
1
+ import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import*as o from"react";import{Field as r}from"@base-ui/react/field";export const FormReportContext=/* @__PURE__ */o.createContext(null);export function useFormReport(e,t,n=!0){const r=o.useContext(FormReportContext),s=o.useRef(t);o.useEffect(()=>{s.current=t}),o.useEffect(()=>{if(!r||!e||!n)return;const entry=()=>s.current();return r.set(e,entry),()=>{r.get(e)===entry&&r.delete(e)}},[r,e,n])}export const FieldsetDisabledContext=/* @__PURE__ */o.createContext(!1);export const FadedContext=/* @__PURE__ */o.createContext(!1);export function useDisabled(e){return o.useContext(FieldsetDisabledContext)||!0===e}function fieldsetsAround(e){const t=[];for(let n=e.parentElement?.closest("fieldset");n;n=n.parentElement?.closest("fieldset"))t.push(n);return t}export function useFieldsetDisabled(e){const t=o.useCallback(t=>{if(!e)return()=>{};const n=new MutationObserver(t);return fieldsetsAround(e).forEach(e=>n.observe(e,{attributes:!0,attributeFilter:["disabled"]})),()=>n.disconnect()},[e]);return o.useSyncExternalStore(t,()=>null!==e&&fieldsetsAround(e).some(t=>t.disabled&&!t.querySelector(":scope > legend")?.contains(e)),()=>!1)}export function leaveFormControl(e){e?.dispatchEvent(new FocusEvent("focusout",{bubbles:!0}))}export const FormControl=/* @__PURE__ */o.forwardRef(function FormControl({name:o,value:s,required:i,disabled:u,standIn:a},l){const d=Array.isArray(s),c=d?s.length>0&&s.every(e=>""!==e):""!==s;return useFormReport(o,()=>[...s],d&&!u),n(t,{children:[e(r.Control,{ref:l,name:o,value:d?c?s.join("\n"):"":s,required:i,disabled:u,tabIndex:-1,"aria-hidden":"true",autoComplete:"off",className:"pointer-events-none absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onFocus:()=>a()?.focus(),render:d?t=>e("input",{...t,name:void 0}):void 0}),d&&o?s.map((t,n)=>e("input",{type:"hidden",name:o,value:t,disabled:u},n)):null]})});
@@ -1,4 +1,4 @@
1
- import type * as React from 'react';
1
+ import * as React from 'react';
2
2
  /**
3
3
  * Moves `.plass-glow`'s light to where the pointer is on the surface.
4
4
  *
@@ -30,3 +30,34 @@ export declare function followPointer(event: React.PointerEvent<HTMLElement>): v
30
30
  * light to move.
31
31
  */
32
32
  export declare function glowPointerMove<E extends HTMLElement>(lit: boolean, onPointerMove?: React.PointerEventHandler<E>): React.PointerEventHandler<E> | undefined;
33
+ /**
34
+ * What a field's shell needs to carry the light: the `pointermove` that moves
35
+ * it, and the attribute that puts it away while the field is being typed into.
36
+ *
37
+ * The second half is the part a key does not want. A pointer resting on a field
38
+ * has been parked — the hand is on the keyboard, the bloom has stopped following
39
+ * anything, and it is sitting under the sentence being written. It fades out on
40
+ * the first keystroke and comes back on the next real pointer move, so the light
41
+ * is only ever on while it is still saying something.
42
+ *
43
+ * `pointermove` is exactly the signal wanted: a mouse held still while its owner
44
+ * types never fires one, and the first nudge of the hand back onto it does. The
45
+ * flag is mirrored in a ref so the state is set once per change of it rather than
46
+ * once per frame of a gesture — the coordinates themselves are still written
47
+ * straight to the element and re-render nothing.
48
+ *
49
+ * The keys that do not count as typing are the ones a reader *leaves* on: `Tab`
50
+ * hands the field to the next control, `Escape` closes whatever is over it, and
51
+ * a modifier on its own is the first half of a chord. A light that goes out on a
52
+ * `Shift` which turns out to be the start of `Shift+Tab` is a light that
53
+ * flickered for no reason.
54
+ *
55
+ * Spread onto the same element `.plass-glow` is on, which is the shell and never
56
+ * the control inside it — the box the light is drawn in has to be the box the
57
+ * reader sees. A `keydown` in the control reaches the shell by bubbling.
58
+ */
59
+ export declare function useFieldLight(lit: boolean): {
60
+ 'data-quiet'?: '';
61
+ onPointerMove?: React.PointerEventHandler<HTMLElement>;
62
+ onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
63
+ };
@@ -1 +1 @@
1
- export function followPointer(t){const e=t.currentTarget;let o=t.nativeEvent.offsetX,n=t.nativeEvent.offsetY;if(t.target!==e){const r=e.getBoundingClientRect();o=t.clientX-r.left,n=t.clientY-r.top}e.style.setProperty("--p-mx",`${o}px`),e.style.setProperty("--p-my",`${n}px`)}export function glowPointerMove(t,e){return t?t=>{followPointer(t),e?.(t)}:e}
1
+ import*as t from"react";export function followPointer(t){const e=t.currentTarget;let o=t.nativeEvent.offsetX,n=t.nativeEvent.offsetY;if(t.target!==e){const r=e.getBoundingClientRect();o=t.clientX-r.left,n=t.clientY-r.top}e.style.setProperty("--p-mx",`${o}px`),e.style.setProperty("--p-my",`${n}px`)}export function glowPointerMove(t,e){return t?t=>{followPointer(t),e?.(t)}:e}const e=/* @__PURE__ */new Set(["Tab","Escape","Shift","Control","Alt","Meta","CapsLock"]);export function useFieldLight(o){const[n,r]=t.useState(!1),l=t.useRef(!1),i=t.useCallback(t=>{l.current!==t&&(l.current=t,r(t))},[]),a=t.useCallback(t=>{followPointer(t),i(!1)},[i]),s=t.useCallback(t=>{e.has(t.key)||i(!0)},[i]);return o?{"data-quiet":n?"":void 0,onPointerMove:a,onKeyDown:s}:{}}
@@ -6,6 +6,13 @@
6
6
  * and the reason that matters is not the duplication, it is that two copies
7
7
  * drift: a spinner in a PlButton and a spinner in a PlTextField have to be the same
8
8
  * object in motion, or a form that is saving looks like two things loading.
9
+ *
10
+ * Every one of them is `block`. An `<svg>` is inline by default and stands on
11
+ * the text baseline with the descender gap under it, so a glyph in a plain
12
+ * `<span>` — a swatch's tick, a sort arrow — would sit a pixel or three off the
13
+ * centre of whatever holds it. Inside a flex row it is blockified anyway;
14
+ * saying it on the glyph is what keeps it right in the places that are not
15
+ * one, without a page reset to do it for them.
9
16
  */
10
17
  import * as React from 'react';
11
18
  import type { PlassColor } from '../types.js';
@@ -65,6 +72,23 @@ export declare function PlusIcon(): React.ReactElement;
65
72
  * weight, and then a page has two kinds of "close" on it.
66
73
  */
67
74
  export declare function CloseIcon(): React.ReactElement;
75
+ /**
76
+ * The two faces of a button that starts and stops something moving on its own:
77
+ * a triangle for "play", two bars for "stop".
78
+ *
79
+ * Only `PlCarousel` draws them today. They are here rather than in its file
80
+ * because the next thing in the library that plays on its own has to be stopped
81
+ * with the same two marks, or a page has two kinds of "stop" on it.
82
+ *
83
+ * Neither is turned under RTL. They are the marks of a player rather than a
84
+ * direction on the page, and every media control a right-to-left reader has
85
+ * ever used points the triangle the same way.
86
+ *
87
+ * The triangle is filled and stroked with a round join, which is what takes the
88
+ * points off its corners without an arc in the path.
89
+ */
90
+ export declare function PlayIcon(): React.ReactElement;
91
+ export declare function PauseIcon(): React.ReactElement;
68
92
  /** The clock: something that has been started and has not finished. */
69
93
  export declare function ClockIcon(): React.ReactElement;
70
94
  /** The calendar: a page with a binding across the top. The pickers' glyph. */
@@ -1 +1 @@
1
- import{jsx as r,jsxs as e}from"react/jsx-runtime";export function Spinner(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"animate-spin",children:[r("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeOpacity:"0.25",strokeWidth:"2"}),r("path",{d:"M14.5 8A6.5 6.5 0 0 0 8 1.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}export function ChevronIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"m4.5 6.5 3.5 3.5 3.5-3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function ArrowRightIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M3 8h10m-3.5-3.5L13 8l-3.5 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function EllipsisIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("circle",{cx:"3.5",cy:"8",r:"1.15",fill:"currentColor"}),r("circle",{cx:"8",cy:"8",r:"1.15",fill:"currentColor"}),r("circle",{cx:"12.5",cy:"8",r:"1.15",fill:"currentColor"})]})}export function CheckIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"m3.5 8.5 3 3 6-6",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round"})})}export function CopyIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("rect",{x:"5.75",y:"5.75",width:"7.5",height:"7.5",rx:"1.75",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M10.25 3.6a1.85 1.85 0 0 0-1.5-.85h-4a2 2 0 0 0-2 2v4c0 .62.28 1.17.72 1.54",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function CodeIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M5.75 4.5 2.5 8l3.25 3.5m4.5-7L13.5 8l-3.25 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function MinusIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M3.5 8h9",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function PlusIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M8 3.5v9M3.5 8h9",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function CloseIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"m4.5 4.5 7 7m0-7-7 7",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function ClockIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M8 4.5V8l2.4 1.6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}export function CalendarIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("rect",{x:"2.25",y:"3.25",width:"11.5",height:"10.5",rx:"2",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M2.25 6.5h11.5",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M5.5 1.75v2.5M10.5 1.75v2.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function LinkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("path",{d:"M6.5 9.5a2.75 2.75 0 0 0 4 .25l1.75-1.75a2.75 2.75 0 0 0-3.9-3.9L7.75 5.2",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("path",{d:"M9.5 6.5a2.75 2.75 0 0 0-4-.25L3.75 8a2.75 2.75 0 0 0 3.9 3.9l.6-.6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function ExternalLinkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("path",{d:"M12.75 9.25v2.5a1.5 1.5 0 0 1-1.5 1.5h-7a1.5 1.5 0 0 1-1.5-1.5v-7a1.5 1.5 0 0 1 1.5-1.5h2.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("path",{d:"M9.5 2.75h3.75V6.5M7.25 8.75l5.75-5.75",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}function NoteIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M8 7.25v4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("circle",{cx:"8",cy:"4.9",r:"0.85",fill:"currentColor"})]})}export function DotIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:r("circle",{cx:"8",cy:"8",r:"3.25"})})}export function StarIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",children:r("path",{d:"m8 1.6 1.86 3.9 4.14.56-3.02 2.9.76 4.24L8 11.16 4.26 13.2l.76-4.24L2 6.06l4.14-.56z"})})}export function StarOutlineIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"m8 1.6 1.86 3.9 4.14.56-3.02 2.9.76 4.24L8 11.16 4.26 13.2l.76-4.24L2 6.06l4.14-.56z",stroke:"currentColor",strokeWidth:"1.3",strokeLinejoin:"round"})})}export function severityIcon(o){return"success"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"m5.25 8.25 1.9 1.9 3.6-3.9",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}):"warning"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("path",{d:"M7.13 2.6 1.9 11.7a1 1 0 0 0 .87 1.5h10.46a1 1 0 0 0 .87-1.5L8.87 2.6a1 1 0 0 0-1.74 0Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinejoin:"round"}),r("path",{d:"M8 6.1v3",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("circle",{cx:"8",cy:"11.2",r:"0.85",fill:"currentColor"})]}):"danger"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"m5.9 5.9 4.2 4.2m0-4.2-4.2 4.2",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}):r(NoteIcon,{})}
1
+ import{jsx as r,jsxs as e}from"react/jsx-runtime";export function Spinner(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block animate-spin",children:[r("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeOpacity:"0.25",strokeWidth:"2"}),r("path",{d:"M14.5 8A6.5 6.5 0 0 0 8 1.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}export function ChevronIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"m4.5 6.5 3.5 3.5 3.5-3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function ArrowRightIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"M3 8h10m-3.5-3.5L13 8l-3.5 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function EllipsisIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("circle",{cx:"3.5",cy:"8",r:"1.15",fill:"currentColor"}),r("circle",{cx:"8",cy:"8",r:"1.15",fill:"currentColor"}),r("circle",{cx:"12.5",cy:"8",r:"1.15",fill:"currentColor"})]})}export function CheckIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"m3.5 8.5 3 3 6-6",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round"})})}export function CopyIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("rect",{x:"5.75",y:"5.75",width:"7.5",height:"7.5",rx:"1.75",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M10.25 3.6a1.85 1.85 0 0 0-1.5-.85h-4a2 2 0 0 0-2 2v4c0 .62.28 1.17.72 1.54",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function CodeIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"M5.75 4.5 2.5 8l3.25 3.5m4.5-7L13.5 8l-3.25 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}export function MinusIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"M3.5 8h9",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function PlusIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"M8 3.5v9M3.5 8h9",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function CloseIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"m4.5 4.5 7 7m0-7-7 7",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}export function PlayIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M5.5 3.75v8.5L12.5 8Z",fill:"currentColor",stroke:"currentColor",strokeWidth:"1.75",strokeLinejoin:"round"})})}export function PauseIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:r("path",{d:"M5.75 4.25v7.5m4.5-7.5v7.5",stroke:"currentColor",strokeWidth:"2.25",strokeLinecap:"round"})})}export function ClockIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M8 4.5V8l2.4 1.6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}export function CalendarIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("rect",{x:"2.25",y:"3.25",width:"11.5",height:"10.5",rx:"2",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M2.25 6.5h11.5",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M5.5 1.75v2.5M10.5 1.75v2.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function LinkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("path",{d:"M6.5 9.5a2.75 2.75 0 0 0 4 .25l1.75-1.75a2.75 2.75 0 0 0-3.9-3.9L7.75 5.2",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("path",{d:"M9.5 6.5a2.75 2.75 0 0 0-4-.25L3.75 8a2.75 2.75 0 0 0 3.9 3.9l.6-.6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function ExternalLinkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("path",{d:"M12.75 9.25v2.5a1.5 1.5 0 0 1-1.5 1.5h-7a1.5 1.5 0 0 1-1.5-1.5v-7a1.5 1.5 0 0 1 1.5-1.5h2.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("path",{d:"M9.5 2.75h3.75V6.5M7.25 8.75l5.75-5.75",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}function NoteIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"M8 7.25v4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("circle",{cx:"8",cy:"4.9",r:"0.85",fill:"currentColor"})]})}export function DotIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",className:"block",children:r("circle",{cx:"8",cy:"8",r:"3.25"})})}export function StarIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",className:"block",children:r("path",{d:"m8 1.6 1.86 3.9 4.14.56-3.02 2.9.76 4.24L8 11.16 4.26 13.2l.76-4.24L2 6.06l4.14-.56z"})})}export function StarOutlineIcon(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:r("path",{d:"m8 1.6 1.86 3.9 4.14.56-3.02 2.9.76 4.24L8 11.16 4.26 13.2l.76-4.24L2 6.06l4.14-.56z",stroke:"currentColor",strokeWidth:"1.3",strokeLinejoin:"round"})})}export function severityIcon(o){return"success"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"m5.25 8.25 1.9 1.9 3.6-3.9",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}):"warning"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("path",{d:"M7.13 2.6 1.9 11.7a1 1 0 0 0 .87 1.5h10.46a1 1 0 0 0 .87-1.5L8.87 2.6a1 1 0 0 0-1.74 0Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinejoin:"round"}),r("path",{d:"M8 6.1v3",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),r("circle",{cx:"8",cy:"11.2",r:"0.85",fill:"currentColor"})]}):"danger"===o?e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"block",children:[r("circle",{cx:"8",cy:"8",r:"6.25",stroke:"currentColor",strokeWidth:"1.5"}),r("path",{d:"m5.9 5.9 4.2 4.2m0-4.2-4.2 4.2",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}):r(NoteIcon,{})}
@@ -40,6 +40,8 @@ export interface PlassLabels {
40
40
  empty: string;
41
41
  /** Marks a step, or anything else, that may be left out. */
42
42
  optional: string;
43
+ /** Why a control that has taken a press is not answering another one yet. */
44
+ loading: string;
43
45
  /** The trail's landmark, and the button that opens the steps it folded away. */
44
46
  breadcrumb: string;
45
47
  breadcrumbExpand: string;
@@ -47,6 +49,10 @@ export interface PlassLabels {
47
49
  carousel: string;
48
50
  carouselPrevious: string;
49
51
  carouselNext: string;
52
+ /** The button that starts a reel advancing on its own, and the same button
53
+ * once it is advancing, which stops it. */
54
+ carouselPlay: string;
55
+ carouselStop: string;
50
56
  /** What a slide is, said after its name: one slide's `aria-roledescription`.
51
57
  * The reel's own is `carousel`. */
52
58
  slide: string;
@@ -54,10 +60,24 @@ export interface PlassLabels {
54
60
  gallery: string;
55
61
  /** What a drawing of numbers is called when the caller has not named it. */
56
62
  chart: string;
63
+ /**
64
+ * The category a chart folds its smallest ones into. Not a name for any of
65
+ * them — it is what is left once the ones worth drawing have been drawn.
66
+ */
67
+ chartOther: string;
68
+ /**
69
+ * "And this many more": on a chart legend with more series than it shows, and
70
+ * under a command palette with more matches than it draws.
71
+ */
72
+ chartMore: (count: number) => string;
73
+ /** And the way back, once they are all showing. */
74
+ chartFewer: string;
57
75
  minimize: string;
58
76
  maximize: string;
59
77
  restore: string;
60
78
  resizeWindow: string;
79
+ /** The title bar of a window that can be dragged, as the keyboard reaches it. */
80
+ moveWindow: string;
61
81
  /** The palette's landmark and the placeholder in its field. */
62
82
  commandPalette: string;
63
83
  commandPalettePlaceholder: string;
@@ -160,6 +180,8 @@ export interface PlassLabels {
160
180
  addCustom: (query: string) => string;
161
181
  /** One slot of a code field, named by its place in the row. */
162
182
  otpSlot: (index: number, count: number) => string;
183
+ /** The tick over one of a transfer's lists, given the name of the list. */
184
+ transferSelectAll: (list: string) => string;
163
185
  /** What a transfer says once rows have moved, given how many and the list. */
164
186
  transferMoved: (count: number, list: string) => string;
165
187
  /**
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{useDefaults as a}from"./defaults.js";export const defaultLabels={close:"Close",cancel:"Cancel",confirm:"Confirm",acknowledge:"OK",clear:"Clear",done:"Done",skip:"Skip",search:"Search",selectAll:"Select all",selectRow:"Select row",remove:"Remove",dismiss:"Dismiss",open:"Open",previous:"Previous",next:"Next",reveal:"Reveal",hide:"Hide",increase:"Increase",decrease:"Decrease",preview:"Preview",empty:"Nothing here",optional:"Optional",breadcrumb:"Breadcrumb",breadcrumbExpand:"Show the hidden steps",carousel:"Carousel",carouselPrevious:"Previous slide",carouselNext:"Next slide",slide:"slide",commandPalette:"Command palette",commandPalettePlaceholder:"Search commands",gallery:"Gallery",chart:"Chart",minimize:"Minimize",maximize:"Maximize",restore:"Restore",resizeWindow:"Resize window",overlay:"Overlay",notifications:"Notifications",pagination:"Pagination",paginationPrevious:"Previous page",paginationNext:"Next page",paginationFirst:"First page",paginationLast:"Last page",rating:"Rating",sidebar:"Sidebar",sidebarOpen:"Open sidebar",sidebarClose:"Close sidebar",sidebarResize:"Resize sidebar",skipToContent:"Skip to content",backToTop:"Back to top",onThisPage:"On this page",typing:"Typing…",messageSending:"Sending",messageSent:"Sent",messageDelivered:"Delivered",messageRead:"Read",messageFailed:"Not delivered",spoilerWarning:"This may contain spoilers",filePickerTitle:"Drop files here, or click to browse",newTab:"(opens in a new tab)",transferAvailable:"Available",transferSelected:"Selected",transferToSelected:"Move to selected",transferToAvailable:"Move to available",copy:"Copy",copied:"Copied",copyFailed:"Could not copy",raw:"Raw",code:"Code",previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End",paginationPage:e=>`Page ${e}`,paginationStatus:(e,a)=>`Page ${e} of ${a}`,ratingValue:(e,a)=>`${e.toLocaleString("en")} out of ${a}`,ratingNone:"No rating",carouselSlide:(e,a)=>`Slide ${e} of ${a}`,galleryItem:(e,a)=>`${e} of ${a}`,removeItem:e=>`Remove ${e}`,addCustom:e=>`Add “${e}”`,otpSlot:(e,a)=>`Character ${e} of ${a}`,transferMoved:(e,a)=>`${e} ${1===e?"item":"items"} moved to ${a}`,filesRejectedType:e=>`${e} ${1===e?"file is":"files are"} not an accepted type`,filesRejectedSize:e=>`${e} ${1===e?"file is":"files are"} too large`,filesRejectedCount:e=>`${e} ${1===e?"file":"files"} did not fit`};export function useLabels(){const{labels:o}=a();return e.useMemo(()=>o?{...defaultLabels,...o}:defaultLabels,[o])}
1
+ "use client";import*as e from"react";import{useDefaults as a}from"./defaults.js";import{loadingLabel as o}from"./loading.js";export const defaultLabels={close:"Close",cancel:"Cancel",confirm:"Confirm",acknowledge:"OK",clear:"Clear",done:"Done",skip:"Skip",search:"Search",selectAll:"Select all",selectRow:"Select row",remove:"Remove",dismiss:"Dismiss",open:"Open",previous:"Previous",next:"Next",reveal:"Reveal",hide:"Hide",increase:"Increase",decrease:"Decrease",preview:"Preview",empty:"Nothing here",optional:"Optional",loading:o,breadcrumb:"Breadcrumb",breadcrumbExpand:"Show the hidden steps",carousel:"Carousel",carouselPrevious:"Previous slide",carouselNext:"Next slide",carouselPlay:"Start slide show",carouselStop:"Stop slide show",slide:"slide",commandPalette:"Command palette",commandPalettePlaceholder:"Search commands",gallery:"Gallery",chart:"Chart",chartOther:"Other",chartMore:e=>`${e} more`,chartFewer:"Show fewer",minimize:"Minimize",maximize:"Maximize",restore:"Restore",resizeWindow:"Resize window",moveWindow:"Move window",overlay:"Overlay",notifications:"Notifications",pagination:"Pagination",paginationPrevious:"Previous page",paginationNext:"Next page",paginationFirst:"First page",paginationLast:"Last page",rating:"Rating",sidebar:"Sidebar",sidebarOpen:"Open sidebar",sidebarClose:"Close sidebar",sidebarResize:"Resize sidebar",skipToContent:"Skip to content",backToTop:"Back to top",onThisPage:"On this page",typing:"Typing…",messageSending:"Sending",messageSent:"Sent",messageDelivered:"Delivered",messageRead:"Read",messageFailed:"Not delivered",spoilerWarning:"This may contain spoilers",filePickerTitle:"Drop files here, or click to browse",newTab:"(opens in a new tab)",transferAvailable:"Available",transferSelected:"Selected",transferToSelected:"Move to selected",transferToAvailable:"Move to available",copy:"Copy",copied:"Copied",copyFailed:"Could not copy",raw:"Raw",code:"Code",previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End",paginationPage:e=>`Page ${e}`,paginationStatus:(e,a)=>`Page ${e} of ${a}`,ratingValue:(e,a)=>`${e.toLocaleString("en")} out of ${a}`,ratingNone:"No rating",carouselSlide:(e,a)=>`Slide ${e} of ${a}`,galleryItem:(e,a)=>`${e} of ${a}`,removeItem:e=>`Remove ${e}`,addCustom:e=>`Add “${e}”`,otpSlot:(e,a)=>`Character ${e} of ${a}`,transferSelectAll:e=>`Select all in ${e}`,transferMoved:(e,a)=>`${e} ${1===e?"item":"items"} moved to ${a}`,filesRejectedType:e=>`${e} ${1===e?"file is":"files are"} not an accepted type`,filesRejectedSize:e=>`${e} ${1===e?"file is":"files are"} too large`,filesRejectedCount:e=>`${e} ${1===e?"file":"files"} did not fit`};export function useLabels(){const{labels:o}=a();return e.useMemo(()=>o?{...defaultLabels,...o}:defaultLabels,[o])}