@castui/cast-ui 4.8.0 → 4.9.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 +55 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/useBreakpoint.d.ts +22 -0
- package/dist/hooks/useBreakpoint.js +45 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +12 -2
- package/dist/tokens/breakpoints.d.ts +57 -0
- package/dist/tokens/breakpoints.js +92 -0
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.js +6 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,6 +163,61 @@ The full guide lives in the
|
|
|
163
163
|
[hosted Storybook](https://main--6990f00d7b8682c18d2ed5f3.chromatic.com)
|
|
164
164
|
under **Guides → Customisation**.
|
|
165
165
|
|
|
166
|
+
## Responsive layout
|
|
167
|
+
|
|
168
|
+
Cast UI ships a set of breakpoints and hooks for building layouts that adapt
|
|
169
|
+
across phones, tablets, and desktops. The values follow the Material 3 window
|
|
170
|
+
size classes, so the same numbers hold up across watches, phones, foldables,
|
|
171
|
+
tablets, and large screens.
|
|
172
|
+
|
|
173
|
+
| Tier | Range (dp) | Typical devices |
|
|
174
|
+
|------|-----------|-----------------|
|
|
175
|
+
| `base` | `< 600` | Watches and every phone in portrait. Your default layout. |
|
|
176
|
+
| `sm` | `>= 600` | Large phones in landscape, foldables unfolded, small tablets |
|
|
177
|
+
| `md` | `>= 840` | Tablets |
|
|
178
|
+
| `lg` | `>= 1200` | Laptops and desktops |
|
|
179
|
+
| `xl` | `>= 1600` | Large desktops and TVs |
|
|
180
|
+
|
|
181
|
+
The hooks read the live window width, so they update on resize, rotation, and
|
|
182
|
+
foldables, and they behave the same on the web. The most common one picks a
|
|
183
|
+
value per tier:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { useResponsiveValue, useBreakpoint, useMinWidth } from '@castui/cast-ui';
|
|
187
|
+
|
|
188
|
+
function Gallery() {
|
|
189
|
+
const columns = useResponsiveValue({ base: 1, md: 2, xl: 4 });
|
|
190
|
+
// 1 column on phones, 2 on tablets, 4 on large desktops
|
|
191
|
+
...
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`useResponsiveValue` is mobile-first: a tier with no value falls back to the
|
|
196
|
+
nearest one below it, so `{ base: 1, md: 2 }` gives 1 up to `md` and 2 from
|
|
197
|
+
`md` on. The other two hooks cover the rest:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
const tier = useBreakpoint(); // 'base' | 'sm' | 'md' | 'lg' | 'xl'
|
|
201
|
+
const isWide = useMinWidth('lg'); // true from 1200dp up
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The raw thresholds are also exported as `breakpoints` if you need a number
|
|
205
|
+
directly.
|
|
206
|
+
|
|
207
|
+
A few things worth knowing. React Native has no CSS media queries, so a
|
|
208
|
+
breakpoint here is a width threshold you compare against, not automatic
|
|
209
|
+
restyling. `base` is the mobile-first default: you write the phone layout with
|
|
210
|
+
no breakpoint, then add overrides for larger screens. The gap between a small
|
|
211
|
+
and a large phone is better handled with flexible layout (flex, percentages,
|
|
212
|
+
`maxWidth`) than with a breakpoint.
|
|
213
|
+
|
|
214
|
+
Breakpoints are a fixed foundation, which sets them apart from the rest of the
|
|
215
|
+
theme. They are not part of `ThemeProvider`: they do not change with density,
|
|
216
|
+
they are not touched by brand colour overrides, and they are not carried in
|
|
217
|
+
`cast-theme.json`. The scale stays identical in every app, so layouts stay
|
|
218
|
+
predictable. The same values live as the `breakpoint/*` primitive variables in
|
|
219
|
+
the [cast-ui-kit Figma file](https://www.figma.com/design/JGtlpxLPJMZcwvQ3UZ9ZUl/cast-ui-kit).
|
|
220
|
+
|
|
166
221
|
## Theming from Figma — the cast-sync plugin
|
|
167
222
|
|
|
168
223
|
[`cast-sync/`](./cast-sync) is a Figma plugin that turns the Figma file's
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useBreakpoint, useMinWidth, useResponsiveValue } from './useBreakpoint';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useResponsiveValue = exports.useMinWidth = exports.useBreakpoint = void 0;
|
|
4
|
+
var useBreakpoint_1 = require("./useBreakpoint");
|
|
5
|
+
Object.defineProperty(exports, "useBreakpoint", { enumerable: true, get: function () { return useBreakpoint_1.useBreakpoint; } });
|
|
6
|
+
Object.defineProperty(exports, "useMinWidth", { enumerable: true, get: function () { return useBreakpoint_1.useMinWidth; } });
|
|
7
|
+
Object.defineProperty(exports, "useResponsiveValue", { enumerable: true, get: function () { return useBreakpoint_1.useResponsiveValue; } });
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Breakpoint, type BreakpointKey } from '../tokens/breakpoints';
|
|
2
|
+
/**
|
|
3
|
+
* The active breakpoint tier for the current window width. Mobile-first:
|
|
4
|
+
* 'base' below `sm`, then 'sm' | 'md' | 'lg' | 'xl' as the width grows.
|
|
5
|
+
*
|
|
6
|
+
* const bp = useBreakpoint(); // 'base' | 'sm' | 'md' | 'lg' | 'xl'
|
|
7
|
+
*/
|
|
8
|
+
export declare function useBreakpoint(): BreakpointKey;
|
|
9
|
+
/**
|
|
10
|
+
* True when the window is at or above the given breakpoint.
|
|
11
|
+
*
|
|
12
|
+
* const isWide = useMinWidth('lg'); // true from 1024dp up
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMinWidth(breakpoint: Breakpoint): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Pick a value for the current breakpoint, mobile-first. Supply values for any
|
|
17
|
+
* subset of tiers; the value at the current tier wins, falling back to the
|
|
18
|
+
* nearest defined tier below it.
|
|
19
|
+
*
|
|
20
|
+
* const columns = useResponsiveValue({ base: 1, md: 2, xl: 4 });
|
|
21
|
+
*/
|
|
22
|
+
export declare function useResponsiveValue<T>(values: Partial<Record<BreakpointKey, T>>): T | undefined;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useBreakpoint = useBreakpoint;
|
|
4
|
+
exports.useMinWidth = useMinWidth;
|
|
5
|
+
exports.useResponsiveValue = useResponsiveValue;
|
|
6
|
+
/**
|
|
7
|
+
* Responsive hooks built on the breakpoint scale.
|
|
8
|
+
*
|
|
9
|
+
* These read the live window width via react-native's useWindowDimensions, so
|
|
10
|
+
* they recompute on resize, rotation, and foldable changes, and they work the
|
|
11
|
+
* same on web (react-native-web). Breakpoints are a standalone foundation: they
|
|
12
|
+
* are not part of the theme and do not change with density.
|
|
13
|
+
*/
|
|
14
|
+
const react_native_1 = require("react-native");
|
|
15
|
+
const breakpoints_1 = require("../tokens/breakpoints");
|
|
16
|
+
/**
|
|
17
|
+
* The active breakpoint tier for the current window width. Mobile-first:
|
|
18
|
+
* 'base' below `sm`, then 'sm' | 'md' | 'lg' | 'xl' as the width grows.
|
|
19
|
+
*
|
|
20
|
+
* const bp = useBreakpoint(); // 'base' | 'sm' | 'md' | 'lg' | 'xl'
|
|
21
|
+
*/
|
|
22
|
+
function useBreakpoint() {
|
|
23
|
+
const { width } = (0, react_native_1.useWindowDimensions)();
|
|
24
|
+
return (0, breakpoints_1.resolveBreakpoint)(width);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* True when the window is at or above the given breakpoint.
|
|
28
|
+
*
|
|
29
|
+
* const isWide = useMinWidth('lg'); // true from 1024dp up
|
|
30
|
+
*/
|
|
31
|
+
function useMinWidth(breakpoint) {
|
|
32
|
+
const { width } = (0, react_native_1.useWindowDimensions)();
|
|
33
|
+
return width >= breakpoints_1.breakpoints[breakpoint];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Pick a value for the current breakpoint, mobile-first. Supply values for any
|
|
37
|
+
* subset of tiers; the value at the current tier wins, falling back to the
|
|
38
|
+
* nearest defined tier below it.
|
|
39
|
+
*
|
|
40
|
+
* const columns = useResponsiveValue({ base: 1, md: 2, xl: 4 });
|
|
41
|
+
*/
|
|
42
|
+
function useResponsiveValue(values) {
|
|
43
|
+
const current = useBreakpoint();
|
|
44
|
+
return (0, breakpoints_1.resolveResponsiveValue)(values, current);
|
|
45
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, menuColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, sliderColors, tableColors, fontFamily, fontWeight, label, title, body, heading, display, caption, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, type LabelSize, iconSize, type IconSize, } from './tokens';
|
|
1
|
+
export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, menuColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, sliderColors, tableColors, fontFamily, fontWeight, label, title, body, heading, display, caption, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, type LabelSize, iconSize, type IconSize, breakpoints, breakpointOrder, resolveBreakpoint, resolveResponsiveValue, type Breakpoint, type BreakpointKey, } from './tokens';
|
|
2
2
|
export { ThemeProvider, useTheme, themes, applyCastTheme, type Theme, type ThemeProviderProps, type CastThemeFile, type CastThemeProps, type DensityTheme, type ComponentTokens, type ButtonSizeTokens, type ButtonThemeTokens, type DialogSizeTokens, type DialogThemeTokens, type InputSizeTokens, type InputThemeTokens, type SelectContentTokens, type SelectOptionTokens, type SelectGroupTokens, type SelectSeparatorTokens, type SelectThemeTokens, type ListItemTokens, type ListSubheaderTokens, type ListThemeTokens, type CheckboxSizeTokens, type CheckboxThemeTokens, type AlertSizeTokens, type AlertThemeTokens, type ToggleSizeTokens, type ToggleThemeTokens, type CardSizeTokens, type CardThemeTokens, type BadgeSizeTokens, type BadgeThemeTokens, type RadioSizeTokens, type RadioThemeTokens, type ToastSizeTokens, type ToastThemeTokens, type ChipSizeTokens, type ChipThemeTokens, type AvatarSizeTokens, type AvatarThemeTokens, type PopoverSizeTokens, type PopoverThemeTokens, type TooltipSizeTokens, type TooltipThemeTokens, type ProgressSizeTokens, type ProgressThemeTokens, type TabsSizeTokens, type TabsThemeTokens, type SpinnerSizeTokens, type SpinnerThemeTokens, type BottomSheetThemeTokens, type LinkSizeTokens, type LinkThemeTokens, type BreadcrumbsSizeTokens, type BreadcrumbsThemeTokens, type CodeBlockSizeTokens, type CodeBlockThemeTokens, type DrawerThemeTokens, type MenuItemTokens, type MenuGroupTokens, type MenuThemeTokens, type ToggleButtonGroupSizeTokens, type ToggleButtonGroupThemeTokens, type AppBarSizeTokens, type AppBarThemeTokens, type SliderSizeTokens, type SliderThemeTokens, type SpeedDialSizeTokens, type SpeedDialThemeTokens, type TableSizeTokens, type TableThemeTokens, type DeepPartial, } from './theme';
|
|
3
|
+
export { useBreakpoint, useMinWidth, useResponsiveValue, } from './hooks';
|
|
3
4
|
export { Button, type ButtonProps, type ButtonSize } from './components/Button';
|
|
4
5
|
export { Icon, type IconProps } from './components/Icon';
|
|
5
6
|
export { Dialog, DialogContent, type DialogProps, type DialogContentProps, type DialogAction, type DialogSize, } from './components/Dialog';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.SelectGroup = exports.SelectOption = exports.Select = exports.DialogContent = exports.Dialog = exports.Icon = exports.Button = exports.useResponsiveValue = exports.useMinWidth = exports.useBreakpoint = exports.applyCastTheme = exports.themes = exports.useTheme = exports.ThemeProvider = exports.resolveResponsiveValue = exports.resolveBreakpoint = exports.breakpointOrder = exports.breakpoints = exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.tableColors = exports.sliderColors = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.menuColors = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
|
|
4
|
+
exports.Table = exports.SpeedDialAction = exports.SpeedDial = exports.Slider = exports.AppBar = exports.ToggleButton = exports.ToggleButtonGroup = exports.MenuContent = exports.MenuLabel = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.DrawerContent = exports.Drawer = exports.CodeBlock = exports.Breadcrumb = exports.Breadcrumbs = exports.Backdrop = exports.Link = exports.AccordionItem = exports.Accordion = exports.Tab = exports.Tabs = exports.BottomSheetContent = exports.BottomSheet = exports.Spinner = exports.Progress = exports.Text = exports.Tooltip = exports.Skeleton = exports.Popover = exports.Avatar = exports.Divider = exports.Chip = exports.Toast = exports.RadioGroup = exports.Radio = exports.Input = exports.Badge = exports.Card = exports.Toggle = exports.Alert = exports.Checkbox = exports.ListDivider = exports.ListSubheader = exports.ListItem = exports.List = exports.SelectDropdown = exports.SelectTag = exports.SelectSeparator = void 0;
|
|
5
|
+
exports.Autocomplete = exports.TableCell = exports.TableRow = exports.TableBody = exports.TableHead = void 0;
|
|
5
6
|
// Cast UI — Cross-platform design system component library
|
|
6
7
|
//
|
|
7
8
|
// Tokens
|
|
@@ -38,12 +39,21 @@ Object.defineProperty(exports, "heading", { enumerable: true, get: function () {
|
|
|
38
39
|
Object.defineProperty(exports, "display", { enumerable: true, get: function () { return tokens_1.display; } });
|
|
39
40
|
Object.defineProperty(exports, "caption", { enumerable: true, get: function () { return tokens_1.caption; } });
|
|
40
41
|
Object.defineProperty(exports, "iconSize", { enumerable: true, get: function () { return tokens_1.iconSize; } });
|
|
42
|
+
Object.defineProperty(exports, "breakpoints", { enumerable: true, get: function () { return tokens_1.breakpoints; } });
|
|
43
|
+
Object.defineProperty(exports, "breakpointOrder", { enumerable: true, get: function () { return tokens_1.breakpointOrder; } });
|
|
44
|
+
Object.defineProperty(exports, "resolveBreakpoint", { enumerable: true, get: function () { return tokens_1.resolveBreakpoint; } });
|
|
45
|
+
Object.defineProperty(exports, "resolveResponsiveValue", { enumerable: true, get: function () { return tokens_1.resolveResponsiveValue; } });
|
|
41
46
|
// Theme
|
|
42
47
|
var theme_1 = require("./theme");
|
|
43
48
|
Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return theme_1.ThemeProvider; } });
|
|
44
49
|
Object.defineProperty(exports, "useTheme", { enumerable: true, get: function () { return theme_1.useTheme; } });
|
|
45
50
|
Object.defineProperty(exports, "themes", { enumerable: true, get: function () { return theme_1.themes; } });
|
|
46
51
|
Object.defineProperty(exports, "applyCastTheme", { enumerable: true, get: function () { return theme_1.applyCastTheme; } });
|
|
52
|
+
// Hooks
|
|
53
|
+
var hooks_1 = require("./hooks");
|
|
54
|
+
Object.defineProperty(exports, "useBreakpoint", { enumerable: true, get: function () { return hooks_1.useBreakpoint; } });
|
|
55
|
+
Object.defineProperty(exports, "useMinWidth", { enumerable: true, get: function () { return hooks_1.useMinWidth; } });
|
|
56
|
+
Object.defineProperty(exports, "useResponsiveValue", { enumerable: true, get: function () { return hooks_1.useResponsiveValue; } });
|
|
47
57
|
// Components
|
|
48
58
|
var Button_1 = require("./components/Button");
|
|
49
59
|
Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return Button_1.Button; } });
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breakpoint scale — named min-width thresholds in density-independent pixels.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the Figma `breakpoint/{sm,md,lg,xl}` primitive variables. This is a
|
|
5
|
+
* foundation reference scale, not a runtime theme value. The numbers do not
|
|
6
|
+
* change with density, they are not part of the ThemeProvider theme, and
|
|
7
|
+
* cast-sync does not export them. Read them with the useBreakpoint /
|
|
8
|
+
* useResponsiveValue hooks, which watch the live window width.
|
|
9
|
+
*
|
|
10
|
+
* Values follow Material 3 window size classes, which are derived from real
|
|
11
|
+
* device-width data across the whole spectrum. The scale is mobile-first: a
|
|
12
|
+
* width is "at" a breakpoint when it is greater than or equal to that
|
|
13
|
+
* breakpoint's value, and anything below `sm` is the implicit `base` tier.
|
|
14
|
+
*
|
|
15
|
+
* Device mapping (width in dp):
|
|
16
|
+
*
|
|
17
|
+
* base < 600 Watches, and every phone in portrait. iPhone SE 320,
|
|
18
|
+
* iPhone 15 390, Pro Max 430, Pixel 7 412, Apple Watch
|
|
19
|
+
* 136-205. This is your default, design-here-first layout.
|
|
20
|
+
* sm >= 600 Large phones in landscape, foldables unfolded, small
|
|
21
|
+
* tablets in portrait.
|
|
22
|
+
* md >= 840 Tablets. iPad portrait ~768-834 (sits at the top of sm),
|
|
23
|
+
* iPad landscape and larger tablets land here and up.
|
|
24
|
+
* lg >= 1200 Laptops and desktops.
|
|
25
|
+
* xl >= 1600 Large desktops and TVs.
|
|
26
|
+
*
|
|
27
|
+
* React Native has no CSS media queries, so a breakpoint here is a width
|
|
28
|
+
* threshold you compare the window against at runtime. It does not restyle
|
|
29
|
+
* anything on its own. Small-vs-large phone differences belong to fluid layout
|
|
30
|
+
* (flex, percentages, maxWidth), not breakpoints. A watch is its own surface,
|
|
31
|
+
* not a tier: it falls into `base` and shares the default layout, which is the
|
|
32
|
+
* safe behaviour for a kit that does not target watchOS.
|
|
33
|
+
*/
|
|
34
|
+
/** The named breakpoint tiers. */
|
|
35
|
+
export type Breakpoint = 'sm' | 'md' | 'lg' | 'xl';
|
|
36
|
+
/** A breakpoint tier including the implicit below-`sm` base tier. */
|
|
37
|
+
export type BreakpointKey = 'base' | Breakpoint;
|
|
38
|
+
/** Min-width thresholds in dp (Material 3 window size classes). */
|
|
39
|
+
export declare const breakpoints: Record<Breakpoint, number>;
|
|
40
|
+
/** Tiers ordered smallest to largest, base first. */
|
|
41
|
+
export declare const breakpointOrder: readonly BreakpointKey[];
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a raw window width (dp) to its active breakpoint tier. Mobile-first:
|
|
44
|
+
* returns the largest tier whose threshold the width has reached, or `base`
|
|
45
|
+
* below `sm`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveBreakpoint(width: number): BreakpointKey;
|
|
48
|
+
/**
|
|
49
|
+
* Pick a value for a tier, mobile-first. Supply values for any subset of tiers.
|
|
50
|
+
* The chosen value is the one at the current tier or, if that tier has none,
|
|
51
|
+
* the nearest defined tier below it. If nothing is defined at or below the
|
|
52
|
+
* current tier, the smallest defined tier above is used. Returns undefined when
|
|
53
|
+
* `values` is empty.
|
|
54
|
+
*
|
|
55
|
+
* resolveResponsiveValue({ base: 1, md: 2, xl: 4 }, 'lg') // => 2
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveResponsiveValue<T>(values: Partial<Record<BreakpointKey, T>>, current: BreakpointKey): T | undefined;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Breakpoint scale — named min-width thresholds in density-independent pixels.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the Figma `breakpoint/{sm,md,lg,xl}` primitive variables. This is a
|
|
6
|
+
* foundation reference scale, not a runtime theme value. The numbers do not
|
|
7
|
+
* change with density, they are not part of the ThemeProvider theme, and
|
|
8
|
+
* cast-sync does not export them. Read them with the useBreakpoint /
|
|
9
|
+
* useResponsiveValue hooks, which watch the live window width.
|
|
10
|
+
*
|
|
11
|
+
* Values follow Material 3 window size classes, which are derived from real
|
|
12
|
+
* device-width data across the whole spectrum. The scale is mobile-first: a
|
|
13
|
+
* width is "at" a breakpoint when it is greater than or equal to that
|
|
14
|
+
* breakpoint's value, and anything below `sm` is the implicit `base` tier.
|
|
15
|
+
*
|
|
16
|
+
* Device mapping (width in dp):
|
|
17
|
+
*
|
|
18
|
+
* base < 600 Watches, and every phone in portrait. iPhone SE 320,
|
|
19
|
+
* iPhone 15 390, Pro Max 430, Pixel 7 412, Apple Watch
|
|
20
|
+
* 136-205. This is your default, design-here-first layout.
|
|
21
|
+
* sm >= 600 Large phones in landscape, foldables unfolded, small
|
|
22
|
+
* tablets in portrait.
|
|
23
|
+
* md >= 840 Tablets. iPad portrait ~768-834 (sits at the top of sm),
|
|
24
|
+
* iPad landscape and larger tablets land here and up.
|
|
25
|
+
* lg >= 1200 Laptops and desktops.
|
|
26
|
+
* xl >= 1600 Large desktops and TVs.
|
|
27
|
+
*
|
|
28
|
+
* React Native has no CSS media queries, so a breakpoint here is a width
|
|
29
|
+
* threshold you compare the window against at runtime. It does not restyle
|
|
30
|
+
* anything on its own. Small-vs-large phone differences belong to fluid layout
|
|
31
|
+
* (flex, percentages, maxWidth), not breakpoints. A watch is its own surface,
|
|
32
|
+
* not a tier: it falls into `base` and shares the default layout, which is the
|
|
33
|
+
* safe behaviour for a kit that does not target watchOS.
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.breakpointOrder = exports.breakpoints = void 0;
|
|
37
|
+
exports.resolveBreakpoint = resolveBreakpoint;
|
|
38
|
+
exports.resolveResponsiveValue = resolveResponsiveValue;
|
|
39
|
+
/** Min-width thresholds in dp (Material 3 window size classes). */
|
|
40
|
+
exports.breakpoints = {
|
|
41
|
+
sm: 600,
|
|
42
|
+
md: 840,
|
|
43
|
+
lg: 1200,
|
|
44
|
+
xl: 1600,
|
|
45
|
+
};
|
|
46
|
+
/** Tiers ordered smallest to largest, base first. */
|
|
47
|
+
exports.breakpointOrder = [
|
|
48
|
+
'base',
|
|
49
|
+
'sm',
|
|
50
|
+
'md',
|
|
51
|
+
'lg',
|
|
52
|
+
'xl',
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Resolve a raw window width (dp) to its active breakpoint tier. Mobile-first:
|
|
56
|
+
* returns the largest tier whose threshold the width has reached, or `base`
|
|
57
|
+
* below `sm`.
|
|
58
|
+
*/
|
|
59
|
+
function resolveBreakpoint(width) {
|
|
60
|
+
if (width >= exports.breakpoints.xl)
|
|
61
|
+
return 'xl';
|
|
62
|
+
if (width >= exports.breakpoints.lg)
|
|
63
|
+
return 'lg';
|
|
64
|
+
if (width >= exports.breakpoints.md)
|
|
65
|
+
return 'md';
|
|
66
|
+
if (width >= exports.breakpoints.sm)
|
|
67
|
+
return 'sm';
|
|
68
|
+
return 'base';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Pick a value for a tier, mobile-first. Supply values for any subset of tiers.
|
|
72
|
+
* The chosen value is the one at the current tier or, if that tier has none,
|
|
73
|
+
* the nearest defined tier below it. If nothing is defined at or below the
|
|
74
|
+
* current tier, the smallest defined tier above is used. Returns undefined when
|
|
75
|
+
* `values` is empty.
|
|
76
|
+
*
|
|
77
|
+
* resolveResponsiveValue({ base: 1, md: 2, xl: 4 }, 'lg') // => 2
|
|
78
|
+
*/
|
|
79
|
+
function resolveResponsiveValue(values, current) {
|
|
80
|
+
const idx = exports.breakpointOrder.indexOf(current);
|
|
81
|
+
for (let i = idx; i >= 0; i--) {
|
|
82
|
+
const v = values[exports.breakpointOrder[i]];
|
|
83
|
+
if (v !== undefined)
|
|
84
|
+
return v;
|
|
85
|
+
}
|
|
86
|
+
for (let i = idx + 1; i < exports.breakpointOrder.length; i++) {
|
|
87
|
+
const v = values[exports.breakpointOrder[i]];
|
|
88
|
+
if (v !== undefined)
|
|
89
|
+
return v;
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
package/dist/tokens/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { lightColors, darkColors, colorSchemes, intentColors, disabledColors, controlTokens, surfaceTokens, textTokens, overlayTokens, selectColors, menuColors, tagTokens, errorTokens, listColors, checkboxColors, toggleColors, progressColors, tabsColors, radioColors, avatarColors, skeletonColors, sliderColors, tableColors, type IntentName, type ProminenceName, type StateName, type ColorMode, type ColorScheme, } from './colors';
|
|
2
2
|
export { fontFamily, fontWeight, label, title, body, heading, display, caption, type LabelSize, } from './typography';
|
|
3
3
|
export { iconSize, type IconSize } from './icon';
|
|
4
|
+
export { breakpoints, breakpointOrder, resolveBreakpoint, resolveResponsiveValue, type Breakpoint, type BreakpointKey, } from './breakpoints';
|
package/dist/tokens/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.tableColors = exports.sliderColors = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.menuColors = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
|
|
3
|
+
exports.resolveResponsiveValue = exports.resolveBreakpoint = exports.breakpointOrder = exports.breakpoints = exports.iconSize = exports.caption = exports.display = exports.heading = exports.body = exports.title = exports.label = exports.fontWeight = exports.fontFamily = exports.tableColors = exports.sliderColors = exports.skeletonColors = exports.avatarColors = exports.radioColors = exports.tabsColors = exports.progressColors = exports.toggleColors = exports.checkboxColors = exports.listColors = exports.errorTokens = exports.tagTokens = exports.menuColors = exports.selectColors = exports.overlayTokens = exports.textTokens = exports.surfaceTokens = exports.controlTokens = exports.disabledColors = exports.intentColors = exports.colorSchemes = exports.darkColors = exports.lightColors = void 0;
|
|
4
4
|
var colors_1 = require("./colors");
|
|
5
5
|
Object.defineProperty(exports, "lightColors", { enumerable: true, get: function () { return colors_1.lightColors; } });
|
|
6
6
|
Object.defineProperty(exports, "darkColors", { enumerable: true, get: function () { return colors_1.darkColors; } });
|
|
@@ -36,3 +36,8 @@ Object.defineProperty(exports, "display", { enumerable: true, get: function () {
|
|
|
36
36
|
Object.defineProperty(exports, "caption", { enumerable: true, get: function () { return typography_1.caption; } });
|
|
37
37
|
var icon_1 = require("./icon");
|
|
38
38
|
Object.defineProperty(exports, "iconSize", { enumerable: true, get: function () { return icon_1.iconSize; } });
|
|
39
|
+
var breakpoints_1 = require("./breakpoints");
|
|
40
|
+
Object.defineProperty(exports, "breakpoints", { enumerable: true, get: function () { return breakpoints_1.breakpoints; } });
|
|
41
|
+
Object.defineProperty(exports, "breakpointOrder", { enumerable: true, get: function () { return breakpoints_1.breakpointOrder; } });
|
|
42
|
+
Object.defineProperty(exports, "resolveBreakpoint", { enumerable: true, get: function () { return breakpoints_1.resolveBreakpoint; } });
|
|
43
|
+
Object.defineProperty(exports, "resolveResponsiveValue", { enumerable: true, get: function () { return breakpoints_1.resolveResponsiveValue; } });
|
package/package.json
CHANGED