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
|
@@ -1,174 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { Toast as BaseUIToast } from '@base-ui/react/toast';
|
|
4
|
-
import { CloseIcon, severityIcon } from '../../internal/icons.js';
|
|
5
|
-
import { controlSlots, focusRingClasses, glassClasses, hasContent, iconClasses, metaTextClasses, radiusClasses, sheetBodyClasses, sheetHeaderGapClasses, sheetPaddingXClasses, sheetPaddingYClasses, sheetSectionGapClasses, sheetTitleClasses } from '../../internal/styles.js';
|
|
6
|
-
/**
|
|
7
|
-
* How a stack is pinned, per position.
|
|
8
|
-
*
|
|
9
|
-
* The viewport is full width in every case and the alignment is done with
|
|
10
|
-
* `items-*`, rather than by pinning one edge and nudging the centre back with a
|
|
11
|
-
* translate. That keeps the one `transform` this component could have wanted out
|
|
12
|
-
* of it, and it means the same three classes serve all six positions.
|
|
13
|
-
*/
|
|
14
|
-
const viewportClasses = {
|
|
15
|
-
'top-start': 'top-0 items-start',
|
|
16
|
-
'top-center': 'top-0 items-center',
|
|
17
|
-
'top-end': 'top-0 items-end',
|
|
18
|
-
'bottom-start': 'bottom-0 flex-col-reverse items-start',
|
|
19
|
-
'bottom-center': 'bottom-0 flex-col-reverse items-center',
|
|
20
|
-
'bottom-end': 'bottom-0 flex-col-reverse items-end'
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* A toast floats over the page, so — with the `PlSelect` popup, the `PlModal`
|
|
24
|
-
* sheet and the `PlTooltip` plate — it carries a shadow by default, at level 3.
|
|
25
|
-
*
|
|
26
|
-
* The two undyed materials are the glass at its most opaque, for the reason the
|
|
27
|
-
* modal's sheet is: what is behind a toast is arbitrary, and a 62%-translucent
|
|
28
|
-
* pane over a photograph is a pane you read the photograph through.
|
|
29
|
-
*/
|
|
30
|
-
const rootClasses = {
|
|
31
|
-
solid: /* @__PURE__ */ [
|
|
32
|
-
'text-(--p-on-solid) [background-image:var(--p-fill)]',
|
|
33
|
-
'[box-shadow:var(--plass-shadow-3),var(--p-lift)]'
|
|
34
|
-
].join(' '),
|
|
35
|
-
glass: /* @__PURE__ */ [
|
|
36
|
-
glassClasses,
|
|
37
|
-
'border text-(--plass-fg) bg-(--plass-glass-press)',
|
|
38
|
-
'[border-color:var(--p-line)]',
|
|
39
|
-
'[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]'
|
|
40
|
-
].join(' '),
|
|
41
|
-
ghost: /* @__PURE__ */ [
|
|
42
|
-
glassClasses,
|
|
43
|
-
'text-(--plass-fg) bg-(--plass-glass-press)',
|
|
44
|
-
'[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]'
|
|
45
|
-
].join(' ')
|
|
46
|
-
};
|
|
47
|
-
const accentClasses = {
|
|
48
|
-
solid: '',
|
|
49
|
-
glass: 'text-(--p-accent)',
|
|
50
|
-
ghost: 'text-(--p-accent)'
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Turns a Plass toast into the object Base UI's manager stores.
|
|
54
|
-
*
|
|
55
|
-
* The style props go into `data` rather than becoming top-level fields, because
|
|
56
|
-
* `data` is the slot Base UI reserves for exactly this and the alternative —
|
|
57
|
-
* shadowing the manager's own option names — is how a library ends up with two
|
|
58
|
-
* `type` props that mean different things.
|
|
59
|
-
*/
|
|
60
|
-
function toManagerOptions(options) {
|
|
61
|
-
const { color, variant, icon, actionLabel, onAction, ...rest } = options;
|
|
62
|
-
return {
|
|
63
|
-
...rest,
|
|
64
|
-
data: { color, variant, icon },
|
|
65
|
-
actionProps: actionLabel === undefined
|
|
66
|
-
? undefined
|
|
67
|
-
: { children: actionLabel, onClick: onAction }
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Raises toasts from anywhere under a `PlToastProvider`.
|
|
72
|
-
*
|
|
73
|
-
* A hook rather than a component, because the thing a caller has at the moment a
|
|
74
|
-
* toast is warranted is a click handler, not a place in the tree — and a
|
|
75
|
-
* `<PlToast open={…} />` they would have to keep mounted, with a piece of state
|
|
76
|
-
* per message, is the shape this component exists to avoid.
|
|
77
|
-
*/
|
|
78
|
-
export function usePlToast() {
|
|
79
|
-
const manager = BaseUIToast.useToastManager();
|
|
80
|
-
return React.useMemo(() => ({
|
|
81
|
-
/** Raises a toast and returns its id. */
|
|
82
|
-
add: (options) => manager.add(toManagerOptions(options)),
|
|
83
|
-
/** Closes one toast, or every toast when called with nothing. */
|
|
84
|
-
close: (id) => manager.close(id),
|
|
85
|
-
/** Changes a toast already on screen. */
|
|
86
|
-
update: (id, options) => manager.update(id, toManagerOptions(options)),
|
|
87
|
-
/**
|
|
88
|
-
* One toast that follows a promise: the loading message while it runs, then
|
|
89
|
-
* the success or the error. `timeout: 0` is applied to the loading state by
|
|
90
|
-
* Base UI, so a slow request cannot dismiss its own toast.
|
|
91
|
-
*/
|
|
92
|
-
promise: (promise, options) => manager.promise(promise, {
|
|
93
|
-
loading: toManagerOptions(options.loading),
|
|
94
|
-
success: (value) => toManagerOptions(typeof options.success === 'function' ? options.success(value) : options.success),
|
|
95
|
-
error: (error) => toManagerOptions(typeof options.error === 'function' ? options.error(error) : options.error)
|
|
96
|
-
}),
|
|
97
|
-
/** Every toast currently in the stack, newest first. */
|
|
98
|
-
toasts: manager.toasts
|
|
99
|
-
}), [manager]);
|
|
100
|
-
}
|
|
101
|
-
function ToastItem({ toast, variant: providerVariant, color: providerColor, size, density, closeLabel, swipeDirection }) {
|
|
102
|
-
const variant = toast.data?.variant ?? providerVariant ?? 'glass';
|
|
103
|
-
const color = toast.data?.color ?? providerColor;
|
|
104
|
-
const glyph = toast.data?.icon === undefined ? severityIcon(color) : toast.data.icon;
|
|
105
|
-
const accent = accentClasses[variant];
|
|
106
|
-
const titled = hasContent(toast.title);
|
|
107
|
-
return (_jsxs(BaseUIToast.Root, { toast: toast, swipeDirection: swipeDirection, className: [
|
|
108
|
-
'pointer-events-auto flex w-full items-start',
|
|
109
|
-
sheetPaddingXClasses[density ?? 'default'][size],
|
|
110
|
-
sheetPaddingYClasses[density ?? 'default'][size],
|
|
111
|
-
radiusClasses[size],
|
|
112
|
-
sheetSectionGapClasses[size],
|
|
113
|
-
sheetBodyClasses[size],
|
|
114
|
-
rootClasses[variant],
|
|
115
|
-
iconClasses,
|
|
116
|
-
// Opacity, and only opacity — the same restraint the modal shows, and
|
|
117
|
-
// for the same reason: this is a box full of text. Base UI still moves
|
|
118
|
-
// it while a finger is dragging it, which is the reader's hand rather
|
|
119
|
-
// than a state change, and it stops the moment the finger lifts.
|
|
120
|
-
'[transition:opacity_var(--plass-duration)_var(--plass-ease)]',
|
|
121
|
-
'data-[starting-style]:opacity-0 data-[ending-style]:opacity-0',
|
|
122
|
-
// A toast pushed out by the limit is kept in the DOM so it can come
|
|
123
|
-
// back; it just has nothing to say while it waits.
|
|
124
|
-
'data-[limited]:hidden',
|
|
125
|
-
focusRingClasses,
|
|
126
|
-
'[outline:none]'
|
|
127
|
-
]
|
|
128
|
-
.filter(Boolean)
|
|
129
|
-
.join(' '), style: controlSlots(color, 3, variant), children: [hasContent(glyph) ? (_jsx("span", { className: `flex h-[1lh] shrink-0 items-center ${accent}`, children: glyph })) : null, _jsxs("div", { className: `flex min-w-0 flex-1 flex-col ${sheetHeaderGapClasses[size]}`, children: [_jsx(BaseUIToast.Title, { className: `plass-title font-semibold ${sheetTitleClasses[size]} ${accent}` }), _jsx(BaseUIToast.Description, { className: titled && variant !== 'solid' ? 'text-(--plass-muted-fg)' : '' })] }), _jsx(BaseUIToast.Action, { className: [
|
|
130
|
-
'flex h-[1lh] shrink-0 cursor-pointer items-center rounded-full px-2',
|
|
131
|
-
'font-medium underline-offset-2',
|
|
132
|
-
accent || 'text-(--p-on-solid)',
|
|
133
|
-
'hover:underline',
|
|
134
|
-
focusRingClasses,
|
|
135
|
-
metaTextClasses[size]
|
|
136
|
-
].join(' ') }), _jsx("span", { className: "flex h-[1lh] shrink-0 items-center", children: _jsx(BaseUIToast.Close, { "aria-label": closeLabel, className: [
|
|
137
|
-
'inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full',
|
|
138
|
-
'opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]',
|
|
139
|
-
'hover:opacity-100 focus-visible:opacity-100',
|
|
140
|
-
focusRingClasses
|
|
141
|
-
].join(' '), children: _jsx(CloseIcon, {}) }) })] }));
|
|
142
|
-
}
|
|
143
|
-
/** The stack itself. Rendered by the provider, never by a caller. */
|
|
144
|
-
function ToastViewport(props) {
|
|
145
|
-
const { toasts } = BaseUIToast.useToastManager();
|
|
146
|
-
const { position, width, ...rest } = props;
|
|
147
|
-
const swipeDirection = [
|
|
148
|
-
position.startsWith('top') ? 'up' : 'down',
|
|
149
|
-
'left',
|
|
150
|
-
'right'
|
|
151
|
-
];
|
|
152
|
-
return (_jsx(BaseUIToast.Portal, { children: _jsx(BaseUIToast.Viewport, { className: [
|
|
153
|
-
// Full width and `pointer-events-none`, so the strip across the top or
|
|
154
|
-
// the bottom of the page is not a wall the rest of the app is behind.
|
|
155
|
-
// The toasts themselves take their events back.
|
|
156
|
-
'plass-portal pointer-events-none fixed inset-x-0 z-50 flex flex-col gap-2 p-4',
|
|
157
|
-
viewportClasses[position]
|
|
158
|
-
].join(' '), children: toasts.map((toast) => (_jsx("div", { className: "w-full", style: { maxWidth: typeof width === 'number' ? `${width}px` : width }, children: _jsx(ToastItem, { toast: toast, swipeDirection: swipeDirection, ...rest }) }, toast.id))) }) }));
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Puts the toast stack on the page and lets anything under it raise a message.
|
|
162
|
-
*
|
|
163
|
-
* Wrap the application once. Everything about how a toast *looks* is decided
|
|
164
|
-
* here — where the stack sits, how wide it is, which material it wears, how long
|
|
165
|
-
* it lasts — so the call site stays the one thing it should be: what happened.
|
|
166
|
-
*
|
|
167
|
-
* Base UI owns the parts of this that are genuinely hard and invisible when they
|
|
168
|
-
* work: the timers and their pausing on hover and on window blur, the limit, the
|
|
169
|
-
* swipe, the F6 focus hotkey, and the live region that makes a message which
|
|
170
|
-
* appeared out of nowhere reach a screen reader at all.
|
|
171
|
-
*/
|
|
172
|
-
export function PlToastProvider({ variant = 'glass', size = 'md', color = 'primary', density = 'default', position = 'bottom-end', timeout = 5000, limit = 3, width = 380, closeLabel = 'Close', children }) {
|
|
173
|
-
return (_jsxs(BaseUIToast.Provider, { timeout: timeout, limit: limit, children: [children, _jsx(ToastViewport, { position: position, variant: variant, size: size, color: color, density: density, width: width, closeLabel: closeLabel })] }));
|
|
174
|
-
}
|
|
1
|
+
"use client";import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as s from"react";import{Toast as o}from"@base-ui/react/toast";import{CloseIcon as a,severityIcon as i}from"../../internal/icons.js";import{controlSlots as r,focusRingClasses as n,glassClasses as l,hasContent as c,iconClasses as p,metaTextClasses as d,radiusClasses as m,sheetBodyClasses as u,sheetHeaderGapClasses as f,sheetPaddingXClasses as h,sheetPaddingYClasses as g,sheetSectionGapClasses as v,sheetTitleClasses as x}from"../../internal/styles.js";const b={"top-start":"top-0 items-start","top-center":"top-0 items-center","top-end":"top-0 items-end","bottom-start":"bottom-0 flex-col-reverse items-start","bottom-center":"bottom-0 flex-col-reverse items-center","bottom-end":"bottom-0 flex-col-reverse items-end"},y={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--plass-shadow-3),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[l,"border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--p-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" "),ghost:/* @__PURE__ */[l,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]"].join(" ")},w={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"};function toManagerOptions(t){const{color:e,variant:s,icon:o,actionLabel:a,onAction:i,...r}=t;return{...r,data:{color:e,variant:s,icon:o},actionProps:void 0===a?void 0:{children:a,onClick:i}}}export function usePlToast(){const t=o.useToastManager();return s.useMemo(()=>({add:e=>t.add(toManagerOptions(e)),close:e=>t.close(e),update:(e,s)=>t.update(e,toManagerOptions(s)),promise:(e,s)=>t.promise(e,{loading:toManagerOptions(s.loading),success:t=>toManagerOptions("function"==typeof s.success?s.success(t):s.success),error:t=>toManagerOptions("function"==typeof s.error?s.error(t):s.error)}),toasts:t.toasts}),[t])}function ToastItem({toast:s,variant:l,color:b,size:j,density:N,closeLabel:T,swipeDirection:M}){const O=s.data?.variant??l??"glass",P=s.data?.color??b,k=void 0===s.data?.icon?i(P):s.data.icon,z=w[O],$=c(s.title);return e(o.Root,{toast:s,swipeDirection:M,className:["pointer-events-auto flex w-full items-start",h[N??"default"][j],g[N??"default"][j],m[j],v[j],u[j],y[O],p,"[transition:opacity_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0","data-[limited]:hidden",n,"[outline:none]"].filter(Boolean).join(" "),style:r(P,3,O),children:[c(k)?t("span",{className:`flex h-[1lh] shrink-0 items-center ${z}`,children:k}):null,e("div",{className:`flex min-w-0 flex-1 flex-col ${f[j]}`,children:[t(o.Title,{className:`plass-title font-semibold ${x[j]} ${z}`}),t(o.Description,{className:$&&"solid"!==O?"text-(--plass-muted-fg)":""})]}),t(o.Action,{className:["flex h-[1lh] shrink-0 cursor-pointer items-center rounded-full px-2","font-medium underline-offset-2",z||"text-(--p-on-solid)","hover:underline",n,d[j]].join(" ")}),t("span",{className:"flex h-[1lh] shrink-0 items-center",children:t(o.Close,{"aria-label":T,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",n].join(" "),children:t(a,{})})})]})}function ToastViewport(e){const{toasts:s}=o.useToastManager(),{position:a,width:i,...r}=e,n=[a.startsWith("top")?"up":"down","left","right"];return t(o.Portal,{children:t(o.Viewport,{className:["plass-portal pointer-events-none fixed inset-x-0 z-50 flex flex-col gap-2 p-4",b[a]].join(" "),children:s.map(e=>t("div",{className:"w-full",style:{maxWidth:"number"==typeof i?`${i}px`:i},children:t(ToastItem,{toast:e,swipeDirection:n,...r})},e.id))})})}export function PlToastProvider({variant:s="glass",size:a="md",color:i="primary",density:r="default",position:n="bottom-end",timeout:l=5e3,limit:c=3,width:p=380,closeLabel:d="Close",children:m}){return e(o.Provider,{timeout:l,limit:c,children:[m,t(ToastViewport,{position:n,variant:s,size:a,color:i,density:r,width:p,closeLabel:d})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlToastProvider,usePlToast}from"./PlToast.js";
|
|
@@ -1,65 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
4
|
-
import { cx, hasContent, radiusClasses, sheetPaddingXClasses, sheetPaddingYClasses, sheetRestClasses, sheetSectionGapClasses, surfaceSlots, transitionClasses } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* The three materials, said the way a *container* says them — the bar is never
|
|
7
|
-
* dyed, exactly as on a `PlBox` and a `PlCard`. A toolbar holds other people's
|
|
8
|
-
* controls, and those controls arrive with colours of their own.
|
|
9
|
-
*/
|
|
10
|
-
const variantClasses = sheetRestClasses;
|
|
11
|
-
const positionClasses = {
|
|
12
|
-
static: { top: '', bottom: '' },
|
|
13
|
-
sticky: { top: 'sticky top-0 z-20', bottom: 'sticky bottom-0 z-20' },
|
|
14
|
-
fixed: { top: 'fixed inset-x-0 top-0 z-30', bottom: 'fixed inset-x-0 bottom-0 z-30' }
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* The rule faces the content, so it moves to the other edge on a bottom bar.
|
|
18
|
-
*
|
|
19
|
-
* `--plass-divider` and not the sheet's own white edge line: this is a mark the
|
|
20
|
-
* sheet makes on *itself*, and white light on a cut edge only reads when the
|
|
21
|
-
* page wash is behind it.
|
|
22
|
-
*/
|
|
23
|
-
const dividerClasses = {
|
|
24
|
-
top: 'border-b [border-color:var(--plass-divider)]',
|
|
25
|
-
bottom: 'border-t [border-color:var(--plass-divider)]'
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* A bar of controls: an application header, a page's action row, the strip along
|
|
29
|
-
* the bottom of an editor.
|
|
30
|
-
*
|
|
31
|
-
* Three slots and a row. `start` and `end` are pinned to their ends and
|
|
32
|
-
* `children` takes what is left, which is the arrangement every toolbar has ever
|
|
33
|
-
* had — so it is laid out here rather than left to a caller and a spacer `<div>`
|
|
34
|
-
* they have to remember.
|
|
35
|
-
*
|
|
36
|
-
* The one thing it does not do is take a height. A toolbar is as tall as the
|
|
37
|
-
* controls in it plus its padding, and that padding is the `size` / `density`
|
|
38
|
-
* pair every other surface uses — so `density="compact"` gives the dense bar
|
|
39
|
-
* without a second prop meaning the same thing, and without the type scale
|
|
40
|
-
* moving.
|
|
41
|
-
*
|
|
42
|
-
* It has **no `role="toolbar"`**, deliberately. That role is a promise about
|
|
43
|
-
* keyboard behaviour — one tab stop for the whole bar, arrow keys between the
|
|
44
|
-
* controls in it — and a bar that claims it without implementing it is worse for
|
|
45
|
-
* a keyboard reader than one that never claimed anything. What a page header
|
|
46
|
-
* wants is `render={<header />}`; what a genuine roving-focus set of choices
|
|
47
|
-
* wants is a `PlSegmentedButton`, which is one.
|
|
48
|
-
*/
|
|
49
|
-
export const PlToolbar = /* @__PURE__ */ React.forwardRef(function PlToolbar({ variant = 'glass', size = 'md', color = 'primary', density = 'default', elevation = 0, position = 'static', side = 'top', divider = false, start, end, render, className, style, children, ...props }, ref) {
|
|
50
|
-
const classNames = cx('flex w-full min-w-0 items-center', sheetPaddingXClasses[density][size], sheetPaddingYClasses[density][size], sheetSectionGapClasses[size],
|
|
51
|
-
// A pinned bar spans an edge of the window, and a rounded corner against
|
|
52
|
-
// the edge of the screen is a gap with nothing behind it. Only a bar
|
|
53
|
-
// sitting in the flow is a sheet with corners.
|
|
54
|
-
position === 'static' ? radiusClasses[size] : '', variantClasses[variant], divider ? dividerClasses[side] : '', positionClasses[position][side], transitionClasses, className);
|
|
55
|
-
return useRender({
|
|
56
|
-
render: render ?? _jsx("div", {}),
|
|
57
|
-
ref,
|
|
58
|
-
props: {
|
|
59
|
-
className: classNames,
|
|
60
|
-
style: { ...surfaceSlots(color, elevation), ...style },
|
|
61
|
-
children: (_jsxs(_Fragment, { children: [hasContent(start) ? (_jsx("div", { className: "flex min-w-0 shrink-0 items-center gap-2", children: start })) : null, _jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: children }), hasContent(end) ? (_jsx("div", { className: "flex min-w-0 shrink-0 items-center gap-2", children: end })) : null] })),
|
|
62
|
-
...props
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
1
|
+
"use client";import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as s from"react";import{useRender as i}from"@base-ui/react/use-render";import{cx as o,hasContent as a,radiusClasses as l,sheetPaddingXClasses as n,sheetPaddingYClasses as c,sheetRestClasses as d,sheetSectionGapClasses as m,surfaceSlots as p,transitionClasses as f}from"../../internal/styles.js";const b=d,x={static:{top:"",bottom:""},sticky:{top:"sticky top-0 z-20",bottom:"sticky bottom-0 z-20"},fixed:{top:"fixed inset-x-0 top-0 z-30",bottom:"fixed inset-x-0 bottom-0 z-30"}},v={top:"border-b [border-color:var(--plass-divider)]",bottom:"border-t [border-color:var(--plass-divider)]"};export const PlToolbar=/* @__PURE__ */s.forwardRef(function PlToolbar({variant:s="glass",size:d="md",color:u="primary",density:h="default",elevation:y=0,position:w="static",side:g="top",divider:k=!1,start:z,end:N,render:j,className:P,style:T,children:F,...R},q){const A=o("flex w-full min-w-0 items-center",n[h][d],c[h][d],m[d],"static"===w?l[d]:"",b[s],k?v[g]:"",x[w][g],f,P);return i({render:j??e("div",{}),ref:q,props:{className:A,style:{...p(u,y),...T},children:r(t,{children:[a(z)?e("div",{className:"flex min-w-0 shrink-0 items-center gap-2",children:z}):null,e("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:F}),a(N)?e("div",{className:"flex min-w-0 shrink-0 items-center gap-2",children:N}):null]}),...R}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlToolbar}from"./PlToolbar.js";
|
|
@@ -1,117 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { Tooltip as BaseUITooltip } from '@base-ui/react/tooltip';
|
|
4
|
-
import { glassClasses, metaTextClasses, paddingXClasses, radiusClasses, surfaceSlots } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* Shares one delay across a group of tooltips: once any of them has opened, its
|
|
7
|
-
* neighbours open instantly, and the wait comes back after a pause.
|
|
8
|
-
*
|
|
9
|
-
* Worth wrapping a toolbar in. Without it, moving along a row of icon buttons
|
|
10
|
-
* means waiting out the full delay at every stop, which is what makes tooltips
|
|
11
|
-
* feel like they are fighting the pointer.
|
|
12
|
-
*/
|
|
13
|
-
export const PlTooltipProvider = BaseUITooltip.Provider;
|
|
14
|
-
/**
|
|
15
|
-
* The plate, and it is the same floating sheet a `PlSelect`'s popup is: the
|
|
16
|
-
* glass at its most opaque, a white hairline round it, shadow 3 under it.
|
|
17
|
-
*
|
|
18
|
-
* Not a filled key, which is what most libraries draw a tooltip as. A tooltip is
|
|
19
|
-
* a note *about* something rather than a thing to press, and the library already
|
|
20
|
-
* has one answer for a surface that floats over arbitrary content — inventing a
|
|
21
|
-
* second would put two kinds of floating sheet on the same screen.
|
|
22
|
-
*
|
|
23
|
-
* `--plass-glass-press` is what makes that safe: at its most opaque the sheet is
|
|
24
|
-
* dense enough to read a line of text off, which the 62% pane is not.
|
|
25
|
-
*/
|
|
26
|
-
const popupClasses = /* @__PURE__ */ [
|
|
27
|
-
glassClasses,
|
|
28
|
-
'max-w-64 border text-(--plass-fg) bg-(--plass-glass-press)',
|
|
29
|
-
'[border-color:var(--plass-glass-line)]',
|
|
30
|
-
'[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]',
|
|
31
|
-
'[outline:none]',
|
|
32
|
-
// Opacity only, and fast: a tooltip that slides in has moved its own text
|
|
33
|
-
// while the reader was already looking at it.
|
|
34
|
-
'[transition:opacity_var(--plass-duration)_var(--plass-ease)]',
|
|
35
|
-
'data-[starting-style]:opacity-0 data-[ending-style]:opacity-0',
|
|
36
|
-
// Base UI sets this while the pointer is moving between grouped tooltips.
|
|
37
|
-
// Fading in a tooltip that is meant to appear instantly is worse than not
|
|
38
|
-
// fading at all — it reads as lag.
|
|
39
|
-
'data-[instant]:[transition-duration:0ms]'
|
|
40
|
-
].join(' ');
|
|
41
|
-
/** A row's vertical padding, against the horizontal track `paddingXClasses` sets. */
|
|
42
|
-
const paddingYClasses = {
|
|
43
|
-
xs: 'py-0.5',
|
|
44
|
-
sm: 'py-0.5',
|
|
45
|
-
md: 'py-1',
|
|
46
|
-
lg: 'py-1.5',
|
|
47
|
-
xl: 'py-2'
|
|
48
|
-
};
|
|
49
|
-
/** The wedge, at roughly a third of the plate's corner radius per step. */
|
|
50
|
-
const arrowSizes = {
|
|
51
|
-
xs: 6,
|
|
52
|
-
sm: 7,
|
|
53
|
-
md: 8,
|
|
54
|
-
lg: 9,
|
|
55
|
-
xl: 10
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* A short label that appears when the pointer rests on something.
|
|
59
|
-
*
|
|
60
|
-
* The whole component is a wrapper:
|
|
61
|
-
* `<PlTooltip content="Copy"><PlButton …/></PlTooltip>`. Base UI's Trigger
|
|
62
|
-
* merges itself onto the child rather than rendering a box of its own, so the
|
|
63
|
-
* tooltip adds no element to the layout and the child stays whatever it was — a
|
|
64
|
-
* button, a chip, a truncated cell.
|
|
65
|
-
*
|
|
66
|
-
* Base UI owns the parts that are genuinely hard: the delay and the group
|
|
67
|
-
* timeout, opening on focus but not on a focus that came from a click, closing
|
|
68
|
-
* on Escape, and keeping the popup off the edges of the window.
|
|
69
|
-
*
|
|
70
|
-
* The one thing it deliberately leaves open is the part that makes a tooltip
|
|
71
|
-
* mean anything to a screen reader — `role="tooltip"` on the plate and an
|
|
72
|
-
* `aria-describedby` pointing at it from the trigger — because a popup can be
|
|
73
|
-
* many things and only the caller knows which. Here it is always a tooltip, so
|
|
74
|
-
* this component wires both, and drops the reference while it is closed rather
|
|
75
|
-
* than pointing at an element that is not in the document.
|
|
76
|
-
*/
|
|
77
|
-
export function PlTooltip({ content, children, size = 'sm',
|
|
78
|
-
// A tooltip is a note about something else, never the thing itself, so the
|
|
79
|
-
// neutral family is the honest default. A red tooltip on a delete button would
|
|
80
|
-
// be saying something the tooltip does not know.
|
|
81
|
-
color = 'secondary', density = 'default', side = 'top', align = 'center', sideOffset = 6, delay, closeDelay, arrow = true, open, defaultOpen, onOpenChange, disabled = false, className, style, ...props }) {
|
|
82
|
-
const arrowSize = arrowSizes[size];
|
|
83
|
-
const popupId = React.useId();
|
|
84
|
-
// Mirrored rather than owned: `open` still drives a controlled tooltip and
|
|
85
|
-
// Base UI still drives an uncontrolled one. This copy exists only so the
|
|
86
|
-
// trigger knows whether the plate it describes is on the page yet.
|
|
87
|
-
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
|
|
88
|
-
const isOpen = open ?? uncontrolledOpen;
|
|
89
|
-
return (_jsxs(BaseUITooltip.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: (next) => {
|
|
90
|
-
setUncontrolledOpen(next);
|
|
91
|
-
onOpenChange?.(next);
|
|
92
|
-
}, children: [_jsx(BaseUITooltip.Trigger, { render: children, delay: delay, closeDelay: closeDelay, disabled: disabled, "aria-describedby": isOpen ? popupId : undefined }), _jsx(BaseUITooltip.Portal, { children: _jsx(BaseUITooltip.Positioner, { className: "plass-portal z-50 [outline:none]", side: side, align: align, sideOffset: sideOffset, children: _jsxs(BaseUITooltip.Popup, { id: popupId, role: "tooltip", className: [
|
|
93
|
-
popupClasses,
|
|
94
|
-
radiusClasses[size],
|
|
95
|
-
paddingXClasses[density][size],
|
|
96
|
-
paddingYClasses[size],
|
|
97
|
-
metaTextClasses[size],
|
|
98
|
-
className ?? ''
|
|
99
|
-
]
|
|
100
|
-
.filter(Boolean)
|
|
101
|
-
.join(' '), style: { ...surfaceSlots(color, 3), ...style }, ...props, children: [arrow ? (_jsx(BaseUITooltip.Arrow
|
|
102
|
-
// Base UI positions the arrow and reports which side it ended up
|
|
103
|
-
// on. The wedge is drawn pointing down and turned to match — a
|
|
104
|
-
// rotation of a glyph, which is the same allowance the chevron
|
|
105
|
-
// takes. Nothing with text in it moves.
|
|
106
|
-
, {
|
|
107
|
-
// Base UI positions the arrow and reports which side it ended up
|
|
108
|
-
// on. The wedge is drawn pointing down and turned to match — a
|
|
109
|
-
// rotation of a glyph, which is the same allowance the chevron
|
|
110
|
-
// takes. Nothing with text in it moves.
|
|
111
|
-
className: [
|
|
112
|
-
'data-[side=top]:bottom-[-1px]',
|
|
113
|
-
'data-[side=bottom]:top-[-1px] data-[side=bottom]:rotate-180',
|
|
114
|
-
'data-[side=left]:right-[-1px] data-[side=left]:-rotate-90',
|
|
115
|
-
'data-[side=right]:left-[-1px] data-[side=right]:rotate-90'
|
|
116
|
-
].join(' '), children: _jsxs("svg", { width: arrowSize, height: arrowSize / 2, viewBox: "0 0 10 5", "aria-hidden": "true", className: "block", children: [_jsx("path", { d: "M0 0h10L5 5z", fill: "var(--plass-glass-line)" }), _jsx("path", { d: "M0 0h10L5 5z", fill: "var(--plass-glass-press)", transform: "translate(0 -1)" })] }) })) : null, content] }) }) })] }));
|
|
117
|
-
}
|
|
1
|
+
"use client";import{jsx as s,jsxs as a}from"react/jsx-runtime";import*as e from"react";import{Tooltip as t}from"@base-ui/react/tooltip";import{glassClasses as o,metaTextClasses as l,paddingXClasses as i,radiusClasses as r,surfaceSlots as n}from"../../internal/styles.js";export const PlTooltipProvider=t.Provider;const d=/* @__PURE__ */[o,"max-w-64 border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]","[outline:none]","[transition:opacity_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0","data-[instant]:[transition-duration:0ms]"].join(" "),p={xs:"py-0.5",sm:"py-0.5",md:"py-1",lg:"py-1.5",xl:"py-2"},c={xs:6,sm:7,md:8,lg:9,xl:10};export function PlTooltip({content:o,children:m,size:g="sm",color:h="secondary",density:f="default",side:y="top",align:u="center",sideOffset:x=6,delay:b,closeDelay:v,arrow:j=!0,open:w,defaultOpen:P,onOpenChange:O,disabled:N=!1,className:z,style:T,...B}){const C=c[g],D=e.useId(),[L,M]=e.useState(P??!1),_=w??L;return a(t.Root,{open:w,defaultOpen:P,onOpenChange:s=>{M(s),O?.(s)},children:[s(t.Trigger,{render:m,delay:b,closeDelay:v,disabled:N,"aria-describedby":_?D:void 0}),s(t.Portal,{children:s(t.Positioner,{className:"plass-portal z-50 [outline:none]",side:y,align:u,sideOffset:x,children:a(t.Popup,{id:D,role:"tooltip",className:[d,r[g],i[f][g],p[g],l[g],z??""].filter(Boolean).join(" "),style:{...n(h,3),...T},...B,children:[j?s(t.Arrow,{className:["data-[side=top]:bottom-[-1px]","data-[side=bottom]:top-[-1px] data-[side=bottom]:rotate-180","data-[side=left]:right-[-1px] data-[side=left]:-rotate-90","data-[side=right]:left-[-1px] data-[side=right]:rotate-90"].join(" "),children:a("svg",{width:C,height:C/2,viewBox:"0 0 10 5","aria-hidden":"true",className:"block",children:[s("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-line)"}),s("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-press)",transform:"translate(0 -1)"})]})}):null,o]})})})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlTooltip,PlTooltipProvider}from"./PlTooltip.js";
|
|
@@ -1,143 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
/**
|
|
4
|
-
* The scale.
|
|
5
|
-
*
|
|
6
|
-
* Body sits on the sheet body ladder at `md` (13px/22px), so a paragraph inside
|
|
7
|
-
* a `PlCard` and a standalone one are the same text. The headings step up from
|
|
8
|
-
* there by roughly a major third, and the leading tightens as they grow — a 30px
|
|
9
|
-
* line does not want the same 1.7 ratio a 13px one does.
|
|
10
|
-
*/
|
|
11
|
-
const levelClasses = {
|
|
12
|
-
h1: 'text-[1.875rem]/[2.25rem] tracking-[-0.02em]',
|
|
13
|
-
h2: 'text-[1.5rem]/[1.875rem] tracking-[-0.015em]',
|
|
14
|
-
h3: 'text-[1.25rem]/[1.625rem] tracking-[-0.01em]',
|
|
15
|
-
h4: 'text-[1.0625rem]/[1.5rem]',
|
|
16
|
-
h5: 'text-[0.9375rem]/[1.375rem]',
|
|
17
|
-
h6: 'text-[0.8125rem]/[1.25rem]',
|
|
18
|
-
lead: 'text-[1.0625rem]/[1.75rem]',
|
|
19
|
-
body: 'text-[0.8125rem]/[1.375rem]',
|
|
20
|
-
caption: 'text-[0.75rem]/[1.125rem]',
|
|
21
|
-
overline: 'text-[0.6875rem]/[1rem] tracking-[0.08em] uppercase'
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Weight is kept out of `levelClasses` and resolved here so that exactly one
|
|
25
|
-
* `font-*` class is ever emitted. Passing both the level's weight and an
|
|
26
|
-
* override would leave two utilities of equal specificity on the element, and
|
|
27
|
-
* which of them wins is decided by their order in the generated stylesheet —
|
|
28
|
-
* `font-semibold` beats `font-normal` there no matter which one was asked for.
|
|
29
|
-
*/
|
|
30
|
-
const levelWeights = {
|
|
31
|
-
h1: 'semibold',
|
|
32
|
-
h2: 'semibold',
|
|
33
|
-
h3: 'semibold',
|
|
34
|
-
h4: 'semibold',
|
|
35
|
-
h5: 'semibold',
|
|
36
|
-
h6: 'semibold',
|
|
37
|
-
lead: 'regular',
|
|
38
|
-
body: 'regular',
|
|
39
|
-
caption: 'regular',
|
|
40
|
-
overline: 'medium'
|
|
41
|
-
};
|
|
42
|
-
/** The element each level renders as when `render` is not given. */
|
|
43
|
-
const levelElements = {
|
|
44
|
-
h1: 'h1',
|
|
45
|
-
h2: 'h2',
|
|
46
|
-
h3: 'h3',
|
|
47
|
-
h4: 'h4',
|
|
48
|
-
h5: 'h5',
|
|
49
|
-
h6: 'h6',
|
|
50
|
-
lead: 'p',
|
|
51
|
-
body: 'p',
|
|
52
|
-
caption: 'span',
|
|
53
|
-
overline: 'span'
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* The two quiet levels are muted by default. Everything else takes the page's
|
|
57
|
-
* own foreground — a heading that arrived pre-greyed is a heading a designer has
|
|
58
|
-
* to undo.
|
|
59
|
-
*/
|
|
60
|
-
const mutedLevels = new Set(['caption', 'overline']);
|
|
61
|
-
/** How much room a level leaves under itself when `gutter` is on. */
|
|
62
|
-
const gutterClasses = {
|
|
63
|
-
h1: 'mb-4',
|
|
64
|
-
h2: 'mb-3.5',
|
|
65
|
-
h3: 'mb-3',
|
|
66
|
-
h4: 'mb-2.5',
|
|
67
|
-
h5: 'mb-2',
|
|
68
|
-
h6: 'mb-2',
|
|
69
|
-
lead: 'mb-4',
|
|
70
|
-
body: 'mb-3',
|
|
71
|
-
caption: 'mb-2',
|
|
72
|
-
overline: 'mb-2'
|
|
73
|
-
};
|
|
74
|
-
const weightClasses = {
|
|
75
|
-
regular: 'font-normal',
|
|
76
|
-
medium: 'font-medium',
|
|
77
|
-
semibold: 'font-semibold',
|
|
78
|
-
bold: 'font-bold'
|
|
79
|
-
};
|
|
80
|
-
const alignClasses = {
|
|
81
|
-
start: 'text-start',
|
|
82
|
-
center: 'text-center',
|
|
83
|
-
end: 'text-end',
|
|
84
|
-
justify: 'text-justify'
|
|
85
|
-
};
|
|
86
|
-
/**
|
|
87
|
-
* Clamping is two different mechanisms. One line is `text-overflow: ellipsis`,
|
|
88
|
-
* which keeps the text on its own baseline; more than one needs the line-clamp
|
|
89
|
-
* box, which only ellipsises because WebKit says so.
|
|
90
|
-
*/
|
|
91
|
-
const clampClasses = {
|
|
92
|
-
1: 'truncate',
|
|
93
|
-
2: 'line-clamp-2',
|
|
94
|
-
3: 'line-clamp-3',
|
|
95
|
-
4: 'line-clamp-4',
|
|
96
|
-
5: 'line-clamp-5',
|
|
97
|
-
6: 'line-clamp-6'
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* Text at one of the library's sizes.
|
|
101
|
-
*
|
|
102
|
-
* The type scale is the one thing in a design system that everything else is
|
|
103
|
-
* measured against, and until now it only existed inside the components that
|
|
104
|
-
* happened to need it — a card's title, a field's label. This is that ladder on
|
|
105
|
-
* its own, so a page can use it without wrapping its prose in a card.
|
|
106
|
-
*
|
|
107
|
-
* `level` sets the scale *and* the element, which is the common case. When they
|
|
108
|
-
* have to differ — a subheading that should not enter the document outline, a
|
|
109
|
-
* `<p>` that has to look like an `h3` — `render` breaks the tie.
|
|
110
|
-
*
|
|
111
|
-
* There is no `variant` and no `elevation`, and there is no `size` either.
|
|
112
|
-
* `level` is the size: a `size` prop alongside it would let a caller ask for an
|
|
113
|
-
* `h1` at `xs`, which is a heading that is not a heading.
|
|
114
|
-
*/
|
|
115
|
-
export const PlTypography = /* @__PURE__ */ React.forwardRef(function PlTypography({ level = 'body', color, weight, align, lines, gutter = false, render, className, style, children, ...props }, ref) {
|
|
116
|
-
const classNames = [
|
|
117
|
-
levelClasses[level],
|
|
118
|
-
weightClasses[weight ?? levelWeights[level]],
|
|
119
|
-
align ? alignClasses[align] : '',
|
|
120
|
-
lines ? (clampClasses[lines] ?? 'line-clamp-6') : '',
|
|
121
|
-
gutter ? gutterClasses[level] : '',
|
|
122
|
-
color
|
|
123
|
-
? 'text-(--p-accent)'
|
|
124
|
-
: mutedLevels.has(level)
|
|
125
|
-
? 'text-(--plass-muted-fg)'
|
|
126
|
-
: 'text-(--plass-fg)',
|
|
127
|
-
className ?? ''
|
|
128
|
-
]
|
|
129
|
-
.filter(Boolean)
|
|
130
|
-
.join(' ');
|
|
131
|
-
return useRender({
|
|
132
|
-
render: render ?? React.createElement(levelElements[level]),
|
|
133
|
-
ref,
|
|
134
|
-
props: {
|
|
135
|
-
className: classNames,
|
|
136
|
-
style: (color
|
|
137
|
-
? { '--p-accent': `var(--plass-${color}-accent)`, ...style }
|
|
138
|
-
: style),
|
|
139
|
-
children,
|
|
140
|
-
...props
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
});
|
|
1
|
+
"use client";import*as e from"react";import{useRender as t}from"@base-ui/react/use-render";const r={h1:"text-[1.875rem]/[2.25rem] tracking-[-0.02em]",h2:"text-[1.5rem]/[1.875rem] tracking-[-0.015em]",h3:"text-[1.25rem]/[1.625rem] tracking-[-0.01em]",h4:"text-[1.0625rem]/[1.5rem]",h5:"text-[0.9375rem]/[1.375rem]",h6:"text-[0.8125rem]/[1.25rem]",lead:"text-[1.0625rem]/[1.75rem]",body:"text-[0.8125rem]/[1.375rem]",caption:"text-[0.75rem]/[1.125rem]",overline:"text-[0.6875rem]/[1rem] tracking-[0.08em] uppercase"},m={h1:"semibold",h2:"semibold",h3:"semibold",h4:"semibold",h5:"semibold",h6:"semibold",lead:"regular",body:"regular",caption:"regular",overline:"medium"},l={h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",lead:"p",body:"p",caption:"span",overline:"span"},n=new Set(["caption","overline"]),a={h1:"mb-4",h2:"mb-3.5",h3:"mb-3",h4:"mb-2.5",h5:"mb-2",h6:"mb-2",lead:"mb-4",body:"mb-3",caption:"mb-2",overline:"mb-2"},o={regular:"font-normal",medium:"font-medium",semibold:"font-semibold",bold:"font-bold"},i={start:"text-start",center:"text-center",end:"text-end",justify:"text-justify"},c={1:"truncate",2:"line-clamp-2",3:"line-clamp-3",4:"line-clamp-4",5:"line-clamp-5",6:"line-clamp-6"};export const PlTypography=/* @__PURE__ */e.forwardRef(function PlTypography({level:s="body",color:h,weight:d,align:p,lines:b,gutter:u=!1,render:x,className:f,style:g,children:y,...v},k){const j=[r[s],o[d??m[s]],p?i[p]:"",b?c[b]??"line-clamp-6":"",u?a[s]:"",h?"text-(--p-accent)":n.has(s)?"text-(--plass-muted-fg)":"text-(--plass-fg)",f??""].filter(Boolean).join(" ");return t({render:x??e.createElement(l[s]),ref:k,props:{className:j,style:h?{"--p-accent":`var(--plass-${h}-accent)`,...g}:g,children:y,...v}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlTypography}from"./PlTypography.js";
|
package/dist/index.js
CHANGED
|
@@ -1,75 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './components/accordion/index.js';
|
|
3
|
-
export * from './components/alert/index.js';
|
|
4
|
-
export * from './components/animate-appear/index.js';
|
|
5
|
-
export * from './components/animate-blink/index.js';
|
|
6
|
-
export * from './components/animate-fade/index.js';
|
|
7
|
-
export * from './components/animate-grow/index.js';
|
|
8
|
-
export * from './components/animate-headline/index.js';
|
|
9
|
-
export * from './components/animate-lighting/index.js';
|
|
10
|
-
export * from './components/animate-marquee/index.js';
|
|
11
|
-
export * from './components/animate-rotate/index.js';
|
|
12
|
-
export * from './components/animate-slide/index.js';
|
|
13
|
-
export * from './components/animate-typing/index.js';
|
|
14
|
-
export * from './components/animate-zoom/index.js';
|
|
15
|
-
export * from './components/aspect-ratio/index.js';
|
|
16
|
-
export * from './components/avatar/index.js';
|
|
17
|
-
export * from './components/badge/index.js';
|
|
18
|
-
export * from './components/blockquote/index.js';
|
|
19
|
-
export * from './components/bottom-navigation/index.js';
|
|
20
|
-
export * from './components/box/index.js';
|
|
21
|
-
export * from './components/breadcrumb/index.js';
|
|
22
|
-
export * from './components/button/index.js';
|
|
23
|
-
export * from './components/button-group/index.js';
|
|
24
|
-
export * from './components/card/index.js';
|
|
25
|
-
export * from './components/carousel/index.js';
|
|
26
|
-
export * from './components/chat-bubble/index.js';
|
|
27
|
-
export * from './components/checkbox/index.js';
|
|
28
|
-
export * from './components/chip/index.js';
|
|
29
|
-
export * from './components/collapsible/index.js';
|
|
30
|
-
export * from './components/combobox/index.js';
|
|
31
|
-
export * from './components/container/index.js';
|
|
32
|
-
export * from './components/date-picker/index.js';
|
|
33
|
-
export * from './components/date-range-picker/index.js';
|
|
34
|
-
export * from './components/date-time-picker/index.js';
|
|
35
|
-
export * from './components/divider/index.js';
|
|
36
|
-
export * from './components/drawer/index.js';
|
|
37
|
-
export * from './components/file-picker/index.js';
|
|
38
|
-
export * from './components/floating-bottom-navigation/index.js';
|
|
39
|
-
export * from './components/grid/index.js';
|
|
40
|
-
export * from './components/highlight/index.js';
|
|
41
|
-
export * from './components/hot-keys/index.js';
|
|
42
|
-
export * from './components/icon/index.js';
|
|
43
|
-
export * from './components/icon-button/index.js';
|
|
44
|
-
export * from './components/list/index.js';
|
|
45
|
-
export * from './components/menu/index.js';
|
|
46
|
-
export * from './components/modal/index.js';
|
|
47
|
-
export * from './components/number-field/index.js';
|
|
48
|
-
export * from './components/otp-field/index.js';
|
|
49
|
-
export * from './components/overlay/index.js';
|
|
50
|
-
export * from './components/pagination/index.js';
|
|
51
|
-
export * from './components/panes/index.js';
|
|
52
|
-
export * from './components/pill/index.js';
|
|
53
|
-
export * from './components/popover/index.js';
|
|
54
|
-
export * from './components/progress-box/index.js';
|
|
55
|
-
export * from './components/progress-circular/index.js';
|
|
56
|
-
export * from './components/progress-linear/index.js';
|
|
57
|
-
export * from './components/radio-group/index.js';
|
|
58
|
-
export * from './components/rating/index.js';
|
|
59
|
-
export * from './components/scroll-zone/index.js';
|
|
60
|
-
export * from './components/segmented-button/index.js';
|
|
61
|
-
export * from './components/select/index.js';
|
|
62
|
-
export * from './components/skeleton/index.js';
|
|
63
|
-
export * from './components/slider/index.js';
|
|
64
|
-
export * from './components/spoiler/index.js';
|
|
65
|
-
export * from './components/switch/index.js';
|
|
66
|
-
export * from './components/table/index.js';
|
|
67
|
-
export * from './components/tabs/index.js';
|
|
68
|
-
export * from './components/text-field/index.js';
|
|
69
|
-
export * from './components/text-link/index.js';
|
|
70
|
-
export * from './components/time-picker/index.js';
|
|
71
|
-
export * from './components/timeline/index.js';
|
|
72
|
-
export * from './components/toast/index.js';
|
|
73
|
-
export * from './components/toolbar/index.js';
|
|
74
|
-
export * from './components/tooltip/index.js';
|
|
75
|
-
export * from './components/typography/index.js';
|
|
1
|
+
export*from"./types.js";export*from"./components/accordion/index.js";export*from"./components/alert/index.js";export*from"./components/animate-appear/index.js";export*from"./components/animate-blink/index.js";export*from"./components/animate-fade/index.js";export*from"./components/animate-grow/index.js";export*from"./components/animate-headline/index.js";export*from"./components/animate-lighting/index.js";export*from"./components/animate-marquee/index.js";export*from"./components/animate-rotate/index.js";export*from"./components/animate-slide/index.js";export*from"./components/animate-typing/index.js";export*from"./components/animate-zoom/index.js";export*from"./components/aspect-ratio/index.js";export*from"./components/avatar/index.js";export*from"./components/badge/index.js";export*from"./components/blockquote/index.js";export*from"./components/bottom-navigation/index.js";export*from"./components/box/index.js";export*from"./components/breadcrumb/index.js";export*from"./components/button/index.js";export*from"./components/button-group/index.js";export*from"./components/card/index.js";export*from"./components/carousel/index.js";export*from"./components/chat-bubble/index.js";export*from"./components/checkbox/index.js";export*from"./components/chip/index.js";export*from"./components/collapsible/index.js";export*from"./components/combobox/index.js";export*from"./components/container/index.js";export*from"./components/date-picker/index.js";export*from"./components/date-range-picker/index.js";export*from"./components/date-time-picker/index.js";export*from"./components/divider/index.js";export*from"./components/drawer/index.js";export*from"./components/file-picker/index.js";export*from"./components/floating-bottom-navigation/index.js";export*from"./components/grid/index.js";export*from"./components/highlight/index.js";export*from"./components/hot-keys/index.js";export*from"./components/icon/index.js";export*from"./components/icon-button/index.js";export*from"./components/list/index.js";export*from"./components/menu/index.js";export*from"./components/modal/index.js";export*from"./components/number-field/index.js";export*from"./components/otp-field/index.js";export*from"./components/overlay/index.js";export*from"./components/pagination/index.js";export*from"./components/panes/index.js";export*from"./components/pill/index.js";export*from"./components/popover/index.js";export*from"./components/progress-box/index.js";export*from"./components/progress-circular/index.js";export*from"./components/progress-linear/index.js";export*from"./components/radio-group/index.js";export*from"./components/rating/index.js";export*from"./components/scroll-zone/index.js";export*from"./components/segmented-button/index.js";export*from"./components/select/index.js";export*from"./components/skeleton/index.js";export*from"./components/slider/index.js";export*from"./components/spoiler/index.js";export*from"./components/switch/index.js";export*from"./components/table/index.js";export*from"./components/tabs/index.js";export*from"./components/text-field/index.js";export*from"./components/text-link/index.js";export*from"./components/time-picker/index.js";export*from"./components/timeline/index.js";export*from"./components/toast/index.js";export*from"./components/toolbar/index.js";export*from"./components/tooltip/index.js";export*from"./components/typography/index.js";
|