@sanity-labs/ui-poc 0.0.1-alpha.14 → 0.0.1-alpha.16
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 +151 -0
- package/dist/index.d.ts +88 -13
- package/dist/index.js +295 -110
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.tsx +1 -0
- package/src/components/button/button.css +3 -1
- package/src/components/button/button.props.ts +16 -0
- package/src/components/icon/Icon.tsx +3 -2
- package/src/components/icon/icon.props.ts +3 -0
- package/src/components/icon-button/IconButton.tsx +27 -0
- package/src/components/icon-button/iconButton.props.ts +26 -0
- package/src/components/index.css +3 -1
- package/src/components/{indicator-group/IndicatorGroup.tsx → indicator-stack/IndicatorStack.tsx} +6 -6
- package/src/components/{indicator-group/indicator-group.css → indicator-stack/indicator-stack.css} +1 -1
- package/src/components/{indicator-group/indicatorGroup.props.ts → indicator-stack/indicatorStack.props.ts} +2 -2
- package/src/components/press-area/PressArea.tsx +24 -0
- package/src/components/press-area/press-area.css +17 -0
- package/src/components/press-area/pressArea.props.ts +14 -0
- package/src/components/tooltip/Tooltip.tsx +87 -0
- package/src/components/tooltip/tooltip.css +52 -0
- package/src/components/tooltip/tooltip.props.ts +20 -0
- package/src/components/tooltip-group/TooltipGroup.tsx +62 -0
- package/src/components/tooltip-group/tooltipGroup.props.ts +13 -0
- package/src/css/classes/generic/index.css +1 -0
- package/src/css/classes/generic/placement.css +171 -0
- package/src/css/classes/system/margin.css +40 -40
- package/src/index.ts +6 -2
- package/src/props/placement.ts +15 -0
- package/src/props/shadow.ts +2 -2
- package/src/types/Placement.ts +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Sanity UI 4
|
|
2
|
+
|
|
3
|
+
The next version of Sanity's component library. Faster, simpler, and built on CSS instead of styled-components.
|
|
4
|
+
|
|
5
|
+
## What's different from v3
|
|
6
|
+
|
|
7
|
+
- **CSS classes instead of styled-components.** No runtime style generation. Smaller bundles, faster renders.
|
|
8
|
+
- **Direct props for layout.** Width, height, position, border, and overflow are first-class props — no more `style={{ ... }}` escape hatches.
|
|
9
|
+
- **Works alongside v3.** Install both packages in the same app. No forced migration.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @sanity-labs/ui-poc
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires React 19.2+ and Node >=20.19 <22 || >=22.12.
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
Import the stylesheet at your app entry point. Without it, components render as unstyled HTML with no error.
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import '@sanity-labs/ui-poc/styles.css'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If your app uses Sanity UI v3, keep the existing `ThemeProvider` setup.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import {ThemeProvider, studioTheme, ToastProvider} from '@sanity/ui'
|
|
31
|
+
import '@sanity-labs/ui-poc/styles.css'
|
|
32
|
+
import App from './App'
|
|
33
|
+
|
|
34
|
+
createRoot(document.getElementById('root')!).render(
|
|
35
|
+
<ThemeProvider theme={studioTheme}>
|
|
36
|
+
<ToastProvider>
|
|
37
|
+
<App />
|
|
38
|
+
</ToastProvider>
|
|
39
|
+
</ThemeProvider>,
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
Import from `@sanity-labs/ui-poc`. Components not yet in v4 — Menu, Dialog, TextInput, Badge — remain in `@sanity/ui`.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import {Box, Flex, Card, Heading, Text, Button} from '@sanity-labs/ui-poc'
|
|
49
|
+
import {AddIcon} from '@sanity/icons'
|
|
50
|
+
|
|
51
|
+
export default function App() {
|
|
52
|
+
return (
|
|
53
|
+
<Flex minHeight="100vh">
|
|
54
|
+
<Box as="nav" aria-label="Main" padding={3} borderRight width="240px">
|
|
55
|
+
<Heading as="h2" size={1}>
|
|
56
|
+
My App
|
|
57
|
+
</Heading>
|
|
58
|
+
</Box>
|
|
59
|
+
<Box as="main" padding={4} flexGrow={1}>
|
|
60
|
+
<Flex alignItems="center" justifyContent="space-between" flexWrap="wrap" gap={2}>
|
|
61
|
+
<Heading as="h1" size={2}>
|
|
62
|
+
Documents
|
|
63
|
+
</Heading>
|
|
64
|
+
<Button iconStart={AddIcon} text="New" />
|
|
65
|
+
</Flex>
|
|
66
|
+
<Box marginTop={3}>
|
|
67
|
+
<Card density="loose">
|
|
68
|
+
<Text size={1}>First document</Text>
|
|
69
|
+
<Text size={1} muted>
|
|
70
|
+
Edited 2 hours ago
|
|
71
|
+
</Text>
|
|
72
|
+
</Card>
|
|
73
|
+
</Box>
|
|
74
|
+
</Box>
|
|
75
|
+
</Flex>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Components
|
|
81
|
+
|
|
82
|
+
All components below are from `@sanity-labs/ui-poc`.
|
|
83
|
+
|
|
84
|
+
### Layout
|
|
85
|
+
|
|
86
|
+
| Component | What it does |
|
|
87
|
+
| ----------- | ----------------------------------------------------------------------------------- |
|
|
88
|
+
| `Box` | General container. Padding, margin, border, overflow, and position as direct props. |
|
|
89
|
+
| `Flex` | Flexbox layout. `alignItems`, `justifyContent`, `flexDirection`, `gap`. |
|
|
90
|
+
| `Grid` | CSS grid. Use `gridTemplateColumns` with a CSS string (e.g. `"repeat(3, 1fr)"`). |
|
|
91
|
+
| `Container` | Max-width content wrapper. |
|
|
92
|
+
| `HStack` | Horizontal stack. Accepts `gap` and `as` only — use `Flex` for alignment control. |
|
|
93
|
+
| `VStack` | Vertical stack. Accepts `gap` and `as` only — use `Flex` for alignment control. |
|
|
94
|
+
| `Inline` | Inline flow layout with wrapping and gap. |
|
|
95
|
+
|
|
96
|
+
### Typography
|
|
97
|
+
|
|
98
|
+
| Component | What it does |
|
|
99
|
+
| --------- | ----------------------------------------------------------------------- |
|
|
100
|
+
| `Heading` | Semantic headings (`h1`–`h6`). Always set `as` to match the level. |
|
|
101
|
+
| `Text` | Body copy, captions, labels. Props: `size`, `weight`, `muted`, `align`. |
|
|
102
|
+
| `Label` | Form input label. Use only with form elements. |
|
|
103
|
+
| `Code` | Inline or block code. Uses the system monospace font. |
|
|
104
|
+
|
|
105
|
+
### Interactive
|
|
106
|
+
|
|
107
|
+
| Component | What it does |
|
|
108
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
109
|
+
| `Button` | `level` (primary/secondary/tertiary), `tone` (neutral/critical), `iconStart`, `iconEnd`, `text`, `fullWidth`, `loading`. |
|
|
110
|
+
| `Checkbox` | Controlled checkbox. Requires `label` (string). |
|
|
111
|
+
| `Radio` | Controlled radio button. |
|
|
112
|
+
| `Switch` | Toggle control. Requires `label` (string). |
|
|
113
|
+
| `Link` | Anchor element styled as a link. |
|
|
114
|
+
|
|
115
|
+
### Display
|
|
116
|
+
|
|
117
|
+
| Component | What it does |
|
|
118
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
119
|
+
| `Card` | Raised surface with background and `tone`. Does not accept padding, margin, or layout props — wrap content in `Box`. |
|
|
120
|
+
| `Divider` | Horizontal rule between content sections. |
|
|
121
|
+
| `Icon` | Renders a `@sanity/icons` icon component. Always set `aria-label` or `aria-hidden`. |
|
|
122
|
+
| `Indicator` | Status dot with `tone`. |
|
|
123
|
+
| `IndicatorGroup` | Grouped `Indicator` elements. |
|
|
124
|
+
| `Spinner` | Loading indicator. |
|
|
125
|
+
|
|
126
|
+
### Lists
|
|
127
|
+
|
|
128
|
+
| Component | What it does |
|
|
129
|
+
| --------- | --------------------------------------------------- |
|
|
130
|
+
| `List` | Semantic list. Use `List.Item` and `List.ItemText`. |
|
|
131
|
+
|
|
132
|
+
### Accessibility
|
|
133
|
+
|
|
134
|
+
| Component | What it does |
|
|
135
|
+
| ---------------- | ------------------------------------------------------------------------------------------------ |
|
|
136
|
+
| `SkipToContent` | Visually hidden skip-nav link. Must be the first focusable element. Requires `hash` and `label`. |
|
|
137
|
+
| `VisuallyHidden` | Hides content visually while keeping it in the accessibility tree. |
|
|
138
|
+
|
|
139
|
+
### Still from `@sanity/ui`
|
|
140
|
+
|
|
141
|
+
Menu, Dialog, TextInput, Select, Stack, Badge, ThemeProvider, ToastProvider, and other components not yet migrated to v4.
|
|
142
|
+
|
|
143
|
+
## Contributing
|
|
144
|
+
|
|
145
|
+
We welcome feedback and contributions. Start here:
|
|
146
|
+
|
|
147
|
+
1. **Try the components** and report what breaks, what confuses, or what's missing.
|
|
148
|
+
2. **Read the contribution model** — build a recipe with existing building block components, then propose graduating it.
|
|
149
|
+
3. **Open a PR** following the branch naming and checklist in the developer contribution docs.
|
|
150
|
+
|
|
151
|
+
During preview, the most useful contribution is using the components and telling us what happens.
|
package/dist/index.d.ts
CHANGED
|
@@ -322,10 +322,26 @@ declare interface HStackProps<T extends React.ElementType> extends Pick<GapProps
|
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
/** @public */
|
|
325
|
-
export declare function Icon({
|
|
325
|
+
export declare function Icon({size, ...props}: IconProps): JSX.Element
|
|
326
326
|
|
|
327
327
|
declare const ICON_SIZE: readonly [0, 1, 2, 3, 4]
|
|
328
328
|
|
|
329
|
+
/** @public */
|
|
330
|
+
export declare function IconButton<T extends ElementType = 'button'>(
|
|
331
|
+
props: IconButtonProps<T> & Omit<ComponentPropsWithRef<T>, keyof IconButtonProps<T>>,
|
|
332
|
+
): JSX.Element
|
|
333
|
+
|
|
334
|
+
/** @public */
|
|
335
|
+
declare interface IconButtonProps<T extends React_2.ElementType> extends Pick<
|
|
336
|
+
ButtonProps<T>,
|
|
337
|
+
'as' | 'density' | 'level' | 'loading' | 'tone'
|
|
338
|
+
> {
|
|
339
|
+
/** Button label */
|
|
340
|
+
'aria-label': string
|
|
341
|
+
/** Icon */
|
|
342
|
+
'icon': React_2.ComponentType<SVGProps<SVGSVGElement>>
|
|
343
|
+
}
|
|
344
|
+
|
|
329
345
|
/** @public */
|
|
330
346
|
declare interface IconProps
|
|
331
347
|
extends ComponentProps<'svg'>, Pick<TypographyProps, 'muted'>, MarginProps, ToneProps {
|
|
@@ -343,17 +359,6 @@ export declare function Indicator<T extends ElementType = 'span'>({
|
|
|
343
359
|
...props
|
|
344
360
|
}: IndicatorProps<T> & Omit<ComponentPropsWithRef<T>, keyof IndicatorProps<T>>): JSX.Element
|
|
345
361
|
|
|
346
|
-
/** @public */
|
|
347
|
-
export declare function IndicatorGroup<T extends ElementType = 'div'>(
|
|
348
|
-
props: IndicatorGroupProps<T> & Omit<ComponentPropsWithRef<T>, keyof IndicatorGroupProps<T>>,
|
|
349
|
-
): JSX.Element
|
|
350
|
-
|
|
351
|
-
/** @public */
|
|
352
|
-
declare interface IndicatorGroupProps<T extends React.ElementType> {
|
|
353
|
-
/** Element to render */
|
|
354
|
-
as?: T
|
|
355
|
-
}
|
|
356
|
-
|
|
357
362
|
/** @beta */
|
|
358
363
|
declare interface IndicatorProps<T extends React.ElementType> extends ToneProps {
|
|
359
364
|
/** Element to render */
|
|
@@ -362,6 +367,17 @@ declare interface IndicatorProps<T extends React.ElementType> extends ToneProps
|
|
|
362
367
|
label?: string
|
|
363
368
|
}
|
|
364
369
|
|
|
370
|
+
/** @public */
|
|
371
|
+
export declare function IndicatorStack<T extends ElementType = 'div'>(
|
|
372
|
+
props: IndicatorStackProps<T> & Omit<ComponentPropsWithRef<T>, keyof IndicatorStackProps<T>>,
|
|
373
|
+
): JSX.Element
|
|
374
|
+
|
|
375
|
+
/** @public */
|
|
376
|
+
declare interface IndicatorStackProps<T extends React.ElementType> {
|
|
377
|
+
/** Element to render */
|
|
378
|
+
as?: T
|
|
379
|
+
}
|
|
380
|
+
|
|
365
381
|
/** @deprecated Use HStack component instead */
|
|
366
382
|
/** @public */
|
|
367
383
|
export declare function Inline<T extends ElementType = 'div'>(
|
|
@@ -535,6 +551,28 @@ declare interface PaddingProps {
|
|
|
535
551
|
paddingLeft?: Responsive<Space>
|
|
536
552
|
}
|
|
537
553
|
|
|
554
|
+
declare const PLACEMENT: readonly [
|
|
555
|
+
'top',
|
|
556
|
+
'top-start',
|
|
557
|
+
'top-end',
|
|
558
|
+
'right',
|
|
559
|
+
'right-start',
|
|
560
|
+
'right-end',
|
|
561
|
+
'bottom',
|
|
562
|
+
'bottom-start',
|
|
563
|
+
'bottom-end',
|
|
564
|
+
'left',
|
|
565
|
+
'left-start',
|
|
566
|
+
'left-end',
|
|
567
|
+
]
|
|
568
|
+
|
|
569
|
+
declare type Placement = (typeof PLACEMENT)[number]
|
|
570
|
+
|
|
571
|
+
declare type PlacementProps = {
|
|
572
|
+
/** Placement relative to anchor */
|
|
573
|
+
placement?: Placement
|
|
574
|
+
}
|
|
575
|
+
|
|
538
576
|
declare const POSITION: readonly ['absolute', 'fixed', 'relative', 'static', 'sticky']
|
|
539
577
|
|
|
540
578
|
declare type Position = (typeof POSITION)[number]
|
|
@@ -554,6 +592,17 @@ declare type PositionProps = {
|
|
|
554
592
|
left?: Responsive<SpaceAuto>
|
|
555
593
|
}
|
|
556
594
|
|
|
595
|
+
/** @public */
|
|
596
|
+
export declare function PressArea<T extends ElementType = 'button'>(
|
|
597
|
+
props: PressAreaProps<T> & Omit<ComponentPropsWithRef<T>, keyof PressAreaProps<T>>,
|
|
598
|
+
): JSX.Element
|
|
599
|
+
|
|
600
|
+
/** @public */
|
|
601
|
+
declare interface PressAreaProps<T extends React.ElementType> {
|
|
602
|
+
/** Element to render */
|
|
603
|
+
as?: InteractiveAs<T>
|
|
604
|
+
}
|
|
605
|
+
|
|
557
606
|
/** @beta */
|
|
558
607
|
export declare function Radio(props: RadioProps): JSX.Element
|
|
559
608
|
|
|
@@ -591,9 +640,13 @@ declare type Responsive<T> =
|
|
|
591
640
|
length: 6
|
|
592
641
|
})
|
|
593
642
|
|
|
643
|
+
declare const SHADOW: readonly [0, 1, 2, 3, 4, 5]
|
|
644
|
+
|
|
645
|
+
declare type Shadow = (typeof SHADOW)[number]
|
|
646
|
+
|
|
594
647
|
declare type ShadowProps = {
|
|
595
648
|
/** CSS **box-shadow** property */
|
|
596
|
-
shadow?:
|
|
649
|
+
shadow?: Shadow
|
|
597
650
|
}
|
|
598
651
|
|
|
599
652
|
/** @beta */
|
|
@@ -701,6 +754,28 @@ declare type ToneProps = {
|
|
|
701
754
|
tone?: Tone
|
|
702
755
|
}
|
|
703
756
|
|
|
757
|
+
/** @public */
|
|
758
|
+
export declare function Tooltip({placement, ...props}: TooltipProps): any
|
|
759
|
+
|
|
760
|
+
/** @public */
|
|
761
|
+
export declare function TooltipGroup<T extends ElementType = 'div'>(
|
|
762
|
+
props: TooltipGroupProps<T> & Omit<ComponentPropsWithRef<T>, keyof TooltipGroupProps<T>>,
|
|
763
|
+
): JSX.Element
|
|
764
|
+
|
|
765
|
+
/** @public */
|
|
766
|
+
declare interface TooltipGroupProps<T extends React.ElementType> {
|
|
767
|
+
/** Element to render */
|
|
768
|
+
as?: T
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/** @public */
|
|
772
|
+
declare interface TooltipProps extends React.ComponentProps<'div'>, PlacementProps {
|
|
773
|
+
/** Tooltip text */
|
|
774
|
+
text?: React.ReactNode
|
|
775
|
+
/** Disabled state */
|
|
776
|
+
disabled?: boolean
|
|
777
|
+
}
|
|
778
|
+
|
|
704
779
|
declare interface TypographyProps extends MarginProps, ToneProps {
|
|
705
780
|
/** CSS **text-align** property */
|
|
706
781
|
align?: TextAlign
|