neba 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/components/app-logo/AppLogo.d.ts +148 -0
- package/dist/components/app-logo/AppLogo.js +1 -0
- package/dist/components/app-logo/index.d.ts +2 -0
- package/dist/components/app-logo/index.js +1 -0
- package/dist/components/avatar/Avatar.js +1 -1
- package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
- package/dist/components/code-block/CodeBlock.d.ts +170 -0
- package/dist/components/code-block/CodeBlock.js +1 -0
- package/dist/components/code-block/index.d.ts +2 -0
- package/dist/components/code-block/index.js +1 -0
- package/dist/components/color-picker/ColorPicker.d.ts +1 -1
- package/dist/components/drawer/Drawer.js +1 -1
- package/dist/components/footer/Footer.d.ts +85 -0
- package/dist/components/footer/Footer.js +1 -0
- package/dist/components/footer/index.d.ts +2 -0
- package/dist/components/footer/index.js +1 -0
- package/dist/components/header/Header.d.ts +114 -0
- package/dist/components/header/Header.js +1 -0
- package/dist/components/header/index.d.ts +2 -0
- package/dist/components/header/index.js +1 -0
- package/dist/components/how-to-steps/HowToSteps.d.ts +167 -0
- package/dist/components/how-to-steps/HowToSteps.js +1 -0
- package/dist/components/how-to-steps/index.d.ts +2 -0
- package/dist/components/how-to-steps/index.js +1 -0
- package/dist/components/page-layout/PageLayout.d.ts +144 -0
- package/dist/components/page-layout/PageLayout.js +1 -0
- package/dist/components/page-layout/index.d.ts +2 -0
- package/dist/components/page-layout/index.js +1 -0
- package/dist/components/sidebar/Sidebar.d.ts +144 -0
- package/dist/components/sidebar/Sidebar.js +1 -0
- package/dist/components/sidebar/SidebarTrigger.d.ts +36 -0
- package/dist/components/sidebar/SidebarTrigger.js +1 -0
- package/dist/components/sidebar/index.d.ts +4 -0
- package/dist/components/sidebar/index.js +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -1
- package/dist/internal/bottom-navigation.d.ts +4 -3
- package/dist/internal/chart.d.ts +3 -2
- package/dist/internal/color.d.ts +2 -2
- package/dist/internal/date.d.ts +3 -4
- package/dist/internal/highlight.d.ts +97 -0
- package/dist/internal/highlight.js +1 -0
- package/dist/internal/i18n.d.ts +85 -0
- package/dist/internal/i18n.js +1 -1
- package/dist/internal/icons.d.ts +20 -0
- package/dist/internal/icons.js +1 -1
- package/dist/internal/initials.d.ts +24 -0
- package/dist/internal/initials.js +1 -0
- package/dist/internal/page-layout.d.ts +143 -0
- package/dist/internal/page-layout.js +1 -0
- package/dist/internal/styles.d.ts +11 -0
- package/dist/internal/styles.js +1 -1
- package/dist/locales/ar.js +1 -1
- package/dist/locales/de.js +1 -1
- package/dist/locales/es.js +1 -1
- package/dist/locales/fr.js +1 -1
- package/dist/locales/hi.js +1 -1
- package/dist/locales/id.js +1 -1
- package/dist/locales/it.js +1 -1
- package/dist/locales/ja.js +1 -1
- package/dist/locales/ko.js +1 -1
- package/dist/locales/nl.js +1 -1
- package/dist/locales/pl.js +1 -1
- package/dist/locales/pt.js +1 -1
- package/dist/locales/ru.js +1 -1
- package/dist/locales/th.js +1 -1
- package/dist/locales/tr.js +1 -1
- package/dist/locales/vi.js +1 -1
- package/dist/locales/zh-hans.js +1 -1
- package/dist/locales/zh-hant.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +473 -0
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ You install one package, add one line to your CSS, and import components. There
|
|
|
21
21
|
- **Accessible by construction** — real roles, labels, focus management and keyboard support, not `div`s with click handlers.
|
|
22
22
|
- **Dark mode with no work** — follows the system, and can be forced either way per subtree.
|
|
23
23
|
- **A design language, not a theme file** — a translucent acrylic surface with a hairline edge, one deliberate motion signature, and shadows that are opt-in.
|
|
24
|
-
- **ESM only**, TypeScript declarations included, and genuinely tree-shakeable — every component compiles to its own module, and importing one costs about what one costs. A `Button` is ~5 kB gzipped including its Base UI parts, a `Chip` is ~3 kB, and a twelve-component app is ~67 kB; the whole library, all one hundred and
|
|
25
|
-
- **
|
|
24
|
+
- **ESM only**, TypeScript declarations included, and genuinely tree-shakeable — every component compiles to its own module, and importing one costs about what one costs. A `Button` is ~5 kB gzipped including its Base UI parts, a `Chip` is ~3 kB, and a twelve-component app is ~67 kB; the whole library, all one hundred and twenty-six exports at once, is ~215 kB.
|
|
25
|
+
- **Two runtime dependencies** — Base UI, and `highlight.js`, which only [CodeBlock](https://neba.cdget.com/components/display/code-block) reaches and only through a dynamic import, so it never lands in a bundle that did not ask for it. React 18 or 19, Node.js 18 or later.
|
|
26
26
|
|
|
27
27
|
## Documentation
|
|
28
28
|
|
|
@@ -115,7 +115,7 @@ Call it once, at module scope, before your first render. Then a `locale` prop tr
|
|
|
115
115
|
<Dialog locale="ko" title="설정" showClose />
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
A registered language costs about 1.
|
|
118
|
+
A registered language costs about 1.9 kB gzipped and you pay only for the ones you name. Tags are matched by script, then by region, then by language — registering `ko` answers `ko-KR`, and `zhHans` registered as `zh-hans` answers `zh-CN` and a bare `zh`. Available: `ko`, `ja`, `zhHans`, `zhHant`, `es`, `pt`, `fr`, `de`, `it`, `nl`, `pl`, `ru`, `tr`, `ar`, `hi`, `id`, `vi`, `th`, each also its own entry point (`neba/locales/ko`).
|
|
119
119
|
|
|
120
120
|
Anything the platform already knows — month names, weekday names, AM/PM, number and date formats — comes from `Intl` and needs no registration. And every string a component invents also has a prop that overrides it, so a language Neba does not carry is never a dead end.
|
|
121
121
|
|
|
@@ -142,19 +142,19 @@ Placement props are logical, not physical — `start`/`end` rather than `left`/`
|
|
|
142
142
|
|
|
143
143
|
**Inputs** — Button, IconButton, ButtonGroup, SegmentedButton, FloatingActionButton (with FloatingAction), TextField, NumberField, OtpField, Select, Combobox, Checkbox, RadioGroup, Switch, Slider, Rating, Menu (with submenus, checkbox and radio items), ContextMenu, FilePicker, Pagination, BottomNavigation, FloatingBottomNavigation, ColorPicker, DatePicker, TimePicker, DateTimePicker, DateRangePicker
|
|
144
144
|
|
|
145
|
-
**Surfaces** — Box, Card, Accordion, Collapsible, Tabs, Carousel, Toolbar, Pill, Spoiler, ChatBubble, Drawer, Popover, Mockup, WindowPane
|
|
145
|
+
**Surfaces** — Box, Card, Accordion, Collapsible, Tabs, Carousel, Toolbar, Pill, Spoiler, HowToSteps, ChatBubble, Drawer, Popover, Mockup, WindowPane
|
|
146
146
|
|
|
147
|
-
**Display** — Typography, TextLink, Blockquote, Highlight, Divider, Chip, Badge, Avatar, Icon, Shortcut, List, Table, DataTable, Timeline, Breadcrumb, TreeView
|
|
147
|
+
**Display** — Typography, TextLink, Blockquote, Highlight, Divider, Chip, Badge, Avatar, AppLogo, Icon, Shortcut, List, Table, DataTable, CodeBlock, Timeline, Breadcrumb, TreeView
|
|
148
148
|
|
|
149
149
|
**Charts** — Statistic, Sparkline, LineChart, AreaChart, BarChart, PieChart, ScatterChart, TimelineChart, HeatmapChart
|
|
150
150
|
|
|
151
151
|
**Feedback** — Alert, Dialog, Toast, Tooltip, Overlay, Skeleton, Empty, ProgressLinear, ProgressCircular, ProgressBox
|
|
152
152
|
|
|
153
|
-
**Layout** — Container, Grid (with GridContainer), Panes, AspectRatio, ScrollZone
|
|
153
|
+
**Layout** — PageLayout (with Header, Footer and Sidebar), Container, Grid (with GridContainer), Panes, AspectRatio, ScrollZone
|
|
154
154
|
|
|
155
155
|
**Transitions** — AnimateFade, AnimateGrow, AnimateZoom, AnimateSlide, AnimateRotate, AnimateBlink, AnimateAppear, AnimateTyping, AnimateLighting, AnimateMarquee, AnimateHeadline
|
|
156
156
|
|
|
157
|
-
**Recently added** — ScrollZone, FloatingBottomNavigation, WindowPane, Collapsible, Rating, BottomNavigation, FloatingActionButton, the charts (Sparkline, LineChart, AreaChart, BarChart, PieChart, ScatterChart, TimelineChart, HeatmapChart), DataTable, Empty, Mockup, the eleven `Animate*` wrappers, ColorPicker, Drawer, Popover, Skeleton, AspectRatio
|
|
157
|
+
**Recently added** — CodeBlock, HowToSteps, ScrollZone, FloatingBottomNavigation, WindowPane, Collapsible, Rating, BottomNavigation, FloatingActionButton, the charts (Sparkline, LineChart, AreaChart, BarChart, PieChart, ScatterChart, TimelineChart, HeatmapChart), DataTable, Empty, Mockup, the eleven `Animate*` wrappers, ColorPicker, Drawer, Popover, Skeleton, AspectRatio
|
|
158
158
|
|
|
159
159
|
Each one has its own page — live previews, every prop, and the variations worth seeing — under [**All components**](https://neba.cdget.com/components/).
|
|
160
160
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
import type { NebaColor, NebaElevation, NebaSize, NebaVariant } from '../../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* How the artwork is *framed*, which is the one question this component exists
|
|
6
|
+
* to answer.
|
|
7
|
+
*
|
|
8
|
+
* - `bare` — drawn as it was given, at the height `size` asks for and whatever
|
|
9
|
+
* width that comes to. No plate, no crop, no padding. This is the default,
|
|
10
|
+
* and it is the only one that is correct for a logo that was drawn with its
|
|
11
|
+
* own background, its own margin, or the product's name set into it.
|
|
12
|
+
* - `app` — an app icon: a filled tile with the artwork inset in it and the
|
|
13
|
+
* corners cut off. What a mark that was drawn as a bare glyph needs before it
|
|
14
|
+
* can sit next to anything else.
|
|
15
|
+
* - `circle` — the same tile, round. For the products whose icon is a disc.
|
|
16
|
+
*
|
|
17
|
+
* There is no `square`. A tile with the corners left on is the one shape the
|
|
18
|
+
* design language does not draw, and an `app` icon at a small size is already
|
|
19
|
+
* so close to a square that a fourth value would be a value nobody could see.
|
|
20
|
+
*/
|
|
21
|
+
export type AppLogoShape = 'bare' | 'app' | 'circle';
|
|
22
|
+
export interface AppLogoProps extends Omit<React.ComponentPropsWithoutRef<'a'>, 'color' | 'href'> {
|
|
23
|
+
/**
|
|
24
|
+
* The artwork, as an image.
|
|
25
|
+
*
|
|
26
|
+
* Beaten by `children`, so a project that inlines its SVG and a project that
|
|
27
|
+
* links a PNG use the same component. A logo file very often has the
|
|
28
|
+
* product's name set into it — that is what `shape="bare"` is the default
|
|
29
|
+
* for, since it keeps the file's own aspect ratio instead of squeezing a
|
|
30
|
+
* wordmark into a square, and why `name` is read out rather than drawn a
|
|
31
|
+
* second time beside it.
|
|
32
|
+
*/
|
|
33
|
+
src?: string;
|
|
34
|
+
/** Candidate images at other resolutions, as on any `<img>`. */
|
|
35
|
+
srcSet?: string;
|
|
36
|
+
/**
|
|
37
|
+
* What the artwork says for a reader who cannot see it. Defaults to `name`,
|
|
38
|
+
* which is almost always the right answer: a logo means the product.
|
|
39
|
+
*/
|
|
40
|
+
alt?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The product's name.
|
|
43
|
+
*
|
|
44
|
+
* One prop doing three jobs, as on Avatar: it names the artwork, it is drawn
|
|
45
|
+
* as the logotype when there is no artwork at all, and its initials are what
|
|
46
|
+
* a tile falls back to. It is what makes `<AppLogo name="Neba" />` — with no
|
|
47
|
+
* file, no icon and no markup — still a logo.
|
|
48
|
+
*/
|
|
49
|
+
name?: string;
|
|
50
|
+
/** The initials on a tile, written out, for when the rule derived the wrong ones. */
|
|
51
|
+
initials?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Draws the name beside the artwork, as the words half of a lockup.
|
|
54
|
+
*
|
|
55
|
+
* Off by default, because the common case is a file that already says the
|
|
56
|
+
* name. Turn it on for a bare mark — the icon in a header with the product
|
|
57
|
+
* next to it — and the name stops being read out twice: what is drawn *is*
|
|
58
|
+
* the accessible name from then on.
|
|
59
|
+
*
|
|
60
|
+
* Ignored when the name is already the whole logo, which is what a `bare`
|
|
61
|
+
* logo with no artwork is.
|
|
62
|
+
* @default false
|
|
63
|
+
*/
|
|
64
|
+
showName?: boolean;
|
|
65
|
+
/** @default 'bare' */
|
|
66
|
+
shape?: AppLogoShape;
|
|
67
|
+
/**
|
|
68
|
+
* Weight of the tile behind the artwork. Nothing at all on `bare`, which
|
|
69
|
+
* draws no tile.
|
|
70
|
+
* @default 'solid'
|
|
71
|
+
*/
|
|
72
|
+
variant?: NebaVariant;
|
|
73
|
+
/**
|
|
74
|
+
* How tall the mark is — the control heights, so a logo and the button beside
|
|
75
|
+
* it in a header are the same height. On `bare` only the height is set and
|
|
76
|
+
* the width is whatever the artwork's own proportions come to; on a tile both
|
|
77
|
+
* are, because a tile is square.
|
|
78
|
+
* @default 'md'
|
|
79
|
+
*/
|
|
80
|
+
size?: NebaSize;
|
|
81
|
+
/** @default 'primary' */
|
|
82
|
+
color?: NebaColor;
|
|
83
|
+
/**
|
|
84
|
+
* Drop shadow depth. `0` (the default) is flat: an app icon is a sticker on
|
|
85
|
+
* the page, not a thing hovering over it.
|
|
86
|
+
* @default 0
|
|
87
|
+
*/
|
|
88
|
+
elevation?: NebaElevation;
|
|
89
|
+
/**
|
|
90
|
+
* Insets the artwork from the tile's edge, the way an app icon's glyph is
|
|
91
|
+
* inset from its own corners. Turn it off for a mark that was drawn to fill
|
|
92
|
+
* the tile — a favicon, a photograph.
|
|
93
|
+
*
|
|
94
|
+
* No effect on `bare`, which has no tile to inset from, and none on a tile
|
|
95
|
+
* showing initials, which are sized by their own type scale.
|
|
96
|
+
* @default true
|
|
97
|
+
*/
|
|
98
|
+
padded?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* An exact height for the mark, overriding `size`. A number is pixels.
|
|
101
|
+
*
|
|
102
|
+
* The one escape hatch this component needs: a brand's artwork is drawn at a
|
|
103
|
+
* height somebody chose, and rounding it to the nearest step of a ladder is
|
|
104
|
+
* how a logo ends up half a pixel off the type beside it.
|
|
105
|
+
*/
|
|
106
|
+
height?: number | string;
|
|
107
|
+
/**
|
|
108
|
+
* Makes the whole lockup a link. A logo in a header is nearly always the way
|
|
109
|
+
* back to the front page, and a `<span>` inside an `<a>` the caller wrote is
|
|
110
|
+
* the same thing with one more element in it.
|
|
111
|
+
*/
|
|
112
|
+
href?: string;
|
|
113
|
+
/** Anything else the `<img>` needs — `loading`, `decoding`, `crossOrigin`. */
|
|
114
|
+
imageProps?: Omit<React.ComponentPropsWithoutRef<'img'>, 'src' | 'srcSet' | 'alt'>;
|
|
115
|
+
/**
|
|
116
|
+
* Renders something other than a `<span>` — or than the `<a>` an `href` makes
|
|
117
|
+
* it. `render={<Link to="/" />}` for a router's own link, `render={<h1 />}`
|
|
118
|
+
* for the one page where the product's name is the page's heading.
|
|
119
|
+
*/
|
|
120
|
+
render?: useRender.RenderProp;
|
|
121
|
+
/**
|
|
122
|
+
* The artwork, as markup. An inline `<svg>` is the usual one, and it is worth
|
|
123
|
+
* preferring to `src`: a mark that is part of the document takes the page's
|
|
124
|
+
* own colours, needs no second request, and cannot arrive late.
|
|
125
|
+
*/
|
|
126
|
+
children?: React.ReactNode;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A product's mark, at a known size, that is never an empty box.
|
|
130
|
+
*
|
|
131
|
+
* Four things can be the mark and exactly one of them is at a time: markup
|
|
132
|
+
* handed to `children`, an image at `src`, the initials of `name` on a tile, or
|
|
133
|
+
* — with no tile to put them on — the name itself, set as the logotype. That
|
|
134
|
+
* last one is the point of the component: a product that has not drawn a logo
|
|
135
|
+
* yet still has a logo, and swapping it for the real file later is one prop.
|
|
136
|
+
*
|
|
137
|
+
* What it adds over an `<img>` is the framing. A mark drawn as a bare glyph and
|
|
138
|
+
* a mark drawn with its own background need opposite treatment, and which one a
|
|
139
|
+
* given file is cannot be worked out from the file — so `shape` is the decision
|
|
140
|
+
* a caller makes once, and everything else follows from it: `bare` keeps the
|
|
141
|
+
* artwork's own proportions and draws nothing behind it, `app` and `circle`
|
|
142
|
+
* inset it into a tile of the page's own colour.
|
|
143
|
+
*
|
|
144
|
+
* It carries no tagline and no version. A logo with a line of text under it is
|
|
145
|
+
* a logo next to a [Typography], and inventing a second spelling for that would
|
|
146
|
+
* give the library two of them.
|
|
147
|
+
*/
|
|
148
|
+
export declare const AppLogo: React.ForwardRefExoticComponent<AppLogoProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,Fragment as r,jsxs as n}from"react/jsx-runtime";import*as t from"react";import{useRender as s}from"@base-ui/react/use-render";import{initialsOf as a}from"../../internal/initials.js";import{controlHeightClasses as l,controlSlots as i,controlSquareClasses as o,cx as m,gapClasses as d,hasContent as c,srOnlyClasses as u,surfaceClasses as x,toLength as f,transitionClasses as g}from"../../internal/styles.js";const h={xs:"text-[0.75rem]",sm:"text-[0.875rem]",md:"text-[1.0625rem]",lg:"text-[1.375rem]",xl:"text-[1.625rem]"},p={xs:"text-[0.75rem]",sm:"text-[0.875rem]",md:"text-[1.0625rem]",lg:"text-[1.3125rem]",xl:"text-[1.5625rem]"},v={xs:"rounded-[0.375rem]",sm:"rounded-[0.4375rem]",md:"rounded-[0.5625rem]",lg:"rounded-[0.6875rem]",xl:"rounded-[0.875rem]"},b={solid:[x,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[x,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--n-accent) bg-(--n-soft-press) [box-shadow:var(--n-elev)]"};export const AppLogo=/*@__PURE__*/t.forwardRef(function({src:t,srcSet:x,alt:w,name:j,initials:_,showName:N=!1,shape:y="bare",variant:k="solid",size:S="md",color:z="primary",elevation:A=0,padded:F=!0,height:L,href:P,imageProps:R,render:$,className:q,style:B,children:C,...D},E){const G="bare"!==y,H=c(C)?C:t?"image":null,I=G&&F,J=null===H&&!G,K=N&&!J&&c(j),M=w??j,O=_??(j?a(j):""),Q="image"===H&&!K&&c(M),T=J||Q,U=!T&&!K&&c(M),V=f(L),W=V?{height:V,width:G?V:void 0}:null,X=e("span",{"aria-hidden":!T||void 0,className:m("flex shrink-0 items-center justify-center overflow-hidden","font-semibold tracking-tight whitespace-nowrap",V?"":l[S],G?m(V?"":o[S],"circle"===y?"rounded-full":v[S],p[S],b[k]):m("w-auto text-(--neba-fg)",h[S]),"[&_svg]:w-auto [&_svg]:shrink-0",I?"[&_svg]:h-[72%] [&_svg]:max-w-[72%]":"[&_svg]:h-full [&_svg]:max-w-full",g),style:{...G?i(z,A,k):null,...W},children:"image"===H?e("img",{src:t,srcSet:x,alt:Q?M??"":"",className:m("w-auto object-contain",I?"h-[72%] max-w-[72%]":"h-full max-w-full"),...R}):H??(J?j:O)});return s({render:$??e(P?"a":"span",{}),ref:E,props:{href:P,className:m("inline-flex max-w-full min-w-0 items-center align-middle","text-(--neba-fg) no-underline select-none",d[S],P?"cursor-pointer rounded-(--neba-radius-sm)":"",P?"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2":"",q),style:{"--n-ring":`var(--neba-${z}-ring)`,...B},children:n(r,{children:[X,K?e("span",{className:m("min-w-0 truncate font-semibold",h[S]),children:j}):null,U?e("span",{className:u,children:M}):null]}),...D}})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{AppLogo}from"./AppLogo.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{Avatar as r}from"@base-ui/react/avatar";import{transitionProps as a}from"../../internal/animate.js";import{initialsOf as o}from"../../internal/initials.js";import{controlHeightClasses as s,controlSlots as i,controlSquareClasses as l,hasContent as d,srOnlyClasses as c,surfaceClasses as m,transitionClasses as f}from"../../internal/styles.js";const u={xs:"text-[0.5625rem]",sm:"text-[0.6875rem]",md:"text-[0.8125rem]",lg:"text-[1rem]",xl:"text-[1.1875rem]"},x={xs:"rounded-[0.375rem]",sm:"rounded-[0.4375rem]",md:"rounded-[0.5625rem]",lg:"rounded-[0.6875rem]",xl:"rounded-[0.875rem]"},v={solid:[m,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev)]"].join(" "),outline:[m,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev)]"].join(" "),text:"text-(--n-accent) bg-(--n-soft-press) [box-shadow:var(--n-elev)]"},h="after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit]",p={solid:`${h} after:[box-shadow:var(--neba-plate-solid)]`,outline:`${h} after:[box-shadow:var(--neba-plate-glass)]`,text:""},g=["relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden","align-middle font-semibold tracking-wide whitespace-nowrap leading-none","[&_svg]:pointer-events-none [&_svg]:size-[55%]",f].join(" ");function b(){return t("svg",{viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:[e("path",{d:"M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Z"}),e("path",{d:"M12 14.25c-4.28 0-7.75 2.42-7.75 5.4 0 .75.6 1.35 1.35 1.35h12.8c.75 0 1.35-.6 1.35-1.35 0-2.98-3.47-5.4-7.75-5.4Z"})]})}export const Avatar=/*@__PURE__*/n.forwardRef(function({src:n,srcSet:m,alt:f,name:h,initials:j,shape:w="circle",variant:y="text",size:N="md",color:z="primary",elevation:S=0,delay:k,imageProps:B,onLoadingStatusChange:C,transition:A,className:L,style:M,children:R,...Z},$){const _=h?o(h):"",F=a(A),I=f??h,P=d(R)?R:(j??_)||e(b,{}),q=d(R)||Boolean(j??_),D=[g,s[N],l[N],u[N],"circle"===w?"rounded-full":x[N],v[y],p[y],F.className,L??""].filter(Boolean).join(" ");return t(r.Root,{ref:$,className:D,style:{...i(z,S,y),...F.style,...M},...Z,children:[n?e(r.Image,{src:n,srcSet:m,alt:I??"",className:"size-full object-cover",onLoadingStatusChange:C,...B}):null,t(r.Fallback,{delay:n?k:void 0,className:"flex size-full items-center justify-center",children:[I&&q?e("span",{className:c,children:I}):null,e("span",{"aria-hidden":!(!I||!q)||void 0,className:"contents",children:P})]})]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,Fragment as t,jsxs as a}from"react/jsx-runtime";import*as n from"react";import{useRender as i}from"@base-ui/react/use-render";import{barMinHeightClasses as
|
|
1
|
+
import{jsx as e,Fragment as t,jsxs as a}from"react/jsx-runtime";import*as n from"react";import{useRender as i}from"@base-ui/react/use-render";import{barMinHeightClasses as l,BottomNavigationContext as r}from"../../internal/bottom-navigation.js";import{cx as o,hasContent as s,iconSizeClasses as d,metaTextClasses as c,paddingXClasses as u,radiusClasses as m,srOnlyClasses as p,surfaceClasses as f,surfaceSlots as b,transitionClasses as g}from"../../internal/styles.js";const v={solid:[f,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[f,"text-(--neba-fg) bg-(--n-panel)","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},x={static:"",sticky:"sticky bottom-0 z-20",fixed:"fixed inset-x-0 bottom-0 z-30"},h={default:{xs:"p-1",sm:"p-1",md:"p-1.5",lg:"p-2",xl:"p-2.5"},compact:{xs:"p-0.5",sm:"p-0.5",md:"p-1",lg:"p-1",xl:"p-1.5"}},y={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const BottomNavigation=/*@__PURE__*/n.forwardRef(function({variant:t="outline",size:a="md",color:s="primary",density:d="default",elevation:c=0,value:u,defaultValue:p=null,onValueChange:f,position:y="fixed",labels:w="all",divider:N=!0,safeArea:z=!0,disabled:j=!1,label:k,render:C,className:B,style:R,children:V,..._},A){const[D,F]=n.useState(p),I=void 0!==u,M=I?u:D,P=n.useCallback(e=>{I||F(e),f?.(e)},[I,f]),S=n.useMemo(()=>({value:M??null,change:P,size:a,density:d,labels:w,disabled:j,floating:!1}),[M,P,a,d,w,j]),q=o("w-full min-w-0","static"===y?m[a]:"",v[t],"outline"===t&&"static"===y?"border [border-color:var(--n-line)]":"",N?"border-t [border-color:var(--n-line)]":"",x[y],z?"pb-[env(safe-area-inset-bottom)]":"",g,B);return i({render:C??e("nav",{}),ref:A,props:{"aria-label":k,className:q,style:{...b(s,c),...R},children:e(r.Provider,{value:S,children:e("div",{className:o("flex w-full items-stretch",l[a],h[d][a]),children:V})}),..._}})});export const BottomNavigationItem=/*@__PURE__*/n.forwardRef(function({value:i,icon:l,href:f,disabled:b=!1,className:v,children:x,onClick:h,...w},N){const z=n.useContext(r),j=b||z.disabled,k=null!==z.value&&z.value===i,C="all"===z.labels||"selected"===z.labels&&k,B=o("flex min-w-0 flex-col items-center justify-center py-1.5",z.floating?o("relative z-10",u[z.density][z.size],"rounded-full"):o("flex-1 px-1",m[z.size]),y[z.size],"[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",g,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]",j?"cursor-not-allowed text-(--neba-disabled-fg)":k?z.floating?"cursor-pointer font-medium text-(--n-accent)":"cursor-pointer font-medium text-(--n-accent) bg-(--n-soft) hover:bg-(--n-soft-hover)":"cursor-pointer text-(--neba-muted-fg) hover:text-(--neba-fg) hover:bg-(--n-panel-hover)",v),R=a(t,{children:[s(l)?e("span",{className:o("flex shrink-0 items-center justify-center",d[z.size]),children:l}):null,s(x)?z.floating&&"selected"===z.labels?e("span",{"data-drawn":C?"":void 0,className:o("grid justify-items-center [grid-template-rows:1fr]","[transition-property:grid-template-columns,opacity]","[transition-duration:var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]","motion-reduce:[transition-duration:0ms]",C?"[grid-template-columns:1fr] opacity-100":"[grid-template-columns:0fr] opacity-0"),children:e("span",{className:o("min-w-0 truncate leading-tight",c[z.size]),children:x})}):e("span",{"data-drawn":C?"":void 0,className:C?o("max-w-full truncate leading-tight",c[z.size]):p,children:x}):null]}),V=e=>{j?e.preventDefault():(z.change(i),h?.(e))};return f?e("a",{ref:N,"data-nav-item":"",href:j?void 0:f,"aria-current":k?"page":void 0,"aria-disabled":j||void 0,className:B,onClick:V,...w,children:R}):e("button",{ref:N,"data-nav-item":"",type:"button",disabled:j,"aria-current":k?"page":void 0,className:B,onClick:V,...w,children:R})});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaColor, NebaDensity, NebaElevation, NebaSize } from '../../types.js';
|
|
3
|
+
export { registerLanguage } from '../../internal/highlight.js';
|
|
4
|
+
/**
|
|
5
|
+
* Which palette the block wears.
|
|
6
|
+
*
|
|
7
|
+
* The four house themes come first. `dark` is the default and is the only one
|
|
8
|
+
* that is not a preference: code has been read on a dark ground since
|
|
9
|
+
* terminals, and a block that matched the page would be the one element on it
|
|
10
|
+
* whose colours were chosen by something other than the code. `auto` is the
|
|
11
|
+
* opt-out, and `mono` has no hue in it at all.
|
|
12
|
+
*
|
|
13
|
+
* The eight after them are ports, kept at their published values. They exist
|
|
14
|
+
* because a code block is the one component whose colours a reader already has
|
|
15
|
+
* an opinion about: someone who writes in One Dark all day reads a Dracula
|
|
16
|
+
* block as a different product's documentation.
|
|
17
|
+
*
|
|
18
|
+
* The type is open on purpose. A theme is a set of `--n-code-*` custom
|
|
19
|
+
* properties under a `[data-code-theme]` selector and nothing else, so a
|
|
20
|
+
* consumer who writes one in their own stylesheet has a theme — with nothing to
|
|
21
|
+
* register, nothing to import, and no cost to anybody who did not.
|
|
22
|
+
*/
|
|
23
|
+
export type CodeBlockTheme = 'dark' | 'light' | 'auto' | 'mono' | 'one-dark' | 'dracula' | 'monokai' | 'nord' | 'night-owl' | 'gruvbox' | 'github' | 'solarized-light';
|
|
24
|
+
export interface CodeBlockProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title' | 'prefix' | 'children' | 'onCopy'> {
|
|
25
|
+
/**
|
|
26
|
+
* The code. Trailing whitespace is trimmed off the end of the block — a
|
|
27
|
+
* template literal is almost always written with a newline before its closing
|
|
28
|
+
* backtick, and that newline is a blank line at the bottom of every block.
|
|
29
|
+
*/
|
|
30
|
+
code: string;
|
|
31
|
+
/**
|
|
32
|
+
* What it is written in — `ts`, `bash`, `yml`, `dockerfile`. The common
|
|
33
|
+
* spellings and file extensions are understood, so a value copied off a
|
|
34
|
+
* fenced code block works as-is.
|
|
35
|
+
*
|
|
36
|
+
* A language nothing here knows is drawn plain rather than refused; teach it
|
|
37
|
+
* one with `registerLanguage`.
|
|
38
|
+
*/
|
|
39
|
+
language?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The palette. Independent of the page's light and dark, except on `auto`.
|
|
42
|
+
*
|
|
43
|
+
* Any other string works too, and is how a project brings its own: write
|
|
44
|
+
* `[data-code-theme='ours'] { --n-code-bg: …; --n-code-keyword: … }` in your
|
|
45
|
+
* own CSS and pass the name. Sixteen slots, five of which are derived from
|
|
46
|
+
* the other two and need no declaration.
|
|
47
|
+
* @default 'dark'
|
|
48
|
+
*/
|
|
49
|
+
theme?: CodeBlockTheme | (string & {});
|
|
50
|
+
/** The type scale and the air around the code. @default 'md' */
|
|
51
|
+
size?: NebaSize;
|
|
52
|
+
/** @default 'primary' */
|
|
53
|
+
color?: NebaColor;
|
|
54
|
+
/** @default 'default' */
|
|
55
|
+
density?: NebaDensity;
|
|
56
|
+
/** Drop shadow depth. `0` (the default) is flat. @default 0 */
|
|
57
|
+
elevation?: NebaElevation;
|
|
58
|
+
/**
|
|
59
|
+
* Colours the code.
|
|
60
|
+
*
|
|
61
|
+
* Off, nothing is fetched at all: the grammar engine is behind a dynamic
|
|
62
|
+
* import, so a block that does not highlight costs no more than the text in
|
|
63
|
+
* it. On, the block draws plain on the first frame and colours itself when
|
|
64
|
+
* the grammar lands — a few milliseconds, and never a blank space where the
|
|
65
|
+
* code should be.
|
|
66
|
+
* @default true
|
|
67
|
+
*/
|
|
68
|
+
highlight?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* The bar over the code, and the master switch for it: with it off there is
|
|
71
|
+
* no bar and none of `showLanguage`, `copyable` or `rawToggle` draws
|
|
72
|
+
* anything, whatever they say.
|
|
73
|
+
* @default true
|
|
74
|
+
*/
|
|
75
|
+
toolbar?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* A name at the start of the bar — a file path, usually. Takes the place the
|
|
78
|
+
* language would otherwise have; both can be shown at once.
|
|
79
|
+
*/
|
|
80
|
+
title?: React.ReactNode;
|
|
81
|
+
/** Names the language at the start of the bar. @default true */
|
|
82
|
+
showLanguage?: boolean;
|
|
83
|
+
/** The button that puts the code on the clipboard. @default true */
|
|
84
|
+
copyable?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* The toggle that drops the colouring and shows the characters as they are.
|
|
87
|
+
* Off by default: it is a second control on a bar that usually wants one, and
|
|
88
|
+
* it means nothing at all when `highlight` is off.
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
rawToggle?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Lines to mark: a tinted row with a rule down its leading edge.
|
|
94
|
+
*
|
|
95
|
+
* A number is one line, a string is a list of lines and ranges —
|
|
96
|
+
* `'4'`, `'4-9'`, `'1,4-9,12'` — and an array is any mix of the two. They
|
|
97
|
+
* are counted the way the gutter counts, so `startLine={286}` means
|
|
98
|
+
* `highlightLines={288}` marks the line the gutter calls 288.
|
|
99
|
+
*
|
|
100
|
+
* The tint is mixed from the theme's own ink rather than from the page's
|
|
101
|
+
* colour family, so it is legible on all twelve palettes and never the one
|
|
102
|
+
* colour on a Dracula block that nobody chose.
|
|
103
|
+
*/
|
|
104
|
+
highlightLines?: number | string | Array<number | string>;
|
|
105
|
+
/** Numbers down the side. @default false */
|
|
106
|
+
lineNumbers?: boolean;
|
|
107
|
+
/** What the first line is numbered. @default 1 */
|
|
108
|
+
startLine?: number;
|
|
109
|
+
/**
|
|
110
|
+
* A shell prompt in front of every line that has something on it — `$`, `#`,
|
|
111
|
+
* `C:\>`, `>>>`.
|
|
112
|
+
*
|
|
113
|
+
* It is drawn but never *present*: the symbol is generated content, so it
|
|
114
|
+
* cannot be selected, cannot be found by find-in-page and is not what `copy`
|
|
115
|
+
* puts on the clipboard. A transcript stays a transcript and still pastes
|
|
116
|
+
* into a shell.
|
|
117
|
+
*/
|
|
118
|
+
prompt?: string;
|
|
119
|
+
/** Wraps long lines instead of scrolling them sideways. @default false */
|
|
120
|
+
wrap?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* How tall the block may get before the code scrolls inside it. A number is
|
|
123
|
+
* pixels; any CSS length works. Left out, the block is as tall as the code.
|
|
124
|
+
*/
|
|
125
|
+
maxHeight?: number | string;
|
|
126
|
+
/** The typeface. Defaults to the page's own monospace stack. */
|
|
127
|
+
fontFamily?: string;
|
|
128
|
+
/** Overrides the size the `size` ladder chose. A number is pixels. */
|
|
129
|
+
fontSize?: number | string;
|
|
130
|
+
/** Overrides the leading. A bare number is a ratio, as in CSS. */
|
|
131
|
+
lineHeight?: number | string;
|
|
132
|
+
/** Tracking. A number is pixels; `-0.01em` and the like work too. */
|
|
133
|
+
letterSpacing?: number | string;
|
|
134
|
+
/**
|
|
135
|
+
* Which language the block's own words are in — the copy button, the raw
|
|
136
|
+
* toggle, the name of the region. A BCP 47 tag such as `ko`, `pt-BR` or
|
|
137
|
+
* `zh-Hant`; unsupported tags fall back to English.
|
|
138
|
+
*/
|
|
139
|
+
locale?: string;
|
|
140
|
+
/** The copy button's label. Defaults to the `locale`'s word for it. */
|
|
141
|
+
copyLabel?: string;
|
|
142
|
+
/** And what it says once the code is on the clipboard. */
|
|
143
|
+
copiedLabel?: string;
|
|
144
|
+
/** The raw toggle's label. */
|
|
145
|
+
rawLabel?: string;
|
|
146
|
+
/** Fires with the copied text once the clipboard has taken it. */
|
|
147
|
+
onCopy?: (code: string) => void;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A viewer for one line of code or a thousand.
|
|
151
|
+
*
|
|
152
|
+
* Everything it draws above the code is optional and off one prop each, because
|
|
153
|
+
* the same component has to be a snippet inside a sentence — no bar, no
|
|
154
|
+
* numbers, no chrome — and the full transcript at the top of a README, and
|
|
155
|
+
* those are the same block with different things turned on rather than two
|
|
156
|
+
* components.
|
|
157
|
+
*
|
|
158
|
+
* The colouring is highlight.js, and it is the one thing in the library reached
|
|
159
|
+
* through a dynamic import: the grammars are forty kilobytes and there are
|
|
160
|
+
* thirty-four of them, so they arrive as their own chunk, one language at a
|
|
161
|
+
* time, and only for a block that asked to be coloured. See
|
|
162
|
+
* `internal/highlight.ts` for why that is a `dependencies` entry rather than an
|
|
163
|
+
* optional peer.
|
|
164
|
+
*
|
|
165
|
+
* The block is rendered as lines rather than as one run of text — even with no
|
|
166
|
+
* numbers and no prompt — because a line is what carries a number, a prompt and
|
|
167
|
+
* a place in the scroll, and a component that switched between two renderings
|
|
168
|
+
* would have two sets of wrapping behaviour to keep in step.
|
|
169
|
+
*/
|
|
170
|
+
export declare const CodeBlock: React.ForwardRefExoticComponent<CodeBlockProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{CheckIcon as o,CodeIcon as l,CopyIcon as r}from"../../internal/icons.js";import{codeMessages as a,useMessages as i}from"../../internal/i18n.js";import{canonicalLanguage as s,highlight as c,plainLines as d}from"../../internal/highlight.js";import{cx as p,hasContent as m,metaTextClasses as u,radiusClasses as x,srOnlyClasses as f,surfaceSlots as g,toLength as h,transitionClasses as y}from"../../internal/styles.js";export{registerLanguage}from"../../internal/highlight.js";const v={xs:"text-[0.6875rem]/[1.55]",sm:"text-[0.75rem]/[1.6]",md:"text-[0.8125rem]/[1.65]",lg:"text-[0.875rem]/[1.7]",xl:"text-[1rem]/[1.7]"},b={default:{xs:"py-2",sm:"py-3",md:"py-3.5",lg:"py-4",xl:"py-5"},compact:{xs:"py-1.5",sm:"py-2",md:"py-2.5",lg:"py-3",xl:"py-3.5"}},w={default:{xs:"px-2",sm:"px-3",md:"px-3.5",lg:"px-4",xl:"px-5"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-3.5"}},N={default:{xs:"px-2.5 py-1",sm:"px-3.5 py-1",md:"px-4 py-1.5",lg:"px-4.5 py-2",xl:"px-5.5 py-2"},compact:{xs:"px-2 py-0.5",sm:"px-2.5 py-0.5",md:"px-3 py-1",lg:"px-3.5 py-1",xl:"px-4 py-1.5"}};export const CodeBlock=/*@__PURE__*/n.forwardRef(function({code:k,language:S,theme:j="dark",size:L="md",color:M="primary",density:T="default",elevation:_=0,highlight:C=!0,toolbar:F=!0,title:R,showLanguage:A=!0,copyable:z=!0,rawToggle:H=!1,highlightLines:K,lineNumbers:E=!1,startLine:$=1,prompt:D,wrap:B=!1,maxHeight:I,fontFamily:q,fontSize:G,lineHeight:J,letterSpacing:O,locale:P,copyLabel:Q,copiedLabel:U,rawLabel:V,onCopy:W,className:X,style:Y,...Z},ee){const te=i(a,P),ne=n.useMemo(()=>k.replace(/\r\n?/g,"\n").replace(/\s+$/,""),[k]),oe=s(S),[le,re]=n.useState(!1),[ae,ie]=n.useState(null),[se,ce]=n.useState(null),de=C&&!le&&null!==oe;n.useEffect(()=>{if(!de||!oe)return void ce(null);let e=!1;return c(ne,oe).then(t=>{e||ce(t)},()=>{e||ce(null)}),()=>{e=!0}},[ne,oe,de]);const pe=n.useMemo(()=>de&&se?se:d(ne),[de,se,ne]),me=`${String($+Math.max(pe.length-1,0)).length}ch`,ue=n.useRef(void 0);n.useEffect(()=>()=>clearTimeout(ue.current),[]);const xe=n.useMemo(()=>function(e){const t=new Set;if(void 0===e)return t;for(const n of Array.isArray(e)?e:[e])if("number"!=typeof n)for(const e of n.split(",")){const n=/^\s*(\d+)\s*(?:-\s*(\d+)\s*)?$/.exec(e);if(!n)continue;const o=Number(n[1]),l=void 0===n[2]?o:Number(n[2]);for(let e=Math.min(o,l);e<=Math.max(o,l);e+=1)t.add(e)}else Number.isFinite(n)&&t.add(Math.trunc(n));return t}(K),[K]),fe=n.useRef(null),ge=Q??te.copy,he=U??te.copied,ye=V??te.raw,ve=p("inline-flex shrink-0 cursor-pointer items-center gap-1 border-0 bg-transparent","px-1.5 py-1 text-(--n-code-dim) hover:text-(--n-code-fg) hover:bg-(--n-code-hover)",x.xs,u[L],"[&_svg]:pointer-events-none [&_svg]:size-[1.15em] [&_svg]:shrink-0",y,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"),be=m(R)?void 0:oe??te.code,we=e("div",{role:"region","aria-label":"string"==typeof R?R:be,tabIndex:0,onKeyDown:e=>{if("a"!==e.key&&"A"!==e.key)return;if(!e.metaKey&&!e.ctrlKey||e.altKey)return;const t=fe.current,n="undefined"==typeof window?null:window.getSelection();if(!t||!n)return;e.preventDefault();const o=document.createRange();o.selectNodeContents(t),n.removeAllRanges(),n.addRange(o)},className:p("min-h-0 overflow-auto",b[T][L],"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:-outline-offset-2"),style:void 0===I?void 0:{maxHeight:h(I)},children:e("pre",{ref:fe,className:p("m-0 bg-transparent p-0 font-mono",B?"w-full":"w-max min-w-full"),children:pe.map((t,o)=>{const l=$+o;return e("div",{className:p("neba-code-line",w[T][L]),"data-line":E?l:void 0,"data-mark":xe.has(l)?"":void 0,"data-prompt":D&&t.length>0?D:void 0,children:e("code",{children:t.map((t,o)=>t.token?e("span",{className:t.token,children:t.text},o):e(n.Fragment,{children:t.text},o))})},o)})})});return t("div",{ref:ee,className:p("neba-code flex min-w-0 flex-col overflow-hidden",x[L],"border bg-(--n-code-bg) text-(--n-code-fg) [border-color:var(--n-code-rule)]","[box-shadow:var(--n-elev)]",y,X),"data-code-theme":j,"data-code-wrap":B?"true":void 0,style:{...g(M,_),"--n-code-gutter":me,...q?{fontFamily:q}:null,...void 0===G?null:{fontSize:h(G)},...void 0===J?null:{lineHeight:J},...void 0===O?null:{letterSpacing:h(O)},...Y},...Z,children:[F&&(A||z||H||m(R))?t("div",{className:p("flex min-w-0 items-center gap-1 border-b [border-color:var(--n-code-rule)]",N[T][L]),children:[m(R)?e("span",{className:p("min-w-0 truncate font-mono",u[L]),children:R}):null,A&&oe?e("span",{className:p("min-w-0 truncate font-mono tracking-wide text-(--n-code-dim) uppercase select-none",u[L]),children:oe}):null,e("span",{className:"flex-1"}),H&&C?e("button",{type:"button","aria-pressed":le,"aria-label":ye,title:ye,onClick:()=>re(e=>!e),className:p(ve,le?"text-(--n-code-fg) bg-(--n-code-hover)":""),children:e(l,{})}):null,z?t("button",{type:"button",onClick:async()=>{const e=await async function(e){try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.cssText="position:fixed;top:0;left:0;opacity:0;pointer-events:none",document.body.append(t),t.select();const n=document.execCommand("copy");return t.remove(),n}catch{return!1}}(ne);clearTimeout(ue.current),ie(e),ue.current=setTimeout(()=>ie(null),2e3),e&&W?.(ne)},className:ve,children:[e(ae?o:r,{}),e("span",{children:null===ae?ge:ae?he:te.copyFailed})]}):null]}):null,e("div",{className:p("flex min-h-0 flex-col",v[L]),children:we}),e("span",{"aria-live":"polite",className:f,children:null===ae?"":ae?he:te.copyFailed})]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{CodeBlock,registerLanguage}from"./CodeBlock.js";
|
|
@@ -97,6 +97,6 @@ export interface ColorPickerProps extends NebaStyleProps, Omit<React.ComponentPr
|
|
|
97
97
|
*
|
|
98
98
|
* There is no colour library under this. The conversions are in
|
|
99
99
|
* `internal/color.ts`, which is a hundred lines of arithmetic — the whole
|
|
100
|
-
* reason
|
|
100
|
+
* reason no colour library comes with it.
|
|
101
101
|
*/
|
|
102
102
|
export declare const ColorPicker: React.ForwardRefExoticComponent<ColorPickerProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{Dialog as l}from"@base-ui/react/dialog";import{boxPaddingXClasses as n,boxPaddingYClasses as o}from"../box/Box.js";import{actionMessages as s,useMessages as i}from"../../internal/i18n.js";import{CloseIcon as d}from"../../internal/icons.js";import{hasContent as t,metaTextClasses as u,sheetBodyClasses as b,sheetHeaderGapClasses as m,sheetSectionGapClasses as c,sheetTitleClasses as f,surfaceClasses as x,surfaceSlots as p}from"../../internal/styles.js";const g={xs:"w-56",sm:"w-64",md:"w-80",lg:"w-96",xl:"w-[28rem]"},h={left:{xs:"rounded-r-(--neba-radius-xs)",sm:"rounded-r-(--neba-radius-sm)",md:"rounded-r-(--neba-radius-md)",lg:"rounded-r-(--neba-radius-lg)",xl:"rounded-r-(--neba-radius-xl)"},right:{xs:"rounded-l-(--neba-radius-xs)",sm:"rounded-l-(--neba-radius-sm)",md:"rounded-l-(--neba-radius-md)",lg:"rounded-l-(--neba-radius-lg)",xl:"rounded-l-(--neba-radius-xl)"},top:{xs:"rounded-b-(--neba-radius-xs)",sm:"rounded-b-(--neba-radius-sm)",md:"rounded-b-(--neba-radius-md)",lg:"rounded-b-(--neba-radius-lg)",xl:"rounded-b-(--neba-radius-xl)"},bottom:{xs:"rounded-t-(--neba-radius-xs)",sm:"rounded-t-(--neba-radius-sm)",md:"rounded-t-(--neba-radius-md)",lg:"rounded-t-(--neba-radius-lg)",xl:"rounded-t-(--neba-radius-xl)"}},v={left:"border-r",right:"border-l",top:"border-b",bottom:"border-t"},y={left:"flex-row justify-start",right:"flex-row justify-end",top:"flex-col justify-start",bottom:"flex-col justify-end"},w=[x,"relative flex flex-col overflow-hidden","text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[outline:none]"].join(" "),j=["[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),N=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]",j].join(" "),$="border-t [border-color:var(--n-line)]",_=["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" ");export const DrawerClose=l.Close;export function Drawer({side:x="left",mode:k="overlay",size:C="md",color:z="primary",density:B="default",open:D,defaultOpen:O,onOpenChange:P,trigger:T,title:F,description:L,actions:R,dividers:V=!1,showClose:q,locale:A,closeLabel:E,extent:G,rounded:H=!0,modal:I=!0,dismissible:J=!0,className:K,style:M,children:Q,...S}){const U=i(s,A),W="overlay"===k,X="left"===x||"right"===x,Y=q??W,Z=n[B][C],ee=o[B][C],re=V?`${Z} ${ee}`:Z,ae=t(F)||t(L),le=t(R),ne=void 0===G?null:{[X?"width":"height"]:"number"==typeof G?`${G}px`:G},oe=[w,b[C],v[x],H?h[x][C]:"",W?"[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]":"[box-shadow:var(--neba-plate-glass)]",W?j:"",X?`h-full max-w-full ${void 0===G?g[C]:""}`:"w-full "+(void 0===G?"max-h-[85%]":""),V?"":`${ee} ${c[C]}`,K??""].filter(Boolean).join(" "),se=W?l.Title:"h2",ie=W?l.Description:"p",de=r(a,{children:[ae||Y?r("div",{className:`flex shrink-0 items-start gap-3 ${re}`,children:[r("div",{className:`flex min-w-0 flex-1 flex-col ${m[C]}`,children:[t(F)?e(se,{className:`m-0 font-semibold ${f[C]}`,children:F}):null,t(L)?e(ie,{className:`m-0 text-(--neba-muted-fg) ${u[C]}`,children:L}):null]}),Y?W?e(l.Close,{"aria-label":E??U.close,className:_,children:e(d,{})}):e("button",{type:"button","aria-label":E??U.close,className:_,onClick:()=>P?.(!1),children:e(d,{})}):null]}):null,t(Q)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",re,V&&(ae||Y)?$:"",V?"":"py-1 -my-1"].filter(Boolean).join(" "),children:Q}):null,le?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",re,V?$:""].filter(Boolean).join(" "),children:R}):null]});return W?r(l.Root,{open:D,defaultOpen:O,modal:I,disablePointerDismissal:!J,onOpenChange:(e,r)=>{J||e||"escape-key"!==r.reason?P?.(e):r.cancel()},children:[T?e(l.Trigger,{render:T}):null,r(l.Portal,{children:[e(l.Backdrop,{className:`neba-portal ${N}`}),e(l.Viewport,{className:`neba-portal fixed inset-0 z-50 flex ${y[x]}`,children:e(l.Popup,{className:oe,style:{...p(z,3),...ne,...M},...S,children:de})})]})]}):D??O
|
|
1
|
+
import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{Dialog as l}from"@base-ui/react/dialog";import{boxPaddingXClasses as n,boxPaddingYClasses as o}from"../box/Box.js";import{actionMessages as s,useMessages as i}from"../../internal/i18n.js";import{CloseIcon as d}from"../../internal/icons.js";import{hasContent as t,metaTextClasses as u,sheetBodyClasses as b,sheetHeaderGapClasses as m,sheetSectionGapClasses as c,sheetTitleClasses as f,surfaceClasses as x,surfaceSlots as p}from"../../internal/styles.js";const g={xs:"w-56",sm:"w-64",md:"w-80",lg:"w-96",xl:"w-[28rem]"},h={left:{xs:"rounded-r-(--neba-radius-xs)",sm:"rounded-r-(--neba-radius-sm)",md:"rounded-r-(--neba-radius-md)",lg:"rounded-r-(--neba-radius-lg)",xl:"rounded-r-(--neba-radius-xl)"},right:{xs:"rounded-l-(--neba-radius-xs)",sm:"rounded-l-(--neba-radius-sm)",md:"rounded-l-(--neba-radius-md)",lg:"rounded-l-(--neba-radius-lg)",xl:"rounded-l-(--neba-radius-xl)"},top:{xs:"rounded-b-(--neba-radius-xs)",sm:"rounded-b-(--neba-radius-sm)",md:"rounded-b-(--neba-radius-md)",lg:"rounded-b-(--neba-radius-lg)",xl:"rounded-b-(--neba-radius-xl)"},bottom:{xs:"rounded-t-(--neba-radius-xs)",sm:"rounded-t-(--neba-radius-sm)",md:"rounded-t-(--neba-radius-md)",lg:"rounded-t-(--neba-radius-lg)",xl:"rounded-t-(--neba-radius-xl)"}},v={left:"border-r",right:"border-l",top:"border-b",bottom:"border-t"},y={left:"flex-row justify-start",right:"flex-row justify-end",top:"flex-col justify-start",bottom:"flex-col justify-end"},w=[x,"relative flex flex-col overflow-hidden","text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[outline:none]"].join(" "),j=["[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),N=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]",j].join(" "),$="border-t [border-color:var(--n-line)]",_=["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" ");export const DrawerClose=l.Close;export function Drawer({side:x="left",mode:k="overlay",size:C="md",color:z="primary",density:B="default",open:D,defaultOpen:O,onOpenChange:P,trigger:T,title:F,description:L,actions:R,dividers:V=!1,showClose:q,locale:A,closeLabel:E,extent:G,rounded:H=!0,modal:I=!0,dismissible:J=!0,className:K,style:M,children:Q,...S}){const U=i(s,A),W="overlay"===k,X="left"===x||"right"===x,Y=q??W,Z=n[B][C],ee=o[B][C],re=V?`${Z} ${ee}`:Z,ae=t(F)||t(L),le=t(R),ne=void 0===G?null:{[X?"width":"height"]:"number"==typeof G?`${G}px`:G},oe=[w,b[C],v[x],H?h[x][C]:"",W?"[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]":"[box-shadow:var(--neba-plate-glass)]",W?j:"",X?`h-full max-w-full ${void 0===G?g[C]:""}`:"w-full "+(void 0===G?"max-h-[85%]":""),V?"":`${ee} ${c[C]}`,K??""].filter(Boolean).join(" "),se=W?l.Title:"h2",ie=W?l.Description:"p",de=r(a,{children:[ae||Y?r("div",{className:`flex shrink-0 items-start gap-3 ${re}`,children:[r("div",{className:`flex min-w-0 flex-1 flex-col ${m[C]}`,children:[t(F)?e(se,{className:`m-0 font-semibold ${f[C]}`,children:F}):null,t(L)?e(ie,{className:`m-0 text-(--neba-muted-fg) ${u[C]}`,children:L}):null]}),Y?W?e(l.Close,{"aria-label":E??U.close,className:_,children:e(d,{})}):e("button",{type:"button","aria-label":E??U.close,className:_,onClick:()=>P?.(!1),children:e(d,{})}):null]}):null,t(Q)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",re,V&&(ae||Y)?$:"",V?"":"py-1 -my-1"].filter(Boolean).join(" "),children:Q}):null,le?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",re,V?$:""].filter(Boolean).join(" "),children:R}):null]});return W?r(l.Root,{open:D,defaultOpen:O,modal:I,disablePointerDismissal:!J,onOpenChange:(e,r)=>{J||e||"escape-key"!==r.reason?P?.(e):r.cancel()},children:[T?e(l.Trigger,{render:T}):null,r(l.Portal,{children:[e(l.Backdrop,{className:`neba-portal ${N}`}),e(l.Viewport,{className:`neba-portal fixed inset-0 z-50 flex ${y[x]}`,children:e(l.Popup,{className:oe,style:{...p(z,3),...ne,...M},...S,children:de})})]})]}):D??O??!0?e("div",{className:oe,style:{...p(z,0),...ne,...M},children:de}):null}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
import type { NebaColor, NebaDensity, NebaElevation, NebaPosition, NebaSize, NebaVariant } from '../../types.js';
|
|
4
|
+
export interface FooterProps extends Omit<React.ComponentPropsWithoutRef<'footer'>, 'color' | 'title'> {
|
|
5
|
+
/**
|
|
6
|
+
* How the bar sits in the page's scroll. `static` — the default, and the
|
|
7
|
+
* opposite of [Header]'s — is what a footer is: the thing at the end of the
|
|
8
|
+
* document, reached by scrolling to it. `sticky` and `fixed` are for the bar
|
|
9
|
+
* that has to stay in reach — a form's save row, a cookie notice — and a
|
|
10
|
+
* [PageLayout] reserves the height a `fixed` one takes out of the flow.
|
|
11
|
+
* @default 'static'
|
|
12
|
+
*/
|
|
13
|
+
position?: NebaPosition;
|
|
14
|
+
/**
|
|
15
|
+
* Weight of the sheet, said the way a *container* says it: the bar is never
|
|
16
|
+
* dyed, because what is on it arrives with colours of its own.
|
|
17
|
+
* @default 'outline'
|
|
18
|
+
*/
|
|
19
|
+
variant?: NebaVariant;
|
|
20
|
+
/**
|
|
21
|
+
* The bar's scale — its gutter and the air above and below its content. As on
|
|
22
|
+
* Box, `size` here is the size of the *sheet*.
|
|
23
|
+
* @default 'md'
|
|
24
|
+
*/
|
|
25
|
+
size?: NebaSize;
|
|
26
|
+
/** @default 'primary' */
|
|
27
|
+
color?: NebaColor;
|
|
28
|
+
/** @default 'default' */
|
|
29
|
+
density?: NebaDensity;
|
|
30
|
+
/** Drop shadow depth. `0` (the default) is flat. @default 0 */
|
|
31
|
+
elevation?: NebaElevation;
|
|
32
|
+
/**
|
|
33
|
+
* Draws a hairline along the top edge. On by default: a footer is the one
|
|
34
|
+
* sheet on the page with content directly above it and nothing below, so the
|
|
35
|
+
* line is the whole of what says the document ended.
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
divider?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Holds the content to a measure and centres it, while the sheet itself still
|
|
41
|
+
* spans the window. On the same ladder Container's own `maxWidth` uses.
|
|
42
|
+
* @default 'none'
|
|
43
|
+
*/
|
|
44
|
+
maxWidth?: NebaSize | 'none';
|
|
45
|
+
/** The gutter and the air above and below. @default true */
|
|
46
|
+
padded?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The name the bar is announced by. Worth writing when a page has more than
|
|
49
|
+
* one `<footer>` in it — an article's own and the site's.
|
|
50
|
+
*/
|
|
51
|
+
label?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Renders something other than a `<footer>`. Base UI's own escape hatch, and
|
|
54
|
+
* rarely what you want: at the top level of a document that tag is the
|
|
55
|
+
* `contentinfo` landmark, and it is what says "this is the site's own
|
|
56
|
+
* information" rather than "this is more of the article".
|
|
57
|
+
*/
|
|
58
|
+
render?: useRender.RenderProp;
|
|
59
|
+
/**
|
|
60
|
+
* Everything in it. A footer's content is columns of links, a copyright line,
|
|
61
|
+
* a logo — all of it the caller's, none of it something a component could
|
|
62
|
+
* guess at, which is why this one has slots for nothing and space for
|
|
63
|
+
* anything.
|
|
64
|
+
*/
|
|
65
|
+
children?: React.ReactNode;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The sheet at the end of a page.
|
|
69
|
+
*
|
|
70
|
+
* A real `<footer>`, which is the whole reason it is a component rather than a
|
|
71
|
+
* div: at the top level of a document that tag is the `contentinfo` landmark —
|
|
72
|
+
* the region a screen reader offers as "the site's own information" and a
|
|
73
|
+
* search engine reads the copyright, the address and the site map out of.
|
|
74
|
+
*
|
|
75
|
+
* It has no slots on purpose, which is the difference between it and [Header].
|
|
76
|
+
* A header's three regions are a fixed arrangement worth writing once; a
|
|
77
|
+
* footer's content is four columns on one site, one line on the next, and a
|
|
78
|
+
* component that guessed at the arrangement would be a component every second
|
|
79
|
+
* site fights. What it decides is the sheet: the surface, the gutter, the
|
|
80
|
+
* hairline that says the document ended, and whether it stays in reach.
|
|
81
|
+
*
|
|
82
|
+
* Inside a [PageLayout] it also registers itself, so a `fixed` footer's height
|
|
83
|
+
* is reserved rather than sitting on top of the last paragraph.
|
|
84
|
+
*/
|
|
85
|
+
export declare const Footer: React.ForwardRefExoticComponent<FooterProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{useRender as t}from"@base-ui/react/use-render";import{boxPaddingXClasses as a,boxPaddingYClasses as o}from"../box/Box.js";import{PageLayoutContext as n}from"../../internal/page-layout.js";import{cx as s,surfaceClasses as i,surfaceSlots as l,transitionClasses as m}from"../../internal/styles.js";const d={solid:[i,"text-(--neba-fg) bg-(--n-panel-press)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[i,"text-(--neba-fg) bg-(--n-panel)","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},x={static:"",sticky:"sticky bottom-0 z-30",fixed:"fixed inset-x-0 bottom-0 z-40"},c={xs:"max-w-[30rem]",sm:"max-w-[40rem]",md:"max-w-[48rem]",lg:"max-w-[64rem]",xl:"max-w-[80rem]"};export const Footer=/*@__PURE__*/r.forwardRef(function({position:i="static",variant:f="outline",size:p="md",color:b="primary",density:u="default",elevation:v=0,divider:w=!0,maxWidth:g="none",padded:y=!0,label:j,render:h,className:k,style:z,children:N,...C},B){const F=r.useContext(n),{register:R}=F,W=r.useCallback(e=>{R("footer",e),"function"==typeof B?B(e):B&&(B.current=e)},[R,B]),q=s("w-full min-w-0",d[f],w?"border-t [border-color:var(--n-line)]":"",x[i],m,k);return t({render:h??e("footer",{}),ref:W,props:{"aria-label":j,className:q,style:{...l(b,v),...z},children:e("div",{className:s("w-full",y?s(a[u][p],o[u][p]):"","none"===g?"":s(c[g],"mx-auto")),children:N}),...C}})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Footer}from"./Footer.js";
|