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.
- package/README.md +165 -0
- package/dist/components/accordion/PlAccordion.js +1 -131
- package/dist/components/accordion/index.js +1 -1
- package/dist/components/alert/PlAlert.js +1 -109
- package/dist/components/alert/index.js +1 -1
- package/dist/components/animate-appear/PlAnimateAppear.js +1 -71
- package/dist/components/animate-appear/index.js +1 -1
- package/dist/components/animate-blink/PlAnimateBlink.js +1 -47
- package/dist/components/animate-blink/index.js +1 -1
- package/dist/components/animate-fade/PlAnimateFade.js +1 -48
- package/dist/components/animate-fade/index.js +1 -1
- package/dist/components/animate-grow/PlAnimateGrow.js +1 -49
- package/dist/components/animate-grow/index.js +1 -1
- package/dist/components/animate-headline/PlAnimateHeadline.js +1 -120
- package/dist/components/animate-headline/index.js +1 -1
- package/dist/components/animate-lighting/PlAnimateLighting.js +1 -65
- package/dist/components/animate-lighting/index.js +1 -1
- package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -94
- package/dist/components/animate-marquee/index.js +1 -1
- package/dist/components/animate-rotate/PlAnimateRotate.js +1 -50
- package/dist/components/animate-rotate/index.js +1 -1
- package/dist/components/animate-slide/PlAnimateSlide.js +1 -49
- package/dist/components/animate-slide/index.js +1 -1
- package/dist/components/animate-typing/PlAnimateTyping.js +1 -177
- package/dist/components/animate-typing/index.js +1 -1
- package/dist/components/animate-zoom/PlAnimateZoom.js +1 -45
- package/dist/components/animate-zoom/index.js +1 -1
- package/dist/components/aspect-ratio/PlAspectRatio.js +1 -58
- package/dist/components/aspect-ratio/index.js +1 -1
- package/dist/components/avatar/PlAvatar.js +1 -121
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/badge/PlBadge.js +1 -168
- package/dist/components/badge/index.js +1 -1
- package/dist/components/blockquote/PlBlockquote.js +1 -112
- package/dist/components/blockquote/index.js +1 -1
- package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -141
- package/dist/components/bottom-navigation/index.js +1 -1
- package/dist/components/box/PlBox.js +1 -46
- package/dist/components/box/index.js +1 -1
- package/dist/components/breadcrumb/PlBreadcrumb.js +1 -201
- package/dist/components/breadcrumb/index.js +1 -1
- package/dist/components/button/PlButton.js +1 -196
- package/dist/components/button/index.js +1 -1
- package/dist/components/button-group/PlButtonGroup.js +1 -64
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/card/PlCard.js +1 -102
- package/dist/components/card/index.js +1 -1
- package/dist/components/carousel/PlCarousel.js +1 -177
- package/dist/components/carousel/index.js +1 -1
- package/dist/components/chat-bubble/PlChatBubble.js +1 -206
- package/dist/components/chat-bubble/index.js +1 -1
- package/dist/components/checkbox/PlCheckbox.js +1 -100
- package/dist/components/checkbox/index.js +1 -1
- package/dist/components/chip/PlChip.js +1 -144
- package/dist/components/chip/index.js +1 -1
- package/dist/components/collapsible/PlCollapsible.js +1 -65
- package/dist/components/collapsible/index.js +1 -1
- package/dist/components/combobox/PlCombobox.js +1 -199
- package/dist/components/combobox/index.js +1 -1
- package/dist/components/container/PlContainer.js +1 -47
- package/dist/components/container/index.js +1 -1
- package/dist/components/date-picker/PlDatePicker.js +1 -87
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/PlDateRangePicker.js +1 -152
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/PlDateTimePicker.js +1 -106
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/divider/PlDivider.js +1 -107
- package/dist/components/divider/index.js +1 -1
- package/dist/components/drawer/PlDrawer.js +1 -190
- package/dist/components/drawer/index.js +1 -1
- package/dist/components/file-picker/PlFilePicker.js +1 -274
- package/dist/components/file-picker/index.js +1 -1
- package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -291
- package/dist/components/floating-bottom-navigation/index.js +1 -1
- package/dist/components/grid/PlGrid.js +1 -51
- package/dist/components/grid/PlGridItem.js +1 -34
- package/dist/components/grid/index.js +1 -2
- package/dist/components/highlight/PlHighlight.js +1 -185
- package/dist/components/highlight/index.js +1 -1
- package/dist/components/hot-keys/PlHotKeys.js +1 -294
- package/dist/components/hot-keys/index.js +1 -1
- package/dist/components/icon/PlIcon.js +1 -58
- package/dist/components/icon/index.js +1 -1
- package/dist/components/icon-button/PlIconButton.js +1 -37
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/list/PlList.js +1 -160
- package/dist/components/list/index.js +1 -1
- package/dist/components/menu/PlMenu.js +1 -209
- package/dist/components/menu/index.js +1 -1
- package/dist/components/modal/PlModal.js +1 -150
- package/dist/components/modal/index.js +1 -1
- package/dist/components/number-field/PlNumberField.js +1 -111
- package/dist/components/number-field/index.js +1 -1
- package/dist/components/otp-field/PlOtpField.js +1 -109
- package/dist/components/otp-field/index.js +1 -1
- package/dist/components/overlay/PlOverlay.js +1 -77
- package/dist/components/overlay/index.js +1 -1
- package/dist/components/pagination/PlPagination.js +1 -159
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/panes/PlPanes.js +1 -324
- package/dist/components/panes/index.js +1 -1
- package/dist/components/pill/PlPill.js +1 -154
- package/dist/components/pill/index.js +1 -1
- package/dist/components/popover/PlPopover.js +1 -113
- package/dist/components/popover/index.js +1 -1
- package/dist/components/progress-box/PlProgressBox.js +1 -34
- package/dist/components/progress-box/index.js +1 -1
- package/dist/components/progress-circular/PlProgressCircular.js +1 -47
- package/dist/components/progress-circular/index.js +1 -1
- package/dist/components/progress-linear/PlProgressLinear.js +1 -40
- package/dist/components/progress-linear/index.js +1 -1
- package/dist/components/radio-group/PlRadioGroup.js +1 -99
- package/dist/components/radio-group/index.js +1 -1
- package/dist/components/rating/PlRating.js +1 -101
- package/dist/components/rating/index.js +1 -1
- package/dist/components/scroll-zone/PlScrollZone.js +1 -411
- package/dist/components/scroll-zone/index.js +1 -1
- package/dist/components/segmented-button/PlSegmentedButton.js +1 -206
- package/dist/components/segmented-button/index.js +1 -1
- package/dist/components/select/PlSelect.js +1 -115
- package/dist/components/select/index.js +1 -1
- package/dist/components/skeleton/PlSkeleton.js +1 -142
- package/dist/components/skeleton/index.js +1 -1
- package/dist/components/slider/PlSlider.js +1 -132
- package/dist/components/slider/index.js +1 -1
- package/dist/components/spoiler/PlSpoiler.js +1 -74
- package/dist/components/spoiler/index.js +1 -1
- package/dist/components/switch/PlSwitch.js +1 -131
- package/dist/components/switch/index.js +1 -1
- package/dist/components/table/PlTable.js +1 -210
- package/dist/components/table/index.js +1 -1
- package/dist/components/tabs/PlTabs.js +1 -182
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/text-field/PlTextField.js +1 -126
- package/dist/components/text-field/index.js +1 -1
- package/dist/components/text-link/PlTextLink.js +1 -136
- package/dist/components/text-link/index.js +1 -1
- package/dist/components/time-picker/PlTimePicker.js +1 -97
- package/dist/components/time-picker/index.js +1 -1
- package/dist/components/timeline/PlTimeline.js +1 -207
- package/dist/components/timeline/index.js +1 -1
- package/dist/components/toast/PlToast.js +1 -174
- package/dist/components/toast/index.js +1 -1
- package/dist/components/toolbar/PlToolbar.js +1 -65
- package/dist/components/toolbar/index.js +1 -1
- package/dist/components/tooltip/PlTooltip.js +1 -117
- package/dist/components/tooltip/index.js +1 -1
- package/dist/components/typography/PlTypography.js +1 -143
- package/dist/components/typography/index.js +1 -1
- package/dist/index.js +1 -75
- package/dist/internal/animate.js +1 -318
- package/dist/internal/button-group.js +2 -19
- package/dist/internal/calendar.js +1 -501
- package/dist/internal/date.js +1 -353
- package/dist/internal/format.js +1 -41
- package/dist/internal/grid.js +1 -143
- package/dist/internal/icons.js +1 -138
- package/dist/internal/menu.js +1 -18
- package/dist/internal/picker.js +1 -139
- package/dist/internal/progress.js +1 -167
- package/dist/internal/sizer.js +1 -35
- package/dist/internal/styles.js +1 -636
- package/dist/types.js +0 -8
- package/package.json +5 -3
package/dist/internal/styles.js
CHANGED
|
@@ -1,636 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* The pieces every Plass component is built out of.
|
|
3
|
-
*
|
|
4
|
-
* None of this is exported from `src/index.ts` — it is the library talking to
|
|
5
|
-
* itself. It lives here for one reason: a `size` of `md` has to be 40px on a
|
|
6
|
-
* PlButton, a PlTextField, a Select and a Chip, and a table copied into eleven
|
|
7
|
-
* files is a table that will disagree with itself by the twelfth.
|
|
8
|
-
*
|
|
9
|
-
* The two things that cannot move out of a component are its variant classes
|
|
10
|
-
* and its layout — those genuinely differ. Heights, radii, type scale, padding
|
|
11
|
-
* tracks, the glass surface, the transition and the colour slots do not.
|
|
12
|
-
*
|
|
13
|
-
* Tailwind only sees class names written out literally, so everything here is a
|
|
14
|
-
* complete class string rather than something assembled at runtime. `@source
|
|
15
|
-
* '.'` in `styles.css` covers this folder in the repository and in `dist/`.
|
|
16
|
-
*/
|
|
17
|
-
/* ---------------------------------------------------------------------------
|
|
18
|
-
* Scales
|
|
19
|
-
* ------------------------------------------------------------------------- */
|
|
20
|
-
/**
|
|
21
|
-
* Corner radius — a moulded fillet rather than a chamfer or a pill.
|
|
22
|
-
*
|
|
23
|
-
* It grows far more slowly than the height does: 33% of an `xs` control, 29% at
|
|
24
|
-
* `md`, 29% at `xl`. That near-constant radius is what makes two controls of
|
|
25
|
-
* different sizes read as two pieces cast in the same mould, which a radius
|
|
26
|
-
* pinned to a percentage of the height does not.
|
|
27
|
-
*/
|
|
28
|
-
export const radiusClasses = {
|
|
29
|
-
xs: 'rounded-(--plass-radius-xs)',
|
|
30
|
-
sm: 'rounded-(--plass-radius-sm)',
|
|
31
|
-
md: 'rounded-(--plass-radius-md)',
|
|
32
|
-
lg: 'rounded-(--plass-radius-lg)',
|
|
33
|
-
xl: 'rounded-(--plass-radius-xl)'
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* The height of a control, and the one number the whole library lines up on:
|
|
37
|
-
* a PlButton, a PlTextField, a Select and a Chip of the same `size` sit on the same
|
|
38
|
-
* baseline in the same row.
|
|
39
|
-
*
|
|
40
|
-
* The ladder is 8px per step, and it starts higher than a dense desktop toolkit
|
|
41
|
-
* would: `md` is 40px, not 32px. A moulded surface needs room to be one — a
|
|
42
|
-
* gradient, a specular highlight and a hairline inside 32px is three effects
|
|
43
|
-
* fighting over eleven pixels of fill. `xs` exists for a table row and is the
|
|
44
|
-
* one step where the gloss is deliberately faint.
|
|
45
|
-
*
|
|
46
|
-
* `lg` at 48px and `xl` at 56px both clear the 44px mobile touch target.
|
|
47
|
-
*
|
|
48
|
-
* Density never touches these.
|
|
49
|
-
*/
|
|
50
|
-
export const controlHeightClasses = {
|
|
51
|
-
xs: 'h-6',
|
|
52
|
-
sm: 'h-8',
|
|
53
|
-
md: 'h-10',
|
|
54
|
-
lg: 'h-12',
|
|
55
|
-
xl: 'h-14'
|
|
56
|
-
};
|
|
57
|
-
/** The same numbers as a width, for a control with nothing to pad against. */
|
|
58
|
-
export const controlSquareClasses = {
|
|
59
|
-
xs: 'w-6',
|
|
60
|
-
sm: 'w-8',
|
|
61
|
-
md: 'w-10',
|
|
62
|
-
lg: 'w-12',
|
|
63
|
-
xl: 'w-14'
|
|
64
|
-
};
|
|
65
|
-
/** A control's label. One line, so the leading comes from `leading-none`. */
|
|
66
|
-
export const controlTextClasses = {
|
|
67
|
-
xs: 'text-[0.6875rem]',
|
|
68
|
-
sm: 'text-[0.8125rem]',
|
|
69
|
-
md: 'text-[0.875rem]',
|
|
70
|
-
lg: 'text-[1rem]',
|
|
71
|
-
xl: 'text-[1.125rem]'
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* The same type scale with an explicit leading, for the controls that hold text
|
|
75
|
-
* which may wrap — a textarea, a select option, a table cell. The line heights
|
|
76
|
-
* have to agree with `controlHeightClasses` or a one-row control would stop
|
|
77
|
-
* lining up with a single-line one.
|
|
78
|
-
*/
|
|
79
|
-
export const controlTextLeadingClasses = {
|
|
80
|
-
xs: 'text-[0.6875rem]/[1rem]',
|
|
81
|
-
sm: 'text-[0.8125rem]/[1.125rem]',
|
|
82
|
-
md: 'text-[0.875rem]/[1.25rem]',
|
|
83
|
-
lg: 'text-[1rem]/[1.5rem]',
|
|
84
|
-
xl: 'text-[1.125rem]/[1.75rem]'
|
|
85
|
-
};
|
|
86
|
-
/** Labels, descriptions and error messages: one step below the control's text. */
|
|
87
|
-
export const metaTextClasses = {
|
|
88
|
-
xs: 'text-[0.625rem]',
|
|
89
|
-
sm: 'text-[0.6875rem]',
|
|
90
|
-
md: 'text-[0.75rem]',
|
|
91
|
-
lg: 'text-[0.8125rem]',
|
|
92
|
-
xl: 'text-[0.875rem]'
|
|
93
|
-
};
|
|
94
|
-
/**
|
|
95
|
-
* Horizontal padding, and the only thing `density` is allowed to touch. The two
|
|
96
|
-
* tracks are roughly 2:1 so the difference is legible at a glance rather than a
|
|
97
|
-
* two-pixel nudge.
|
|
98
|
-
*/
|
|
99
|
-
export const paddingXClasses = {
|
|
100
|
-
default: { xs: 'px-2.5', sm: 'px-3', md: 'px-4', lg: 'px-6', xl: 'px-7' },
|
|
101
|
-
compact: { xs: 'px-1.5', sm: 'px-2', md: 'px-2.5', lg: 'px-3.5', xl: 'px-4' }
|
|
102
|
-
};
|
|
103
|
-
/**
|
|
104
|
-
* A standalone glyph's box: 14, 16, 20, 24 and 28px.
|
|
105
|
-
*
|
|
106
|
-
* Its own ladder rather than a step off `controlHeightClasses`, because an icon
|
|
107
|
-
* is not a control — it is content, and it is measured against the text it sits
|
|
108
|
-
* beside rather than against the row it sits in.
|
|
109
|
-
*
|
|
110
|
-
* `iconClasses` is the other half of the same idea and is not this: that one
|
|
111
|
-
* sizes a glyph *inside* a control, in `em`, so it tracks the label it belongs
|
|
112
|
-
* to. This one is for the glyph that is the whole object.
|
|
113
|
-
*/
|
|
114
|
-
export const iconSizeClasses = {
|
|
115
|
-
xs: 'size-3.5',
|
|
116
|
-
sm: 'size-4',
|
|
117
|
-
md: 'size-5',
|
|
118
|
-
lg: 'size-6',
|
|
119
|
-
xl: 'size-7'
|
|
120
|
-
};
|
|
121
|
-
/**
|
|
122
|
-
* A tick box: the square a PlCheckbox draws and the circle a PlRadioGroup draws.
|
|
123
|
-
*
|
|
124
|
-
* Its own ladder rather than a step off `controlHeightClasses`, because a tick
|
|
125
|
-
* is not a control you can put a label inside — it is an indicator next to one,
|
|
126
|
-
* and it is sized against the text beside it rather than against the row.
|
|
127
|
-
*/
|
|
128
|
-
export const tickSizeClasses = {
|
|
129
|
-
xs: 'size-3.5',
|
|
130
|
-
sm: 'size-4',
|
|
131
|
-
md: 'size-4.5',
|
|
132
|
-
lg: 'size-5',
|
|
133
|
-
xl: 'size-6'
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* And its own radius, well below the control ladder's.
|
|
137
|
-
*
|
|
138
|
-
* `--plass-radius-md` is 12px, which on an 18px box is most of the way to a
|
|
139
|
-
* circle — and a checkbox that is round is a radio button. The intent is the
|
|
140
|
-
* same fillet as everywhere else, measured against a much smaller object.
|
|
141
|
-
*/
|
|
142
|
-
export const tickRadiusClasses = {
|
|
143
|
-
xs: 'rounded-[0.25rem]',
|
|
144
|
-
sm: 'rounded-[0.3125rem]',
|
|
145
|
-
md: 'rounded-[0.375rem]',
|
|
146
|
-
lg: 'rounded-[0.4375rem]',
|
|
147
|
-
xl: 'rounded-[0.5rem]'
|
|
148
|
-
};
|
|
149
|
-
/**
|
|
150
|
-
* The dot inside a checked radio.
|
|
151
|
-
*
|
|
152
|
-
* Whole pixels at every step rather than a percentage of the ring around it —
|
|
153
|
-
* and, which is the half that was missing, whole pixels *of margin* as well.
|
|
154
|
-
* A diameter can be an exact 7px and still be centred at x.5, because what
|
|
155
|
-
* decides the offset is `(box − border − border − dot) / 2`: a 7px dot inside
|
|
156
|
-
* an 18px ring with a 1px edge sits 4.5px from each side, and a circle whose
|
|
157
|
-
* four sides are antialiased at half coverage reads as "the dot is not
|
|
158
|
-
* centred" even though the box says it is — and reads as *up and to the left*,
|
|
159
|
-
* because that is the way the paint rounds.
|
|
160
|
-
*
|
|
161
|
-
* So every dot here has the same parity as the ring's content box: 12/6, 14/6,
|
|
162
|
-
* 16/8, 18/8, 22/10. The ratio wanders between 38% and 44% as a result, which
|
|
163
|
-
* is the price, and it is invisible next to the thing it buys.
|
|
164
|
-
*/
|
|
165
|
-
export const tickDotClasses = {
|
|
166
|
-
xs: 'size-1.5',
|
|
167
|
-
sm: 'size-1.5',
|
|
168
|
-
md: 'size-2',
|
|
169
|
-
lg: 'size-2',
|
|
170
|
-
xl: 'size-2.5'
|
|
171
|
-
};
|
|
172
|
-
/**
|
|
173
|
-
* The line box a tick and its label share.
|
|
174
|
-
*
|
|
175
|
-
* Both the tick's wrapper and the label are measured against it: the wrapper is
|
|
176
|
-
* `h-[1lh]` so the box centres on the label's *first* line rather than on the
|
|
177
|
-
* whole block, and that only lines up if the two agree on what a line is. Left
|
|
178
|
-
* to inherit, `1lh` picks up whatever leading the host page happens to set and
|
|
179
|
-
* the tick drifts a pixel or two off the text beside it.
|
|
180
|
-
*
|
|
181
|
-
* It is `controlTextLeadingClasses` and not a ratio of its own, and that is the
|
|
182
|
-
* whole point of it having moved: a ratio produces a fractional line box at
|
|
183
|
-
* every step but one — 14px of text at 1.4 is a 19.6px line — and an 18px tick
|
|
184
|
-
* centred in 19.6px starts at 0.8px, which drags the ring, its edge and the dot
|
|
185
|
-
* inside it off the pixel grid together. The table's line boxes are whole
|
|
186
|
-
* numbers with the same parity as the ticks that sit in them (16/14, 18/16,
|
|
187
|
-
* 20/18, 24/20, 28/24), so every one of those offsets is a whole pixel.
|
|
188
|
-
*
|
|
189
|
-
* The label needs no leading of its own; it inherits this one, which is the
|
|
190
|
-
* only way the two can be guaranteed to agree.
|
|
191
|
-
*/
|
|
192
|
-
export const tickRowTextClasses = controlTextLeadingClasses;
|
|
193
|
-
/**
|
|
194
|
-
* The same two tracks again, as raw lengths.
|
|
195
|
-
*
|
|
196
|
-
* These exist for one element: a table cell. `<td>` and `<th>` are among the
|
|
197
|
-
* very few tags that host stylesheets still style by name — VitePress's
|
|
198
|
-
* `.vp-doc td`, Tailwind Typography's `.prose td`, every CSS framework ever —
|
|
199
|
-
* and all of those are two-class selectors that a one-class utility cannot
|
|
200
|
-
* outrank. A table therefore writes its cell padding inline, where nothing can
|
|
201
|
-
* reach it.
|
|
202
|
-
*
|
|
203
|
-
* Keep these in step with `paddingXClasses`. They are the same numbers: the
|
|
204
|
-
* Tailwind spacing scale is 0.25rem per step.
|
|
205
|
-
*/
|
|
206
|
-
export const paddingXValues = {
|
|
207
|
-
default: { xs: '0.625rem', sm: '0.75rem', md: '1rem', lg: '1.5rem', xl: '1.75rem' },
|
|
208
|
-
compact: { xs: '0.375rem', sm: '0.5rem', md: '0.625rem', lg: '0.875rem', xl: '1rem' }
|
|
209
|
-
};
|
|
210
|
-
/** Between a control's own parts — an icon and its label. */
|
|
211
|
-
export const gapClasses = {
|
|
212
|
-
xs: 'gap-1',
|
|
213
|
-
sm: 'gap-1.5',
|
|
214
|
-
md: 'gap-2',
|
|
215
|
-
lg: 'gap-2.5',
|
|
216
|
-
xl: 'gap-3'
|
|
217
|
-
};
|
|
218
|
-
/** Between a label, the control under it and the text under that. */
|
|
219
|
-
export const stackGapClasses = {
|
|
220
|
-
xs: 'gap-1',
|
|
221
|
-
sm: 'gap-1.5',
|
|
222
|
-
md: 'gap-1.5',
|
|
223
|
-
lg: 'gap-2',
|
|
224
|
-
xl: 'gap-2'
|
|
225
|
-
};
|
|
226
|
-
/* ---------------------------------------------------------------------------
|
|
227
|
-
* Sheets
|
|
228
|
-
*
|
|
229
|
-
* A control holds one line of text at a fixed height, which is what every
|
|
230
|
-
* ladder above is about. A *sheet* — a Card, an Accordion section, an Alert, a
|
|
231
|
-
* Modal — holds a heading, a paragraph and a footer, and all three of them
|
|
232
|
-
* wrap. That is a different problem, and these tables are its answer.
|
|
233
|
-
*
|
|
234
|
-
* A sheet's subtitle deliberately has no table of its own: it is
|
|
235
|
-
* `metaTextClasses`, the same step below the body that a field's description
|
|
236
|
-
* sits on.
|
|
237
|
-
* ------------------------------------------------------------------------- */
|
|
238
|
-
/**
|
|
239
|
-
* A sheet's own padding, which is not a control's.
|
|
240
|
-
*
|
|
241
|
-
* `paddingXClasses` is the room a label needs beside the edge of the key it is
|
|
242
|
-
* printed on. This is the margin a sheet keeps around whatever it is holding,
|
|
243
|
-
* and it is bigger, because the thing inside is a paragraph rather than a word.
|
|
244
|
-
* Both axes are offered separately: a sheet with hairlines between its sections
|
|
245
|
-
* gives its vertical padding away to them.
|
|
246
|
-
*/
|
|
247
|
-
export const sheetPaddingXClasses = {
|
|
248
|
-
default: { xs: 'px-2.5', sm: 'px-3.5', md: 'px-5', lg: 'px-6', xl: 'px-7' },
|
|
249
|
-
compact: { xs: 'px-2', sm: 'px-2.5', md: 'px-3.5', lg: 'px-4', xl: 'px-5' }
|
|
250
|
-
};
|
|
251
|
-
export const sheetPaddingYClasses = {
|
|
252
|
-
default: { xs: 'py-2.5', sm: 'py-3.5', md: 'py-5', lg: 'py-6', xl: 'py-7' },
|
|
253
|
-
compact: { xs: 'py-2', sm: 'py-2.5', md: 'py-3.5', lg: 'py-4', xl: 'py-5' }
|
|
254
|
-
};
|
|
255
|
-
/**
|
|
256
|
-
* A sheet's heading: one step above the body, on the same ladder the controls
|
|
257
|
-
* use, so a card's title lines up with the buttons that end up inside it.
|
|
258
|
-
*/
|
|
259
|
-
export const sheetTitleClasses = {
|
|
260
|
-
xs: 'text-[0.75rem]/[1rem]',
|
|
261
|
-
sm: 'text-[0.8125rem]/[1.125rem]',
|
|
262
|
-
md: 'text-[0.9375rem]/[1.25rem]',
|
|
263
|
-
lg: 'text-[1.0625rem]/[1.5rem]',
|
|
264
|
-
xl: 'text-[1.25rem]/[1.75rem]'
|
|
265
|
-
};
|
|
266
|
-
/**
|
|
267
|
-
* Body copy: the control type scale with the leading opened up, because a
|
|
268
|
-
* label is one line and a body is a paragraph.
|
|
269
|
-
*/
|
|
270
|
-
export const sheetBodyClasses = {
|
|
271
|
-
xs: 'text-[0.6875rem]/[1rem]',
|
|
272
|
-
sm: 'text-[0.75rem]/[1.125rem]',
|
|
273
|
-
md: 'text-[0.8125rem]/[1.375rem]',
|
|
274
|
-
lg: 'text-[0.9375rem]/[1.5rem]',
|
|
275
|
-
xl: 'text-[1.0625rem]/[1.75rem]'
|
|
276
|
-
};
|
|
277
|
-
/** Between a sheet's sections, when there are no hairlines to separate them. */
|
|
278
|
-
export const sheetSectionGapClasses = {
|
|
279
|
-
xs: 'gap-1.5',
|
|
280
|
-
sm: 'gap-2',
|
|
281
|
-
md: 'gap-3',
|
|
282
|
-
lg: 'gap-3.5',
|
|
283
|
-
xl: 'gap-4'
|
|
284
|
-
};
|
|
285
|
-
/**
|
|
286
|
-
* The hairline that scores a sheet into sections — a card's body from its
|
|
287
|
-
* footer, one accordion fold from the next, one table row from the next.
|
|
288
|
-
*
|
|
289
|
-
* `--plass-divider` and **not** the `--plass-glass-line` the sheet's own edge is
|
|
290
|
-
* drawn in, which is what this used to be. The edge line is white light caught
|
|
291
|
-
* on a cut edge, and it reads because what is behind it is the page wash. The
|
|
292
|
-
* same white laid *across* the middle of the sheet has the sheet behind it
|
|
293
|
-
* instead, and a white line on a 62%-white pane over a near-white page is not a
|
|
294
|
-
* line — which is why a light-mode list, card or table had no visible structure
|
|
295
|
-
* at all unless the host page happened to be drawing its own.
|
|
296
|
-
*/
|
|
297
|
-
export const sheetLineClasses = 'border-t [border-color:var(--plass-divider)]';
|
|
298
|
-
/** Title to subtitle. Tight — they are one block of text, not two sections. */
|
|
299
|
-
export const sheetHeaderGapClasses = {
|
|
300
|
-
xs: 'gap-0.5',
|
|
301
|
-
sm: 'gap-0.5',
|
|
302
|
-
md: 'gap-1',
|
|
303
|
-
lg: 'gap-1',
|
|
304
|
-
xl: 'gap-1.5'
|
|
305
|
-
};
|
|
306
|
-
/* ---------------------------------------------------------------------------
|
|
307
|
-
* Surface
|
|
308
|
-
* ------------------------------------------------------------------------- */
|
|
309
|
-
/**
|
|
310
|
-
* Glass: a translucent fill over a heavily blurred backdrop.
|
|
311
|
-
*
|
|
312
|
-
* The blur is the whole material. Plass is not trying to let you read what is
|
|
313
|
-
* behind a sheet — it is trying to make the sheet look thick, which is why the
|
|
314
|
-
* radius is 22px and not the 8–10px a frosted-acrylic language would use.
|
|
315
|
-
* Below about 14px the surface stops being glass and becomes a white box with
|
|
316
|
-
* an alpha on it.
|
|
317
|
-
*
|
|
318
|
-
* `-webkit-backdrop-filter` is written alongside the standard property because
|
|
319
|
-
* Safari still needs it, and Tailwind will not add it for an arbitrary value.
|
|
320
|
-
*/
|
|
321
|
-
export const glassClasses = '[backdrop-filter:var(--plass-blur)] [-webkit-backdrop-filter:var(--plass-blur)]';
|
|
322
|
-
/**
|
|
323
|
-
* The house transition.
|
|
324
|
-
*
|
|
325
|
-
* One duration and one curve, applied the same way in both directions — a key
|
|
326
|
-
* going down and a key coming back up are the same spring. `background-image`
|
|
327
|
-
* is in the list because a gradient fill is the thing being changed on a solid
|
|
328
|
-
* surface, and `filter` because that is what hover and press actually move.
|
|
329
|
-
*
|
|
330
|
-
* There is no `transform` in the list and none should be added to a *control*:
|
|
331
|
-
* scaling a key resamples its label, and text that shimmers under the cursor
|
|
332
|
-
* undoes the restraint everything else is spending effort on. A surface that
|
|
333
|
-
* holds content rather than being pressed — a Card — may lift, and does.
|
|
334
|
-
*/
|
|
335
|
-
export const transitionClasses = /* @__PURE__ */ [
|
|
336
|
-
'[transition-property:background-color,background-image,border-color,box-shadow,color,filter]',
|
|
337
|
-
'[transition-duration:var(--plass-duration)]',
|
|
338
|
-
'[transition-timing-function:var(--plass-ease)]'
|
|
339
|
-
].join(' ');
|
|
340
|
-
/**
|
|
341
|
-
* The focus ring, written as the `outline` shorthand rather than Tailwind's
|
|
342
|
-
* `outline-2` + colour pair: the utilities route the style through
|
|
343
|
-
* `--tw-outline-style`, which any `outline-none` on the element (ours or a
|
|
344
|
-
* consumer's) would zero out.
|
|
345
|
-
*
|
|
346
|
-
* An `outline` and not a `ring`, which is the other way this could be drawn:
|
|
347
|
-
* Tailwind's `ring-*` is a `box-shadow`, and every Plass surface already spends
|
|
348
|
-
* its `box-shadow` on the elevation, the tinted glow and the gloss line. A ring
|
|
349
|
-
* would have to be spliced into that chain in each of the three variants, and
|
|
350
|
-
* the first one that forgot would silently lose its focus ring.
|
|
351
|
-
*
|
|
352
|
-
* **It is flush.** The offset used to be 2px, and a 2px gap is the one thing a
|
|
353
|
-
* ring must not have on a control that already draws an edge of its own: a
|
|
354
|
-
* field, a select, a tick, a switch. The eye reads the field's hairline, then a
|
|
355
|
-
* band of page, then the ring — three concentric rectangles where there is one
|
|
356
|
-
* object, and the control looks as though it has come loose from the ring
|
|
357
|
-
* around it. At offset 0 the outline sits directly on the outside of the edge
|
|
358
|
-
* and the edge simply thickens and takes the family's colour, which is what
|
|
359
|
-
* "this one is focused" should look like.
|
|
360
|
-
*
|
|
361
|
-
* Nothing is lost on a control with no edge either: the outline is still drawn
|
|
362
|
-
* entirely *outside* the border box, so on a filled key it is a rim against the
|
|
363
|
-
* page rather than a band over the fill.
|
|
364
|
-
*/
|
|
365
|
-
export const focusRingClasses = 'focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:[outline-offset:0px]';
|
|
366
|
-
/** The same ring, drawn by whichever descendant actually takes focus. */
|
|
367
|
-
export const focusWithinRingClasses = 'has-[:focus-visible]:[outline:2px_solid_var(--p-ring)] has-[:focus-visible]:[outline-offset:0px]';
|
|
368
|
-
/**
|
|
369
|
-
* The same ring again, turned inward.
|
|
370
|
-
*
|
|
371
|
-
* For an element that is *inside* something that clips — a segment in a
|
|
372
|
-
* groove, a tab on a rail, a row in a sheet with rounded corners, an accordion
|
|
373
|
-
* header in a scored pane. A ring drawn outside those is a ring with its top or
|
|
374
|
-
* its bottom sliced off by the container's own overflow, so it is drawn just
|
|
375
|
-
* inside the edge instead. Same width, same colour, same absence of a gap.
|
|
376
|
-
*/
|
|
377
|
-
export const focusRingInsetClasses = 'focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:[outline-offset:-2px]';
|
|
378
|
-
/**
|
|
379
|
-
* The × that takes something off a chip.
|
|
380
|
-
*
|
|
381
|
-
* Here rather than in `PlChip` because a `PlCombobox` draws the same affordance
|
|
382
|
-
* on the chips *it* puts in its field, and it cannot reach into the component to
|
|
383
|
-
* borrow one — Base UI owns that button so the primitive can wire it up. Two
|
|
384
|
-
* copies of this would be two ×s that stop matching.
|
|
385
|
-
*
|
|
386
|
-
* Kept quiet until it is wanted: the glyph sits at 70% until the pointer or the
|
|
387
|
-
* keyboard arrives.
|
|
388
|
-
*/
|
|
389
|
-
export const chipRemoveClasses = /* @__PURE__ */ [
|
|
390
|
-
'ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full',
|
|
391
|
-
'size-[1.15em] cursor-pointer opacity-70',
|
|
392
|
-
'[transition:opacity_var(--plass-duration)_var(--plass-ease)]',
|
|
393
|
-
'hover:opacity-100 focus-visible:opacity-100',
|
|
394
|
-
focusRingClasses,
|
|
395
|
-
'disabled:cursor-not-allowed'
|
|
396
|
-
].join(' ');
|
|
397
|
-
/** Icons track their label rather than carrying a size of their own. */
|
|
398
|
-
export const iconClasses = '[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0';
|
|
399
|
-
/**
|
|
400
|
-
* Text for a screen reader and nobody else.
|
|
401
|
-
*
|
|
402
|
-
* Not `hidden`, not `display:none` and not `opacity:0` — the first two take the
|
|
403
|
-
* text off the accessibility tree along with the screen, and the third leaves a
|
|
404
|
-
* clickable ghost the size of the words. A 1px clipped box is the one form that
|
|
405
|
-
* is invisible to a sighted reader and present to every other kind.
|
|
406
|
-
*/
|
|
407
|
-
export const srOnlyClasses = 'absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]';
|
|
408
|
-
/* ---------------------------------------------------------------------------
|
|
409
|
-
* Colour slots
|
|
410
|
-
*
|
|
411
|
-
* These are inline styles rather than Tailwind arbitrary properties on purpose:
|
|
412
|
-
* Tailwind only sees class names that appear literally in the source, so the
|
|
413
|
-
* alternative is one hardcoded `[--p-fill:var(--plass-primary-fill)]` per
|
|
414
|
-
* family per component. Generating the slots keeps adding a colour family down
|
|
415
|
-
* to one entry in `PlassColor` plus its tokens in `styles.css`.
|
|
416
|
-
* ------------------------------------------------------------------------- */
|
|
417
|
-
/**
|
|
418
|
-
* The tinted lift — the shadow a control casts in its own colour, and the
|
|
419
|
-
* single loudest thing in the design language.
|
|
420
|
-
*
|
|
421
|
-
* It is deliberately **not** part of the elevation ladder, and it does not
|
|
422
|
-
* scale with `elevation`. Elevation says how far a surface is off the page;
|
|
423
|
-
* this says what the surface is made of, and a `danger` button one step higher
|
|
424
|
-
* is not a redder piece of glass. The two are composed in the same `box-shadow`
|
|
425
|
-
* and each one moves on its own.
|
|
426
|
-
*
|
|
427
|
-
* It reads `--p-tint` and not `--p-glow`: the tint is the family colour bleeding
|
|
428
|
-
* into a shadow *under* the control, the glow is the light that arrives *on* it
|
|
429
|
-
* with the pointer. Two different lights, two different slots.
|
|
430
|
-
*/
|
|
431
|
-
const lift = '0 6px 16px -4px var(--p-tint)';
|
|
432
|
-
const liftHover = '0 10px 24px -6px var(--p-tint)';
|
|
433
|
-
/* Pressed, the control is against the sheet and its tint has nowhere to fall. */
|
|
434
|
-
const liftPress = '0 2px 6px -2px var(--p-tint)';
|
|
435
|
-
/**
|
|
436
|
-
* Every slot a control reads.
|
|
437
|
-
*
|
|
438
|
-
* The three elevation slots are resolved here rather than in CSS because
|
|
439
|
-
* hovering adds a level and pressing removes one, and doing that arithmetic in
|
|
440
|
-
* a stylesheet would mean four ladders instead of one.
|
|
441
|
-
*
|
|
442
|
-
* `variant` is taken for one reason: the two interaction-light slots switch
|
|
443
|
-
* with it. Light thrown onto a filled surface is white; onto a tinted or a bare
|
|
444
|
-
* one it has to be the family's own soft tint, or there is nothing for it to
|
|
445
|
-
* show up against.
|
|
446
|
-
*/
|
|
447
|
-
export function controlSlots(color, elevation, variant) {
|
|
448
|
-
const onFill = variant === 'solid';
|
|
449
|
-
return {
|
|
450
|
-
'--p-fill': `var(--plass-${color}-fill)`,
|
|
451
|
-
'--p-on-solid': `var(--plass-${color}-on-solid)`,
|
|
452
|
-
'--p-accent': `var(--plass-${color}-accent)`,
|
|
453
|
-
'--p-tint': `var(--plass-${color}-tint)`,
|
|
454
|
-
'--p-soft': `var(--plass-${color}-soft)`,
|
|
455
|
-
'--p-soft-hover': `var(--plass-${color}-soft-hover)`,
|
|
456
|
-
'--p-soft-press': `var(--plass-${color}-soft-press)`,
|
|
457
|
-
'--p-line': `var(--plass-${color}-line)`,
|
|
458
|
-
'--p-line-hover': `var(--plass-${color}-line-hover)`,
|
|
459
|
-
'--p-ring': `var(--plass-${color}-ring)`,
|
|
460
|
-
'--p-glow': onFill ? 'var(--plass-glow-on-fill)' : `var(--plass-${color}-soft)`,
|
|
461
|
-
'--p-flash': onFill ? 'var(--plass-flash-on-fill)' : `var(--plass-${color}-soft-hover)`,
|
|
462
|
-
'--p-elev': `var(--plass-shadow-${elevation})`,
|
|
463
|
-
'--p-elev-hover': `var(--plass-shadow-${Math.min(elevation + 1, 4)})`,
|
|
464
|
-
'--p-elev-press': `var(--plass-shadow-${Math.max(elevation - 1, 0)})`,
|
|
465
|
-
'--p-lift': lift,
|
|
466
|
-
'--p-lift-hover': liftHover,
|
|
467
|
-
'--p-lift-press': liftPress
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* The same slots for a surface that **holds** content rather than being
|
|
472
|
-
* pressed: a Box, a Card, a PlTextField's shell, a popup.
|
|
473
|
-
*
|
|
474
|
-
* There is no `--p-fill` and no `--p-lift` here, and that is the point. A
|
|
475
|
-
* container's sheet is the undyed glass, because what it holds arrives with its
|
|
476
|
-
* own colours and tinting the sheet under them puts every one on a background
|
|
477
|
-
* it was not chosen against. The family shows up in the hairline, the focus
|
|
478
|
-
* ring and the caret, and the glass stays clear.
|
|
479
|
-
*/
|
|
480
|
-
export function surfaceSlots(color, elevation) {
|
|
481
|
-
return {
|
|
482
|
-
'--p-accent': `var(--plass-${color}-accent)`,
|
|
483
|
-
'--p-soft': `var(--plass-${color}-soft)`,
|
|
484
|
-
'--p-soft-hover': `var(--plass-${color}-soft-hover)`,
|
|
485
|
-
'--p-soft-press': `var(--plass-${color}-soft-press)`,
|
|
486
|
-
'--p-line': `var(--plass-${color}-line)`,
|
|
487
|
-
'--p-line-hover': `var(--plass-${color}-line-hover)`,
|
|
488
|
-
'--p-ring': `var(--plass-${color}-ring)`,
|
|
489
|
-
'--p-elev': `var(--plass-shadow-${elevation})`,
|
|
490
|
-
'--p-elev-hover': `var(--plass-shadow-${Math.min(elevation + 1, 4)})`,
|
|
491
|
-
'--p-elev-press': `var(--plass-shadow-${Math.max(elevation - 1, 0)})`
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
/* ---------------------------------------------------------------------------
|
|
495
|
-
* Shared state treatments
|
|
496
|
-
* ------------------------------------------------------------------------- */
|
|
497
|
-
/**
|
|
498
|
-
* Disabled is **the light going out.** The key keeps its shape, its colour and
|
|
499
|
-
* its place in the layout, and stops catching any light: no gloss, no tinted
|
|
500
|
-
* lift, no shadow, most of the saturation gone and half the opacity with it.
|
|
501
|
-
*
|
|
502
|
-
* Opacity is doing real work here rather than standing in for a decision, which
|
|
503
|
-
* is the usual complaint against it. On a page made of translucent sheets, a
|
|
504
|
-
* surface that has gone part-transparent is a surface the page is showing
|
|
505
|
-
* *through* — it has stopped being an object. That reads as unavailable in a
|
|
506
|
-
* way a grey swatch does not, and it is the one state in the library that uses
|
|
507
|
-
* the axis.
|
|
508
|
-
*/
|
|
509
|
-
export const disabledClasses = {
|
|
510
|
-
solid: /* @__PURE__ */ [
|
|
511
|
-
'cursor-not-allowed text-(--p-on-solid) [background-image:var(--p-fill)]',
|
|
512
|
-
'opacity-50 saturate-[0.35] shadow-none'
|
|
513
|
-
].join(' '),
|
|
514
|
-
glass: /* @__PURE__ */ [
|
|
515
|
-
glassClasses,
|
|
516
|
-
'cursor-not-allowed border text-(--plass-fg) bg-(--plass-glass)',
|
|
517
|
-
'[border-color:var(--plass-border)]',
|
|
518
|
-
'opacity-50 saturate-[0.35] shadow-none'
|
|
519
|
-
].join(' '),
|
|
520
|
-
ghost: 'cursor-not-allowed bg-transparent text-(--p-accent) opacity-50 saturate-[0.35]'
|
|
521
|
-
};
|
|
522
|
-
/**
|
|
523
|
-
* Read-only keeps the colour and the edge, goes flat and drains most of the
|
|
524
|
-
* saturation — a label that happens to be control-shaped. It is not dimmed:
|
|
525
|
-
* the value is still there to be read and copied, which is the whole difference
|
|
526
|
-
* from `disabled`.
|
|
527
|
-
*
|
|
528
|
-
* The cursor is left to the component. A read-only button stops being something
|
|
529
|
-
* you click; a read-only field is still something you select text out of.
|
|
530
|
-
*/
|
|
531
|
-
export const readOnlyFilterClasses = 'saturate-[0.55]';
|
|
532
|
-
/**
|
|
533
|
-
* The sheet a **container** is drawn on — a PlCard, a PlAccordion, a PlTable, a
|
|
534
|
-
* PlModal's panel. Everything that holds other people's content rather than
|
|
535
|
-
* being pressed.
|
|
536
|
-
*
|
|
537
|
-
* The three variants say what they say everywhere else, read as a *material*
|
|
538
|
-
* rather than as an appearance, and the ladder between them is opacity:
|
|
539
|
-
*
|
|
540
|
-
* - `solid` — the clear glass at its most opaque. The sheet you cannot see the
|
|
541
|
-
* page through, for a panel that has to sit forward of everything around it.
|
|
542
|
-
* No border, because a slab that dense has no edge left to catch light on.
|
|
543
|
-
* - `glass` — the canonical Plass sheet, and the default on every container:
|
|
544
|
-
* translucent, blurred, a white hairline round it and the light lying along
|
|
545
|
-
* its top edge.
|
|
546
|
-
* - `ghost` — no sheet at all. For a container inside a container, where a
|
|
547
|
-
* second bordered rectangle is a second rectangle.
|
|
548
|
-
*
|
|
549
|
-
* None of the three is dyed, and there is no `--p-fill` in `surfaceSlots` to
|
|
550
|
-
* dye them with. What a container holds arrives with its own colours; the
|
|
551
|
-
* family reaches the hairline, the focus ring and the caret and stops.
|
|
552
|
-
*/
|
|
553
|
-
export const sheetRestClasses = {
|
|
554
|
-
solid: /* @__PURE__ */ [
|
|
555
|
-
glassClasses,
|
|
556
|
-
'text-(--plass-fg) bg-(--plass-glass-press)',
|
|
557
|
-
'[box-shadow:var(--p-elev),var(--plass-gloss-glass)]'
|
|
558
|
-
].join(' '),
|
|
559
|
-
glass: /* @__PURE__ */ [
|
|
560
|
-
glassClasses,
|
|
561
|
-
'border text-(--plass-fg) bg-(--plass-glass)',
|
|
562
|
-
'[border-color:var(--plass-glass-line)]',
|
|
563
|
-
'[box-shadow:var(--p-elev),var(--plass-gloss-glass)]'
|
|
564
|
-
].join(' '),
|
|
565
|
-
ghost: 'text-(--plass-fg) bg-transparent'
|
|
566
|
-
};
|
|
567
|
-
/**
|
|
568
|
-
* The shell a field-shaped control is drawn on — a PlTextField's box and a
|
|
569
|
-
* Select's trigger, which have to be indistinguishable or a form looks like two
|
|
570
|
-
* different forms stacked on each other.
|
|
571
|
-
*
|
|
572
|
-
* The three variants say what they say everywhere else, with one deliberate
|
|
573
|
-
* difference: `solid` is not a moulded key. What a field holds is user data,
|
|
574
|
-
* and a caret, a text selection and a placeholder all have to stay legible on
|
|
575
|
-
* top of it, which they are not on a gradient fill. So a `solid` field is the
|
|
576
|
-
* **well** — the glass at its most opaque with an inset shadow falling into it,
|
|
577
|
-
* the one shadow in the library that points downward — and the colour family
|
|
578
|
-
* shows up in the hairline, the ring and the caret instead.
|
|
579
|
-
*
|
|
580
|
-
* The edge is `--plass-border` and not the sheet's own `--plass-glass-line`,
|
|
581
|
-
* which is the same correction a PlCheckbox's tick, a PlRadio's ring and a
|
|
582
|
-
* PlTabs rail already carry, made for the third time and for the last: white
|
|
583
|
-
* light on a cut edge is a claim about the page wash behind the pane, and a
|
|
584
|
-
* field is very often *not* on the page — it is on a card, and a white hairline
|
|
585
|
-
* round a 76%-white box on a white card is a field a reader cannot see the
|
|
586
|
-
* shape of. A neutral hairline reads on both, and it means every edge on a form
|
|
587
|
-
* — the tick beside the field, the switch under it, the rail over it — is one
|
|
588
|
-
* line rather than two kinds of line that only agree on one background.
|
|
589
|
-
*/
|
|
590
|
-
export const fieldRestClasses = {
|
|
591
|
-
solid: /* @__PURE__ */ [
|
|
592
|
-
glassClasses,
|
|
593
|
-
'text-(--plass-fg) bg-(--plass-glass-press)',
|
|
594
|
-
'[box-shadow:var(--p-elev),var(--plass-well)]',
|
|
595
|
-
'hover:bg-(--plass-glass-hover)',
|
|
596
|
-
'focus-within:bg-(--plass-glass-press)'
|
|
597
|
-
].join(' '),
|
|
598
|
-
glass: /* @__PURE__ */ [
|
|
599
|
-
glassClasses,
|
|
600
|
-
'border text-(--plass-fg) bg-(--plass-glass-hover)',
|
|
601
|
-
'[border-color:var(--plass-border)]',
|
|
602
|
-
'[box-shadow:var(--p-elev),var(--plass-gloss-glass)]',
|
|
603
|
-
'hover:bg-(--plass-glass-press) hover:[border-color:var(--p-line)]',
|
|
604
|
-
'focus-within:bg-(--plass-glass-press) focus-within:[border-color:var(--p-line-hover)]'
|
|
605
|
-
].join(' '),
|
|
606
|
-
// No surface until it is wanted — the field in a table cell that only looks
|
|
607
|
-
// like a field once you go near it.
|
|
608
|
-
ghost: /* @__PURE__ */ [
|
|
609
|
-
'text-(--plass-fg) bg-transparent',
|
|
610
|
-
'hover:bg-(--p-soft)',
|
|
611
|
-
'focus-within:bg-(--p-soft-hover)'
|
|
612
|
-
].join(' ')
|
|
613
|
-
};
|
|
614
|
-
/** The same three, held still. */
|
|
615
|
-
export const fieldReadOnlyClasses = {
|
|
616
|
-
solid: /* @__PURE__ */ [
|
|
617
|
-
glassClasses,
|
|
618
|
-
'text-(--plass-fg) bg-(--plass-glass-press)',
|
|
619
|
-
`[box-shadow:var(--plass-well)] ${readOnlyFilterClasses}`
|
|
620
|
-
].join(' '),
|
|
621
|
-
glass: /* @__PURE__ */ [
|
|
622
|
-
glassClasses,
|
|
623
|
-
'border text-(--plass-fg) bg-(--plass-glass-hover)',
|
|
624
|
-
'[border-color:var(--plass-border)]',
|
|
625
|
-
`[box-shadow:var(--plass-gloss-glass)] ${readOnlyFilterClasses}`
|
|
626
|
-
].join(' '),
|
|
627
|
-
ghost: `text-(--plass-fg) bg-transparent ${readOnlyFilterClasses}`
|
|
628
|
-
};
|
|
629
|
-
/** `false`, `null`, `undefined` and `''` all mean "this slot is not filled". */
|
|
630
|
-
export function hasContent(node) {
|
|
631
|
-
return node !== undefined && node !== null && node !== false && node !== '';
|
|
632
|
-
}
|
|
633
|
-
/** Joins class name fragments, dropping the empty ones. */
|
|
634
|
-
export function cx(...parts) {
|
|
635
|
-
return parts.filter(Boolean).join(' ');
|
|
636
|
-
}
|
|
1
|
+
export const radiusClasses={xs:"rounded-(--plass-radius-xs)",sm:"rounded-(--plass-radius-sm)",md:"rounded-(--plass-radius-md)",lg:"rounded-(--plass-radius-lg)",xl:"rounded-(--plass-radius-xl)"};export const controlHeightClasses={xs:"h-6",sm:"h-8",md:"h-10",lg:"h-12",xl:"h-14"};export const controlSquareClasses={xs:"w-6",sm:"w-8",md:"w-10",lg:"w-12",xl:"w-14"};export const controlTextClasses={xs:"text-[0.6875rem]",sm:"text-[0.8125rem]",md:"text-[0.875rem]",lg:"text-[1rem]",xl:"text-[1.125rem]"};export const controlTextLeadingClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.875rem]/[1.25rem]",lg:"text-[1rem]/[1.5rem]",xl:"text-[1.125rem]/[1.75rem]"};export const metaTextClasses={xs:"text-[0.625rem]",sm:"text-[0.6875rem]",md:"text-[0.75rem]",lg:"text-[0.8125rem]",xl:"text-[0.875rem]"};export const paddingXClasses={default:{xs:"px-2.5",sm:"px-3",md:"px-4",lg:"px-6",xl:"px-7"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3.5",xl:"px-4"}};export const iconSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-5",lg:"size-6",xl:"size-7"};export const tickSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-4.5",lg:"size-5",xl:"size-6"};export const tickRadiusClasses={xs:"rounded-[0.25rem]",sm:"rounded-[0.3125rem]",md:"rounded-[0.375rem]",lg:"rounded-[0.4375rem]",xl:"rounded-[0.5rem]"};export const tickDotClasses={xs:"size-1.5",sm:"size-1.5",md:"size-2",lg:"size-2",xl:"size-2.5"};export const tickRowTextClasses=controlTextLeadingClasses;export const paddingXValues={default:{xs:"0.625rem",sm:"0.75rem",md:"1rem",lg:"1.5rem",xl:"1.75rem"},compact:{xs:"0.375rem",sm:"0.5rem",md:"0.625rem",lg:"0.875rem",xl:"1rem"}};export const gapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"};export const stackGapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-1.5",lg:"gap-2",xl:"gap-2"};export const sheetPaddingXClasses={default:{xs:"px-2.5",sm:"px-3.5",md:"px-5",lg:"px-6",xl:"px-7"},compact:{xs:"px-2",sm:"px-2.5",md:"px-3.5",lg:"px-4",xl:"px-5"}};export const sheetPaddingYClasses={default:{xs:"py-2.5",sm:"py-3.5",md:"py-5",lg:"py-6",xl:"py-7"},compact:{xs:"py-2",sm:"py-2.5",md:"py-3.5",lg:"py-4",xl:"py-5"}};export const sheetTitleClasses={xs:"text-[0.75rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.9375rem]/[1.25rem]",lg:"text-[1.0625rem]/[1.5rem]",xl:"text-[1.25rem]/[1.75rem]"};export const sheetBodyClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.75rem]/[1.125rem]",md:"text-[0.8125rem]/[1.375rem]",lg:"text-[0.9375rem]/[1.5rem]",xl:"text-[1.0625rem]/[1.75rem]"};export const sheetSectionGapClasses={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-3.5",xl:"gap-4"};export const sheetLineClasses="border-t [border-color:var(--plass-divider)]";export const sheetHeaderGapClasses={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const glassClasses="[backdrop-filter:var(--plass-blur)] [-webkit-backdrop-filter:var(--plass-blur)]";export const transitionClasses=/* @__PURE__ */["[transition-property:background-color,background-image,border-color,box-shadow,color,filter]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]"].join(" ");export const focusRingClasses="focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:[outline-offset:0px]";export const focusWithinRingClasses="has-[:focus-visible]:[outline:2px_solid_var(--p-ring)] has-[:focus-visible]:[outline-offset:0px]";export const focusRingInsetClasses="focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:[outline-offset:-2px]";export const chipRemoveClasses=/* @__PURE__ */["ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full","size-[1.15em] cursor-pointer opacity-70","[transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",focusRingClasses,"disabled:cursor-not-allowed"].join(" ");export const iconClasses="[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";export const srOnlyClasses="absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";export function controlSlots(s,e,a){const r="solid"===a;return{"--p-fill":`var(--plass-${s}-fill)`,"--p-on-solid":`var(--plass-${s}-on-solid)`,"--p-accent":`var(--plass-${s}-accent)`,"--p-tint":`var(--plass-${s}-tint)`,"--p-soft":`var(--plass-${s}-soft)`,"--p-soft-hover":`var(--plass-${s}-soft-hover)`,"--p-soft-press":`var(--plass-${s}-soft-press)`,"--p-line":`var(--plass-${s}-line)`,"--p-line-hover":`var(--plass-${s}-line-hover)`,"--p-ring":`var(--plass-${s}-ring)`,"--p-glow":r?"var(--plass-glow-on-fill)":`var(--plass-${s}-soft)`,"--p-flash":r?"var(--plass-flash-on-fill)":`var(--plass-${s}-soft-hover)`,"--p-elev":`var(--plass-shadow-${e})`,"--p-elev-hover":`var(--plass-shadow-${Math.min(e+1,4)})`,"--p-elev-press":`var(--plass-shadow-${Math.max(e-1,0)})`,"--p-lift":"0 6px 16px -4px var(--p-tint)","--p-lift-hover":"0 10px 24px -6px var(--p-tint)","--p-lift-press":"0 2px 6px -2px var(--p-tint)"}}export function surfaceSlots(s,e){return{"--p-accent":`var(--plass-${s}-accent)`,"--p-soft":`var(--plass-${s}-soft)`,"--p-soft-hover":`var(--plass-${s}-soft-hover)`,"--p-soft-press":`var(--plass-${s}-soft-press)`,"--p-line":`var(--plass-${s}-line)`,"--p-line-hover":`var(--plass-${s}-line-hover)`,"--p-ring":`var(--plass-${s}-ring)`,"--p-elev":`var(--plass-shadow-${e})`,"--p-elev-hover":`var(--plass-shadow-${Math.min(e+1,4)})`,"--p-elev-press":`var(--plass-shadow-${Math.max(e-1,0)})`}}export const disabledClasses={solid:/* @__PURE__ */["cursor-not-allowed text-(--p-on-solid) [background-image:var(--p-fill)]","opacity-50 saturate-[0.35] shadow-none"].join(" "),glass:/* @__PURE__ */[glassClasses,"cursor-not-allowed border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--plass-border)]","opacity-50 saturate-[0.35] shadow-none"].join(" "),ghost:"cursor-not-allowed bg-transparent text-(--p-accent) opacity-50 saturate-[0.35]"};export const readOnlyFilterClasses="saturate-[0.55]";export const sheetRestClasses={solid:/* @__PURE__ */[glassClasses,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[glassClasses,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-transparent"};export const fieldRestClasses={solid:/* @__PURE__ */[glassClasses,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-well)]","hover:bg-(--plass-glass-hover)","focus-within:bg-(--plass-glass-press)"].join(" "),glass:/* @__PURE__ */[glassClasses,"border text-(--plass-fg) bg-(--plass-glass-hover)","[border-color:var(--plass-border)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]","hover:bg-(--plass-glass-press) hover:[border-color:var(--p-line)]","focus-within:bg-(--plass-glass-press) focus-within:[border-color:var(--p-line-hover)]"].join(" "),ghost:/* @__PURE__ */["text-(--plass-fg) bg-transparent","hover:bg-(--p-soft)","focus-within:bg-(--p-soft-hover)"].join(" ")};export const fieldReadOnlyClasses={solid:/* @__PURE__ */[glassClasses,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-well)] saturate-[0.55]"].join(" "),glass:/* @__PURE__ */[glassClasses,"border text-(--plass-fg) bg-(--plass-glass-hover)","[border-color:var(--plass-border)]","[box-shadow:var(--plass-gloss-glass)] saturate-[0.55]"].join(" "),ghost:"text-(--plass-fg) bg-transparent saturate-[0.55]"};export function hasContent(s){return null!=s&&!1!==s&&""!==s}export function cx(...s){return s.filter(Boolean).join(" ")}
|
package/dist/types.js
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared prop vocabulary for every Plass component.
|
|
3
|
-
*
|
|
4
|
-
* These names and values are deliberately generic: a `size` of `md` or a
|
|
5
|
-
* `color` of `primary` has to mean the same thing on a PlButton, a PlTextField, a
|
|
6
|
-
* Card or a Dialog. Components pick the subset they need from here and never
|
|
7
|
-
* invent a parallel spelling of the same idea.
|
|
8
|
-
*/
|