neba 1.1.0 → 1.3.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 +12 -7
- package/dist/components/alert/Alert.d.ts +7 -1
- package/dist/components/alert/Alert.js +1 -1
- package/dist/components/animate-appear/AnimateAppear.d.ts +55 -0
- package/dist/components/animate-appear/AnimateAppear.js +1 -0
- package/dist/components/animate-appear/index.d.ts +2 -0
- package/dist/components/animate-appear/index.js +1 -0
- package/dist/components/animate-blink/AnimateBlink.d.ts +31 -0
- package/dist/components/animate-blink/AnimateBlink.js +1 -0
- package/dist/components/animate-blink/index.d.ts +2 -0
- package/dist/components/animate-blink/index.js +1 -0
- package/dist/components/animate-fade/AnimateFade.d.ts +31 -0
- package/dist/components/animate-fade/AnimateFade.js +1 -0
- package/dist/components/animate-fade/index.d.ts +2 -0
- package/dist/components/animate-fade/index.js +1 -0
- package/dist/components/animate-grow/AnimateGrow.d.ts +41 -0
- package/dist/components/animate-grow/AnimateGrow.js +1 -0
- package/dist/components/animate-grow/index.d.ts +2 -0
- package/dist/components/animate-grow/index.js +1 -0
- package/dist/components/animate-headline/AnimateHeadline.d.ts +55 -0
- package/dist/components/animate-headline/AnimateHeadline.js +1 -0
- package/dist/components/animate-headline/index.d.ts +2 -0
- package/dist/components/animate-headline/index.js +1 -0
- package/dist/components/animate-lighting/AnimateLighting.d.ts +62 -0
- package/dist/components/animate-lighting/AnimateLighting.js +1 -0
- package/dist/components/animate-lighting/index.d.ts +2 -0
- package/dist/components/animate-lighting/index.js +1 -0
- package/dist/components/animate-marquee/AnimateMarquee.d.ts +65 -0
- package/dist/components/animate-marquee/AnimateMarquee.js +1 -0
- package/dist/components/animate-marquee/index.d.ts +2 -0
- package/dist/components/animate-marquee/index.js +1 -0
- package/dist/components/animate-rotate/AnimateRotate.d.ts +48 -0
- package/dist/components/animate-rotate/AnimateRotate.js +1 -0
- package/dist/components/animate-rotate/index.d.ts +2 -0
- package/dist/components/animate-rotate/index.js +1 -0
- package/dist/components/animate-slide/AnimateSlide.d.ts +46 -0
- package/dist/components/animate-slide/AnimateSlide.js +1 -0
- package/dist/components/animate-slide/index.d.ts +2 -0
- package/dist/components/animate-slide/index.js +1 -0
- package/dist/components/animate-typing/AnimateTyping.d.ts +58 -0
- package/dist/components/animate-typing/AnimateTyping.js +1 -0
- package/dist/components/animate-typing/index.d.ts +2 -0
- package/dist/components/animate-typing/index.js +1 -0
- package/dist/components/animate-zoom/AnimateZoom.d.ts +37 -0
- package/dist/components/animate-zoom/AnimateZoom.js +1 -0
- package/dist/components/animate-zoom/index.d.ts +2 -0
- package/dist/components/animate-zoom/index.js +1 -0
- package/dist/components/aspect-ratio/AspectRatio.d.ts +63 -0
- package/dist/components/aspect-ratio/AspectRatio.js +1 -0
- package/dist/components/aspect-ratio/index.d.ts +2 -0
- package/dist/components/aspect-ratio/index.js +1 -0
- package/dist/components/avatar/Avatar.d.ts +106 -0
- package/dist/components/avatar/Avatar.js +1 -0
- package/dist/components/avatar/index.d.ts +2 -0
- package/dist/components/avatar/index.js +1 -0
- package/dist/components/blockquote/Blockquote.d.ts +7 -1
- package/dist/components/blockquote/Blockquote.js +1 -1
- package/dist/components/box/Box.d.ts +7 -1
- package/dist/components/box/Box.js +1 -1
- package/dist/components/breadcrumb/Breadcrumb.d.ts +92 -0
- package/dist/components/breadcrumb/Breadcrumb.js +1 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/chat-bubble/ChatBubble.d.ts +114 -0
- package/dist/components/chat-bubble/ChatBubble.js +1 -0
- package/dist/components/chat-bubble/index.d.ts +2 -0
- package/dist/components/chat-bubble/index.js +1 -0
- package/dist/components/chip/Chip.d.ts +7 -1
- package/dist/components/chip/Chip.js +1 -1
- package/dist/components/color-picker/ColorPicker.d.ts +102 -0
- package/dist/components/color-picker/ColorPicker.js +1 -0
- package/dist/components/color-picker/index.d.ts +2 -0
- package/dist/components/color-picker/index.js +1 -0
- package/dist/components/drawer/Drawer.d.ts +145 -0
- package/dist/components/drawer/Drawer.js +1 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/icon/Icon.d.ts +8 -1
- package/dist/components/icon/Icon.js +1 -1
- package/dist/components/otp-field/OtpField.d.ts +85 -0
- package/dist/components/otp-field/OtpField.js +1 -0
- package/dist/components/otp-field/index.d.ts +2 -0
- package/dist/components/otp-field/index.js +1 -0
- package/dist/components/panes/Panes.d.ts +78 -0
- package/dist/components/panes/Panes.js +1 -0
- package/dist/components/panes/index.d.ts +2 -0
- package/dist/components/panes/index.js +1 -0
- package/dist/components/popover/Popover.d.ts +109 -0
- package/dist/components/popover/Popover.js +1 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/skeleton/Skeleton.d.ts +76 -0
- package/dist/components/skeleton/Skeleton.js +1 -0
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/index.js +1 -0
- package/dist/components/spoiler/Spoiler.d.ts +95 -0
- package/dist/components/spoiler/Spoiler.js +1 -0
- package/dist/components/spoiler/index.d.ts +2 -0
- package/dist/components/spoiler/index.js +1 -0
- package/dist/components/text-link/TextLink.d.ts +82 -0
- package/dist/components/text-link/TextLink.js +1 -0
- package/dist/components/text-link/index.d.ts +2 -0
- package/dist/components/text-link/index.js +1 -0
- package/dist/components/tree-view/TreeView.d.ts +115 -0
- package/dist/components/tree-view/TreeView.js +1 -0
- package/dist/components/tree-view/index.d.ts +2 -0
- package/dist/components/tree-view/index.js +1 -0
- package/dist/components/typography/Typography.d.ts +7 -1
- package/dist/components/typography/Typography.js +1 -1
- package/dist/index.d.ts +24 -0
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +175 -0
- package/dist/internal/animate.js +1 -0
- package/dist/internal/color.d.ts +108 -0
- package/dist/internal/color.js +1 -0
- package/dist/internal/i18n.d.ts +103 -0
- package/dist/internal/i18n.js +1 -0
- package/dist/internal/icons.d.ts +23 -0
- package/dist/internal/icons.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +504 -0
- package/dist/types.d.ts +112 -0
- package/package.json +14 -14
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{ChevronIcon as a}from"../../internal/icons";import{controlTextClasses as l,cx as s,gapClasses as o,hasContent as i,iconClasses as c,radiusClasses as d,surfaceClasses as u,surfaceSlots as m,transitionClasses as f}from"../../internal/styles";const p=n.createContext({size:"md",density:"default",disabled:!1,expandedKeys:new Set,selectedKeys:new Set,activeKey:null,toggle:()=>{},select:()=>{},activate:()=>{},register:()=>()=>{}}),x={solid:[u,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[u,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},g={xs:"0.875rem",sm:"1rem",md:"1.25rem",lg:"1.5rem",xl:"1.75rem"},b={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"},h={default:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-3.5"},compact:{xs:"px-1",sm:"px-1",md:"px-1.5",lg:"px-2",xl:"px-2.5"}},v={xs:"rounded-[0.3125rem]",sm:"rounded-[0.375rem]",md:"rounded-[0.5rem]",lg:"rounded-[0.625rem]",xl:"rounded-[0.75rem]"},y={none:"",simple:"neba-tree-simple",folder:"neba-tree-folder"};function w(e){return Array.from(e.querySelectorAll('[role="treeitem"]'))}const k=e=>String(e);export const TreeView=n.forwardRef(function({variant:t="outline",size:r="md",color:a="primary",density:l="default",elevation:o=0,lines:i="simple",expanded:c,defaultExpanded:u,onExpandedChange:h,selected:v,defaultSelected:C,onSelectedChange:N,multiple:S=!1,disabled:K=!1,label:A,className:D,style:R,children:E,onKeyDown:j,...I},P){const[V,z]=n.useState(u??[]),[_,O]=n.useState(C??[]),[J,L]=n.useState(null),M=c??V,T=v??_,q=n.useRef(null),F=n.useCallback(e=>{q.current=e,"function"==typeof P?P(e):P&&(P.current=e)},[P]),H=n.useCallback(e=>{const t=k(e),r=c??V,n=r.some(e=>k(e)===t)?r.filter(e=>k(e)!==t):[...r,e];void 0===c&&z(n),h?.(n)},[c,V,h]),U=n.useCallback(e=>{const t=k(e),r=v??_,n=r.some(e=>k(e)===t),a=S?n?r.filter(e=>k(e)!==t):[...r,e]:[e];void 0===v&&O(a),N?.(a)},[S,v,_,N]),B=n.useRef(new Map),G=n.useCallback((e,t)=>(B.current.set(e,t),()=>{B.current.delete(e)}),[]),Q=JSON.stringify(M.map(k)),W=JSON.stringify(T.map(k)),X=n.useMemo(()=>({size:r,density:l,disabled:K,expandedKeys:new Set(M.map(k)),selectedKeys:new Set(T.map(k)),activeKey:J,toggle:H,select:U,activate:L,register:G}),[r,l,K,Q,W,J,H,U,G]);n.useEffect(()=>{const e=q.current;if(!e)return;const t=w(e);0!==t.length&&(null!==J&&t.some(e=>e.dataset.nebaValue===J)||L(t[0].dataset.nebaValue??null))});const Y=s("flex list-none flex-col p-1",d[r],x[t],f,y[i],D);return e(p.Provider,{value:X,children:e("ul",{ref:F,role:"tree","aria-label":A,"aria-multiselectable":S||void 0,className:Y,style:{...m(a,o),"--n-tree-indent":g[r],"--n-tree-row":b[r],...R},onKeyDown:function(e){if(j?.(e),e.defaultPrevented)return;const t=q.current,r=e.target?.closest?.('[role="treeitem"]');if(!t||!r||!t.contains(r))return;const n=w(t),a=n.indexOf(r);if(-1===a)return;const l=t=>{t&&(e.preventDefault(),L(t.dataset.nebaValue??null),t.focus())},s=e=>{const t=e.dataset.nebaValue;t&&B.current.get(t)?.toggle()},o="rtl"===getComputedStyle(t).direction,i=o?"ArrowLeft":"ArrowRight",c=o?"ArrowRight":"ArrowLeft",d=r.getAttribute("aria-expanded");switch(e.key){case"ArrowDown":l(n[a+1]);break;case"ArrowUp":l(n[a-1]);break;case"Home":l(n[0]);break;case"End":l(n[n.length-1]);break;case i:"false"===d?(e.preventDefault(),s(r)):"true"===d&&l(n[a+1]);break;case c:"true"===d?(e.preventDefault(),s(r)):l(r.parentElement?.closest('[role="treeitem"]'));break;case"Enter":case" ":e.preventDefault(),r.click()}},...I,children:E})})});export const TreeItem=n.forwardRef(function({value:d,label:u,startIcon:m,endIcon:x,action:g,href:b,expandable:y,disabled:w=!1,className:C,children:N,onClick:S,...K},A){const{size:D,density:R,disabled:E,expandedKeys:j,selectedKeys:I,activeKey:P,toggle:V,select:z,activate:_,register:O}=n.useContext(p),J=n.useId(),L=d??J,M=k(L),T=n.useRef(null),q=n.useCallback(e=>{T.current=e,"function"==typeof A?A(e):A&&(A.current=e)},[A]),F=n.Children.toArray(N),H=y??F.length>0,U=H&&j.has(M),B=I.has(M),G=w||E,Q=n.useRef({toggle:()=>{}});Q.current.toggle=()=>{!G&&H&&V(L)},n.useEffect(()=>O(M,Q.current),[M,O]);const W=s("flex min-w-0 flex-1 cursor-pointer items-center text-start","h-(--n-tree-row)",h[R][D],v[D],o[D],l[D],f,c,"group-focus-visible/tree-item:[outline:2px_solid_var(--n-ring)]","group-focus-visible/tree-item:outline-offset-[-2px]",G?"cursor-not-allowed text-(--neba-disabled-fg)":B?"bg-(--n-soft-press) font-medium text-(--n-accent) hover:bg-(--n-soft-press)":"hover:bg-(--n-soft)"),X=r(t,{children:[e("span",{"aria-hidden":"true",onClick:e=>{!G&&H&&(e.stopPropagation(),e.preventDefault(),T.current?.focus(),_(M),V(L))},className:s("flex h-[1lh] w-[1.15em] shrink-0 items-center justify-center","[transition:rotate_var(--neba-duration)_var(--neba-ease)]",H?"text-(--neba-muted-fg)":"",U?"rotate-0":"-rotate-90 rtl:rotate-90"),children:H?e(a,{}):null}),i(m)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)",children:m}):null,e("span",{className:"min-w-0 flex-1 truncate",children:u}),i(x)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)",children:x}):null]});return r("li",{ref:q,role:"treeitem","aria-expanded":H?U:void 0,"aria-selected":!!B||void 0,"aria-disabled":G||void 0,"data-neba-value":M,tabIndex:P===M?0:-1,className:s("group/tree-item relative block [outline:none]",C),onClick:function(e){e.stopPropagation(),G?e.preventDefault():(T.current?.focus(),_(M),S?.(e),e.defaultPrevented||(H&&V(L),z(L)))},...K,children:[r("div",{className:"flex w-full items-center",children:[b&&!G?e("a",{href:b,tabIndex:-1,className:W,"aria-current":B?"page":void 0,children:X}):e("div",{className:W,children:X}),i(g)?e("span",{className:s("flex shrink-0 items-center",h[R][D]),onClick:e=>e.stopPropagation(),children:g}):null]}),H&&U&&F.length>0?e("ul",{role:"group",className:"list-none ps-(--n-tree-indent)",children:N}):null]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{TreeItem,TreeView}from"./TreeView";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
import type { NebaColor } from '../../types';
|
|
3
|
+
import type { NebaColor, NebaTransition } from '../../types';
|
|
4
4
|
/**
|
|
5
5
|
* What a piece of text *is*, which decides both its type scale and the element
|
|
6
6
|
* it renders as.
|
|
@@ -19,6 +19,12 @@ export interface TypographyProps extends Omit<React.ComponentPropsWithoutRef<'p'
|
|
|
19
19
|
* @default 'body'
|
|
20
20
|
*/
|
|
21
21
|
level?: TypographyLevel;
|
|
22
|
+
/**
|
|
23
|
+
* An entrance animation, run once on mount: `transition="fade"`, or an object
|
|
24
|
+
* for the details. For a trigger, a replay or anything under your own
|
|
25
|
+
* control, wrap it in an `Animate*` component instead.
|
|
26
|
+
*/
|
|
27
|
+
transition?: NebaTransition;
|
|
22
28
|
/**
|
|
23
29
|
* Semantic colour role. Unlike every other component this has **no default**:
|
|
24
30
|
* text inherits the page's own colour unless a role is asked for, because the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react";import{useRender as t}from"@base-ui/react/use-render";const
|
|
1
|
+
import*as e from"react";import{useRender as t}from"@base-ui/react/use-render";import{transitionProps as r}from"../../internal/animate";const m={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"},n={h1:"semibold",h2:"semibold",h3:"semibold",h4:"semibold",h5:"semibold",h6:"semibold",lead:"regular",body:"regular",caption:"regular",overline:"medium"},a={h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",lead:"p",body:"p",caption:"span",overline:"span"},l=new Set(["caption","overline"]),o={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"},i={regular:"font-normal",medium:"font-medium",semibold:"font-semibold",bold:"font-bold"},c={start:"text-start",center:"text-center",end:"text-end",justify:"text-justify"},h={1:"truncate",2:"line-clamp-2",3:"line-clamp-3",4:"line-clamp-4",5:"line-clamp-5",6:"line-clamp-6"};export const Typography=e.forwardRef(function({level:s="body",color:d,weight:b,align:p,lines:x,gutter:u=!1,transition:f,render:g,className:y,style:v,children:k,...j},w){const N=r(f),B=[m[s],i[b??n[s]],p?c[p]:"",x?h[x]??"line-clamp-6":"",u?o[s]:"",d?"text-(--n-accent)":l.has(s)?"text-(--neba-muted-fg)":"text-(--neba-fg)",N.className,y??""].filter(Boolean).join(" ");return t({render:g??e.createElement(a[s]),ref:w,props:{className:B,style:d?{"--n-accent":`var(--neba-${d}-accent)`,...N.style,...v}:{...N.style,...v},children:k,...j}})});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
export * from './types';
|
|
2
2
|
export * from './components/accordion';
|
|
3
3
|
export * from './components/alert';
|
|
4
|
+
export * from './components/animate-appear';
|
|
5
|
+
export * from './components/animate-blink';
|
|
6
|
+
export * from './components/animate-fade';
|
|
7
|
+
export * from './components/animate-grow';
|
|
8
|
+
export * from './components/animate-headline';
|
|
9
|
+
export * from './components/animate-lighting';
|
|
10
|
+
export * from './components/animate-marquee';
|
|
11
|
+
export * from './components/animate-rotate';
|
|
12
|
+
export * from './components/animate-slide';
|
|
13
|
+
export * from './components/animate-typing';
|
|
14
|
+
export * from './components/animate-zoom';
|
|
15
|
+
export * from './components/aspect-ratio';
|
|
16
|
+
export * from './components/avatar';
|
|
4
17
|
export * from './components/badge';
|
|
5
18
|
export * from './components/blockquote';
|
|
6
19
|
export * from './components/box';
|
|
20
|
+
export * from './components/breadcrumb';
|
|
7
21
|
export * from './components/button';
|
|
8
22
|
export * from './components/button-group';
|
|
9
23
|
export * from './components/card';
|
|
10
24
|
export * from './components/carousel';
|
|
25
|
+
export * from './components/chat-bubble';
|
|
11
26
|
export * from './components/checkbox';
|
|
12
27
|
export * from './components/chip';
|
|
28
|
+
export * from './components/color-picker';
|
|
13
29
|
export * from './components/combobox';
|
|
14
30
|
export * from './components/container';
|
|
15
31
|
export * from './components/date-picker';
|
|
@@ -17,6 +33,7 @@ export * from './components/date-range-picker';
|
|
|
17
33
|
export * from './components/date-time-picker';
|
|
18
34
|
export * from './components/dialog';
|
|
19
35
|
export * from './components/divider';
|
|
36
|
+
export * from './components/drawer';
|
|
20
37
|
export * from './components/file-picker';
|
|
21
38
|
export * from './components/grid';
|
|
22
39
|
export * from './components/grid-container';
|
|
@@ -26,9 +43,12 @@ export * from './components/icon-button';
|
|
|
26
43
|
export * from './components/list';
|
|
27
44
|
export * from './components/menu';
|
|
28
45
|
export * from './components/number-field';
|
|
46
|
+
export * from './components/otp-field';
|
|
29
47
|
export * from './components/overlay';
|
|
30
48
|
export * from './components/pagination';
|
|
49
|
+
export * from './components/panes';
|
|
31
50
|
export * from './components/pill';
|
|
51
|
+
export * from './components/popover';
|
|
32
52
|
export * from './components/progress-box';
|
|
33
53
|
export * from './components/progress-circular';
|
|
34
54
|
export * from './components/progress-linear';
|
|
@@ -36,15 +56,19 @@ export * from './components/radio-group';
|
|
|
36
56
|
export * from './components/segmented-button';
|
|
37
57
|
export * from './components/select';
|
|
38
58
|
export * from './components/shortcut';
|
|
59
|
+
export * from './components/skeleton';
|
|
39
60
|
export * from './components/slider';
|
|
61
|
+
export * from './components/spoiler';
|
|
40
62
|
export * from './components/statistic';
|
|
41
63
|
export * from './components/switch';
|
|
42
64
|
export * from './components/table';
|
|
43
65
|
export * from './components/tabs';
|
|
44
66
|
export * from './components/text-field';
|
|
67
|
+
export * from './components/text-link';
|
|
45
68
|
export * from './components/time-picker';
|
|
46
69
|
export * from './components/timeline';
|
|
47
70
|
export * from './components/toast';
|
|
48
71
|
export * from './components/toolbar';
|
|
49
72
|
export * from './components/tooltip';
|
|
73
|
+
export * from './components/tree-view';
|
|
50
74
|
export * from './components/typography';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types";export*from"./components/accordion";export*from"./components/alert";export*from"./components/badge";export*from"./components/blockquote";export*from"./components/box";export*from"./components/button";export*from"./components/button-group";export*from"./components/card";export*from"./components/carousel";export*from"./components/checkbox";export*from"./components/chip";export*from"./components/combobox";export*from"./components/container";export*from"./components/date-picker";export*from"./components/date-range-picker";export*from"./components/date-time-picker";export*from"./components/dialog";export*from"./components/divider";export*from"./components/file-picker";export*from"./components/grid";export*from"./components/grid-container";export*from"./components/highlight";export*from"./components/icon";export*from"./components/icon-button";export*from"./components/list";export*from"./components/menu";export*from"./components/number-field";export*from"./components/overlay";export*from"./components/pagination";export*from"./components/pill";export*from"./components/progress-box";export*from"./components/progress-circular";export*from"./components/progress-linear";export*from"./components/radio-group";export*from"./components/segmented-button";export*from"./components/select";export*from"./components/shortcut";export*from"./components/slider";export*from"./components/statistic";export*from"./components/switch";export*from"./components/table";export*from"./components/tabs";export*from"./components/text-field";export*from"./components/time-picker";export*from"./components/timeline";export*from"./components/toast";export*from"./components/toolbar";export*from"./components/tooltip";export*from"./components/typography";
|
|
1
|
+
export*from"./types";export*from"./components/accordion";export*from"./components/alert";export*from"./components/animate-appear";export*from"./components/animate-blink";export*from"./components/animate-fade";export*from"./components/animate-grow";export*from"./components/animate-headline";export*from"./components/animate-lighting";export*from"./components/animate-marquee";export*from"./components/animate-rotate";export*from"./components/animate-slide";export*from"./components/animate-typing";export*from"./components/animate-zoom";export*from"./components/aspect-ratio";export*from"./components/avatar";export*from"./components/badge";export*from"./components/blockquote";export*from"./components/box";export*from"./components/breadcrumb";export*from"./components/button";export*from"./components/button-group";export*from"./components/card";export*from"./components/carousel";export*from"./components/chat-bubble";export*from"./components/checkbox";export*from"./components/chip";export*from"./components/color-picker";export*from"./components/combobox";export*from"./components/container";export*from"./components/date-picker";export*from"./components/date-range-picker";export*from"./components/date-time-picker";export*from"./components/dialog";export*from"./components/divider";export*from"./components/drawer";export*from"./components/file-picker";export*from"./components/grid";export*from"./components/grid-container";export*from"./components/highlight";export*from"./components/icon";export*from"./components/icon-button";export*from"./components/list";export*from"./components/menu";export*from"./components/number-field";export*from"./components/otp-field";export*from"./components/overlay";export*from"./components/pagination";export*from"./components/panes";export*from"./components/pill";export*from"./components/popover";export*from"./components/progress-box";export*from"./components/progress-circular";export*from"./components/progress-linear";export*from"./components/radio-group";export*from"./components/segmented-button";export*from"./components/select";export*from"./components/shortcut";export*from"./components/skeleton";export*from"./components/slider";export*from"./components/spoiler";export*from"./components/statistic";export*from"./components/switch";export*from"./components/table";export*from"./components/tabs";export*from"./components/text-field";export*from"./components/text-link";export*from"./components/time-picker";export*from"./components/timeline";export*from"./components/toast";export*from"./components/toolbar";export*from"./components/tooltip";export*from"./components/tree-view";export*from"./components/typography";
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The machinery every `Animate*` component runs on, and the `transition` prop
|
|
3
|
+
* with it.
|
|
4
|
+
*
|
|
5
|
+
* It lives in `internal/` for the reason `button-group.ts` and `menu.ts` do:
|
|
6
|
+
* eleven components need it and none of them should have to import another. The
|
|
7
|
+
* `transition` prop needs the same table from the other side — a Card and an
|
|
8
|
+
* `AnimateFade` must produce the same fade, or the library has two fades.
|
|
9
|
+
*
|
|
10
|
+
* ## The shape of it
|
|
11
|
+
*
|
|
12
|
+
* Every effect is one `@keyframes` in `styles.css` running from a state written
|
|
13
|
+
* entirely in custom properties to the element's natural one. Nothing here
|
|
14
|
+
* generates CSS: it fills `--n-anim-*` slots, and the stylesheet decides what
|
|
15
|
+
* they mean. That is the same split `styleSlots()` makes for colour, for the
|
|
16
|
+
* same reason — Tailwind only ever sees class names that appear literally in
|
|
17
|
+
* the source, so a per-value class would not scale past the first prop.
|
|
18
|
+
*
|
|
19
|
+
* Because the from-state is the *keyframe* rather than a second class, running
|
|
20
|
+
* an effect backwards is `animation-direction: reverse` and nothing else. That
|
|
21
|
+
* is what makes `mode="out"` free on all six.
|
|
22
|
+
*
|
|
23
|
+
* ## What is deliberately not here
|
|
24
|
+
*
|
|
25
|
+
* An animation that has to know what its children *are* — a marquee that
|
|
26
|
+
* duplicates them, a headline that swaps between them, a typewriter that
|
|
27
|
+
* counts characters — cannot be a class name and a few numbers. Those are
|
|
28
|
+
* components, and their logic stays in their own files.
|
|
29
|
+
*/
|
|
30
|
+
import * as React from 'react';
|
|
31
|
+
import type { NebaAnimateRepeat, NebaAnimateTrigger, NebaAnimation, NebaSide, NebaTransition } from '../types';
|
|
32
|
+
/**
|
|
33
|
+
* Which keyframe an effect runs.
|
|
34
|
+
*
|
|
35
|
+
* `grow` and `zoom` share one: they are the same arithmetic at two strengths,
|
|
36
|
+
* and a second identical `@keyframes` would only be a second place to fix a
|
|
37
|
+
* bug. What separates them is their defaults and their origin, which is a
|
|
38
|
+
* property rather than a keyframe.
|
|
39
|
+
*/
|
|
40
|
+
export declare const animationClasses: Record<NebaAnimation, string>;
|
|
41
|
+
/** The class that reads the slots. Always paired with one of the above. */
|
|
42
|
+
export declare const animBaseClass = "neba-anim";
|
|
43
|
+
/**
|
|
44
|
+
* How long each effect takes when nobody said.
|
|
45
|
+
*
|
|
46
|
+
* They are not one number because they do not travel the same distance. A fade
|
|
47
|
+
* crosses one axis of opacity; a rotate crosses half a turn and reads as rushed
|
|
48
|
+
* at the same duration. `blink` is the odd one out — it is a cycle rather than
|
|
49
|
+
* an arrival, so its number is a period.
|
|
50
|
+
*/
|
|
51
|
+
export declare const defaultDurations: Record<NebaAnimation, number>;
|
|
52
|
+
/** A number is pixels; a string is already a CSS length. */
|
|
53
|
+
export declare function lengthValue(value: number | string): string;
|
|
54
|
+
export declare function isInfinite(repeat: NebaAnimateRepeat | undefined): boolean;
|
|
55
|
+
export interface AnimationSlotOptions {
|
|
56
|
+
duration: number;
|
|
57
|
+
delay: number;
|
|
58
|
+
easing?: string;
|
|
59
|
+
repeat: NebaAnimateRepeat;
|
|
60
|
+
alternate?: boolean;
|
|
61
|
+
mode?: 'in' | 'out';
|
|
62
|
+
/** Where the animated properties start. Only the ones an effect reads. */
|
|
63
|
+
opacity?: number;
|
|
64
|
+
scale?: number;
|
|
65
|
+
x?: string;
|
|
66
|
+
y?: string;
|
|
67
|
+
angle?: string;
|
|
68
|
+
angleTo?: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The `--n-anim-*` slots, as an inline style object.
|
|
72
|
+
*
|
|
73
|
+
* Inline rather than utilities for the reason the colour slots are: these are
|
|
74
|
+
* per-instance numbers, and Tailwind cannot generate a class for a duration it
|
|
75
|
+
* has never seen written down.
|
|
76
|
+
*/
|
|
77
|
+
export declare function animationSlots(options: AnimationSlotOptions): React.CSSProperties;
|
|
78
|
+
/**
|
|
79
|
+
* Which way a slide starts, given the edge it comes from.
|
|
80
|
+
*
|
|
81
|
+
* `NebaSide` is physical everywhere in the library, and it stays physical here:
|
|
82
|
+
* something sliding in from the top of the window comes from the top in every
|
|
83
|
+
* writing direction.
|
|
84
|
+
*/
|
|
85
|
+
export declare function slideOffsets(from: NebaSide, distance: number | string): {
|
|
86
|
+
x: string;
|
|
87
|
+
y: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* What a component's `transition` prop turns into: one class pair and a handful
|
|
91
|
+
* of custom properties, merged into whatever the component was already writing.
|
|
92
|
+
*
|
|
93
|
+
* No hook, no ref, no observer — which is the whole design. A component that
|
|
94
|
+
* offers `transition` gains four lines and no behaviour it has to own, and a
|
|
95
|
+
* caller who needs a trigger, a replay or a hover reaches for the `Animate*`
|
|
96
|
+
* component that does exactly that.
|
|
97
|
+
*/
|
|
98
|
+
export declare function transitionProps(transition: NebaTransition | undefined): {
|
|
99
|
+
className: string;
|
|
100
|
+
style: React.CSSProperties;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Whether the reader has asked for less motion.
|
|
104
|
+
*
|
|
105
|
+
* The CSS side of this is handled in the stylesheet, where every keyframe is
|
|
106
|
+
* switched off at once. This is for the three effects whose motion is written
|
|
107
|
+
* in JavaScript — a typewriter, a headline reel, a measured marquee — where
|
|
108
|
+
* there is no rule to switch off and the component has to decide for itself
|
|
109
|
+
* what "still" means.
|
|
110
|
+
*/
|
|
111
|
+
export declare function usePrefersReducedMotion(): boolean;
|
|
112
|
+
export interface AnimationRunOptions {
|
|
113
|
+
trigger: NebaAnimateTrigger;
|
|
114
|
+
play?: boolean;
|
|
115
|
+
once: boolean;
|
|
116
|
+
threshold: number;
|
|
117
|
+
paused?: boolean;
|
|
118
|
+
/** An infinite effect stops when the pointer leaves; a finite one finishes. */
|
|
119
|
+
infinite: boolean;
|
|
120
|
+
}
|
|
121
|
+
export interface AnimationRun {
|
|
122
|
+
/** Goes on the animated element. */
|
|
123
|
+
ref: React.RefCallback<HTMLElement>;
|
|
124
|
+
/** `running` or `paused`, for `--n-anim-state`. */
|
|
125
|
+
state: 'running' | 'paused';
|
|
126
|
+
/** Whether the animation has been let go at all, for `data-state`. */
|
|
127
|
+
started: boolean;
|
|
128
|
+
/** Spread onto the element when `trigger` is `hover`; empty otherwise. */
|
|
129
|
+
handlers: React.HTMLAttributes<HTMLElement>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Starts, restarts and holds an animation.
|
|
133
|
+
*
|
|
134
|
+
* Two things here are less obvious than they look.
|
|
135
|
+
*
|
|
136
|
+
* **Waiting is `animation-play-state: paused`, not a second class.** An
|
|
137
|
+
* element that has not been triggered yet has to already look like its own
|
|
138
|
+
* first frame, or a `visible` fade would be fully drawn until it scrolled into
|
|
139
|
+
* view and then blink out to start. With `fill-mode: both` a paused animation
|
|
140
|
+
* shows exactly that frame, so waiting and running are one animation in two
|
|
141
|
+
* states rather than two states to keep in step.
|
|
142
|
+
*
|
|
143
|
+
* **Restarting reaches for the DOM.** There is no way to rewind a CSS animation
|
|
144
|
+
* from React: re-rendering with the same class changes nothing, and a `key`
|
|
145
|
+
* would restart the animation by unmounting the children, taking their state
|
|
146
|
+
* with it. Clearing `animation-name`, reading a layout property to force the
|
|
147
|
+
* style to settle, and putting it back is the one move that rewinds the element
|
|
148
|
+
* and leaves everything inside it alone.
|
|
149
|
+
*/
|
|
150
|
+
export declare function useAnimationRun({ trigger, play, once, threshold, paused, infinite }: AnimationRunOptions): AnimationRun;
|
|
151
|
+
export interface AnimateElementParams extends AnimationSlotOptions, AnimationRunOptions {
|
|
152
|
+
/** Which keyframe. `null` for the components that write their own. */
|
|
153
|
+
effect: NebaAnimation | null;
|
|
154
|
+
}
|
|
155
|
+
export interface AnimateElement {
|
|
156
|
+
ref: React.RefCallback<HTMLElement>;
|
|
157
|
+
className: string;
|
|
158
|
+
style: React.CSSProperties;
|
|
159
|
+
/** The hover handlers and the two data attributes, ready to be spread. */
|
|
160
|
+
props: React.HTMLAttributes<HTMLElement> & Record<string, unknown>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Everything an `Animate*` root needs, in one call.
|
|
164
|
+
*
|
|
165
|
+
* The six effect components differ only in their defaults and in which slots
|
|
166
|
+
* they fill, so this is where the identical two-thirds of each of them lives.
|
|
167
|
+
* The four that have to understand their children — Typing, Marquee, Headline,
|
|
168
|
+
* Appear — call `useAnimationRun` directly and put the classes where their own
|
|
169
|
+
* structure needs them, which is why `effect` is allowed to be `null`.
|
|
170
|
+
*
|
|
171
|
+
* `data-neba-animation` and `data-state` are here rather than in each component
|
|
172
|
+
* because they are the same two facts every time, and because a test that has
|
|
173
|
+
* to assert on a class name is a test that breaks when a class name changes.
|
|
174
|
+
*/
|
|
175
|
+
export declare function useAnimateElement(params: AnimateElementParams): AnimateElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as e from"react";export const animationClasses={fade:"neba-anim-fade",grow:"neba-anim-scale",slide:"neba-anim-slide",zoom:"neba-anim-scale",rotate:"neba-anim-rotate",blink:"neba-anim-blink"};export const animBaseClass="neba-anim";export const defaultDurations={fade:320,grow:340,slide:380,zoom:340,rotate:460,blink:900};export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function isInfinite(e){return"infinite"===e}export function animationSlots(e){const n={"--n-anim-duration":`${e.duration}ms`,"--n-anim-delay":`${e.delay}ms`,"--n-anim-repeat":(i=e.repeat,"infinite"===i?"infinite":String(i)),"--n-anim-direction":(t=e.mode??"in",a=e.alternate,"out"===t?a?"alternate-reverse":"reverse":a?"alternate":"normal")};var t,a,i;return e.easing&&(n["--n-anim-ease"]=e.easing),void 0!==e.opacity&&(n["--n-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(n["--n-anim-scale"]=String(e.scale)),void 0!==e.x&&(n["--n-anim-x"]=e.x),void 0!==e.y&&(n["--n-anim-y"]=e.y),void 0!==e.angle&&(n["--n-anim-angle"]=e.angle),void 0!==e.angleTo&&(n["--n-anim-angle-to"]=e.angleTo),n}export function slideOffsets(e,n){const t=lengthValue(n),a="number"==typeof n?-n+"px":`calc(-1 * ${t})`;switch(e){case"top":return{x:"0px",y:a};case"bottom":return{x:"0px",y:t};case"left":return{x:a,y:"0px"};default:return{x:t,y:"0px"}}}export function transitionProps(e){if(!e)return{className:"",style:{}};const n="string"==typeof e?{type:e}:e,{type:t}=n,a={duration:n.duration??defaultDurations[t],delay:n.delay??0,easing:n.easing,repeat:n.repeat??("blink"===t?"infinite":1),alternate:n.alternate};if("grow"!==t&&"zoom"!==t||(a.scale=n.scale??("zoom"===t?.4:.8)),"slide"===t){const{x:e,y:t}=slideOffsets(n.from??"bottom",n.distance??"100%");a.x=e,a.y=t}return"rotate"===t&&(a.angle=`${n.angle??-180}deg`),{className:`neba-anim ${animationClasses[t]}`,style:animationSlots(a)}}export function usePrefersReducedMotion(){const[n,t]=e.useState(!1);return e.useEffect(()=>{if("undefined"==typeof window||!window.matchMedia)return;const e=window.matchMedia("(prefers-reduced-motion: reduce)");t(e.matches);const n=e=>t(e.matches);return e.addEventListener("change",n),()=>e.removeEventListener("change",n)},[]),n}export function useAnimationRun({trigger:n,play:t,once:a,threshold:i,paused:o,infinite:r}){const s=e.useRef(null),[c,l]=e.useState("mount"===n),[u,m]=e.useState(0),d=e.useCallback(()=>{l(!0),m(e=>e+1)},[]);e.useLayoutEffect(()=>{const e=s.current;if(!e||0===u)return;const n=[e,...e.querySelectorAll(".neba-anim, .neba-marquee-track")];for(const e of n)e.style.animationName="none";e.offsetWidth;for(const e of n)e.style.animationName=""},[u]),e.useEffect(()=>{if("visible"!==n)return;const e=s.current;if(!e||"undefined"==typeof IntersectionObserver)return void l(!0);const t=new IntersectionObserver(([e])=>{e.isIntersecting?(d(),a&&t.disconnect()):a||l(!1)},{threshold:i});return t.observe(e),()=>t.disconnect()},[n,a,i,d]),e.useEffect(()=>{"manual"===n&&(t?d():l(!1))},[n,t,d]);const f="hover"===n?{onPointerEnter:d,onFocus:d,onPointerLeave:()=>{r&&l(!1)},onBlur:()=>{r&&l(!1)}}:{};return{ref:e.useCallback(e=>{s.current=e},[]),state:c&&!o?"running":"paused",started:c,handlers:f}}export function useAnimateElement(e){const{effect:n,trigger:t,play:a,once:i,threshold:o,paused:r,infinite:s,...c}=e,l=useAnimationRun({trigger:t,play:a,once:i,threshold:o,paused:r,infinite:s});return{ref:l.ref,className:n?`neba-anim ${animationClasses[n]}`:"",style:{...animationSlots(c),"--n-anim-state":l.state},props:{...l.handlers,"data-neba-animation":n??void 0,"data-state":l.state}}}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour arithmetic, written out rather than installed.
|
|
3
|
+
*
|
|
4
|
+
* ColorPicker is the only component that has to *compute* a colour rather than
|
|
5
|
+
* name one, and the whole of what it needs is here: three representations, the
|
|
6
|
+
* conversions between them, one parser and one formatter. It is a hundred lines
|
|
7
|
+
* of trigonometry-free arithmetic, which is the entire reason the library still
|
|
8
|
+
* has one runtime dependency.
|
|
9
|
+
*
|
|
10
|
+
* Two decisions worth knowing before reading:
|
|
11
|
+
*
|
|
12
|
+
* - **HSV is the model the panel is drawn in, and it never leaves.** A
|
|
13
|
+
* saturation/value square with a hue rail beside it *is* HSV, so the picker
|
|
14
|
+
* keeps its state that way and converts on the way out. Round-tripping
|
|
15
|
+
* through RGB instead would lose the hue of every greyscale colour — black is
|
|
16
|
+
* `#000` at every hue — and the rail would jump to red the moment the pointer
|
|
17
|
+
* reached a corner.
|
|
18
|
+
* - **`alpha` is 0–1, everything else is what CSS says it is.** `h` is degrees,
|
|
19
|
+
* `s`/`v`/`l` are percentages, `r`/`g`/`b` are 0–255. No component invents a
|
|
20
|
+
* normalised unit, because every one of these numbers is eventually written
|
|
21
|
+
* into a string a human reads.
|
|
22
|
+
*
|
|
23
|
+
* Nothing here is exported from `src/index.ts`. It is the library talking to
|
|
24
|
+
* itself, in the sense that `internal/` always means.
|
|
25
|
+
*/
|
|
26
|
+
/** 0–255 per channel, the way a hex triplet and `rgb()` both spell it. */
|
|
27
|
+
export interface Rgb {
|
|
28
|
+
r: number;
|
|
29
|
+
g: number;
|
|
30
|
+
b: number;
|
|
31
|
+
}
|
|
32
|
+
/** `h` in degrees, `s` and `v` as percentages. The panel's own model. */
|
|
33
|
+
export interface Hsv {
|
|
34
|
+
h: number;
|
|
35
|
+
s: number;
|
|
36
|
+
v: number;
|
|
37
|
+
}
|
|
38
|
+
/** `h` in degrees, `s` and `l` as percentages. Only ever an output format. */
|
|
39
|
+
export interface Hsl {
|
|
40
|
+
h: number;
|
|
41
|
+
s: number;
|
|
42
|
+
l: number;
|
|
43
|
+
}
|
|
44
|
+
/** A colour and how much of it there is. `alpha` is 0–1. */
|
|
45
|
+
export interface ColorValue {
|
|
46
|
+
hsv: Hsv;
|
|
47
|
+
alpha: number;
|
|
48
|
+
}
|
|
49
|
+
/** The three ways the picker will write a colour back out. */
|
|
50
|
+
export type ColorFormat = 'hex' | 'rgb' | 'hsl';
|
|
51
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
52
|
+
export declare function hsvToRgb({ h, s, v }: Hsv): Rgb;
|
|
53
|
+
export declare function rgbToHsv({ r, g, b }: Rgb): Hsv;
|
|
54
|
+
export declare function rgbToHsl({ r, g, b }: Rgb): Hsl;
|
|
55
|
+
export declare function hslToRgb({ h, s, l }: Hsl): Rgb;
|
|
56
|
+
/**
|
|
57
|
+
* A CSS colour string, or `null` if it is not one this understands.
|
|
58
|
+
*
|
|
59
|
+
* Hex in all four lengths, `rgb()`/`rgba()` and `hsl()`/`hsla()` in both the
|
|
60
|
+
* comma and the space syntax. Named colours and `color()` are deliberately out:
|
|
61
|
+
* a picker has to be able to write every value it can read, and there is no
|
|
62
|
+
* honest way back from `rebeccapurple` to a point on the panel.
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseColor(input: string): ColorValue | null;
|
|
65
|
+
export declare function rgbToHex({ r, g, b }: Rgb, alpha?: number): string;
|
|
66
|
+
/**
|
|
67
|
+
* The value the component hands back, in whichever notation was asked for.
|
|
68
|
+
*
|
|
69
|
+
* `hex` drops the alpha pair when the colour is opaque, and the two functional
|
|
70
|
+
* forms drop the fourth argument for the same reason — a caller who never
|
|
71
|
+
* turned `alpha` on should never see `rgba(…, 1)` come out of a control they
|
|
72
|
+
* only used three channels of.
|
|
73
|
+
*/
|
|
74
|
+
export declare function formatColor(hsv: Hsv, alpha: number, format: ColorFormat): string;
|
|
75
|
+
/** A plain `rgb()` for the swatches and rails, where alpha is drawn separately. */
|
|
76
|
+
export declare function cssColor(hsv: Hsv, alpha?: number): string;
|
|
77
|
+
/**
|
|
78
|
+
* Black or white, whichever can be read on top of this colour.
|
|
79
|
+
*
|
|
80
|
+
* The tick on a chosen swatch is the only thing the picker draws *on* an
|
|
81
|
+
* arbitrary colour, and a fixed white tick disappears on yellow. The threshold
|
|
82
|
+
* is relative luminance rather than plain lightness, because the eye weighs
|
|
83
|
+
* green about six times as heavily as blue and a colour model that pretends
|
|
84
|
+
* otherwise puts the tick the wrong way round on both.
|
|
85
|
+
*/
|
|
86
|
+
export declare function readableInk(hsv: Hsv): string;
|
|
87
|
+
/**
|
|
88
|
+
* The swatches a picker shows when it was given none.
|
|
89
|
+
*
|
|
90
|
+
* Deliberately not the library's own six families: those are semantic roles and
|
|
91
|
+
* a picker is asked for a colour, not for a meaning. This is a plain spectrum
|
|
92
|
+
* plus the greys — the row somebody reaches for when they are labelling a
|
|
93
|
+
* calendar, a tag or a project, which is what a colour picker in an application
|
|
94
|
+
* is nearly always for.
|
|
95
|
+
*/
|
|
96
|
+
export declare const defaultSwatches: readonly string[];
|
|
97
|
+
/**
|
|
98
|
+
* The chequerboard behind a translucent colour, as a background shorthand.
|
|
99
|
+
*
|
|
100
|
+
* Two conic gradients would be one declaration fewer, but a chequer drawn with
|
|
101
|
+
* conic gradients has a seam down the middle of every tile on a fractional
|
|
102
|
+
* device pixel ratio. Four linear stops at 45° do not.
|
|
103
|
+
*/
|
|
104
|
+
export declare const checkerBackground: {
|
|
105
|
+
readonly backgroundImage: "linear-gradient(45deg, var(--neba-border) 25%, transparent 25%), linear-gradient(-45deg, var(--neba-border) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--neba-border) 75%), linear-gradient(-45deg, transparent 75%, var(--neba-border) 75%)";
|
|
106
|
+
readonly backgroundSize: "8px 8px";
|
|
107
|
+
readonly backgroundPosition: "0 0, 0 4px, 4px -4px, -4px 0";
|
|
108
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function clamp(r,n,t){return r<n?n:r>t?t:r}function r(r){const n=r%360;return n<0?n+360:n}function n(r){return Math.round(r)}export function hsvToRgb({h:t,s:e,v:o}){const a=r(t)/60,s=clamp(e,0,100)/100,c=clamp(o,0,100)/100,g=c*s,u=g*(1-Math.abs(a%2-1)),l=c-g,b=Math.floor(a)%6,[i,f,h]=[[g,u,0],[u,g,0],[0,g,u],[0,u,g],[u,0,g],[g,0,u]][b];return{r:n(255*(i+l)),g:n(255*(f+l)),b:n(255*(h+l))}}export function rgbToHsv({r:n,g:t,b:e}){const o=clamp(n,0,255)/255,a=clamp(t,0,255)/255,s=clamp(e,0,255)/255,c=Math.max(o,a,s),g=c-Math.min(o,a,s);let u=0;return 0!==g&&(u=c===o?(a-s)/g%6:c===a?(s-o)/g+2:(o-a)/g+4),{h:r(60*u),s:0===c?0:g/c*100,v:100*c}}export function rgbToHsl({r:r,g:n,b:t}){const{h:e,s:o,v:a}=rgbToHsv({r:r,g:n,b:t}),s=a/100,c=s*(1-o/100/2),g=Math.min(c,1-c);return{h:e,s:0===g?0:(s-c)/g*100,l:100*c}}export function hslToRgb({h:r,s:n,l:t}){const e=clamp(t,0,100)/100,o=e+clamp(n,0,100)/100*Math.min(e,1-e);return hsvToRgb({h:r,s:0===o?0:2*(1-e/o)*100,v:100*o})}const t=/^#?([0-9a-f]{3,8})$/i;export function parseColor(r){const n=r.trim().toLowerCase();if(!n)return null;if(n.startsWith("#")||t.test(n))return function(r){const n=t.exec(r.trim());if(!n)return null;const e=n[1],o=3===e.length||4===e.length?[...e].map(r=>r+r).join(""):e;if(6!==o.length&&8!==o.length)return null;const a=r=>parseInt(o.slice(2*r,2*r+2),16);return{hsv:rgbToHsv({r:a(0),g:a(1),b:a(2)}),alpha:8===o.length?a(3)/255:1}}(n);const e=/^(rgba?|hsla?)\((.*)\)$/.exec(n);if(!e)return null;const[,o,a]=e,s=function(r){return(r.match(/-?[\d.]+%?/g)??[]).map(r=>(r.endsWith("%"),parseFloat(r)))}(a);if(s.length<3||s.some(Number.isNaN))return null;const c=function(r,n,t){if(n.length<=t)return 1;const e=r.match(/-?[\d.]+%?/g)??[];return clamp(e[t]?.endsWith("%")?n[t]/100:n[t],0,1)}(a,s,3);return o.startsWith("rgb")?{hsv:rgbToHsv({r:s[0],g:s[1],b:s[2]}),alpha:c}:{hsv:rgbToHsv(hslToRgb({h:s[0],s:s[1],l:s[2]})),alpha:c}}function e(r){return clamp(n(r),0,255).toString(16).padStart(2,"0")}export function rgbToHex({r:r,g:n,b:t},o=1){const a=`#${e(r)}${e(n)}${e(t)}`;return o>=1?a:`${a}${e(255*o)}`}function o(r){return String(Math.round(100*clamp(r,0,1))/100)}export function formatColor(r,t,e){const a=hsvToRgb(r);if("hex"===e)return rgbToHex(a,t);if("rgb"===e){const r=`${n(a.r)}, ${n(a.g)}, ${n(a.b)}`;return t>=1?`rgb(${r})`:`rgba(${r}, ${o(t)})`}const{h:s,s:c,l:g}=rgbToHsl(a),u=`${n(s)}, ${n(c)}%, ${n(g)}%`;return t>=1?`hsl(${u})`:`hsla(${u}, ${o(t)})`}export function cssColor(r,n=1){const{r:t,g:e,b:a}=hsvToRgb(r);return n>=1?`rgb(${t}, ${e}, ${a})`:`rgba(${t}, ${e}, ${a}, ${o(n)})`}export function readableInk(r){const{r:n,g:t,b:e}=hsvToRgb(r),o=r=>{const n=r/255;return n<=.03928?n/12.92:((n+.055)/1.055)**2.4};return.2126*o(n)+.7152*o(t)+.0722*o(e)>.42?"#000000":"#ffffff"}export const defaultSwatches=["#000000","#4b5563","#9ca3af","#ffffff","#ef4444","#f97316","#f59e0b","#84cc16","#22c55e","#14b8a6","#06b6d4","#3b82f6","#6366f1","#8b5cf6","#d946ef","#ec4899"];export const checkerBackground={backgroundImage:"linear-gradient(45deg, var(--neba-border) 25%, transparent 25%), linear-gradient(-45deg, var(--neba-border) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--neba-border) 75%), linear-gradient(-45deg, transparent 75%, var(--neba-border) 75%)",backgroundSize:"8px 8px",backgroundPosition:"0 0, 0 4px, 4px -4px, -4px 0"};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words the library says on its own behalf.
|
|
3
|
+
*
|
|
4
|
+
* Almost nothing in Neba writes text a reader sees — a Button says whatever it
|
|
5
|
+
* was handed, a Card's title is the caller's. The exceptions are the strings a
|
|
6
|
+
* component has to invent because there is nowhere else for them to come from:
|
|
7
|
+
* the sentence behind a link that opens a new tab, the label on the button that
|
|
8
|
+
* uncovers a Spoiler, the word under a chat message that says it was read.
|
|
9
|
+
*
|
|
10
|
+
* Those are collected here rather than defaulted inside each component, for the
|
|
11
|
+
* reason every other table in `internal/` exists: they are a set. A product in
|
|
12
|
+
* Korean does not want eight components each defaulting to English and each
|
|
13
|
+
* needing its own override prop, and the next component that needs a word —
|
|
14
|
+
* a picker's "Today", a Pagination's "Next page" — should get it from the same
|
|
15
|
+
* place rather than starting a second table beside this one.
|
|
16
|
+
*
|
|
17
|
+
* What is *not* in here is anything `Intl` already knows. Month names, weekday
|
|
18
|
+
* names, AM/PM and number formats come from the platform, which speaks more
|
|
19
|
+
* languages than this file ever will. This is only for the words the platform
|
|
20
|
+
* has no opinion about.
|
|
21
|
+
*
|
|
22
|
+
* Every component that reads this takes a `locale` and an override prop for the
|
|
23
|
+
* string itself, so an unsupported language is never a dead end: `locale` gets
|
|
24
|
+
* you a translation for free, and the prop gets you one for anything else.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* One namespace per component, rather than one flat list of keys.
|
|
28
|
+
*
|
|
29
|
+
* A namespace is what makes a partial translation possible: a locale supplies
|
|
30
|
+
* whatever it has and the rest falls back to English one namespace at a time,
|
|
31
|
+
* so adding a namespace here does not silently blank the strings in every
|
|
32
|
+
* language that has not caught up with it yet.
|
|
33
|
+
*/
|
|
34
|
+
export interface NebaMessages {
|
|
35
|
+
/** TextLink. */
|
|
36
|
+
link: {
|
|
37
|
+
/**
|
|
38
|
+
* What is read out after a link that opens a new tab, and never drawn. A
|
|
39
|
+
* window changing under the reader is the one thing about a link that is
|
|
40
|
+
* invisible until it has already happened.
|
|
41
|
+
*/
|
|
42
|
+
newTab: string;
|
|
43
|
+
};
|
|
44
|
+
/** Spoiler. */
|
|
45
|
+
spoiler: {
|
|
46
|
+
/** The button that uncovers the content. */
|
|
47
|
+
reveal: string;
|
|
48
|
+
/** And the one that covers it again, when the Spoiler is reversible. */
|
|
49
|
+
hide: string;
|
|
50
|
+
/** The line above the button, saying why the content is covered. */
|
|
51
|
+
notice: string;
|
|
52
|
+
};
|
|
53
|
+
/** ChatBubble. */
|
|
54
|
+
chat: {
|
|
55
|
+
/** The four steps a message goes through, as the mark under it. */
|
|
56
|
+
sending: string;
|
|
57
|
+
sent: string;
|
|
58
|
+
delivered: string;
|
|
59
|
+
read: string;
|
|
60
|
+
/** And the fifth, which is not a step: it did not go. */
|
|
61
|
+
failed: string;
|
|
62
|
+
/** What the three dots mean. */
|
|
63
|
+
typing: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* ColorPicker.
|
|
67
|
+
*
|
|
68
|
+
* All but one of these are names for something with no text on it: a square
|
|
69
|
+
* of colour, two rails, a grid of swatches. A control a sighted reader
|
|
70
|
+
* understands from a glance at a gradient is a control that says nothing at
|
|
71
|
+
* all without them, which makes this the one namespace here where the strings
|
|
72
|
+
* are the entire accessible interface rather than a convenience on top of it.
|
|
73
|
+
*/
|
|
74
|
+
color: {
|
|
75
|
+
/** The saturation/brightness square. */
|
|
76
|
+
area: string;
|
|
77
|
+
/** The rail beside it. */
|
|
78
|
+
hue: string;
|
|
79
|
+
/** The rail below that, when `alpha` is on. */
|
|
80
|
+
alpha: string;
|
|
81
|
+
/** The field the colour can be typed into. */
|
|
82
|
+
value: string;
|
|
83
|
+
/** The grid of ready-made colours. */
|
|
84
|
+
swatches: string;
|
|
85
|
+
/** The × that empties the control. */
|
|
86
|
+
clear: string;
|
|
87
|
+
/** What the trigger reads before anything has been chosen. */
|
|
88
|
+
empty: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The strings for a locale, merged over English.
|
|
93
|
+
*
|
|
94
|
+
* `undefined` is English rather than the runtime's own locale, and that is
|
|
95
|
+
* deliberate: `navigator.language` differs between the server that renders the
|
|
96
|
+
* markup and the browser that hydrates it, and text that changes between those
|
|
97
|
+
* two is a hydration mismatch in the one part of the page a reader is looking
|
|
98
|
+
* at. A component that should follow the reader is told which language to
|
|
99
|
+
* follow.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveMessages(locale?: string): NebaMessages;
|
|
102
|
+
/** The same, as a hook, for the components that read it during a render. */
|
|
103
|
+
export declare function useMessages(locale?: string): NebaMessages;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as e from"react";const a={link:{newTab:"(opens in a new tab)"},spoiler:{reveal:"Reveal",hide:"Hide",notice:"This may contain spoilers"},chat:{sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",typing:"Typing…"},color:{area:"Saturation and brightness",hue:"Hue",alpha:"Opacity",value:"Colour value",swatches:"Preset colours",clear:"Clear",empty:"Choose a colour"}},n={ko:{link:{newTab:"(새 창에서 열림)"},spoiler:{reveal:"내용 보기",hide:"숨기기",notice:"스포일러가 포함되어 있을 수 있습니다"},chat:{sending:"보내는 중",sent:"보냄",delivered:"전달됨",read:"읽음",failed:"전송 실패",typing:"입력 중…"},color:{area:"채도와 명도",hue:"색상",alpha:"불투명도",value:"색상 값",swatches:"기본 색상",clear:"지우기",empty:"색상 선택"}},ja:{link:{newTab:"(新しいタブで開きます)"},spoiler:{reveal:"表示する",hide:"隠す",notice:"ネタバレを含む可能性があります"},chat:{sending:"送信中",sent:"送信済み",delivered:"配信済み",read:"既読",failed:"送信できませんでした",typing:"入力中…"},color:{area:"彩度と明度",hue:"色相",alpha:"不透明度",value:"カラー値",swatches:"プリセットの色",clear:"クリア",empty:"色を選択"}},"zh-hans":{link:{newTab:"(在新标签页中打开)"},spoiler:{reveal:"显示内容",hide:"隐藏",notice:"此内容可能包含剧透"},chat:{sending:"发送中",sent:"已发送",delivered:"已送达",read:"已读",failed:"发送失败",typing:"正在输入…"},color:{area:"饱和度和明度",hue:"色相",alpha:"不透明度",value:"颜色值",swatches:"预设颜色",clear:"清除",empty:"选择颜色"}},"zh-hant":{link:{newTab:"(在新分頁中開啟)"},spoiler:{reveal:"顯示內容",hide:"隱藏",notice:"此內容可能包含劇透"},chat:{sending:"傳送中",sent:"已傳送",delivered:"已送達",read:"已讀",failed:"傳送失敗",typing:"正在輸入…"},color:{area:"飽和度與明度",hue:"色相",alpha:"不透明度",value:"顏色值",swatches:"預設顏色",clear:"清除",empty:"選擇顏色"}},es:{link:{newTab:"(se abre en una pestaña nueva)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Puede contener spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregado",read:"Leído",failed:"No enviado",typing:"Escribiendo…"},color:{area:"Saturación y brillo",hue:"Tono",alpha:"Opacidad",value:"Valor del color",swatches:"Colores predefinidos",clear:"Borrar",empty:"Elegir un color"}},pt:{link:{newTab:"(abre em uma nova aba)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Pode conter spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregue",read:"Lido",failed:"Não enviado",typing:"Digitando…"},color:{area:"Saturação e brilho",hue:"Matiz",alpha:"Opacidade",value:"Valor da cor",swatches:"Cores predefinidas",clear:"Limpar",empty:"Escolher uma cor"}},fr:{link:{newTab:"(s’ouvre dans un nouvel onglet)"},spoiler:{reveal:"Afficher",hide:"Masquer",notice:"Peut contenir des spoilers"},chat:{sending:"Envoi en cours",sent:"Envoyé",delivered:"Distribué",read:"Lu",failed:"Non envoyé",typing:"En train d’écrire…"},color:{area:"Saturation et luminosité",hue:"Teinte",alpha:"Opacité",value:"Valeur de la couleur",swatches:"Couleurs prédéfinies",clear:"Effacer",empty:"Choisir une couleur"}},de:{link:{newTab:"(wird in einem neuen Tab geöffnet)"},spoiler:{reveal:"Anzeigen",hide:"Ausblenden",notice:"Kann Spoiler enthalten"},chat:{sending:"Wird gesendet",sent:"Gesendet",delivered:"Zugestellt",read:"Gelesen",failed:"Nicht gesendet",typing:"Schreibt…"},color:{area:"Sättigung und Helligkeit",hue:"Farbton",alpha:"Deckkraft",value:"Farbwert",swatches:"Vorgegebene Farben",clear:"Löschen",empty:"Farbe auswählen"}},it:{link:{newTab:"(si apre in una nuova scheda)"},spoiler:{reveal:"Mostra",hide:"Nascondi",notice:"Può contenere spoiler"},chat:{sending:"Invio in corso",sent:"Inviato",delivered:"Consegnato",read:"Letto",failed:"Non inviato",typing:"Sta scrivendo…"},color:{area:"Saturazione e luminosità",hue:"Tonalità",alpha:"Opacità",value:"Valore del colore",swatches:"Colori predefiniti",clear:"Cancella",empty:"Scegli un colore"}},nl:{link:{newTab:"(opent in een nieuw tabblad)"},spoiler:{reveal:"Tonen",hide:"Verbergen",notice:"Kan spoilers bevatten"},chat:{sending:"Wordt verzonden",sent:"Verzonden",delivered:"Afgeleverd",read:"Gelezen",failed:"Niet verzonden",typing:"Aan het typen…"},color:{area:"Verzadiging en helderheid",hue:"Kleurtoon",alpha:"Dekking",value:"Kleurwaarde",swatches:"Vooraf ingestelde kleuren",clear:"Wissen",empty:"Kies een kleur"}},pl:{link:{newTab:"(otwiera się w nowej karcie)"},spoiler:{reveal:"Pokaż",hide:"Ukryj",notice:"Może zawierać spoilery"},chat:{sending:"Wysyłanie",sent:"Wysłano",delivered:"Dostarczono",read:"Przeczytano",failed:"Nie wysłano",typing:"Pisze…"},color:{area:"Nasycenie i jasność",hue:"Barwa",alpha:"Krycie",value:"Wartość koloru",swatches:"Kolory predefiniowane",clear:"Wyczyść",empty:"Wybierz kolor"}},ru:{link:{newTab:"(откроется в новой вкладке)"},spoiler:{reveal:"Показать",hide:"Скрыть",notice:"Может содержать спойлеры"},chat:{sending:"Отправляется",sent:"Отправлено",delivered:"Доставлено",read:"Прочитано",failed:"Не отправлено",typing:"Печатает…"},color:{area:"Насыщенность и яркость",hue:"Оттенок",alpha:"Непрозрачность",value:"Значение цвета",swatches:"Готовые цвета",clear:"Очистить",empty:"Выберите цвет"}},tr:{link:{newTab:"(yeni sekmede açılır)"},spoiler:{reveal:"Göster",hide:"Gizle",notice:"Spoiler içerebilir"},chat:{sending:"Gönderiliyor",sent:"Gönderildi",delivered:"İletildi",read:"Okundu",failed:"Gönderilemedi",typing:"Yazıyor…"},color:{area:"Doygunluk ve parlaklık",hue:"Renk tonu",alpha:"Opaklık",value:"Renk değeri",swatches:"Hazır renkler",clear:"Temizle",empty:"Bir renk seçin"}},ar:{link:{newTab:"(يفتح في علامة تبويب جديدة)"},spoiler:{reveal:"إظهار",hide:"إخفاء",notice:"قد يحتوي على حرق للأحداث"},chat:{sending:"جارٍ الإرسال",sent:"تم الإرسال",delivered:"تم التسليم",read:"تمت القراءة",failed:"لم يتم الإرسال",typing:"يكتب الآن…"},color:{area:"التشبع والسطوع",hue:"درجة اللون",alpha:"العتامة",value:"قيمة اللون",swatches:"ألوان جاهزة",clear:"مسح",empty:"اختر لونًا"}},hi:{link:{newTab:"(नए टैब में खुलता है)"},spoiler:{reveal:"दिखाएँ",hide:"छिपाएँ",notice:"इसमें स्पॉइलर हो सकते हैं"},chat:{sending:"भेजा जा रहा है",sent:"भेजा गया",delivered:"डिलीवर हुआ",read:"पढ़ा गया",failed:"नहीं भेजा गया",typing:"टाइप कर रहे हैं…"},color:{area:"संतृप्ति और चमक",hue:"रंग",alpha:"अपारदर्शिता",value:"रंग मान",swatches:"पूर्व निर्धारित रंग",clear:"साफ़ करें",empty:"एक रंग चुनें"}},id:{link:{newTab:"(terbuka di tab baru)"},spoiler:{reveal:"Tampilkan",hide:"Sembunyikan",notice:"Mungkin mengandung spoiler"},chat:{sending:"Mengirim",sent:"Terkirim",delivered:"Diterima",read:"Dibaca",failed:"Gagal terkirim",typing:"Sedang mengetik…"},color:{area:"Saturasi dan kecerahan",hue:"Rona",alpha:"Opasitas",value:"Nilai warna",swatches:"Warna preset",clear:"Hapus",empty:"Pilih warna"}},vi:{link:{newTab:"(mở trong tab mới)"},spoiler:{reveal:"Hiện nội dung",hide:"Ẩn",notice:"Có thể chứa nội dung tiết lộ"},chat:{sending:"Đang gửi",sent:"Đã gửi",delivered:"Đã nhận",read:"Đã xem",failed:"Chưa gửi được",typing:"Đang nhập…"},color:{area:"Độ bão hòa và độ sáng",hue:"Sắc độ",alpha:"Độ mờ đục",value:"Giá trị màu",swatches:"Màu dựng sẵn",clear:"Xóa",empty:"Chọn màu"}},th:{link:{newTab:"(เปิดในแท็บใหม่)"},spoiler:{reveal:"แสดงเนื้อหา",hide:"ซ่อน",notice:"อาจมีการเปิดเผยเนื้อหา"},chat:{sending:"กำลังส่ง",sent:"ส่งแล้ว",delivered:"ส่งถึงแล้ว",read:"อ่านแล้ว",failed:"ส่งไม่สำเร็จ",typing:"กำลังพิมพ์…"},color:{area:"ความอิ่มตัวและความสว่าง",hue:"เฉดสี",alpha:"ความทึบ",value:"ค่าสี",swatches:"สีที่กำหนดไว้",clear:"ล้าง",empty:"เลือกสี"}}},i={zh:"zh-hans","zh-cn":"zh-hans","zh-my":"zh-hans","zh-sg":"zh-hans","zh-hk":"zh-hant","zh-mo":"zh-hant","zh-tw":"zh-hant"};const r=new Map([["",a]]);export function resolveMessages(e){const l=e?.trim()??"",t=r.get(l);if(t)return t;const o=function(e){const a=e.toLowerCase().split(/[-_]/).filter(Boolean),n=a[0];if(!n)return[];const i=a.slice(1),r=i.find(e=>/^[a-z]{4}$/.test(e)),l=i.find(e=>/^([a-z]{2}|\d{3})$/.test(e));return[r?`${n}-${r}`:"",l?`${n}-${l}`:"",n].filter(Boolean)}(l).map(e=>n[e]??n[i[e]??""]).find(Boolean),s=o?{link:{...a.link,...o.link},spoiler:{...a.spoiler,...o.spoiler},chat:{...a.chat,...o.chat},color:{...a.color,...o.color}}:a;return r.set(l,s),s}export function useMessages(a){return e.useMemo(()=>resolveMessages(a),[a])}
|
package/dist/internal/icons.d.ts
CHANGED
|
@@ -67,6 +67,29 @@ export declare function ClockIcon(): React.JSX.Element;
|
|
|
67
67
|
* reason the chevron is: it is a glyph, and there is no text in it to resample.
|
|
68
68
|
*/
|
|
69
69
|
export declare function ArrowRightIcon(): React.JSX.Element;
|
|
70
|
+
/**
|
|
71
|
+
* The two marks a link wears.
|
|
72
|
+
*
|
|
73
|
+
* A pair for the same reason the steppers are: they answer the same question —
|
|
74
|
+
* "where does this go" — and a chain drawn at one weight beside an arrow drawn
|
|
75
|
+
* at another reads as two icon sets in one paragraph. The chain says "this is a
|
|
76
|
+
* link", the arrow leaving its box says "and it leaves this page", which is the
|
|
77
|
+
* one thing about a link that is invisible until it has already happened.
|
|
78
|
+
*
|
|
79
|
+
* TextLink draws whichever one matches its `newTab`; a ChatBubble's link
|
|
80
|
+
* preview draws the chain beside the site it points at.
|
|
81
|
+
*/
|
|
82
|
+
export declare function LinkIcon(): React.JSX.Element;
|
|
83
|
+
export declare function ExternalLinkIcon(): React.JSX.Element;
|
|
84
|
+
/**
|
|
85
|
+
* The three dots that stand for what has been left out.
|
|
86
|
+
*
|
|
87
|
+
* Drawn rather than typed: `…` is a single glyph whose dots are spaced by
|
|
88
|
+
* whatever font the page happens to load, and it sits on the baseline rather
|
|
89
|
+
* than in the middle of the row it is standing in for. Breadcrumb draws it on
|
|
90
|
+
* the button that opens the collapsed middle of a trail.
|
|
91
|
+
*/
|
|
92
|
+
export declare function EllipsisIcon(): React.JSX.Element;
|
|
70
93
|
/** The filled dot: the chosen one of a set, where a tick would say "and". */
|
|
71
94
|
export declare function DotIcon(): React.JSX.Element;
|
|
72
95
|
/**
|