plass-ui 1.0.0 → 1.0.2

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/README.md +165 -0
  2. package/dist/components/accordion/PlAccordion.js +1 -131
  3. package/dist/components/accordion/index.js +1 -1
  4. package/dist/components/alert/PlAlert.js +1 -109
  5. package/dist/components/alert/index.js +1 -1
  6. package/dist/components/animate-appear/PlAnimateAppear.js +1 -71
  7. package/dist/components/animate-appear/index.js +1 -1
  8. package/dist/components/animate-blink/PlAnimateBlink.js +1 -47
  9. package/dist/components/animate-blink/index.js +1 -1
  10. package/dist/components/animate-fade/PlAnimateFade.js +1 -48
  11. package/dist/components/animate-fade/index.js +1 -1
  12. package/dist/components/animate-grow/PlAnimateGrow.js +1 -49
  13. package/dist/components/animate-grow/index.js +1 -1
  14. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -120
  15. package/dist/components/animate-headline/index.js +1 -1
  16. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -65
  17. package/dist/components/animate-lighting/index.js +1 -1
  18. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -94
  19. package/dist/components/animate-marquee/index.js +1 -1
  20. package/dist/components/animate-rotate/PlAnimateRotate.js +1 -50
  21. package/dist/components/animate-rotate/index.js +1 -1
  22. package/dist/components/animate-slide/PlAnimateSlide.js +1 -49
  23. package/dist/components/animate-slide/index.js +1 -1
  24. package/dist/components/animate-typing/PlAnimateTyping.js +1 -177
  25. package/dist/components/animate-typing/index.js +1 -1
  26. package/dist/components/animate-zoom/PlAnimateZoom.js +1 -45
  27. package/dist/components/animate-zoom/index.js +1 -1
  28. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -58
  29. package/dist/components/aspect-ratio/index.js +1 -1
  30. package/dist/components/avatar/PlAvatar.js +1 -121
  31. package/dist/components/avatar/index.js +1 -1
  32. package/dist/components/badge/PlBadge.js +1 -168
  33. package/dist/components/badge/index.js +1 -1
  34. package/dist/components/blockquote/PlBlockquote.js +1 -112
  35. package/dist/components/blockquote/index.js +1 -1
  36. package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -141
  37. package/dist/components/bottom-navigation/index.js +1 -1
  38. package/dist/components/box/PlBox.js +1 -46
  39. package/dist/components/box/index.js +1 -1
  40. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -201
  41. package/dist/components/breadcrumb/index.js +1 -1
  42. package/dist/components/button/PlButton.js +1 -196
  43. package/dist/components/button/index.js +1 -1
  44. package/dist/components/button-group/PlButtonGroup.js +1 -64
  45. package/dist/components/button-group/index.js +1 -1
  46. package/dist/components/card/PlCard.js +1 -102
  47. package/dist/components/card/index.js +1 -1
  48. package/dist/components/carousel/PlCarousel.js +1 -177
  49. package/dist/components/carousel/index.js +1 -1
  50. package/dist/components/chat-bubble/PlChatBubble.js +1 -206
  51. package/dist/components/chat-bubble/index.js +1 -1
  52. package/dist/components/checkbox/PlCheckbox.js +1 -100
  53. package/dist/components/checkbox/index.js +1 -1
  54. package/dist/components/chip/PlChip.js +1 -144
  55. package/dist/components/chip/index.js +1 -1
  56. package/dist/components/collapsible/PlCollapsible.js +1 -65
  57. package/dist/components/collapsible/index.js +1 -1
  58. package/dist/components/combobox/PlCombobox.js +1 -199
  59. package/dist/components/combobox/index.js +1 -1
  60. package/dist/components/container/PlContainer.js +1 -47
  61. package/dist/components/container/index.js +1 -1
  62. package/dist/components/date-picker/PlDatePicker.js +1 -87
  63. package/dist/components/date-picker/index.js +1 -1
  64. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -152
  65. package/dist/components/date-range-picker/index.js +1 -1
  66. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -106
  67. package/dist/components/date-time-picker/index.js +1 -1
  68. package/dist/components/divider/PlDivider.js +1 -107
  69. package/dist/components/divider/index.js +1 -1
  70. package/dist/components/drawer/PlDrawer.js +1 -190
  71. package/dist/components/drawer/index.js +1 -1
  72. package/dist/components/file-picker/PlFilePicker.js +1 -274
  73. package/dist/components/file-picker/index.js +1 -1
  74. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -291
  75. package/dist/components/floating-bottom-navigation/index.js +1 -1
  76. package/dist/components/grid/PlGrid.js +1 -51
  77. package/dist/components/grid/PlGridItem.js +1 -34
  78. package/dist/components/grid/index.js +1 -2
  79. package/dist/components/highlight/PlHighlight.js +1 -185
  80. package/dist/components/highlight/index.js +1 -1
  81. package/dist/components/hot-keys/PlHotKeys.js +1 -294
  82. package/dist/components/hot-keys/index.js +1 -1
  83. package/dist/components/icon/PlIcon.js +1 -58
  84. package/dist/components/icon/index.js +1 -1
  85. package/dist/components/icon-button/PlIconButton.js +1 -37
  86. package/dist/components/icon-button/index.js +1 -1
  87. package/dist/components/list/PlList.js +1 -160
  88. package/dist/components/list/index.js +1 -1
  89. package/dist/components/menu/PlMenu.js +1 -209
  90. package/dist/components/menu/index.js +1 -1
  91. package/dist/components/modal/PlModal.js +1 -150
  92. package/dist/components/modal/index.js +1 -1
  93. package/dist/components/number-field/PlNumberField.js +1 -111
  94. package/dist/components/number-field/index.js +1 -1
  95. package/dist/components/otp-field/PlOtpField.js +1 -109
  96. package/dist/components/otp-field/index.js +1 -1
  97. package/dist/components/overlay/PlOverlay.js +1 -77
  98. package/dist/components/overlay/index.js +1 -1
  99. package/dist/components/pagination/PlPagination.js +1 -159
  100. package/dist/components/pagination/index.js +1 -1
  101. package/dist/components/panes/PlPanes.js +1 -324
  102. package/dist/components/panes/index.js +1 -1
  103. package/dist/components/pill/PlPill.js +1 -154
  104. package/dist/components/pill/index.js +1 -1
  105. package/dist/components/popover/PlPopover.js +1 -113
  106. package/dist/components/popover/index.js +1 -1
  107. package/dist/components/progress-box/PlProgressBox.js +1 -34
  108. package/dist/components/progress-box/index.js +1 -1
  109. package/dist/components/progress-circular/PlProgressCircular.js +1 -47
  110. package/dist/components/progress-circular/index.js +1 -1
  111. package/dist/components/progress-linear/PlProgressLinear.js +1 -40
  112. package/dist/components/progress-linear/index.js +1 -1
  113. package/dist/components/radio-group/PlRadioGroup.js +1 -99
  114. package/dist/components/radio-group/index.js +1 -1
  115. package/dist/components/rating/PlRating.js +1 -101
  116. package/dist/components/rating/index.js +1 -1
  117. package/dist/components/scroll-zone/PlScrollZone.js +1 -411
  118. package/dist/components/scroll-zone/index.js +1 -1
  119. package/dist/components/segmented-button/PlSegmentedButton.js +1 -206
  120. package/dist/components/segmented-button/index.js +1 -1
  121. package/dist/components/select/PlSelect.js +1 -115
  122. package/dist/components/select/index.js +1 -1
  123. package/dist/components/skeleton/PlSkeleton.js +1 -142
  124. package/dist/components/skeleton/index.js +1 -1
  125. package/dist/components/slider/PlSlider.js +1 -132
  126. package/dist/components/slider/index.js +1 -1
  127. package/dist/components/spoiler/PlSpoiler.js +1 -74
  128. package/dist/components/spoiler/index.js +1 -1
  129. package/dist/components/switch/PlSwitch.js +1 -131
  130. package/dist/components/switch/index.js +1 -1
  131. package/dist/components/table/PlTable.js +1 -210
  132. package/dist/components/table/index.js +1 -1
  133. package/dist/components/tabs/PlTabs.js +1 -182
  134. package/dist/components/tabs/index.js +1 -1
  135. package/dist/components/text-field/PlTextField.js +1 -126
  136. package/dist/components/text-field/index.js +1 -1
  137. package/dist/components/text-link/PlTextLink.js +1 -136
  138. package/dist/components/text-link/index.js +1 -1
  139. package/dist/components/time-picker/PlTimePicker.js +1 -97
  140. package/dist/components/time-picker/index.js +1 -1
  141. package/dist/components/timeline/PlTimeline.js +1 -207
  142. package/dist/components/timeline/index.js +1 -1
  143. package/dist/components/toast/PlToast.js +1 -174
  144. package/dist/components/toast/index.js +1 -1
  145. package/dist/components/toolbar/PlToolbar.js +1 -65
  146. package/dist/components/toolbar/index.js +1 -1
  147. package/dist/components/tooltip/PlTooltip.js +1 -117
  148. package/dist/components/tooltip/index.js +1 -1
  149. package/dist/components/typography/PlTypography.js +1 -143
  150. package/dist/components/typography/index.js +1 -1
  151. package/dist/index.js +1 -75
  152. package/dist/internal/animate.js +1 -318
  153. package/dist/internal/button-group.js +2 -19
  154. package/dist/internal/calendar.js +1 -501
  155. package/dist/internal/date.js +1 -353
  156. package/dist/internal/format.js +1 -41
  157. package/dist/internal/grid.js +1 -143
  158. package/dist/internal/icons.js +1 -138
  159. package/dist/internal/menu.js +1 -18
  160. package/dist/internal/picker.js +1 -139
  161. package/dist/internal/progress.js +1 -167
  162. package/dist/internal/sizer.js +1 -35
  163. package/dist/internal/styles.js +1 -636
  164. package/dist/types.js +0 -8
  165. package/package.json +5 -3
@@ -1,131 +1 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { Switch as BaseUISwitch } from '@base-ui/react/switch';
4
- import { Field } from '@base-ui/react/field';
5
- import { controlSlots, focusRingClasses, hasContent, metaTextClasses, tickRowTextClasses } from '../../internal/styles.js';
6
- /**
7
- * Track and thumb.
8
- *
9
- * The thumb is inset 2px on every side, so its diameter is the track's height
10
- * minus 4 and the `left` it travels to is `100% − 2px − diameter`. That is the
11
- * one number per step that has to be written out; everything else falls out of
12
- * `inset-y-0.5` and `aspect-square`.
13
- */
14
- const trackClasses = {
15
- xs: 'h-3.5 w-6',
16
- sm: 'h-4 w-7',
17
- md: 'h-5 w-9',
18
- lg: 'h-6 w-11',
19
- xl: 'h-7 w-13'
20
- };
21
- const thumbTravelClasses = {
22
- xs: 'data-[checked]:left-[calc(100%-0.75rem)]',
23
- sm: 'data-[checked]:left-[calc(100%-0.875rem)]',
24
- md: 'data-[checked]:left-[calc(100%-1.125rem)]',
25
- lg: 'data-[checked]:left-[calc(100%-1.375rem)]',
26
- xl: 'data-[checked]:left-[calc(100%-1.625rem)]'
27
- };
28
- /**
29
- * A pill, and one of the two places in the library that is right.
30
- *
31
- * Everywhere else the radius stops well short of 50%, because the flat run
32
- * along the top and bottom edge is what reads as a sheet with its corners cut
33
- * off. A switch is not a sheet — it is a track something runs along, and a
34
- * track with corners is a track the thumb would have to climb out of.
35
- */
36
- const trackBaseClasses = /* @__PURE__ */ [
37
- 'relative inline-flex shrink-0 rounded-full',
38
- '[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]',
39
- // `background-image` is in the list because the on state is the gradient, and
40
- // `left` deliberately is not: it belongs to the thumb, which is the one thing
41
- // in the library that actually moves.
42
- '[transition-property:background-color,background-image,box-shadow,filter]',
43
- '[transition-duration:var(--plass-duration)]',
44
- '[transition-timing-function:var(--plass-ease)]',
45
- focusRingClasses
46
- ].join(' ');
47
- /**
48
- * Off, the track is the **groove** — `--plass-track`, the one neutral ink in the
49
- * library whose job is to be seen from across a room. On, it is the family's
50
- * gradient.
51
- *
52
- * Off used to be the glass at its most opaque with `--plass-well` falling into
53
- * it, and it was wrong twice over. It was invisible: a 88%-white pill with a
54
- * white thumb in it, set on a near-white page, is a switch a reader cannot find
55
- * until they have already flipped it — and the off state is the one a settings
56
- * list is mostly made of. And where it *was* visible, in the dark, an inset
57
- * shadow under a thumb carrying a drop shadow of its own was a moulded rocker
58
- * in a bevelled slot, which is the one picture this design language exists to
59
- * not draw.
60
- *
61
- * So there is no well, no gloss and no edge either. A groove that is a *tone*
62
- * rather than a recess needs no hairline to say where it ends, and the hairline
63
- * it used to have was the second of two lines round the same object once the
64
- * focus ring arrived.
65
- *
66
- * Dropping the border also squares the thumb's travel. `inset-y-0.5` and
67
- * `left-0.5` are measured from the padding box; the `left` a checked thumb
68
- * travels to is measured from the track's *width*. With a 1px edge between
69
- * them the two disagreed, and every switch in the library sat 2px from its
70
- * track on the left and 4px from it on the right.
71
- */
72
- const restTrackClasses = /* @__PURE__ */ [
73
- 'cursor-pointer bg-(--plass-track)',
74
- 'hover:brightness-[0.97] dark:hover:brightness-110',
75
- 'data-[checked]:[background-image:var(--p-fill)]',
76
- 'data-[checked]:[box-shadow:var(--p-lift)] data-[checked]:hover:brightness-105'
77
- ].join(' ');
78
- const readOnlyTrackClasses = /* @__PURE__ */ [
79
- 'cursor-default bg-(--plass-track) saturate-[0.55]',
80
- 'data-[checked]:[background-image:var(--p-fill)]',
81
- 'data-[checked]:shadow-none'
82
- ].join(' ');
83
- const disabledTrackClasses = /* @__PURE__ */ [
84
- 'cursor-not-allowed bg-(--plass-track)',
85
- 'opacity-50 saturate-[0.35] shadow-none',
86
- 'data-[checked]:[background-image:var(--p-fill)]'
87
- ].join(' ');
88
- /**
89
- * The thumb is white in both themes — not `--plass-surface`, which is a near
90
- * navy in the dark and left the off state as a grey lozenge in a grey slot.
91
- *
92
- * It keeps a shadow, and it is the smallest one on the ladder rather than the
93
- * `--plass-shadow-1` it used to carry: the thumb is the one part of a switch
94
- * that genuinely is above the surface it moves along, so it casts something —
95
- * but a 14px disc under a 4px-blurred, 14px-wide shadow is a knob, not a light.
96
- */
97
- const thumbClasses = /* @__PURE__ */ [
98
- 'absolute inset-y-0.5 left-0.5 aspect-square rounded-full bg-white',
99
- '[box-shadow:0_1px_2px_rgb(20_40_90/0.25)]',
100
- '[transition:left_var(--plass-duration)_var(--plass-ease)]'
101
- ].join(' ');
102
- /**
103
- * An immediate on/off.
104
- *
105
- * The difference from a PlCheckbox is not visual, it is temporal: a checkbox is
106
- * a value that gets submitted with a form, a switch takes effect the moment it
107
- * moves. If there is a Save button underneath, it should have been a checkbox.
108
- */
109
- export const PlSwitch = /* @__PURE__ */ React.forwardRef(function PlSwitch({ size = 'md', color = 'primary', label, description, error, invalid, labelPlacement = 'end', disabled = false, readOnly = false, className, style, ...props }, ref) {
110
- const hasError = hasContent(error);
111
- const isInvalid = invalid ?? hasError;
112
- const family = isInvalid ? 'danger' : color;
113
- const track = (_jsx("span", { className: "flex h-[1lh] shrink-0 items-center", children: _jsx(BaseUISwitch.Root, { ref: ref, className: [
114
- trackBaseClasses,
115
- trackClasses[size],
116
- disabled ? disabledTrackClasses : readOnly ? readOnlyTrackClasses : restTrackClasses
117
- ].join(' '), disabled: disabled, readOnly: readOnly, ...props, children: _jsx(BaseUISwitch.Thumb, { className: `${thumbClasses} ${thumbTravelClasses[size]}` }) }) }));
118
- const text = label || description ? (_jsxs("span", { className: [
119
- 'flex min-w-0 flex-col gap-0.5',
120
- // With the label on the left it has to take the slack, or the switch
121
- // sits against the text instead of against the edge of the row.
122
- labelPlacement === 'start' ? 'flex-1' : ''
123
- ]
124
- .filter(Boolean)
125
- .join(' '), children: [label ? (_jsx(Field.Label, { className: disabled ? 'text-(--plass-muted-fg)' : 'cursor-pointer text-(--plass-fg)', children: label })) : null, description ? (_jsx(Field.Description, { className: `${metaTextClasses[size]} text-(--plass-muted-fg)`, children: description })) : null] })) : null;
126
- return (_jsxs(Field.Root, { disabled: disabled, invalid: isInvalid, className: ['inline-flex flex-col gap-1 align-top', className ?? '']
127
- .filter(Boolean)
128
- .join(' '),
129
- // `solid`, because an on track *is* the coloured thing.
130
- style: { ...controlSlots(family, 0, 'solid'), ...style }, children: [_jsx("div", { className: `flex items-start gap-2.5 ${tickRowTextClasses[size]}`, children: labelPlacement === 'start' ? (_jsxs(_Fragment, { children: [text, track] })) : (_jsxs(_Fragment, { children: [track, text] })) }), hasError ? (_jsx(Field.Error, { match: true, className: `${metaTextClasses[size]} text-(--p-accent)`, children: error })) : null] }));
131
- });
1
+ "use client";import{jsx as a,jsxs as e,Fragment as t}from"react/jsx-runtime";import*as l from"react";import{Switch as r}from"@base-ui/react/switch";import{Field as s}from"@base-ui/react/field";import{controlSlots as i,focusRingClasses as c,hasContent as n,metaTextClasses as o,tickRowTextClasses as d}from"../../internal/styles.js";const h={xs:"h-3.5 w-6",sm:"h-4 w-7",md:"h-5 w-9",lg:"h-6 w-11",xl:"h-7 w-13"},m={xs:"data-[checked]:left-[calc(100%-0.75rem)]",sm:"data-[checked]:left-[calc(100%-0.875rem)]",md:"data-[checked]:left-[calc(100%-1.125rem)]",lg:"data-[checked]:left-[calc(100%-1.375rem)]",xl:"data-[checked]:left-[calc(100%-1.625rem)]"},p=/* @__PURE__ */["relative inline-flex shrink-0 rounded-full","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","[transition-property:background-color,background-image,box-shadow,filter]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]",c].join(" "),f=/* @__PURE__ */["cursor-pointer bg-(--plass-track)","hover:brightness-[0.97] dark:hover:brightness-110","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:[box-shadow:var(--p-lift)] data-[checked]:hover:brightness-105"].join(" "),u=/* @__PURE__ */["cursor-default bg-(--plass-track) saturate-[0.55]","data-[checked]:[background-image:var(--p-fill)]","data-[checked]:shadow-none"].join(" "),g=/* @__PURE__ */["cursor-not-allowed bg-(--plass-track)","opacity-50 saturate-[0.35] shadow-none","data-[checked]:[background-image:var(--p-fill)]"].join(" "),b=/* @__PURE__ */["absolute inset-y-0.5 left-0.5 aspect-square rounded-full bg-white","[box-shadow:0_1px_2px_rgb(20_40_90/0.25)]","[transition:left_var(--plass-duration)_var(--plass-ease)]"].join(" ");export const PlSwitch=/* @__PURE__ */l.forwardRef(function PlSwitch({size:l="md",color:c="primary",label:x,description:k,error:w,invalid:v,labelPlacement:j="end",disabled:N=!1,readOnly:y=!1,className:_,style:$,...P},R){const S=n(w),B=v??S,O=B?"danger":c,q=a("span",{className:"flex h-[1lh] shrink-0 items-center",children:a(r.Root,{ref:R,className:[p,h[l],N?g:y?u:f].join(" "),disabled:N,readOnly:y,...P,children:a(r.Thumb,{className:`${b} ${m[l]}`})})}),z=x||k?e("span",{className:["flex min-w-0 flex-col gap-0.5","start"===j?"flex-1":""].filter(Boolean).join(" "),children:[x?a(s.Label,{className:N?"text-(--plass-muted-fg)":"cursor-pointer text-(--plass-fg)",children:x}):null,k?a(s.Description,{className:`${o[l]} text-(--plass-muted-fg)`,children:k}):null]}):null;return e(s.Root,{disabled:N,invalid:B,className:["inline-flex flex-col gap-1 align-top",_??""].filter(Boolean).join(" "),style:{...i(O,0,"solid"),...$},children:[a("div",{className:`flex items-start gap-2.5 ${d[l]}`,children:e(t,"start"===j?{children:[z,q]}:{children:[q,z]})}),S?a(s.Error,{match:!0,className:`${o[l]} text-(--p-accent)`,children:w}):null]})});
@@ -1 +1 @@
1
- export { PlSwitch } from './PlSwitch.js';
1
+ export{PlSwitch}from"./PlSwitch.js";
@@ -1,210 +1 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { controlTextLeadingClasses, focusRingInsetClasses, metaTextClasses, paddingXValues, radiusClasses, sheetRestClasses, surfaceSlots } from '../../internal/styles.js';
4
- /**
5
- * Row height, as vertical padding — and, like the horizontal track, a raw
6
- * length rather than a class. See the note on `paddingXValues`.
7
- */
8
- const cellPaddingYValues = {
9
- default: { xs: '0.375rem', sm: '0.5rem', md: '0.75rem', lg: '0.875rem', xl: '1rem' },
10
- compact: { xs: '0.125rem', sm: '0.25rem', md: '0.4375rem', lg: '0.5625rem', xl: '0.6875rem' }
11
- };
12
- /**
13
- * Everything a table is painted with is written inline, `<table>` included.
14
- *
15
- * This is the one component in the library that has to do that, and the reason
16
- * is the elements it renders. A PlButton owns its `<button>`; nobody else
17
- * styles it. `<table>`, `<th>` and `<td>` are different — VitePress's
18
- * `.vp-doc table`, Tailwind Typography's `.prose td` and every CSS framework in
19
- * existence style them by tag name, at two-class specificity that a one-class
20
- * Tailwind utility cannot outrank.
21
- *
22
- * Padding and alignment were already written inline for that reason. **The
23
- * borders, the display mode and the margins were not**, and that omission was
24
- * most of what a Plass table looked like on a documentation page: the host's
25
- * `td { border: 1px solid }` drew a full grid of cell rules the design never
26
- * asked for, its `table { display: block }` stopped `width: 100%` filling the
27
- * sheet, and its `table { margin: 20px 0 }` pushed the whole thing off the
28
- * top-left corner of the pane it is supposed to be flush inside. A grid of
29
- * boxed cells floating inside a rounded sheet is not a restrained table with a
30
- * problem — it is somebody else's table wearing this one's frame.
31
- *
32
- * So every cell states `border: 0` and then draws the one rule it actually
33
- * wants, and the `<table>` states the four properties a prose stylesheet is
34
- * known to take off it. It is verbose, and it is the only way the component
35
- * looks the same in a bare app and inside `.prose`.
36
- *
37
- * What is *not* inline is the row's own background, because it has a hover
38
- * state and inline styles have no `:hover`. It reads a `--p-row` slot instead,
39
- * which classes then set — a custom property is invisible to a host stylesheet,
40
- * so a one-class variant wins there without a fight.
41
- */
42
- const tableStyle = {
43
- display: 'table',
44
- width: '100%',
45
- margin: 0,
46
- borderCollapse: 'collapse',
47
- borderSpacing: 0
48
- };
49
- const rowClasses = /* @__PURE__ */ [
50
- '[--p-row:transparent]',
51
- '[transition:background-color_var(--plass-duration)_var(--plass-ease)]'
52
- ].join(' ');
53
- /**
54
- * What a row that answers a press needs beyond the pointer treatment.
55
- *
56
- * `tabIndex` is the whole point: a row whose only way in is `onClick` is a
57
- * control a keyboard cannot reach at all, and `cursor-pointer` advertises it as
58
- * one anyway. The ring is inset rather than offset, because the sheet clips at
59
- * its own rounded edge and an outline drawn outside the first or last row is an
60
- * outline with its top or bottom sliced off.
61
- *
62
- * The `role` is deliberately left alone. `role="button"` on a `<tr>` reads well
63
- * in isolation and takes the row semantics off it — which orphans every `<td>`
64
- * inside from the table they belong to, and costs a screen reader the column
65
- * headers, the row position and the count.
66
- */
67
- const clickableRowClasses = /* @__PURE__ */ [
68
- 'cursor-pointer [outline:none]',
69
- focusRingInsetClasses
70
- ].join(' ');
71
- /**
72
- * Two weights of rule, and the whole of the table's structure.
73
- *
74
- * `--plass-divider` scores one row off the next, the same ink a PlCard and a
75
- * PlList are scored with, so a table on a card and the card's own dividers are
76
- * one family of lines. The header sits on `--plass-border`, one step firmer,
77
- * because the break between the names of the columns and the data in them is
78
- * the one division a reader has to find without looking for it.
79
- *
80
- * Both are neutral inks rather than the `--plass-glass-line` this used to use.
81
- * That line is white, and a white rule between two rows of a white sheet is
82
- * not a rule — which is why the table had no visible structure of its own in
83
- * light mode, and why it looked like whatever grid the host page happened to
84
- * be drawing over it.
85
- *
86
- * They are on the *cells* rather than on the `<tr>`, which is where a rule can
87
- * be written inline and therefore where a host stylesheet cannot reach it.
88
- */
89
- const rowRule = '1px solid var(--plass-divider)';
90
- const headRule = '1px solid var(--plass-border)';
91
- /**
92
- * A grid of data on a sheet of glass.
93
- *
94
- * The sheet is the ordinary Plass container — `variant`, `size`, `color`,
95
- * `density` and `elevation` all mean what they mean everywhere else, and it is
96
- * never dyed. What the table adds is the part that is genuinely tabular: the
97
- * columns, the rows, and the fact that the two cannot drift apart.
98
- *
99
- * Not a `forwardRef`, because it is generic: a component wrapped in
100
- * `React.forwardRef` loses its type parameter, and `Row` is the whole point of
101
- * the API. `ref` is not offered rather than being offered with `Row` widened to
102
- * `any`.
103
- */
104
- export function PlTable({ variant = 'glass', size = 'md', color = 'primary', density = 'default', elevation = 0, columns, rows, getRowKey, caption, empty = 'No data', striped = false, hoverable = false, stickyHeader = false, maxHeight, onRowClick, className, style, ...props }) {
105
- const padX = paddingXValues[density][size];
106
- const padY = cellPaddingYValues[density][size];
107
- const clickable = Boolean(onRowClick);
108
- const lit = hoverable || clickable;
109
- const capped = maxHeight !== undefined;
110
- const captionId = React.useId();
111
- // `border: 0` first, then the one edge this cell actually draws. Written as
112
- // the longhand rather than a `border` shorthand carrying `0` so the rule and
113
- // the reset cannot be reordered into each other.
114
- const cellStyle = {
115
- padding: `${padY} ${padX}`,
116
- border: 0,
117
- background: 'none'
118
- };
119
- const headCellStyle = {
120
- ...cellStyle,
121
- // The rule under the column names, and the one place the table draws an
122
- // edge as a shadow rather than as a border. `border-collapse: collapse`
123
- // hands a cell's borders to the *table's* border grid, and that grid does
124
- // not travel with a `position: sticky` cell — so a pinned header keeps its
125
- // fill and leaves its underline behind at the top of the scroll. An inset
126
- // shadow belongs to the cell's own box and goes where the cell goes.
127
- ...(stickyHeader
128
- ? { boxShadow: `inset 0 -1px 0 var(--plass-border)` }
129
- : { borderBottom: headRule }),
130
- // No band behind the column names.
131
- //
132
- // The header used to be `--plass-glass-press`, one step up the glass ladder
133
- // — and one step up a ladder whose rungs are 62%, 76% and 88% white is, on
134
- // a light page, a white bar. A filled strip across the top of a grid is the
135
- // single fastest way to make data look like chrome, and it was doing that
136
- // while the rules between the rows underneath were invisible: all of the
137
- // table's weight in the one place that needed none of it. Muted, semibold
138
- // names over a firmer rule say "these are the columns" with nothing filled
139
- // in at all.
140
- //
141
- // A *pinned* header is the exception, and it is not decoration: rows pass
142
- // directly underneath it, and a translucent fill lets them through. Two
143
- // stacked opaque layers stop the light — the sheet's own densest glass over
144
- // the page's surface colour — which is the same trick a pinned first
145
- // column needs for the same reason.
146
- ...(stickyHeader
147
- ? {
148
- background: 'linear-gradient(var(--plass-glass-press), var(--plass-glass-press)),' +
149
- ' linear-gradient(var(--plass-surface), var(--plass-surface))'
150
- }
151
- : null)
152
- };
153
- /** The rule above a row — every row but the first, which has the header's. */
154
- const bodyCellStyle = (index) => index === 0 ? cellStyle : { ...cellStyle, borderTop: rowRule };
155
- return (_jsxs("div", { className: [
156
- // The sheet clips, and the box inside it scrolls. Two elements rather
157
- // than one because a `caption` has to stay out of what scrolls: a
158
- // pinned header over rows that pass under it is the point of
159
- // `stickyHeader`, and a title that slid away above it would take the
160
- // table's name off the screen with it.
161
- 'overflow-hidden',
162
- radiusClasses[size],
163
- sheetRestClasses[variant],
164
- className ?? ''
165
- ]
166
- .filter(Boolean)
167
- .join(' '), style: { ...surfaceSlots(color, elevation), ...style }, ...props, children: [caption ? (_jsx("div", { id: captionId, className: `${metaTextClasses[size]} font-semibold text-(--plass-muted-fg)`, style: { ...cellStyle, borderBottom: rowRule, textAlign: 'start' }, children: caption })) : null, _jsx("div", { className: [
168
- 'overflow-x-auto',
169
- // Only when there is a cap to scroll against. A box that is as tall
170
- // as its content has nothing to scroll, and `overscroll-contain` on
171
- // one of those would swallow the page's own scroll at its edges.
172
- capped ? 'overflow-y-auto overscroll-contain' : ''
173
- ]
174
- .filter(Boolean)
175
- .join(' '), style: capped ? { maxHeight } : undefined, children: _jsxs("table", { "aria-labelledby": caption ? captionId : undefined, className: `text-start ${controlTextLeadingClasses[size]} text-(--plass-fg)`, style: tableStyle, children: [_jsx("colgroup", { children: columns.map((column) => (_jsx("col", { style: column.width === undefined
176
- ? undefined
177
- : {
178
- width: typeof column.width === 'number' ? `${column.width}px` : column.width
179
- } }, column.key))) }), _jsx("thead", { children: _jsx("tr", { children: columns.map((column) => (_jsx("th", { scope: "col", className: [
180
- 'font-semibold whitespace-nowrap text-(--plass-muted-fg)',
181
- stickyHeader ? 'sticky top-0 z-10' : ''
182
- ]
183
- .filter(Boolean)
184
- .join(' '), style: { ...headCellStyle, textAlign: column.align ?? 'start' }, children: column.header ?? column.key }, column.key))) }) }), _jsx("tbody", { children: rows.length === 0 ? (_jsx("tr", { className: rowClasses, children: _jsx("td", { colSpan: columns.length, className: "text-(--plass-muted-fg)", style: { ...cellStyle, padding: `2rem ${padX}`, textAlign: 'center' }, children: empty }) })) : (rows.map((row, index) => (_jsx("tr", { className: [
185
- rowClasses,
186
- striped && index % 2 === 1 ? '[--p-row:var(--plass-stripe)]' : '',
187
- lit ? 'hover:[--p-row:var(--p-soft)]' : '',
188
- clickable ? clickableRowClasses : ''
189
- ]
190
- .filter(Boolean)
191
- .join(' '), style: { backgroundColor: 'var(--p-row)' }, tabIndex: clickable ? 0 : undefined, onClick: onRowClick ? () => onRowClick(row, index) : undefined, onKeyDown: onRowClick
192
- ? (event) => {
193
- // Only the row's own keys. A cell can hold a link or a
194
- // button, and those have an Enter of their own — running
195
- // both would open the row and follow the link at once.
196
- if (event.target !== event.currentTarget) {
197
- return;
198
- }
199
- if (event.key !== 'Enter' && event.key !== ' ') {
200
- return;
201
- }
202
- // Space scrolls the page otherwise, which is the one
203
- // thing a reader pressing it on a row did not ask for.
204
- event.preventDefault();
205
- onRowClick(row, index);
206
- }
207
- : undefined, children: columns.map((column) => (_jsx("td", { style: { ...bodyCellStyle(index), textAlign: column.align ?? 'start' }, children: column.render
208
- ? column.render(row, index)
209
- : row[column.key] }, column.key))) }, getRowKey ? getRowKey(row, index) : index)))) })] }) })] }));
210
- }
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as a from"react";import{controlTextLeadingClasses as t,focusRingInsetClasses as l,metaTextClasses as o,paddingXValues as s,radiusClasses as i,sheetRestClasses as n,surfaceSlots as d}from"../../internal/styles.js";const c={default:{xs:"0.375rem",sm:"0.5rem",md:"0.75rem",lg:"0.875rem",xl:"1rem"},compact:{xs:"0.125rem",sm:"0.25rem",md:"0.4375rem",lg:"0.5625rem",xl:"0.6875rem"}},p={display:"table",width:"100%",margin:0,borderCollapse:"collapse",borderSpacing:0},m=/* @__PURE__ */["[--p-row:transparent]","[transition:background-color_var(--plass-duration)_var(--plass-ease)]"].join(" "),g=/* @__PURE__ */["cursor-pointer [outline:none]",l].join(" "),v="1px solid var(--plass-divider)";export function PlTable({variant:l="glass",size:h="md",color:y="primary",density:u="default",elevation:x=0,columns:b,rows:f,getRowKey:w,caption:k,empty:j="No data",striped:N=!1,hoverable:B=!1,stickyHeader:$=!1,maxHeight:A,onRowClick:C,className:H,style:S,...T}){const z=s[u][h],D=c[u][h],I=Boolean(C),K=B||I,R=void 0!==A,_=a.useId(),E={padding:`${D} ${z}`,border:0,background:"none"},P={...E,...$?{boxShadow:"inset 0 -1px 0 var(--plass-border)"}:{borderBottom:"1px solid var(--plass-border)"},...$?{background:"linear-gradient(var(--plass-glass-press), var(--plass-glass-press)), linear-gradient(var(--plass-surface), var(--plass-surface))"}:null},bodyCellStyle=e=>0===e?E:{...E,borderTop:v};return r("div",{className:["overflow-hidden",i[h],n[l],H??""].filter(Boolean).join(" "),style:{...d(y,x),...S},...T,children:[k?e("div",{id:_,className:`${o[h]} font-semibold text-(--plass-muted-fg)`,style:{...E,borderBottom:v,textAlign:"start"},children:k}):null,e("div",{className:["overflow-x-auto",R?"overflow-y-auto overscroll-contain":""].filter(Boolean).join(" "),style:R?{maxHeight:A}:void 0,children:r("table",{"aria-labelledby":k?_:void 0,className:`text-start ${t[h]} text-(--plass-fg)`,style:p,children:[e("colgroup",{children:b.map(r=>e("col",{style:void 0===r.width?void 0:{width:"number"==typeof r.width?`${r.width}px`:r.width}},r.key))}),e("thead",{children:e("tr",{children:b.map(r=>e("th",{scope:"col",className:["font-semibold whitespace-nowrap text-(--plass-muted-fg)",$?"sticky top-0 z-10":""].filter(Boolean).join(" "),style:{...P,textAlign:r.align??"start"},children:r.header??r.key},r.key))})}),e("tbody",{children:0===f.length?e("tr",{className:m,children:e("td",{colSpan:b.length,className:"text-(--plass-muted-fg)",style:{...E,padding:`2rem ${z}`,textAlign:"center"},children:j})}):f.map((r,a)=>e("tr",{className:[m,N&&a%2==1?"[--p-row:var(--plass-stripe)]":"",K?"hover:[--p-row:var(--p-soft)]":"",I?g:""].filter(Boolean).join(" "),style:{backgroundColor:"var(--p-row)"},tabIndex:I?0:void 0,onClick:C?()=>C(r,a):void 0,onKeyDown:C?e=>{e.target===e.currentTarget&&("Enter"!==e.key&&" "!==e.key||(e.preventDefault(),C(r,a)))}:void 0,children:b.map(t=>e("td",{style:{...bodyCellStyle(a),textAlign:t.align??"start"},children:t.render?t.render(r,a):r[t.key]},t.key))},w?w(r,a):a))})]})})]})}
@@ -1 +1 @@
1
- export { PlTable } from './PlTable.js';
1
+ export{PlTable}from"./PlTable.js";
@@ -1,182 +1 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { Tabs as BaseUITabs } from '@base-ui/react/tabs';
4
- import { controlHeightClasses, controlTextClasses, focusRingClasses, focusRingInsetClasses, gapClasses, glassClasses, hasContent, iconClasses, paddingXClasses, radiusClasses, surfaceSlots, transitionClasses } from '../../internal/styles.js';
5
- const TabsContext = /* @__PURE__ */ React.createContext({
6
- variant: 'glass',
7
- size: 'md',
8
- density: 'default',
9
- orientation: 'horizontal',
10
- fullWidth: false
11
- });
12
- /* ---------------------------------------------------------------------------
13
- * The bar
14
- * ------------------------------------------------------------------------- */
15
- /**
16
- * What the bar itself looks like, per material and per axis.
17
- *
18
- * `glass` is one border on one edge rather than a box, which is why it needs the
19
- * axis: the rule belongs under a horizontal bar and beside a vertical one. It is
20
- * `--plass-border` rather than the sheet's own white hairline, because a bar
21
- * drawn on a light card would otherwise have no rule at all.
22
- */
23
- const listClasses = {
24
- solid: {
25
- horizontal: `${glassClasses} inline-flex bg-(--plass-glass) p-1 [box-shadow:var(--plass-well)]`,
26
- vertical: `${glassClasses} inline-flex flex-col bg-(--plass-glass) p-1 [box-shadow:var(--plass-well)]`
27
- },
28
- glass: {
29
- horizontal: 'flex border-b [border-color:var(--plass-border)]',
30
- vertical: 'flex flex-col border-e [border-color:var(--plass-border)]'
31
- },
32
- ghost: {
33
- horizontal: 'flex',
34
- vertical: 'flex flex-col'
35
- }
36
- };
37
- /**
38
- * The indicator.
39
- *
40
- * `solid` fills the tab — a tile that slides between them. The other two draw a
41
- * 2px bar along the bar's own edge. All three move by animating `left`/`top` and
42
- * `width`/`height`, which Base UI measures onto `--active-tab-*`. That is a
43
- * layout animation on an empty box, not a transform on a label: nothing with
44
- * text in it moves, which is the distinction the house rule actually draws.
45
- *
46
- * `left`, not `inset-inline-start`, and this is one of the two places in the
47
- * library that reaches for a physical property on purpose. `--active-tab-left`
48
- * is a measurement — the distance from the list's left edge to the active tab's,
49
- * in pixels — and it stays a distance from the *left* under RTL. Pairing a
50
- * physical measurement with a logical property is what would break the
51
- * direction, not what would fix it. The edge the bar sits on is logical, because
52
- * that one genuinely flips.
53
- */
54
- const indicatorClasses = {
55
- solid: {
56
- horizontal: 'absolute top-(--active-tab-top) left-(--active-tab-left) h-(--active-tab-height) w-(--active-tab-width)',
57
- vertical: 'absolute top-(--active-tab-top) left-(--active-tab-left) h-(--active-tab-height) w-(--active-tab-width)'
58
- },
59
- glass: {
60
- horizontal: 'absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)',
61
- vertical: 'absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5'
62
- },
63
- ghost: {
64
- horizontal: 'absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)',
65
- vertical: 'absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5'
66
- }
67
- };
68
- const indicatorSurfaceClasses = {
69
- solid: `${glassClasses} bg-(--plass-glass-press) [box-shadow:var(--plass-shadow-1),var(--plass-gloss-glass)]`,
70
- glass: 'bg-(--p-accent)',
71
- ghost: 'bg-(--p-accent)'
72
- };
73
- /**
74
- * A tab is a control, so it takes the control height ladder — a `md` tab and a
75
- * `md` PlButton are the same 40px, which is what lets a tab bar sit in a toolbar
76
- * next to one without the row losing its baseline.
77
- *
78
- * `data-active`, not `data-selected` — Base UI spells a chosen tab's state that
79
- * way, and the wrong attribute is a class that silently never matches.
80
- */
81
- const tabStateClasses = 'text-(--plass-muted-fg) hover:text-(--plass-fg) data-[active]:text-(--p-accent)';
82
- /**
83
- * One tab, and one place a tab differs from a PlButton: `solid` puts the tile
84
- * *behind* the tab rather than on it, so the tab needs a stacking context of its
85
- * own or the indicator would cover the label it is meant to be under.
86
- */
87
- export const PlTab = /* @__PURE__ */ React.forwardRef(function PlTab({ value, startIcon, endIcon, disabled = false, className, children, ...props }, ref) {
88
- const { variant, size, density, fullWidth } = React.useContext(TabsContext);
89
- return (_jsxs(BaseUITabs.Tab, { ref: ref, value: value, disabled: disabled, className: [
90
- 'relative z-10 inline-flex shrink-0 cursor-pointer items-center justify-center select-none',
91
- 'font-semibold whitespace-nowrap',
92
- '[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]',
93
- controlHeightClasses[size],
94
- controlTextClasses[size],
95
- gapClasses[size],
96
- paddingXClasses[density][size],
97
- variant === 'solid' ? radiusClasses[size] : '',
98
- transitionClasses,
99
- iconClasses,
100
- tabStateClasses,
101
- // The ring is inset rather than offset: an offset ring on a tab inside a
102
- // `solid` groove is drawn on top of its neighbours.
103
- focusRingInsetClasses,
104
- 'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
105
- fullWidth ? 'flex-1' : '',
106
- className ?? ''
107
- ]
108
- .filter(Boolean)
109
- .join(' '), ...props, children: [hasContent(startIcon) ? (_jsx("span", { className: "flex h-[1lh] shrink-0 items-center", children: startIcon })) : null, children, hasContent(endIcon) ? (_jsx("span", { className: "flex h-[1lh] shrink-0 items-center", children: endIcon })) : null] }));
110
- });
111
- /** The content behind one tab. */
112
- export const PlTabPanel = /* @__PURE__ */ React.forwardRef(function PlTabPanel({ value, keepMounted = false, className, children, ...props }, ref) {
113
- const { size } = React.useContext(TabsContext);
114
- return (_jsx(BaseUITabs.Panel, { ref: ref, value: value, keepMounted: keepMounted, className: [
115
- 'min-w-0 flex-1 text-(--plass-fg)',
116
- // The panel takes focus when it holds nothing focusable of its own, so
117
- // it is reachable by keyboard — and it gets the house ring rather than
118
- // the browser's.
119
- focusRingClasses,
120
- radiusClasses[size],
121
- className ?? ''
122
- ]
123
- .filter(Boolean)
124
- .join(' '), ...props, children: children }));
125
- });
126
- /**
127
- * One set of panels, one of which is shown.
128
- *
129
- * Base UI owns everything that makes a tab bar a tab bar rather than a row of
130
- * buttons: roving focus so the whole bar is one tab stop, the arrow keys on
131
- * whichever axis the bar runs, Home and End, the `tab` / `tabpanel` roles and
132
- * the `aria-controls` wiring between them, and the measurement that puts the
133
- * indicator under the chosen tab. What is here is the surface and the ladders.
134
- *
135
- * The tabs and the panels are composed rather than passed as data, unlike
136
- * `PlSelect` — because a panel is a subtree, and there is no useful shape for
137
- * "an array of arbitrary React trees" that is not just children.
138
- */
139
- export const PlTabs = /* @__PURE__ */ React.forwardRef(function PlTabs({ variant = 'glass', size = 'md', color = 'primary', density = 'default', value, defaultValue, onValueChange, orientation = 'horizontal', activateOnFocus = false, loopFocus = true, fullWidth = false, className, style, children, ...props }, ref) {
140
- const context = React.useMemo(() => ({ variant, size, density, orientation, fullWidth }), [variant, size, density, orientation, fullWidth]);
141
- // Everything a caller writes between the tags is either a tab or a panel, and
142
- // the two go in different boxes — so they are sorted here rather than made the
143
- // caller's problem with a `<PlTabList>` wrapper they would have to remember.
144
- const tabs = [];
145
- const panels = [];
146
- React.Children.forEach(children, (child) => {
147
- if (React.isValidElement(child) && child.type === PlTabPanel) {
148
- panels.push(child);
149
- }
150
- else if (child !== null && child !== undefined && child !== false) {
151
- tabs.push(child);
152
- }
153
- });
154
- return (_jsx(TabsContext.Provider, { value: context, children: _jsxs(BaseUITabs.Root, { ref: ref, value: value, defaultValue: defaultValue, onValueChange: (next) => onValueChange?.(next), orientation: orientation, className: [
155
- 'flex min-w-0',
156
- orientation === 'vertical' ? 'flex-row gap-4' : 'flex-col gap-4',
157
- className ?? ''
158
- ]
159
- .filter(Boolean)
160
- .join(' '), style: { ...surfaceSlots(color, 0), ...style }, ...props, children: [_jsxs(BaseUITabs.List, { activateOnFocus: activateOnFocus, loopFocus: loopFocus, className: [
161
- 'relative shrink-0',
162
- listClasses[variant][orientation],
163
- variant === 'solid' ? radiusClasses[size] : '',
164
- fullWidth && orientation === 'horizontal' ? 'w-full' : '',
165
- // A bar with more tabs than room scrolls rather than wrapping: a tab
166
- // bar on two lines has stopped being a bar, and the indicator has
167
- // nowhere sensible to sit.
168
- orientation === 'horizontal' ? 'overflow-x-auto overflow-y-hidden' : ''
169
- ]
170
- .filter(Boolean)
171
- .join(' '), children: [tabs, _jsx(BaseUITabs.Indicator, { className: [
172
- 'pointer-events-none',
173
- indicatorClasses[variant][orientation],
174
- indicatorSurfaceClasses[variant],
175
- variant === 'solid' ? radiusClasses[size] : 'rounded-full',
176
- // The same easing everything else uses, on the four properties the
177
- // measurement actually writes.
178
- '[transition-property:left,top,width,height]',
179
- '[transition-duration:var(--plass-duration)]',
180
- '[transition-timing-function:var(--plass-ease)]'
181
- ].join(' ') })] }), panels] }) }));
182
- });
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as a from"react";import{Tabs as l}from"@base-ui/react/tabs";import{controlHeightClasses as o,controlTextClasses as s,focusRingClasses as i,focusRingInsetClasses as n,gapClasses as r,glassClasses as c,hasContent as d,iconClasses as h,paddingXClasses as f,radiusClasses as u,surfaceSlots as p,transitionClasses as b}from"../../internal/styles.js";const v=/* @__PURE__ */a.createContext({variant:"glass",size:"md",density:"default",orientation:"horizontal",fullWidth:!1}),m={solid:{horizontal:`${c} inline-flex bg-(--plass-glass) p-1 [box-shadow:var(--plass-well)]`,vertical:`${c} inline-flex flex-col bg-(--plass-glass) p-1 [box-shadow:var(--plass-well)]`},glass:{horizontal:"flex border-b [border-color:var(--plass-border)]",vertical:"flex flex-col border-e [border-color:var(--plass-border)]"},ghost:{horizontal:"flex",vertical:"flex flex-col"}},x={solid:{horizontal:"absolute top-(--active-tab-top) left-(--active-tab-left) h-(--active-tab-height) w-(--active-tab-width)",vertical:"absolute top-(--active-tab-top) left-(--active-tab-left) h-(--active-tab-height) w-(--active-tab-width)"},glass:{horizontal:"absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)",vertical:"absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5"},ghost:{horizontal:"absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)",vertical:"absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5"}},g={solid:`${c} bg-(--plass-glass-press) [box-shadow:var(--plass-shadow-1),var(--plass-gloss-glass)]`,glass:"bg-(--p-accent)",ghost:"bg-(--p-accent)"},w="text-(--plass-muted-fg) hover:text-(--plass-fg) data-[active]:text-(--p-accent)";export const PlTab=/* @__PURE__ */a.forwardRef(function PlTab({value:i,startIcon:c,endIcon:p,disabled:m=!1,className:x,children:g,...z},y){const{variant:P,size:j,density:N,fullWidth:T}=a.useContext(v);return t(l.Tab,{ref:y,value:i,disabled:m,className:["relative z-10 inline-flex shrink-0 cursor-pointer items-center justify-center select-none","font-semibold whitespace-nowrap","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",o[j],s[j],r[j],f[N][j],"solid"===P?u[j]:"",b,h,w,n,"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",T?"flex-1":"",x??""].filter(Boolean).join(" "),...z,children:[d(c)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:c}):null,g,d(p)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:p}):null]})});export const PlTabPanel=/* @__PURE__ */a.forwardRef(function PlTabPanel({value:t,keepMounted:o=!1,className:s,children:n,...r},c){const{size:d}=a.useContext(v);return e(l.Panel,{ref:c,value:t,keepMounted:o,className:["min-w-0 flex-1 text-(--plass-fg)",i,u[d],s??""].filter(Boolean).join(" "),...r,children:n})});export const PlTabs=/* @__PURE__ */a.forwardRef(function PlTabs({variant:o="glass",size:s="md",color:i="primary",density:n="default",value:r,defaultValue:c,onValueChange:d,orientation:h="horizontal",activateOnFocus:f=!1,loopFocus:b=!0,fullWidth:w=!1,className:z,style:y,children:P,...j},N){const T=a.useMemo(()=>({variant:o,size:s,density:n,orientation:h,fullWidth:w}),[o,s,n,h,w]),k=[],C=[];return a.Children.forEach(P,e=>{a.isValidElement(e)&&e.type===PlTabPanel?C.push(e):null!=e&&!1!==e&&k.push(e)}),e(v.Provider,{value:T,children:t(l.Root,{ref:N,value:r,defaultValue:c,onValueChange:e=>d?.(e),orientation:h,className:["flex min-w-0","vertical"===h?"flex-row gap-4":"flex-col gap-4",z??""].filter(Boolean).join(" "),style:{...p(i,0),...y},...j,children:[t(l.List,{activateOnFocus:f,loopFocus:b,className:["relative shrink-0",m[o][h],"solid"===o?u[s]:"",w&&"horizontal"===h?"w-full":"","horizontal"===h?"overflow-x-auto overflow-y-hidden":""].filter(Boolean).join(" "),children:[k,e(l.Indicator,{className:["pointer-events-none",x[o][h],g[o],"solid"===o?u[s]:"rounded-full","[transition-property:left,top,width,height]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]"].join(" ")})]}),C]})})});
@@ -1 +1 @@
1
- export { PlTab, PlTabPanel, PlTabs } from './PlTabs.js';
1
+ export{PlTab,PlTabPanel,PlTabs}from"./PlTabs.js";