@trypattern/sdk 0.1.35 → 0.1.37
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/dist/cli/app.js +9 -1
- package/dist/components/Calendar.js +5 -5
- package/dist/components/Choice.js +1 -1
- package/dist/components/FilePicker.js +1 -1
- package/dist/components/Sidebar.d.ts +1 -1
- package/dist/components/Sidebar.js +7 -7
- package/dist/components/Skeleton.d.ts +4 -2
- package/dist/components/Skeleton.js +54 -2
- package/dist/components/TableRow.js +2 -2
- package/dist/rules/lintPlugin.js +1 -0
- package/dist/rules/messages.d.ts +1 -1
- package/dist/rules/messages.js +1 -1
- package/dist/theme/tokens.stylex.d.ts +3 -0
- package/dist/theme/tokens.stylex.js +3 -0
- package/package.json +1 -1
package/dist/cli/app.js
CHANGED
|
@@ -1598,6 +1598,9 @@ function installShim() {
|
|
|
1598
1598
|
path: SHIM_PATH
|
|
1599
1599
|
};
|
|
1600
1600
|
}
|
|
1601
|
+
const NO_MATCHING = 'ERR_PNPM_NO_MATCHING_VERSION';
|
|
1602
|
+
const NPM_SETTLE_TRIES = 8;
|
|
1603
|
+
const NPM_SETTLE_MS = 15_000;
|
|
1601
1604
|
async function update() {
|
|
1602
1605
|
const current = sdkVersion();
|
|
1603
1606
|
const latest = await latestPattern(true);
|
|
@@ -1616,7 +1619,12 @@ async function update() {
|
|
|
1616
1619
|
};
|
|
1617
1620
|
}
|
|
1618
1621
|
say(`Updating Pattern ${current} → ${latest}`);
|
|
1619
|
-
|
|
1622
|
+
let installed = await capture('pnpm', ['add', `@trypattern/sdk@${latest}`]);
|
|
1623
|
+
for (let attempt = 1; attempt <= NPM_SETTLE_TRIES && installed.output.includes(NO_MATCHING); attempt += 1) {
|
|
1624
|
+
say(` npm is still sharing Pattern ${latest}, trying again in a moment`);
|
|
1625
|
+
await sleep(NPM_SETTLE_MS);
|
|
1626
|
+
installed = await capture('pnpm', ['add', `@trypattern/sdk@${latest}`]);
|
|
1627
|
+
}
|
|
1620
1628
|
if (installed.code !== 0) {
|
|
1621
1629
|
return {
|
|
1622
1630
|
code: 1,
|
|
@@ -90,7 +90,7 @@ const styles = stylex.create({
|
|
|
90
90
|
display: 'flex',
|
|
91
91
|
flexDirection: 'column',
|
|
92
92
|
gap: space.xxs,
|
|
93
|
-
width:
|
|
93
|
+
width: '100%'
|
|
94
94
|
},
|
|
95
95
|
header: {
|
|
96
96
|
display: 'flex',
|
|
@@ -139,7 +139,7 @@ const styles = stylex.create({
|
|
|
139
139
|
},
|
|
140
140
|
row: {
|
|
141
141
|
display: 'grid',
|
|
142
|
-
gridTemplateColumns:
|
|
142
|
+
gridTemplateColumns: 'repeat(7, minmax(0, 1fr))'
|
|
143
143
|
},
|
|
144
144
|
weekday: {
|
|
145
145
|
display: 'flex',
|
|
@@ -153,15 +153,15 @@ const styles = stylex.create({
|
|
|
153
153
|
},
|
|
154
154
|
cell: {
|
|
155
155
|
display: 'flex',
|
|
156
|
-
|
|
157
|
-
height: `calc(${space.xxxl} - ${space.xs})`
|
|
156
|
+
justifyContent: 'center'
|
|
158
157
|
},
|
|
159
158
|
day: {
|
|
160
159
|
display: 'flex',
|
|
161
160
|
alignItems: 'center',
|
|
162
161
|
justifyContent: 'center',
|
|
163
162
|
width: '100%',
|
|
164
|
-
|
|
163
|
+
maxWidth: `calc(${space.xxxl} - ${space.xs})`,
|
|
164
|
+
aspectRatio: '1',
|
|
165
165
|
fontSize: fontSizes.bodyMd,
|
|
166
166
|
lineHeight: lineHeights.bodySm,
|
|
167
167
|
outlineOffset: 0,
|
|
@@ -15,7 +15,7 @@ export function Choice({ value, title, label, subline, isDisabled = false, child
|
|
|
15
15
|
!state.disabled &&
|
|
16
16
|
styles.faded, state.disabled && styles.disabled, isPhoto && styles.photo, focusRing.visible).className, children: [children === undefined ? null : (_jsx("span", { ...stylex.props(styles.content, isPhoto && styles.photoContent), children: children })), title === undefined ? null : (_jsx("span", { ...stylex.props(styles.title), children: title })), subline === undefined ? null : (_jsx("span", { ...stylex.props(styles.subline, isDisabled && styles.sublineDisabled), children: subline }))] }));
|
|
17
17
|
}
|
|
18
|
-
const checkedRing = `inset 0 0 0 ${borders.thin} ${colors.borderInverted}
|
|
18
|
+
const checkedRing = `inset 0 0 0 ${borders.thin} ${colors.borderInverted}`;
|
|
19
19
|
const styles = stylex.create({
|
|
20
20
|
choice: {
|
|
21
21
|
display: 'flex',
|
|
@@ -48,7 +48,7 @@ const styles = stylex.create({
|
|
|
48
48
|
backgroundColor: colors.containerRecessed,
|
|
49
49
|
borderColor: colors.borderStrong,
|
|
50
50
|
borderStyle: 'dashed',
|
|
51
|
-
borderWidth:
|
|
51
|
+
borderWidth: borders.thin,
|
|
52
52
|
borderRadius: radii.lg,
|
|
53
53
|
transitionTimingFunction: motion.easeOut,
|
|
54
54
|
transitionDuration: motion.fast,
|
|
@@ -17,7 +17,7 @@ export function Sidebar({ workspace, workspaceMenu, links, isToggled, isAnimatin
|
|
|
17
17
|
};
|
|
18
18
|
return (_jsxs("nav", { ...stylex.props(styles.sidebar, isToggled && styles.sidebarToggled, isAnimating && styles.sidebarAnimating), children: [_jsx("div", { ...stylex.props(styles.header), children: _jsx(Menu, { trigger: _jsxs(_Fragment, { children: [_jsx("span", { ...stylex.props(styles.logo), children: _jsx(Text, { variant: "caption", children: workspace.charAt(0) }) }), _jsx(Text, { variant: "label", isTruncated: true, children: workspace }), _jsx(Icon, { name: "chevronDown" })] }), items: workspaceMenu }) }), onSearch === undefined ? null : (_jsx(Button, { variant: "secondary", icon: "search", shortcut: ['mod', 'k'], isFullWidth: true, align: "start", onClick: onSearch, children: "Search" })), _jsx("div", { ...stylex.props(styles.body), children: _jsx(ScrollArea, { children: _jsxs("div", { ...stylex.props(styles.group), children: [_jsx("span", { ...stylex.props(styles.groupLabel), children: _jsx(Text, { variant: "label", tone: "tertiary", children: "Workspace" }) }), links.map((item) => (_jsxs(NavLink, { onClick: () => followLink(item), to: item.to, end: item.to === '/' ||
|
|
19
19
|
links.some((other) => String(other.to).startsWith(`${String(item.to)}/`)), className: ({ isActive }) => stylex.props(styles.item, isActive && styles.itemCurrent, focusRing.visible, focusRing.inside).className ?? '', children: [_jsx(Icon, { name: item.icon }), _jsx(Text, { variant: "label", isTruncated: true, style: styles.itemLabel, children: item.label }), typeof item.count !== 'number' ? null : item.countTone ===
|
|
20
|
-
'
|
|
20
|
+
'attention' ? (_jsx("span", { ...stylex.props(styles.count), children: item.count })) : (_jsx(Badge, { variant: "transparent", children: item.count }))] }, item.to)))] }) }) })] }));
|
|
21
21
|
}
|
|
22
22
|
const styles = stylex.create({
|
|
23
23
|
sidebar: {
|
|
@@ -138,14 +138,14 @@ const styles = stylex.create({
|
|
|
138
138
|
flexShrink: 0,
|
|
139
139
|
alignItems: 'center',
|
|
140
140
|
justifyContent: 'center',
|
|
141
|
-
minWidth:
|
|
142
|
-
height:
|
|
143
|
-
paddingInline:
|
|
144
|
-
fontSize: fontSizes.
|
|
141
|
+
minWidth: space.lg,
|
|
142
|
+
height: space.lg,
|
|
143
|
+
paddingInline: space.xs,
|
|
144
|
+
fontSize: fontSizes.badge,
|
|
145
145
|
fontWeight: fontWeights.medium,
|
|
146
146
|
lineHeight: lineHeights.caption,
|
|
147
|
-
color: colors.
|
|
148
|
-
backgroundColor: colors.
|
|
147
|
+
color: colors.onAttentionSolidForeground,
|
|
148
|
+
backgroundColor: colors.attentionSolid,
|
|
149
149
|
borderRadius: radii.full
|
|
150
150
|
},
|
|
151
151
|
itemLabel: {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Placement } from './Placement.ts';
|
|
2
|
+
type SkeletonText = 'heading' | 'subheading' | 'title' | 'lead' | 'label' | 'body' | 'caption';
|
|
2
3
|
type SkeletonProps = {
|
|
3
4
|
variant?: 'text' | 'heading' | 'icon' | 'card';
|
|
4
|
-
|
|
5
|
+
text?: SkeletonText;
|
|
6
|
+
width?: 'xs' | 'sm' | 'md' | 'lg' | 'full';
|
|
5
7
|
style?: Placement;
|
|
6
8
|
};
|
|
7
|
-
export declare function Skeleton({ variant, width, style }: SkeletonProps): import("react").JSX.Element;
|
|
9
|
+
export declare function Skeleton({ variant, text, width, style }: SkeletonProps): import("react").JSX.Element;
|
|
8
10
|
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as stylex from '@stylexjs/stylex';
|
|
3
|
-
import { breakpoints, colors, iconSizes, lineHeights, motion, radii, space } from "../theme/tokens.stylex.js";
|
|
4
|
-
export function Skeleton({ variant = 'text', width = 'full', style }) {
|
|
3
|
+
import { breakpoints, colors, fontSizes, iconSizes, lineHeights, motion, radii, space } from "../theme/tokens.stylex.js";
|
|
4
|
+
export function Skeleton({ variant = 'text', text, width = 'full', style }) {
|
|
5
|
+
if (text !== undefined) {
|
|
6
|
+
return (_jsx("span", { ...stylex.props(styles.line, lines[text], widthsOf[width], style), children: _jsx("span", { ...stylex.props(styles.skeleton, styles.bar, bars[text]) }) }));
|
|
7
|
+
}
|
|
5
8
|
return (_jsx("span", { ...stylex.props(styles.skeleton, variant !== 'icon' && widthsOf[width], variants[variant], style) }));
|
|
6
9
|
}
|
|
7
10
|
const pulse = stylex.keyframes({
|
|
@@ -19,8 +22,56 @@ const styles = stylex.create({
|
|
|
19
22
|
animationDuration: motion.pulse,
|
|
20
23
|
animationTimingFunction: motion.easeInOut,
|
|
21
24
|
animationIterationCount: 'infinite'
|
|
25
|
+
},
|
|
26
|
+
line: {
|
|
27
|
+
display: 'flex',
|
|
28
|
+
flexShrink: 0,
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
maxWidth: '100%'
|
|
31
|
+
},
|
|
32
|
+
bar: {
|
|
33
|
+
width: '100%',
|
|
34
|
+
borderRadius: radii.sm
|
|
22
35
|
}
|
|
23
36
|
});
|
|
37
|
+
const lines = stylex.create({
|
|
38
|
+
heading: { height: lineHeights.heading5 },
|
|
39
|
+
subheading: { height: lineHeights.heading6 },
|
|
40
|
+
title: { height: lineHeights.body },
|
|
41
|
+
lead: { height: lineHeights.body },
|
|
42
|
+
label: {
|
|
43
|
+
height: {
|
|
44
|
+
default: lineHeights.bodySm,
|
|
45
|
+
[breakpoints.compact]: lineHeights.bodyCompact
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
body: {
|
|
49
|
+
height: {
|
|
50
|
+
default: lineHeights.bodySm,
|
|
51
|
+
[breakpoints.compact]: lineHeights.bodyCompact
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
caption: { height: lineHeights.caption }
|
|
55
|
+
});
|
|
56
|
+
const bars = stylex.create({
|
|
57
|
+
heading: { height: fontSizes.heading5 },
|
|
58
|
+
subheading: { height: fontSizes.heading6 },
|
|
59
|
+
title: { height: fontSizes.bodyBase },
|
|
60
|
+
lead: { height: fontSizes.bodyBase },
|
|
61
|
+
label: {
|
|
62
|
+
height: {
|
|
63
|
+
default: fontSizes.bodySm,
|
|
64
|
+
[breakpoints.compact]: fontSizes.bodyCompact
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
body: {
|
|
68
|
+
height: {
|
|
69
|
+
default: fontSizes.bodySm,
|
|
70
|
+
[breakpoints.compact]: fontSizes.bodyCompact
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
caption: { height: fontSizes.captionLg }
|
|
74
|
+
});
|
|
24
75
|
const variants = stylex.create({
|
|
25
76
|
text: {
|
|
26
77
|
height: lineHeights.caption,
|
|
@@ -41,6 +92,7 @@ const variants = stylex.create({
|
|
|
41
92
|
}
|
|
42
93
|
});
|
|
43
94
|
const widthsOf = stylex.create({
|
|
95
|
+
xs: { width: `calc(${space.xxxl} + ${space.lg})` },
|
|
44
96
|
sm: { width: '25%' },
|
|
45
97
|
md: { width: '40%' },
|
|
46
98
|
lg: { width: '60%' },
|
|
@@ -21,7 +21,7 @@ const styles = stylex.create({
|
|
|
21
21
|
textAlign: 'start',
|
|
22
22
|
backgroundColor: {
|
|
23
23
|
default: 'transparent',
|
|
24
|
-
':hover': colors.
|
|
24
|
+
':hover': colors.componentOnContainerStrongHover
|
|
25
25
|
},
|
|
26
26
|
borderBottomColor: {
|
|
27
27
|
default: colors.borderDefault,
|
|
@@ -34,6 +34,6 @@ const styles = stylex.create({
|
|
|
34
34
|
height: `calc(${space.xxxl} + ${space.sm})`
|
|
35
35
|
},
|
|
36
36
|
current: {
|
|
37
|
-
backgroundColor: colors.
|
|
37
|
+
backgroundColor: colors.componentOnContainerStrongHover
|
|
38
38
|
}
|
|
39
39
|
});
|
package/dist/rules/lintPlugin.js
CHANGED
|
@@ -374,6 +374,7 @@ const hoverUsesHighlight = styleRule((declarations) => declarations
|
|
|
374
374
|
(SELECTED_STYLE_NAME.test(d.styleName) &&
|
|
375
375
|
d.conditions.length === 0)) &&
|
|
376
376
|
!isMember(d.value, 'colors', 'transparentHover') &&
|
|
377
|
+
!isMember(d.value, 'colors', 'componentOnContainerStrongHover') &&
|
|
377
378
|
!(!SELECTED_STYLE_NAME.test(d.styleName) && isButtonStateToken(d.value)) &&
|
|
378
379
|
!(d.value.type === 'Literal' && d.value['value'] === null))
|
|
379
380
|
.map((d) => ({
|
package/dist/rules/messages.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const NO_POINTER_CURSOR_MESSAGE = "cursor: pointer is not allowed
|
|
|
5
5
|
export declare const USE_COLOR_TOKEN_MESSAGE = "Raw colors are not allowed in styles. Use a token from @trypattern/sdk/tokens.stylex (colors.*). To change what a token looks like in this app, re-value it in src/theme/theme.ts, the one file where raw colors are allowed. Keywords like transparent and currentColor are fine.";
|
|
6
6
|
export declare const USE_FONT_TOKEN_MESSAGE = "Raw font sizes, families and weights are not allowed in styles. Use fontSizes.*, fonts.* or fontWeights.* from @trypattern/sdk/tokens.stylex; to change a font or a size for the whole app, re-value it in src/theme/theme.ts. Text inherits Inter 13px/20px (15px/24px on phones) from <body>, so most styles need no font properties at all.";
|
|
7
7
|
export declare const NO_INTERACTIVE_TRANSITION_MESSAGE = "Hover and press transitions use the motion tokens, as Interfere does: motion.fast with motion.easeOut for buttons, motion.instant for fields, motion.base for segmented controls. Never a raw duration or easing, so every control responds at the same speed. Navigation items change instantly with no transition.";
|
|
8
|
-
export declare const HOVER_USES_HIGHLIGHT_MESSAGE = "Hover, active and selected backgrounds must be colors.transparentHover (with radii.md), so hovering then selecting an item never flashes a second color. Styles named *Active, *Selected or *Current count as selected. Buttons and switches, which have no selected state, may instead use their own colors.*Hover and colors.*Active tokens.";
|
|
8
|
+
export declare const HOVER_USES_HIGHLIGHT_MESSAGE = "Hover, active and selected backgrounds must be colors.transparentHover (with radii.md), or colors.componentOnContainerStrongHover for rows on a white card, so hovering then selecting an item never flashes a second color. Styles named *Active, *Selected or *Current count as selected. Buttons and switches, which have no selected state, may instead use their own colors.*Hover and colors.*Active tokens.";
|
|
9
9
|
export declare const SCROLL_VIEW_ONLY_MESSAGE = "Only ScrollArea may scroll (overflow auto/scroll). The page itself never scrolls or bounces in Pattern; wrap scrollable content in <ScrollArea> from @trypattern/sdk/react.";
|
|
10
10
|
export declare const SELECTABLE_ONLY_MESSAGE = "Do not set userSelect. Text is not selectable by default in Pattern (inputs and editable fields are). For words people need to copy, write <Text isSelectable> from @trypattern/sdk/react.";
|
|
11
11
|
export declare const USE_BREAKPOINTS_MESSAGE = "Media queries come from breakpoints in @trypattern/sdk/tokens.stylex, e.g. [breakpoints.compact]: value, so every screen adapts at the same sizes.";
|
package/dist/rules/messages.js
CHANGED
|
@@ -5,7 +5,7 @@ export const NO_POINTER_CURSOR_MESSAGE = 'cursor: pointer is not allowed in Patt
|
|
|
5
5
|
export const USE_COLOR_TOKEN_MESSAGE = 'Raw colors are not allowed in styles. Use a token from @trypattern/sdk/tokens.stylex (colors.*). To change what a token looks like in this app, re-value it in src/theme/theme.ts, the one file where raw colors are allowed. Keywords like transparent and currentColor are fine.';
|
|
6
6
|
export const USE_FONT_TOKEN_MESSAGE = 'Raw font sizes, families and weights are not allowed in styles. Use fontSizes.*, fonts.* or fontWeights.* from @trypattern/sdk/tokens.stylex; to change a font or a size for the whole app, re-value it in src/theme/theme.ts. Text inherits Inter 13px/20px (15px/24px on phones) from <body>, so most styles need no font properties at all.';
|
|
7
7
|
export const NO_INTERACTIVE_TRANSITION_MESSAGE = 'Hover and press transitions use the motion tokens, as Interfere does: motion.fast with motion.easeOut for buttons, motion.instant for fields, motion.base for segmented controls. Never a raw duration or easing, so every control responds at the same speed. Navigation items change instantly with no transition.';
|
|
8
|
-
export const HOVER_USES_HIGHLIGHT_MESSAGE = 'Hover, active and selected backgrounds must be colors.transparentHover (with radii.md), so hovering then selecting an item never flashes a second color. Styles named *Active, *Selected or *Current count as selected. Buttons and switches, which have no selected state, may instead use their own colors.*Hover and colors.*Active tokens.';
|
|
8
|
+
export const HOVER_USES_HIGHLIGHT_MESSAGE = 'Hover, active and selected backgrounds must be colors.transparentHover (with radii.md), or colors.componentOnContainerStrongHover for rows on a white card, so hovering then selecting an item never flashes a second color. Styles named *Active, *Selected or *Current count as selected. Buttons and switches, which have no selected state, may instead use their own colors.*Hover and colors.*Active tokens.';
|
|
9
9
|
export const SCROLL_VIEW_ONLY_MESSAGE = 'Only ScrollArea may scroll (overflow auto/scroll). The page itself never scrolls or bounces in Pattern; wrap scrollable content in <ScrollArea> from @trypattern/sdk/react.';
|
|
10
10
|
export const SELECTABLE_ONLY_MESSAGE = 'Do not set userSelect. Text is not selectable by default in Pattern (inputs and editable fields are). For words people need to copy, write <Text isSelectable> from @trypattern/sdk/react.';
|
|
11
11
|
export const USE_BREAKPOINTS_MESSAGE = 'Media queries come from breakpoints in @trypattern/sdk/tokens.stylex, e.g. [breakpoints.compact]: value, so every screen adapts at the same sizes.';
|
|
@@ -9,6 +9,7 @@ export declare const breakpoints: {
|
|
|
9
9
|
coarsePointer: string;
|
|
10
10
|
};
|
|
11
11
|
export declare const colors: stylex.VarGroup<Readonly<{
|
|
12
|
+
attentionSolid: string;
|
|
12
13
|
blackFill: string;
|
|
13
14
|
blackTransparent: string;
|
|
14
15
|
borderDefault: string;
|
|
@@ -56,6 +57,7 @@ export declare const colors: stylex.VarGroup<Readonly<{
|
|
|
56
57
|
invertedSolidHover: string;
|
|
57
58
|
modal: string;
|
|
58
59
|
onBrandSolidForeground: string;
|
|
60
|
+
onAttentionSolidForeground: string;
|
|
59
61
|
onBrandSubtleForeground: string;
|
|
60
62
|
onDangerSolidForeground: string;
|
|
61
63
|
onDangerSubtleForeground: string;
|
|
@@ -184,6 +186,7 @@ export declare const corners: stylex.VarGroup<Readonly<{
|
|
|
184
186
|
}>, symbol>;
|
|
185
187
|
export declare const fontSizes: stylex.VarGroup<Readonly<{
|
|
186
188
|
captionXs: string;
|
|
189
|
+
badge: string;
|
|
187
190
|
captionSm: string;
|
|
188
191
|
captionBase: string;
|
|
189
192
|
captionLg: string;
|
|
@@ -7,6 +7,7 @@ export const breakpoints = stylex.defineConsts({
|
|
|
7
7
|
coarsePointer: '@media (pointer: coarse)'
|
|
8
8
|
});
|
|
9
9
|
export const colors = stylex.defineVars({
|
|
10
|
+
attentionSolid: '#0090ff',
|
|
10
11
|
blackFill: '#000',
|
|
11
12
|
blackTransparent: '#0000',
|
|
12
13
|
borderDefault: 'light-dark(#0000000f, #ffffff12)',
|
|
@@ -54,6 +55,7 @@ export const colors = stylex.defineVars({
|
|
|
54
55
|
invertedSolidHover: 'light-dark(#000c, #fffc)',
|
|
55
56
|
modal: 'light-dark(oklch(100% 0 0), oklch(25.2% 0 0))',
|
|
56
57
|
onBrandSolidForeground: '#fff',
|
|
58
|
+
onAttentionSolidForeground: '#fff',
|
|
57
59
|
onBrandSubtleForeground: 'light-dark(#0090ff, #70b8ff)',
|
|
58
60
|
onDangerSolidForeground: 'light-dark(#fffcfc, #fff)',
|
|
59
61
|
onDangerSubtleForeground: 'light-dark(#df2600d1, #ff977d)',
|
|
@@ -182,6 +184,7 @@ export const corners = stylex.defineVars({
|
|
|
182
184
|
});
|
|
183
185
|
export const fontSizes = stylex.defineVars({
|
|
184
186
|
captionXs: '8px',
|
|
187
|
+
badge: '9px',
|
|
185
188
|
captionSm: '10px',
|
|
186
189
|
captionBase: '11px',
|
|
187
190
|
captionLg: '12px',
|