@krapwoo/ds-viewer 0.9.1 → 0.11.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 +82 -0
- package/dist/cli/doctor.js +182 -3
- package/dist/cli/staticPage.js +129 -0
- package/dist/native/catalog/catalogNavigation.js +62 -3
- package/dist/native/catalog/comparison.js +14 -3
- package/dist/native/catalog/pageApi.js +408 -0
- package/dist/native/catalog/tokens.js +67 -12
- package/native/catalog/BoundedOverlayViewport.tsx +2 -2
- package/native/catalog/CatalogButton.tsx +2 -2
- package/native/catalog/CatalogSearchInput.tsx +3 -3
- package/native/catalog/CatalogShell.tsx +213 -32
- package/native/catalog/CatalogSidebar.tsx +69 -19
- package/native/catalog/ComparisonGrid.tsx +4 -4
- package/native/catalog/ComparisonGroups.tsx +3 -3
- package/native/catalog/ComparisonList.tsx +2 -2
- package/native/catalog/FamilyPage.tsx +1188 -0
- package/native/catalog/MotionSpecimen.tsx +3 -3
- package/native/catalog/PhoneFrame.tsx +2 -2
- package/native/catalog/PropsTable.tsx +7 -7
- package/native/catalog/ReferenceDetails.tsx +33 -22
- package/native/catalog/SectionBlock.tsx +57 -27
- package/native/catalog/SpacingScaleGallery.tsx +3 -3
- package/native/catalog/Swatch.tsx +3 -3
- package/native/catalog/TokenLayouts.tsx +6 -9
- package/native/catalog/TokenRow.tsx +2 -2
- package/native/catalog/TypeScaleGallery.tsx +2 -2
- package/native/catalog/UpdatePanel.tsx +29 -30
- package/native/catalog/VariantGroup.tsx +3 -6
- package/native/catalog/catalogNavigation.ts +89 -3
- package/native/catalog/comparison.ts +17 -6
- package/native/catalog/familyModel.ts +192 -0
- package/native/catalog/index.ts +8 -2
- package/native/catalog/overlayViewport.ts +30 -10
- package/native/catalog/pageApi.ts +357 -15
- package/native/catalog/tokens.ts +70 -12
- package/native/catalog/types.ts +106 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { Animated, AccessibilityInfo, Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_RADIUS, CATALOG_SPACE,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_RADIUS, CATALOG_SPACE, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { motionReplayLabel, motionTranslatesDirectly, motionValueTarget, type MotionValueRange } from './motionValueDomain';
|
|
5
5
|
|
|
6
6
|
/** `Animated.spring`'s physics fields — the same shape as a design system's own spring-config
|
|
@@ -137,7 +137,7 @@ const styles = StyleSheet.create({
|
|
|
137
137
|
backgroundColor: CATALOG_COLOR.accent,
|
|
138
138
|
},
|
|
139
139
|
footer: { flexDirection: 'row', alignItems: 'center', gap: CATALOG_SPACE.md },
|
|
140
|
-
label: {
|
|
140
|
+
label: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
141
141
|
labelSpacer: { flex: 1 },
|
|
142
142
|
replayButton: {
|
|
143
143
|
paddingHorizontal: CATALOG_SPACE.md,
|
|
@@ -148,5 +148,5 @@ const styles = StyleSheet.create({
|
|
|
148
148
|
backgroundColor: CATALOG_COLOR.surface,
|
|
149
149
|
},
|
|
150
150
|
replayButtonPressed: { backgroundColor: CATALOG_COLOR.surfacePressed },
|
|
151
|
-
replayText: {
|
|
151
|
+
replayText: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
152
152
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useRef } from 'react';
|
|
2
2
|
import { Platform, StyleSheet, Text, View, type LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_RADIUS,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_RADIUS, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { DEVICE_FRAME, DEVICE_SCALE_WARN_BELOW, deviceFrameScale } from './deviceFrame';
|
|
5
5
|
import { resolveOverlayViewport } from './overlayViewport';
|
|
6
6
|
import { useSpecimenAddress } from './SpecimenAddress';
|
|
@@ -149,5 +149,5 @@ const styles = StyleSheet.create({
|
|
|
149
149
|
justifyContent: 'center',
|
|
150
150
|
overflow: 'hidden',
|
|
151
151
|
},
|
|
152
|
-
status: { position: 'absolute',
|
|
152
|
+
status: { position: 'absolute', ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
153
153
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { View, Text, StyleSheet } from 'react-native';
|
|
2
|
-
import {
|
|
2
|
+
import { CATALOG_TEXT, CATALOG_COLOR, CATALOG_SPACE } from './tokens';
|
|
3
3
|
import { PROPS_COLUMN_GAP } from './comparison';
|
|
4
4
|
import type { PropDef } from './types';
|
|
5
5
|
|
|
@@ -86,14 +86,14 @@ const styles = StyleSheet.create({
|
|
|
86
86
|
rowFirst: { paddingTop: 0 },
|
|
87
87
|
rowLast: { borderBottomWidth: 0, paddingBottom: 0 },
|
|
88
88
|
header: { width: 140, gap: 2 },
|
|
89
|
-
name: {
|
|
90
|
-
optionalMark: {
|
|
91
|
-
type: {
|
|
89
|
+
name: { ...CATALOG_TEXT.codeSmallStrong, color: CATALOG_COLOR.text },
|
|
90
|
+
optionalMark: { ...CATALOG_TEXT.codeSmall, color: CATALOG_COLOR.textMuted },
|
|
91
|
+
type: { ...CATALOG_TEXT.codeMicro, color: CATALOG_COLOR.accent },
|
|
92
92
|
// The second column — description + default — sized by the row's remaining width.
|
|
93
93
|
body: { flex: 1, gap: 2 },
|
|
94
|
-
desc: {
|
|
95
|
-
default: {
|
|
96
|
-
defaultVal: {
|
|
94
|
+
desc: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
95
|
+
default: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
96
|
+
defaultVal: { ...CATALOG_TEXT.codeMicro, color: CATALOG_COLOR.textMuted },
|
|
97
97
|
gridRow: { flexDirection: 'row', gap: PROPS_COLUMN_GAP },
|
|
98
98
|
cell: { flex: 1, minWidth: 0, paddingVertical: CATALOG_SPACE.md, gap: 4 },
|
|
99
99
|
cellDivider: { borderBottomWidth: 1, borderBottomColor: CATALOG_COLOR.border },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, type LayoutChangeEvent, type TextStyle } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { PropsTable } from './PropsTable';
|
|
5
5
|
import { propsColumns, referenceColumns } from './comparison';
|
|
6
6
|
import type { ComposedOfEntry, SectionDef } from './types';
|
|
@@ -8,9 +8,12 @@ import type { ComposedOfEntry, SectionDef } from './types';
|
|
|
8
8
|
// react-native-web reads `aria-level`; React Native's prop types do not declare it.
|
|
9
9
|
const HEADING_LEVEL_2 = { 'aria-level': 2 } as Record<string, unknown>;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/** `last` drops the trailing divider and its padding, the same convention `TokenRow`'s `last` and
|
|
12
|
+
* `PropsTable`'s `rowLast` already use. Without it the final fact's bottom padding stacks on the
|
|
13
|
+
* card's own `panelPadding`, so a card's contents sat ~10px lower than centred. */
|
|
14
|
+
function Fact({ label, value, mono = false, last = false }: { label: string; value: string; mono?: boolean; last?: boolean }) {
|
|
12
15
|
return (
|
|
13
|
-
<View style={styles.fact}>
|
|
16
|
+
<View style={[styles.fact, last && styles.factLast]}>
|
|
14
17
|
<Text style={styles.factLabel}>{label}</Text>
|
|
15
18
|
<Text style={[styles.factValue, mono && styles.mono]}>{value}</Text>
|
|
16
19
|
</View>
|
|
@@ -47,11 +50,16 @@ function compositionLabel(entry: ComposedOfEntry): string {
|
|
|
47
50
|
return entry.relationship === 'built-in' ? entry.component : `${entry.component} · ${entry.relationship}`;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
function CompositionFacts({ composedOf }: { composedOf: ComposedOfEntry[] }) {
|
|
53
|
+
function CompositionFacts({ composedOf, lastIsFlush = false }: { composedOf: ComposedOfEntry[]; lastIsFlush?: boolean }) {
|
|
51
54
|
return (
|
|
52
55
|
<>
|
|
53
56
|
{composedOf.map((entry, i) => (
|
|
54
|
-
<Fact
|
|
57
|
+
<Fact
|
|
58
|
+
key={`${entry.component}-${entry.relationship}-${i}`}
|
|
59
|
+
label={compositionLabel(entry)}
|
|
60
|
+
value={entry.role}
|
|
61
|
+
last={lastIsFlush && i === composedOf.length - 1}
|
|
62
|
+
/>
|
|
55
63
|
))}
|
|
56
64
|
</>
|
|
57
65
|
);
|
|
@@ -91,11 +99,11 @@ export function ReferenceDetails<TId extends string>({ def }: { def: SectionDef<
|
|
|
91
99
|
return (
|
|
92
100
|
<View style={styles.card}>
|
|
93
101
|
<Text role="heading" {...HEADING_LEVEL_2} style={styles.heading}>Quick reference</Text>
|
|
94
|
-
{def.path && <Fact label="Source" value={def.path} mono />}
|
|
102
|
+
{def.path && <Fact label="Source" value={def.path} mono last={!(def.composedOf && def.composedOf.length > 0)} />}
|
|
95
103
|
{def.composedOf && def.composedOf.length > 0 && (
|
|
96
104
|
<>
|
|
97
105
|
<Text style={styles.subheading}>Composition</Text>
|
|
98
|
-
<CompositionFacts composedOf={def.composedOf} />
|
|
106
|
+
<CompositionFacts composedOf={def.composedOf} lastIsFlush />
|
|
99
107
|
</>
|
|
100
108
|
)}
|
|
101
109
|
</View>
|
|
@@ -117,19 +125,25 @@ export function ReferenceDetails<TId extends string>({ def }: { def: SectionDef<
|
|
|
117
125
|
</View>
|
|
118
126
|
<View style={columnStyle}>
|
|
119
127
|
<Text role="heading" {...HEADING_LEVEL_2} style={styles.heading}>Quick reference</Text>
|
|
120
|
-
{def.path && <Fact label="Source" value={def.path} mono />}
|
|
121
|
-
{!hide.accessibility &&
|
|
128
|
+
{def.path && <Fact label="Source" value={def.path} mono last={hide.accessibility && !(!compositionIsOwnColumn && hasComposition)} />}
|
|
129
|
+
{!hide.accessibility && (
|
|
130
|
+
<Fact
|
|
131
|
+
label="Accessibility"
|
|
132
|
+
value={def.a11y ?? 'No accessibility notes documented.'}
|
|
133
|
+
last={!(!compositionIsOwnColumn && hasComposition)}
|
|
134
|
+
/>
|
|
135
|
+
)}
|
|
122
136
|
{!compositionIsOwnColumn && hasComposition && def.composedOf && (
|
|
123
137
|
<>
|
|
124
138
|
<Text style={styles.subheading}>Composition</Text>
|
|
125
|
-
<CompositionFacts composedOf={def.composedOf} />
|
|
139
|
+
<CompositionFacts composedOf={def.composedOf} lastIsFlush />
|
|
126
140
|
</>
|
|
127
141
|
)}
|
|
128
142
|
</View>
|
|
129
143
|
{compositionIsOwnColumn && def.composedOf && (
|
|
130
144
|
<View style={columnStyle}>
|
|
131
145
|
<Text role="heading" {...HEADING_LEVEL_2} style={styles.heading}>Composition</Text>
|
|
132
|
-
<CompositionFacts composedOf={def.composedOf} />
|
|
146
|
+
<CompositionFacts composedOf={def.composedOf} lastIsFlush />
|
|
133
147
|
</View>
|
|
134
148
|
)}
|
|
135
149
|
</View>
|
|
@@ -153,17 +167,13 @@ const styles = StyleSheet.create({
|
|
|
153
167
|
column: { flex: 1, minWidth: 0 },
|
|
154
168
|
columnStacked: { minWidth: 0 },
|
|
155
169
|
heading: {
|
|
156
|
-
|
|
157
|
-
fontWeight: '700',
|
|
158
|
-
letterSpacing: 0.52,
|
|
159
|
-
textTransform: 'uppercase',
|
|
170
|
+
...CATALOG_TEXT.label,
|
|
160
171
|
color: CATALOG_COLOR.text,
|
|
161
172
|
marginBottom: 10,
|
|
162
173
|
},
|
|
163
|
-
body: {
|
|
174
|
+
body: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.textMuted },
|
|
164
175
|
subheading: {
|
|
165
|
-
|
|
166
|
-
fontWeight: '700',
|
|
176
|
+
...CATALOG_TEXT.captionStrong,
|
|
167
177
|
color: CATALOG_COLOR.text,
|
|
168
178
|
marginTop: CATALOG_SPACE.md,
|
|
169
179
|
marginBottom: CATALOG_SPACE.xs,
|
|
@@ -175,14 +185,15 @@ const styles = StyleSheet.create({
|
|
|
175
185
|
borderBottomWidth: 1,
|
|
176
186
|
borderBottomColor: CATALOG_COLOR.borderSubtle,
|
|
177
187
|
},
|
|
178
|
-
|
|
179
|
-
|
|
188
|
+
factLast: { paddingBottom: 0, borderBottomWidth: 0 },
|
|
189
|
+
factLabel: { flexShrink: 1, minWidth: 0, ...CATALOG_TEXT.bodyStrong, color: CATALOG_COLOR.text },
|
|
190
|
+
factValue: { minWidth: 0, ...CATALOG_TEXT.body, textAlign: 'left', color: CATALOG_COLOR.textMuted },
|
|
180
191
|
// `wordBreak` isn't in the installed `TextStyle` type (RN's own, not RNW's — RNW's own
|
|
181
192
|
// `Text/types.js` declares it; a browser applies any valid CSS property name it recognizes
|
|
182
193
|
// regardless), so a bare literal here would report an unknown property under `--noEmit` even
|
|
183
194
|
// though it genuinely works: a long unbroken token (a source path with no spaces, e.g.
|
|
184
195
|
// `AnimatedChevron.tsx`) has no space for the browser's default line-breaking to use, so without
|
|
185
196
|
// this it stays one unbroken run and overflows a narrow card instead of wrapping at its '/'s.
|
|
186
|
-
mono: {
|
|
187
|
-
empty: {
|
|
197
|
+
mono: { ...CATALOG_TEXT.code, wordBreak: 'break-word' } as TextStyle,
|
|
198
|
+
empty: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
188
199
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { View, Text, Pressable, StyleSheet, type LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { ComparisonGrid } from './ComparisonGrid';
|
|
5
5
|
import { ComparisonGroups } from './ComparisonGroups';
|
|
6
6
|
import { ComparisonList } from './ComparisonList';
|
|
@@ -53,7 +53,7 @@ export interface SectionPager<TId extends string> {
|
|
|
53
53
|
labelOf?: (id: TId) => string;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function PagerButton<TId extends string>({
|
|
56
|
+
export function PagerButton<TId extends string>({
|
|
57
57
|
direction,
|
|
58
58
|
targetId,
|
|
59
59
|
onNavigate,
|
|
@@ -209,7 +209,40 @@ function placementBlock(block: PresentationBlock, height: number): PlacementBloc
|
|
|
209
209
|
* are never recorded while side by side, so the decision never feeds on its own result; a width
|
|
210
210
|
* change returns to stacked and decides again.
|
|
211
211
|
*/
|
|
212
|
-
|
|
212
|
+
/** The previous/next pager buttons, in their row — shared by `SectionBlock` and `FamilyPage` so a
|
|
213
|
+
* family page's own page head gets the same pager chrome as every other page. */
|
|
214
|
+
export function SectionPagerRow<TId extends string>({ pager }: { pager: SectionPager<TId> }) {
|
|
215
|
+
return (
|
|
216
|
+
<View style={styles.pager}>
|
|
217
|
+
<PagerButton direction="previous" targetId={pager.previousId} onNavigate={pager.onNavigate} labelOf={pager.labelOf} />
|
|
218
|
+
<PagerButton direction="next" targetId={pager.nextId} onNavigate={pager.onNavigate} labelOf={pager.labelOf} />
|
|
219
|
+
</View>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** The page's specimen blocks (grid, grouped rows, list, or preview), stacked or side by side —
|
|
224
|
+
* exported so `FamilyPage` can render a member's own specimens through the exact same placement
|
|
225
|
+
* logic a normal page's blocks use, rather than a second copy of it. */
|
|
226
|
+
export function Blocks<TId extends string>({
|
|
227
|
+
blocks,
|
|
228
|
+
def,
|
|
229
|
+
surface,
|
|
230
|
+
showLabels = true,
|
|
231
|
+
trimOuterMargin = false,
|
|
232
|
+
}: {
|
|
233
|
+
blocks: PresentationBlock[];
|
|
234
|
+
def: SectionDef<TId>;
|
|
235
|
+
surface: SpecimenSurfaceKind;
|
|
236
|
+
/** V2b item 4: a family member's own specimens render with no uppercase "Variants" / "States /
|
|
237
|
+
* configurations" block label — v8 has none inside a member block. A page's own `SectionBlock`
|
|
238
|
+
* keeps its labels (the default, unchanged). */
|
|
239
|
+
showLabels?: boolean;
|
|
240
|
+
/** V2b item 5: drops this component's own page-level `marginBottom` — `FamilyPage`'s own
|
|
241
|
+
* wrapper (`memberSpecimens`) supplies the exact spacing a member block needs instead, so the
|
|
242
|
+
* two never double-stack. A page's own `SectionBlock` keeps the margin (the default,
|
|
243
|
+
* unchanged). */
|
|
244
|
+
trimOuterMargin?: boolean;
|
|
245
|
+
}) {
|
|
213
246
|
const [available, setAvailable] = useState(0);
|
|
214
247
|
const [heights, setHeights] = useState<number[]>([]);
|
|
215
248
|
const [placement, setPlacement] = useState<'side' | 'stacked'>('stacked');
|
|
@@ -248,15 +281,22 @@ function Blocks<TId extends string>({ blocks, def, surface }: { blocks: Presenta
|
|
|
248
281
|
|
|
249
282
|
const side = placement === 'side';
|
|
250
283
|
return (
|
|
251
|
-
<View onLayout={onContainerLayout} style={[styles.blocks, side && styles.blocksSide]}>
|
|
284
|
+
<View onLayout={onContainerLayout} style={[styles.blocks, side && styles.blocksSide, trimOuterMargin && styles.blocksNoMargin]}>
|
|
252
285
|
{blocks.map((block, i) => (
|
|
253
286
|
<View
|
|
254
|
-
|
|
287
|
+
// A4: keyed by index, not `block.title || block.kind` — a member that sets the same
|
|
288
|
+
// `axis` on both `variants` and `states` now produces two blocks with identical titles,
|
|
289
|
+
// which would otherwise collide as React keys (as the family-section list already keys
|
|
290
|
+
// by index for the same reason — FamilyPage.tsx).
|
|
291
|
+
key={`${block.kind}-${i}`}
|
|
255
292
|
onLayout={onBlockLayout(i)}
|
|
256
293
|
// Side by side, each block fills its own half: a card always fills the column it is given.
|
|
257
294
|
style={side ? styles.blockFill : undefined}
|
|
258
295
|
>
|
|
259
|
-
{
|
|
296
|
+
{/* A3: `axis` now reaches grid/grouped blocks too (not only list), so any block kind
|
|
297
|
+
carrying one shows its (already informative) title on a family page, which otherwise
|
|
298
|
+
hides every generic block label via `showLabels={false}`. */}
|
|
299
|
+
{(showLabels && block.title) || ('axis' in block && block.axis) ? <Text style={styles.blockLabel}>{('axis' in block && block.axis) || block.title}</Text> : null}
|
|
260
300
|
<BlockContent block={block} def={def} surface={surface} />
|
|
261
301
|
</View>
|
|
262
302
|
))}
|
|
@@ -318,12 +358,7 @@ export function SectionBlock<TId extends string>({
|
|
|
318
358
|
)}
|
|
319
359
|
<Text style={styles.desc}>{def.description}</Text>
|
|
320
360
|
</View>
|
|
321
|
-
{pager &&
|
|
322
|
-
<View style={styles.pager}>
|
|
323
|
-
<PagerButton direction="previous" targetId={pager.previousId} onNavigate={pager.onNavigate} labelOf={pager.labelOf} />
|
|
324
|
-
<PagerButton direction="next" targetId={pager.nextId} onNavigate={pager.onNavigate} labelOf={pager.labelOf} />
|
|
325
|
-
</View>
|
|
326
|
-
)}
|
|
361
|
+
{pager && <SectionPagerRow pager={pager} />}
|
|
327
362
|
</View>
|
|
328
363
|
|
|
329
364
|
{blocks.length > 0 && <Blocks blocks={blocks} def={def} surface={surface} />}
|
|
@@ -334,7 +369,7 @@ export function SectionBlock<TId extends string>({
|
|
|
334
369
|
}
|
|
335
370
|
|
|
336
371
|
const styles = StyleSheet.create({
|
|
337
|
-
breadcrumb: {
|
|
372
|
+
breadcrumb: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
338
373
|
titlebar: {
|
|
339
374
|
flexDirection: 'row',
|
|
340
375
|
alignItems: 'flex-start',
|
|
@@ -355,9 +390,9 @@ const styles = StyleSheet.create({
|
|
|
355
390
|
borderColor: CATALOG_COLOR.borderStrong,
|
|
356
391
|
backgroundColor: CATALOG_COLOR.surface,
|
|
357
392
|
},
|
|
358
|
-
osBadgeText: {
|
|
359
|
-
title: {
|
|
360
|
-
desc: {
|
|
393
|
+
osBadgeText: { ...CATALOG_TEXT.microLabel, color: CATALOG_COLOR.text },
|
|
394
|
+
title: { ...CATALOG_TEXT.pageTitle, color: CATALOG_COLOR.text, marginBottom: 5 },
|
|
395
|
+
desc: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.textMuted, maxWidth: 700 },
|
|
361
396
|
pager: { flexDirection: 'row', gap: 6, flexShrink: 0 },
|
|
362
397
|
pagerButton: {
|
|
363
398
|
width: CATALOG_LAYOUT.controlSize,
|
|
@@ -372,26 +407,21 @@ const styles = StyleSheet.create({
|
|
|
372
407
|
pagerButtonActive: { backgroundColor: CATALOG_COLOR.surfacePressed },
|
|
373
408
|
pagerButtonDisabled: { backgroundColor: CATALOG_COLOR.pageBackground },
|
|
374
409
|
focusRing: { outlineWidth: CATALOG_LAYOUT.focusRingWidth, outlineStyle: 'solid', outlineColor: CATALOG_COLOR.focusRing },
|
|
375
|
-
pagerGlyph: {
|
|
410
|
+
pagerGlyph: { ...CATALOG_TEXT.icon, color: CATALOG_COLOR.text },
|
|
376
411
|
pagerGlyphDisabled: { color: CATALOG_COLOR.textMuted },
|
|
377
412
|
blocks: { gap: CATALOG_LAYOUT.blockGap, marginBottom: CATALOG_LAYOUT.blockGap },
|
|
413
|
+
blocksNoMargin: { marginBottom: 0 },
|
|
378
414
|
blocksSide: { flexDirection: 'row', alignItems: 'flex-start' },
|
|
379
415
|
blockFill: { flex: 1, minWidth: 0 },
|
|
380
416
|
// Centred in the card, like every other example (a single phone-width frame used to sit left).
|
|
381
417
|
frames: { flexDirection: 'row', flexWrap: 'wrap', gap: CATALOG_SPACE.xl, alignItems: 'flex-start', justifyContent: 'center' },
|
|
382
418
|
frame: { maxWidth: '100%', gap: CATALOG_SPACE.sm },
|
|
383
419
|
frameLabel: {
|
|
384
|
-
|
|
385
|
-
fontWeight: '800',
|
|
386
|
-
letterSpacing: 0.44,
|
|
387
|
-
textTransform: 'uppercase',
|
|
420
|
+
...CATALOG_TEXT.label,
|
|
388
421
|
color: CATALOG_COLOR.textMuted,
|
|
389
422
|
},
|
|
390
423
|
blockLabel: {
|
|
391
|
-
|
|
392
|
-
fontWeight: '700',
|
|
393
|
-
letterSpacing: 0.72,
|
|
394
|
-
textTransform: 'uppercase',
|
|
424
|
+
...CATALOG_TEXT.label,
|
|
395
425
|
color: CATALOG_COLOR.text,
|
|
396
426
|
marginBottom: CATALOG_LAYOUT.blockLabelGap,
|
|
397
427
|
},
|
|
@@ -423,10 +453,10 @@ const styles = StyleSheet.create({
|
|
|
423
453
|
borderBottomWidth: 1,
|
|
424
454
|
borderBottomColor: CATALOG_COLOR.border,
|
|
425
455
|
},
|
|
426
|
-
tableCaptionText: {
|
|
456
|
+
tableCaptionText: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
427
457
|
// Same cell padding `ComparisonList` uses: the requested width instead reaches the live demo
|
|
428
458
|
// untouched through `tableBodyViewport`, the inner width-qualified group nested inside this body.
|
|
429
459
|
tableBody: { padding: MATRIX_LAYOUT.cellPadding, flexGrow: 1, alignItems: 'center', justifyContent: 'flex-start' },
|
|
430
460
|
tableBodyViewport: { maxWidth: '100%' },
|
|
431
|
-
emptyText: {
|
|
461
|
+
emptyText: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
432
462
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { View, Text, StyleSheet } from 'react-native';
|
|
2
2
|
import { TokenRow, TokenRowGroup } from './TokenRow';
|
|
3
|
-
import {
|
|
3
|
+
import { CATALOG_TEXT, CATALOG_COLOR, CATALOG_SPACE, CATALOG_RADIUS } from './tokens';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Renders a spacing scale as a stack of `TokenRow`s, each showing a step's name, a bar sized to its
|
|
@@ -39,7 +39,7 @@ const styles = StyleSheet.create({
|
|
|
39
39
|
// Wider gap than a plain gap-only stack — one row's use-note shouldn't crowd the next row's label.
|
|
40
40
|
tokenStack: { gap: CATALOG_SPACE.lg },
|
|
41
41
|
row: { flexDirection: 'row', alignItems: 'center', gap: CATALOG_SPACE.md },
|
|
42
|
-
label: { width: 48,
|
|
42
|
+
label: { width: 48, ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
43
43
|
bar: { height: 12, borderRadius: CATALOG_RADIUS.sm, backgroundColor: CATALOG_COLOR.accent },
|
|
44
|
-
value: {
|
|
44
|
+
value: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
45
45
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { View, Text, StyleSheet } from 'react-native';
|
|
2
|
-
import {
|
|
2
|
+
import { CATALOG_TEXT, CATALOG_COLOR, CATALOG_SPACE, CATALOG_RADIUS } from './tokens';
|
|
3
3
|
|
|
4
4
|
/** One token swatch: its rendered value (a colour chip) plus name/value as data — the shared shape
|
|
5
5
|
* behind every Colors gallery (this framework's own, and any host app's, e.g. the Native App DS
|
|
@@ -35,6 +35,6 @@ const styles = StyleSheet.create({
|
|
|
35
35
|
borderWidth: StyleSheet.hairlineWidth,
|
|
36
36
|
borderColor: CATALOG_COLOR.border,
|
|
37
37
|
},
|
|
38
|
-
name: {
|
|
39
|
-
value: {
|
|
38
|
+
name: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
39
|
+
value: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
40
40
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, type LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { sectionColumns, tileGeometry, TOKEN_LAYOUT_GAP, TOKEN_SECTION_MIN_WIDTH } from './tokenLayout';
|
|
5
5
|
import type { TokenSection } from './types';
|
|
6
6
|
|
|
@@ -78,13 +78,10 @@ export function TokenTile({ name, value, note, children }: { name: string; value
|
|
|
78
78
|
const styles = StyleSheet.create({
|
|
79
79
|
sections: { flexDirection: 'row', flexWrap: 'wrap', gap: TOKEN_LAYOUT_GAP, rowGap: CATALOG_LAYOUT.blockGap, alignItems: 'flex-start' },
|
|
80
80
|
sectionLabel: {
|
|
81
|
-
|
|
82
|
-
fontWeight: '700',
|
|
83
|
-
letterSpacing: 0.72,
|
|
84
|
-
textTransform: 'uppercase',
|
|
81
|
+
...CATALOG_TEXT.label,
|
|
85
82
|
color: CATALOG_COLOR.text,
|
|
86
83
|
},
|
|
87
|
-
sectionDesc: {
|
|
84
|
+
sectionDesc: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted, marginTop: CATALOG_SPACE.xs },
|
|
88
85
|
card: {
|
|
89
86
|
marginTop: CATALOG_LAYOUT.blockLabelGap,
|
|
90
87
|
backgroundColor: CATALOG_COLOR.surface,
|
|
@@ -97,7 +94,7 @@ const styles = StyleSheet.create({
|
|
|
97
94
|
grid: { flexDirection: 'row', flexWrap: 'wrap', gap: TOKEN_LAYOUT_GAP },
|
|
98
95
|
tile: { gap: CATALOG_SPACE.xs },
|
|
99
96
|
tilePreview: { minHeight: 56, justifyContent: 'center', marginBottom: CATALOG_SPACE.xs },
|
|
100
|
-
tileName: {
|
|
101
|
-
tileValue: {
|
|
102
|
-
tileNote: {
|
|
97
|
+
tileName: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
98
|
+
tileValue: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
99
|
+
tileNote: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
103
100
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, type LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import { CATALOG_TEXT, CATALOG_COLOR, CATALOG_SPACE } from './tokens';
|
|
4
4
|
|
|
5
5
|
type Lane = { width: number; report: (width: number) => void };
|
|
6
6
|
|
|
@@ -104,5 +104,5 @@ const styles = StyleSheet.create({
|
|
|
104
104
|
borderBottomWidth: 1,
|
|
105
105
|
borderBottomColor: CATALOG_COLOR.border,
|
|
106
106
|
},
|
|
107
|
-
use: {
|
|
107
|
+
use: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
108
108
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { View, Text, StyleSheet, type TextStyle } from 'react-native';
|
|
2
2
|
import { TokenRow, TokenRowGroup } from './TokenRow';
|
|
3
|
-
import {
|
|
3
|
+
import { CATALOG_TEXT, CATALOG_COLOR, CATALOG_SPACE } from './tokens';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Renders a type scale as a stack of `TokenRow`s, each showing a step's name (rendered at its own
|
|
@@ -44,5 +44,5 @@ const styles = StyleSheet.create({
|
|
|
44
44
|
// two read as one unit at a glance.
|
|
45
45
|
row: { flexDirection: 'row', alignItems: 'baseline', gap: CATALOG_SPACE.sm },
|
|
46
46
|
sample: { color: CATALOG_COLOR.text },
|
|
47
|
-
meta: {
|
|
47
|
+
meta: { ...CATALOG_TEXT.micro, color: CATALOG_COLOR.textMuted },
|
|
48
48
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { ActivityIndicator, Platform, Pressable, ScrollView, StyleSheet, Switch, Text, View } from 'react-native';
|
|
3
|
-
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE,
|
|
3
|
+
import { CATALOG_COLOR, CATALOG_LAYOUT, CATALOG_RADIUS, CATALOG_SPACE, CATALOG_TEXT } from './tokens';
|
|
4
4
|
import { CatalogButton } from './CatalogButton';
|
|
5
5
|
import { DS_VIEWER_SECRET_HEADER } from './catalogNavigation';
|
|
6
6
|
import {
|
|
@@ -1080,9 +1080,9 @@ const styles = StyleSheet.create({
|
|
|
1080
1080
|
resultNote: { borderRadius: CATALOG_RADIUS.md, padding: 14, marginTop: 12, marginBottom: 18, gap: 4 },
|
|
1081
1081
|
resultNoteOk: { backgroundColor: CATALOG_COLOR.successSubtle },
|
|
1082
1082
|
resultNoteErr: { backgroundColor: CATALOG_COLOR.dangerSubtle, borderWidth: 1, borderColor: CATALOG_COLOR.dangerBorder },
|
|
1083
|
-
resultTitle: {
|
|
1084
|
-
resultDescription: {
|
|
1085
|
-
resultDetail: {
|
|
1083
|
+
resultTitle: { ...CATALOG_TEXT.heading3 },
|
|
1084
|
+
resultDescription: { ...CATALOG_TEXT.caption },
|
|
1085
|
+
resultDetail: { ...CATALOG_TEXT.caption },
|
|
1086
1086
|
resultRow: { flexDirection: 'row', alignItems: 'center', gap: CATALOG_SPACE.md, marginTop: 8 },
|
|
1087
1087
|
// The catalog's smallest control size (the major banner's close button), filled in the note's colour.
|
|
1088
1088
|
resultButton: { height: 32, paddingHorizontal: 14, borderRadius: 16, alignItems: 'center', justifyContent: 'center' },
|
|
@@ -1091,15 +1091,14 @@ const styles = StyleSheet.create({
|
|
|
1091
1091
|
// uses, so "unavailable" doesn't read as merely "pressed" (the note's own full-colour fill at
|
|
1092
1092
|
// reduced opacity).
|
|
1093
1093
|
resultButtonDisabled: { backgroundColor: CATALOG_COLOR.controlDisabled },
|
|
1094
|
-
resultButtonText: { color: '#ffffff'
|
|
1094
|
+
resultButtonText: { ...CATALOG_TEXT.captionStrong, color: '#ffffff' },
|
|
1095
1095
|
resultButtonTextDisabled: { color: CATALOG_COLOR.controlDisabledText },
|
|
1096
|
-
resultLink: {
|
|
1097
|
-
crumb: {
|
|
1096
|
+
resultLink: { ...CATALOG_TEXT.captionStrong, textDecorationLine: 'underline' },
|
|
1097
|
+
crumb: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
1098
1098
|
headingTarget: { marginTop: 4, marginBottom: 6 },
|
|
1099
|
-
title: {
|
|
1099
|
+
title: { ...CATALOG_TEXT.pageTitle, color: CATALOG_COLOR.text },
|
|
1100
1100
|
code: {
|
|
1101
|
-
|
|
1102
|
-
fontSize: CATALOG_TYPE.sm,
|
|
1101
|
+
...CATALOG_TEXT.codeSmall,
|
|
1103
1102
|
backgroundColor: CATALOG_COLOR.surfaceMuted,
|
|
1104
1103
|
borderWidth: 1,
|
|
1105
1104
|
borderColor: CATALOG_COLOR.border,
|
|
@@ -1108,39 +1107,39 @@ const styles = StyleSheet.create({
|
|
|
1108
1107
|
paddingVertical: 2,
|
|
1109
1108
|
},
|
|
1110
1109
|
versionsRow: { flexDirection: 'row', alignItems: 'center', gap: 10 },
|
|
1111
|
-
versionsText: {
|
|
1112
|
-
arrow: {
|
|
1110
|
+
versionsText: { ...CATALOG_TEXT.heading1, color: CATALOG_COLOR.text },
|
|
1111
|
+
arrow: { ...CATALOG_TEXT.heading1, color: CATALOG_COLOR.textMuted },
|
|
1113
1112
|
pill: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 10, backgroundColor: CATALOG_COLOR.accentSubtle },
|
|
1114
1113
|
pillMajor: { backgroundColor: CATALOG_COLOR.warningSubtle },
|
|
1115
1114
|
pillSuccess: { backgroundColor: CATALOG_COLOR.successSubtle },
|
|
1116
|
-
pillText: {
|
|
1115
|
+
pillText: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.accent },
|
|
1117
1116
|
pillTextMajor: { color: CATALOG_COLOR.warning },
|
|
1118
1117
|
pillTextSuccess: { color: CATALOG_COLOR.success },
|
|
1119
1118
|
pillOff: { backgroundColor: CATALOG_COLOR.chip },
|
|
1120
1119
|
pillTextOff: { color: CATALOG_COLOR.textMuted },
|
|
1121
1120
|
facts: { marginTop: 18, borderTopWidth: 1, borderTopColor: CATALOG_COLOR.border },
|
|
1122
1121
|
factRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: CATALOG_SPACE.md, paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: CATALOG_COLOR.border },
|
|
1123
|
-
factLabel: {
|
|
1124
|
-
factValue: {
|
|
1122
|
+
factLabel: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.textMuted },
|
|
1123
|
+
factValue: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.text },
|
|
1125
1124
|
switchText: { flex: 1, gap: 2 },
|
|
1126
|
-
switchLabel: {
|
|
1125
|
+
switchLabel: { ...CATALOG_TEXT.bodyStrong, color: CATALOG_COLOR.text },
|
|
1127
1126
|
switch: { width: 44, height: 26 },
|
|
1128
|
-
switchHelp: {
|
|
1129
|
-
muted: {
|
|
1127
|
+
switchHelp: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
1128
|
+
muted: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted, marginTop: 4 },
|
|
1130
1129
|
block: { marginTop: 18 },
|
|
1131
|
-
h3: {
|
|
1132
|
-
bullet: {
|
|
1130
|
+
h3: { ...CATALOG_TEXT.label, color: CATALOG_COLOR.text, marginBottom: 8 },
|
|
1131
|
+
bullet: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.text, marginVertical: 2 },
|
|
1133
1132
|
filesBox: { borderWidth: 1, borderColor: CATALOG_COLOR.border, borderRadius: CATALOG_RADIUS.md },
|
|
1134
1133
|
fileRow: { flexDirection: 'row', justifyContent: 'space-between', paddingVertical: 8, paddingHorizontal: 12 },
|
|
1135
1134
|
fileRowBorder: { borderTopWidth: 1, borderTopColor: CATALOG_COLOR.border },
|
|
1136
|
-
filePath: {
|
|
1137
|
-
fileReason: {
|
|
1138
|
-
fileReasonDirty: { color: CATALOG_COLOR.warning
|
|
1135
|
+
filePath: { ...CATALOG_TEXT.codeSmall, color: CATALOG_COLOR.text },
|
|
1136
|
+
fileReason: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
1137
|
+
fileReasonDirty: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.warning },
|
|
1139
1138
|
actions: { flexDirection: 'row', alignItems: 'center', gap: CATALOG_SPACE.md, marginTop: 20 },
|
|
1140
1139
|
noteBox: { borderRadius: CATALOG_RADIUS.md, padding: 12, marginTop: 18 },
|
|
1141
1140
|
noteBoxRow: { flexDirection: 'row', alignItems: 'flex-start', gap: 9 },
|
|
1142
|
-
noteBoxText: {
|
|
1143
|
-
noteBoxBold: {
|
|
1141
|
+
noteBoxText: { ...CATALOG_TEXT.body, flexShrink: 1 },
|
|
1142
|
+
noteBoxBold: { ...CATALOG_TEXT.bodyStrong },
|
|
1144
1143
|
steps: { marginTop: 12 },
|
|
1145
1144
|
stepRow: { flexDirection: 'row', alignItems: 'center', gap: 10, paddingVertical: 6 },
|
|
1146
1145
|
stepIcon: { width: 20, height: 20, borderRadius: 10, alignItems: 'center', justifyContent: 'center' },
|
|
@@ -1151,10 +1150,10 @@ const styles = StyleSheet.create({
|
|
|
1151
1150
|
stepIconNow: { borderWidth: 2, borderColor: CATALOG_COLOR.accent },
|
|
1152
1151
|
stepIconTodo: { borderWidth: 2, borderColor: CATALOG_COLOR.borderStrong },
|
|
1153
1152
|
stepIconFail: { backgroundColor: CATALOG_COLOR.dangerSubtle },
|
|
1154
|
-
stepIconGlyph: {
|
|
1155
|
-
stepLabel: {
|
|
1156
|
-
stepLabelNow: {
|
|
1157
|
-
stepLabelFail: {
|
|
1153
|
+
stepIconGlyph: { ...CATALOG_TEXT.captionStrong, color: CATALOG_COLOR.text },
|
|
1154
|
+
stepLabel: { ...CATALOG_TEXT.body, color: CATALOG_COLOR.textMuted },
|
|
1155
|
+
stepLabelNow: { ...CATALOG_TEXT.bodyStrong, color: CATALOG_COLOR.text },
|
|
1156
|
+
stepLabelFail: { ...CATALOG_TEXT.bodyStrong, color: CATALOG_COLOR.text },
|
|
1158
1157
|
logBox: { backgroundColor: '#1d1d1f', borderRadius: CATALOG_RADIUS.md, padding: 12, marginTop: 8, maxHeight: 240 },
|
|
1159
|
-
logText: { color: '#e8e8e8'
|
|
1158
|
+
logText: { ...CATALOG_TEXT.codeSmall, color: '#e8e8e8' },
|
|
1160
1159
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet } from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import { CATALOG_TEXT, CATALOG_COLOR } from './tokens';
|
|
4
4
|
|
|
5
5
|
/** Labels one example (or small group of examples) inside a section's Examples card — a bold
|
|
6
6
|
* uppercase name plus a one-line description stacked below it, sitting above whatever demo content
|
|
@@ -39,10 +39,7 @@ const styles = StyleSheet.create({
|
|
|
39
39
|
group: { gap: 6 },
|
|
40
40
|
groupCenter: { alignItems: 'center' },
|
|
41
41
|
groupLeft: { alignItems: 'flex-start' },
|
|
42
|
-
name: {
|
|
43
|
-
|
|
44
|
-
textTransform: 'uppercase', letterSpacing: 0.4,
|
|
45
|
-
},
|
|
46
|
-
desc: { fontSize: CATALOG_TYPE.sm, color: CATALOG_COLOR.textMuted },
|
|
42
|
+
name: { ...CATALOG_TEXT.microLabel, color: CATALOG_COLOR.text },
|
|
43
|
+
desc: { ...CATALOG_TEXT.caption, color: CATALOG_COLOR.textMuted },
|
|
47
44
|
textCenter: { textAlign: 'center' },
|
|
48
45
|
});
|