@sincpro/mobile-ui 3.0.1 → 3.2.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/dist/Actions/Actions.Button.d.ts +6 -6
- package/dist/Actions/Actions.Button.js +650 -180
- package/dist/Actions/Actions.Dock.d.ts +1 -1
- package/dist/Actions/Actions.Dock.js +297 -18
- package/dist/Actions/Actions.FAB.js +100 -12
- package/dist/Actions/Actions.FilterButton.d.ts +17 -0
- package/dist/Actions/Actions.FilterButton.js +263 -33
- package/dist/Actions/Actions.IconButton.d.ts +1 -0
- package/dist/Actions/Actions.IconButton.js +196 -33
- package/dist/Actions/index.js +13 -13
- package/dist/Dialog/Confirmation.context.js +82 -16
- package/dist/Dialog/Dialog.ActionSheet.js +200 -41
- package/dist/Dialog/Dialog.Confirmation.js +168 -31
- package/dist/Dialog/Dialog.EditValue.js +437 -62
- package/dist/Dialog/Dialog.Sheet.d.ts +7 -3
- package/dist/Dialog/Dialog.Sheet.js +267 -15
- package/dist/Dialog/OverlayHost.d.ts +24 -0
- package/dist/Dialog/OverlayHost.js +230 -0
- package/dist/Dialog/SheetSurface.d.ts +43 -0
- package/dist/Dialog/SheetSurface.js +495 -0
- package/dist/Dialog/dialog-actions.d.ts +17 -0
- package/dist/Dialog/dialog-actions.js +59 -0
- package/dist/Dialog/index.d.ts +4 -1
- package/dist/Dialog/index.js +8 -7
- package/dist/Dialog/overlay.store.d.ts +24 -0
- package/dist/Dialog/overlay.store.js +59 -0
- package/dist/Dialog/requestConfirmation.js +20 -10
- package/dist/Display/Display.Accordion.js +185 -13
- package/dist/Display/Display.AmountSummary.js +206 -15
- package/dist/Display/Display.Avatar.js +93 -31
- package/dist/Display/Display.AvatarGroup.js +132 -17
- package/dist/Display/Display.Badge.d.ts +18 -2
- package/dist/Display/Display.Badge.js +117 -49
- package/dist/Display/Display.Card.js +163 -26
- package/dist/Display/Display.Carousel.js +459 -105
- package/dist/Display/Display.Chip.d.ts +4 -1
- package/dist/Display/Display.Chip.js +165 -31
- package/dist/Display/Display.CircleButton.d.ts +1 -0
- package/dist/Display/Display.CircleButton.js +86 -27
- package/dist/Display/Display.CopyableText.js +289 -66
- package/dist/Display/Display.CountRecords.js +60 -3
- package/dist/Display/Display.DataTable.js +123 -13
- package/dist/Display/Display.Date.js +243 -33
- package/dist/Display/Display.Divider.d.ts +10 -10
- package/dist/Display/Display.Divider.js +67 -20
- package/dist/Display/Display.ExpoImage.js +97 -8
- package/dist/Display/Display.GradientSurface.d.ts +9 -4
- package/dist/Display/Display.GradientSurface.js +196 -46
- package/dist/Display/Display.Icon.js +129 -15
- package/dist/Display/Display.IconBadge.js +95 -25
- package/dist/Display/Display.Image.d.ts +7 -1
- package/dist/Display/Display.Image.js +344 -39
- package/dist/Display/Display.KeyValue.js +90 -5
- package/dist/Display/Display.ListGroup.js +181 -9
- package/dist/Display/Display.ListItem.js +324 -28
- package/dist/Display/Display.Logo.js +84 -29
- package/dist/Display/Display.MediaCard.js +125 -4
- package/dist/Display/Display.MediaEmbed.d.ts +0 -5
- package/dist/Display/Display.MediaEmbed.js +170 -26
- package/dist/Display/Display.MenuButton.d.ts +2 -2
- package/dist/Display/Display.MenuButton.js +380 -94
- package/dist/Display/Display.MenuCard.js +122 -18
- package/dist/Display/Display.MenuGrid.js +43 -3
- package/dist/Display/Display.Monetary.js +90 -5
- package/dist/Display/Display.Pattern.js +306 -47
- package/dist/Display/Display.PriceTag.js +117 -14
- package/dist/Display/Display.ProductCard.js +154 -4
- package/dist/Display/Display.Rating.js +92 -11
- package/dist/Display/Display.SearchHistory.js +132 -6
- package/dist/Display/Display.SectionHeader.d.ts +5 -1
- package/dist/Display/Display.SectionHeader.js +125 -12
- package/dist/Display/Display.Stat.js +62 -3
- package/dist/Display/Display.StatCard.js +131 -7
- package/dist/Display/Display.StatusBadge.d.ts +29 -0
- package/dist/Display/Display.StatusBadge.js +68 -0
- package/dist/Display/Display.StatusDot.js +93 -18
- package/dist/Display/Display.Story.js +285 -35
- package/dist/Display/Display.StoryTray.js +354 -34
- package/dist/Display/Display.StoryViewer.js +571 -72
- package/dist/Display/Display.SwipeableRow.js +148 -20
- package/dist/Display/Display.Tag.d.ts +4 -1
- package/dist/Display/Display.Tag.js +66 -4
- package/dist/Display/Display.Timeline.js +102 -13
- package/dist/Display/Display.Tooltip.js +122 -26
- package/dist/Display/chevron.d.ts +6 -0
- package/dist/Display/chevron.js +32 -0
- package/dist/Display/count-badge.d.ts +21 -0
- package/dist/Display/count-badge.js +124 -0
- package/dist/Display/group-title.d.ts +10 -0
- package/dist/Display/group-title.js +53 -0
- package/dist/Display/icon-font.d.ts +3 -0
- package/dist/Display/icon-font.ios.d.ts +3 -0
- package/dist/Display/icon-font.ios.js +4 -0
- package/dist/Display/icon-font.js +7 -0
- package/dist/Display/icon-glyphs.d.ts +2 -0
- package/dist/Display/icon-glyphs.js +87 -0
- package/dist/Display/icon-map.d.ts +15 -11
- package/dist/Display/icon-map.js +344 -84
- package/dist/Display/icon-registry.d.ts +21 -0
- package/dist/Display/icon-registry.js +21 -0
- package/dist/Display/index.d.ts +6 -1
- package/dist/Display/index.js +53 -48
- package/dist/Display/pill.d.ts +16 -0
- package/dist/Display/pill.js +47 -0
- package/dist/Feedback/ErrorBoundary.js +35 -23
- package/dist/Feedback/Feedback.Banner.js +202 -24
- package/dist/Feedback/Feedback.DomainSplashScreen.js +246 -70
- package/dist/Feedback/Feedback.Empty.js +54 -3
- package/dist/Feedback/Feedback.EmptyState.js +114 -5
- package/dist/Feedback/Feedback.Error.d.ts +1 -1
- package/dist/Feedback/Feedback.Error.js +130 -5
- package/dist/Feedback/Feedback.Loading.d.ts +1 -1
- package/dist/Feedback/Feedback.Loading.js +70 -3
- package/dist/Feedback/Feedback.PermissionCard.js +161 -5
- package/dist/Feedback/Feedback.Progress.js +199 -41
- package/dist/Feedback/Feedback.ProgressCircle.js +184 -12
- package/dist/Feedback/Feedback.Skeleton.js +149 -36
- package/dist/Feedback/Feedback.Spinner.js +407 -79
- package/dist/Feedback/Feedback.Splash.js +240 -33
- package/dist/Feedback/Feedback.State.d.ts +17 -0
- package/dist/Feedback/Feedback.State.js +104 -0
- package/dist/Feedback/Toast.context.js +883 -167
- package/dist/Feedback/index.d.ts +3 -0
- package/dist/Feedback/index.js +15 -13
- package/dist/Form/Form.Checkbox.js +212 -22
- package/dist/Form/Form.ControlledCheckbox.d.ts +1 -1
- package/dist/Form/Form.ControlledCheckbox.js +46 -4
- package/dist/Form/Form.ControlledDropdown.d.ts +1 -1
- package/dist/Form/Form.ControlledDropdown.js +62 -4
- package/dist/Form/Form.ControlledInput.d.ts +4 -3
- package/dist/Form/Form.ControlledInput.js +72 -4
- package/dist/Form/Form.ControlledMonetaryInput.d.ts +6 -3
- package/dist/Form/Form.ControlledMonetaryInput.js +50 -4
- package/dist/Form/Form.ControlledRadioButton.d.ts +2 -2
- package/dist/Form/Form.ControlledRadioButton.js +45 -4
- package/dist/Form/Form.DatePicker.js +507 -107
- package/dist/Form/Form.Dropdown.js +303 -52
- package/dist/Form/Form.ErrorSummary.js +236 -44
- package/dist/Form/Form.Field.d.ts +24 -0
- package/dist/Form/Form.Field.js +55 -0
- package/dist/Form/Form.FractionalQuantityInput.js +508 -96
- package/dist/Form/Form.Input.d.ts +17 -3
- package/dist/Form/Form.Input.js +497 -29
- package/dist/Form/Form.KeyboardForm.d.ts +22 -8
- package/dist/Form/Form.KeyboardForm.js +83 -8
- package/dist/Form/Form.KeyboardToolbarHost.d.ts +14 -0
- package/dist/Form/Form.KeyboardToolbarHost.js +223 -0
- package/dist/Form/Form.MonetaryInput.js +164 -17
- package/dist/Form/Form.PickerField.d.ts +31 -0
- package/dist/Form/Form.PickerField.js +539 -0
- package/dist/Form/Form.PinInput.js +150 -15
- package/dist/Form/Form.QuantitySelector.js +229 -25
- package/dist/Form/Form.RadioButton.d.ts +1 -0
- package/dist/Form/Form.RadioButton.js +26 -29
- package/dist/Form/Form.Select.d.ts +2 -1
- package/dist/Form/Form.Select.js +388 -60
- package/dist/Form/Form.Slider.js +133 -10
- package/dist/Form/Form.Switch.js +99 -4
- package/dist/Form/choice-row.d.ts +15 -0
- package/dist/Form/choice-row.js +236 -0
- package/dist/Form/index.d.ts +11 -6
- package/dist/Form/index.js +26 -27
- package/dist/Form/input-text.d.ts +7 -0
- package/dist/Form/input-text.js +18 -0
- package/dist/Navigation/Navigation.AppBar.d.ts +3 -4
- package/dist/Navigation/Navigation.AppBar.js +535 -99
- package/dist/Navigation/Navigation.BottomNav.js +363 -98
- package/dist/Navigation/Navigation.CollapsingHeader.d.ts +28 -13
- package/dist/Navigation/Navigation.CollapsingHeader.js +369 -36
- package/dist/Navigation/Navigation.FloatingBar.js +71 -11
- package/dist/Navigation/Navigation.Menu.js +309 -95
- package/dist/Navigation/Navigation.MenuSection.js +80 -11
- package/dist/Navigation/Navigation.RowItem.d.ts +4 -2
- package/dist/Navigation/Navigation.RowItem.js +93 -8
- package/dist/Navigation/Navigation.Search.js +241 -27
- package/dist/Navigation/Navigation.SearchBar.d.ts +7 -1
- package/dist/Navigation/Navigation.SearchBar.js +218 -29
- package/dist/Navigation/Navigation.SearchSuggestions.js +77 -3
- package/dist/Navigation/Navigation.SegmentedControl.js +152 -14
- package/dist/Navigation/Navigation.Steps.js +105 -11
- package/dist/Navigation/Navigation.Tabs.js +449 -41
- package/dist/Navigation/index.d.ts +9 -4
- package/dist/Navigation/index.js +13 -13
- package/dist/Typography/Typography.Heading.js +33 -3
- package/dist/Typography/Typography.SelectableText.js +95 -7
- package/dist/Typography/Typography.Text.d.ts +4 -2
- package/dist/Typography/Typography.Text.js +217 -7
- package/dist/Typography/index.js +3 -3
- package/dist/branding.js +29 -13
- package/dist/icons/AddItemIcon.js +76 -2
- package/dist/icons/ArrangeCircle.js +82 -2
- package/dist/icons/ArrowDownIcon.js +63 -3
- package/dist/icons/ArrowUpIcon.js +63 -3
- package/dist/icons/BoxIcon.js +64 -2
- package/dist/icons/BoxTimeIcon.js +63 -2
- package/dist/icons/CalendarIcon.js +145 -2
- package/dist/icons/CardIcon.js +80 -2
- package/dist/icons/CashierIcon.js +39 -2
- package/dist/icons/CreditIcon.js +76 -3
- package/dist/icons/DuoIcon.js +75 -2
- package/dist/icons/HomeIcon.js +39 -2
- package/dist/icons/HomeIconOutlined.js +53 -2
- package/dist/icons/LogoIcon.js +87 -2
- package/dist/icons/MoneyReceiveIcon.js +86 -2
- package/dist/icons/PinIcon.js +39 -2
- package/dist/icons/ProfileIcon.js +47 -2
- package/dist/icons/SettingsIcon.js +114 -2
- package/dist/icons/SinpeIcon.js +60 -2
- package/dist/icons/ToggleOffIcon.js +53 -2
- package/dist/icons/WalletMoneyIcon.js +81 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8 -2
- package/dist/layouts/AuthContainer.d.ts +4 -5
- package/dist/layouts/AuthContainer.js +231 -7
- package/dist/layouts/BottomInset.js +4 -1
- package/dist/layouts/Container.d.ts +2 -2
- package/dist/layouts/Container.js +45 -3
- package/dist/layouts/GradientContainer.js +37 -5
- package/dist/layouts/PlainLayout.js +19 -3
- package/dist/layouts/ScrollContainer.d.ts +14 -9
- package/dist/layouts/ScrollContainer.js +125 -4
- package/dist/layouts/edges.d.ts +2 -0
- package/dist/layouts/edges.js +1 -0
- package/dist/primitives/AspectRatio.js +75 -3
- package/dist/primitives/Box.js +45 -3
- package/dist/primitives/Pressable.js +95 -5
- package/dist/primitives/Row.js +84 -13
- package/dist/primitives/Spacer.js +42 -5
- package/dist/primitives/Stack.js +66 -7
- package/dist/primitives/index.js +1 -1
- package/dist/theme/active.d.ts +2 -0
- package/dist/theme/active.js +33 -18
- package/dist/theme/build.js +118 -87
- package/dist/theme/color.js +87 -87
- package/dist/theme/components/ThemedActivityIndicator.d.ts +2 -15
- package/dist/theme/components/ThemedActivityIndicator.js +35 -3
- package/dist/theme/components/index.js +1 -0
- package/dist/theme/contrast.js +32 -33
- package/dist/theme/css-vars.js +71 -75
- package/dist/theme/dark.js +116 -97
- package/dist/theme/default.js +116 -97
- package/dist/theme/define.js +16 -12
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.js +7 -6
- package/dist/theme/on-dark-surface.d.ts +12 -0
- package/dist/theme/on-dark-surface.js +13 -0
- package/dist/theme/theme.js +1 -0
- package/dist/theme/tw.js +3 -1
- package/dist/theme/types.js +0 -18
- package/dist/theme/typography.d.ts +1 -1
- package/dist/theme/typography.js +337 -303
- package/dist/theme/useTheme.d.ts +4 -0
- package/dist/theme/useTheme.js +7 -3
- package/dist/theme/useThemeVars.d.ts +9 -0
- package/dist/theme/useThemeVars.js +23 -0
- package/dist/theme/validate.js +175 -166
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/motion.js +30 -13
- package/dist/utils/async.d.ts +14 -0
- package/dist/utils/async.js +22 -0
- package/dist/utils/criteria.js +66 -85
- package/dist/utils/date.d.ts +8 -2
- package/dist/utils/date.js +63 -50
- package/dist/utils/image.js +8 -8
- package/dist/utils/intl.d.ts +1 -0
- package/dist/utils/intl.js +13 -0
- package/dist/utils/keys.js +3 -5
- package/dist/utils/monetary.d.ts +1 -0
- package/dist/utils/monetary.js +28 -24
- package/dist/utils/progress.js +2 -3
- package/dist/utils/quantity.js +25 -26
- package/dist/utils/reorder.js +11 -20
- package/dist/utils/search.d.ts +4 -0
- package/dist/utils/search.js +12 -0
- package/dist/utils/serializer.js +38 -38
- package/dist/utils/useReducedMotion.js +32 -30
- package/dist/views/AppSplashView.js +117 -3
- package/dist/views/AuthFormView.d.ts +4 -5
- package/dist/views/AuthFormView.js +119 -11
- package/dist/views/FormViewV2.context.js +75 -23
- package/dist/views/FormViewV2.d.ts +4 -5
- package/dist/views/FormViewV2.js +658 -92
- package/dist/views/ListViewV2.context.js +91 -47
- package/dist/views/ListViewV2.d.ts +84 -43
- package/dist/views/ListViewV2.js +1350 -200
- package/dist/views/Wizard/Wizard.context.js +248 -84
- package/dist/views/Wizard/Wizard.js +260 -67
- package/dist/views/types/IListView.js +34 -31
- package/dist/widgets/CollectionOptions.js +557 -138
- package/dist/widgets/FilterBar.js +159 -7
- package/dist/widgets/FilterBuilder.js +375 -102
- package/dist/widgets/JSONViewer.js +275 -129
- package/dist/widgets/PromoBanner.js +336 -42
- package/dist/widgets/PromoModal.d.ts +2 -2
- package/dist/widgets/PromoModal.js +389 -62
- package/dist/widgets/QueryChoice.js +150 -8
- package/dist/widgets/QuickActions.js +120 -31
- package/dist/widgets/ReorderableList.js +399 -128
- package/dist/widgets/TimeZoneSelectorModal.js +458 -51
- package/dist/widgets/index.js +3 -3
- package/package.json +6 -1
- package/tailwind.preset.js +7 -5
- package/dist/Form/Form.InputField.d.ts +0 -10
- package/dist/Form/Form.InputField.js +0 -38
- package/dist/Form/Form.KeyboardToolbar.d.ts +0 -22
- package/dist/Form/Form.KeyboardToolbar.js +0 -66
- package/dist/Form/Form.PasswordInput.d.ts +0 -9
- package/dist/Form/Form.PasswordInput.js +0 -17
- package/dist/Form/Form.TextInput.d.ts +0 -8
- package/dist/Form/Form.TextInput.js +0 -8
- package/dist/primitives/BaseButton.d.ts +0 -150
- package/dist/primitives/BaseButton.js +0 -229
- package/dist/utils/useSheetTranslation.d.ts +0 -5
- package/dist/utils/useSheetTranslation.js +0 -23
package/dist/theme/useTheme.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { ThemeTokens } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The active theme, as a new object after every `setActiveTheme`. Values memoized on it
|
|
4
|
+
* (by hand or by React Compiler) recompute on a light/dark switch.
|
|
5
|
+
*/
|
|
2
6
|
export declare function useTheme(): ThemeTokens;
|
|
3
7
|
export declare const theme: ThemeTokens;
|
package/dist/theme/useTheme.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { getActiveTheme,
|
|
1
|
+
import { getActiveTheme, getThemeSnapshot, subscribeTheme } from "./active.js";
|
|
2
2
|
import { useSyncExternalStore } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The active theme, as a new object after every `setActiveTheme`. Values memoized on it
|
|
6
|
+
* (by hand or by React Compiler) recompute on a light/dark switch.
|
|
7
|
+
*/
|
|
3
8
|
export function useTheme() {
|
|
4
|
-
|
|
5
|
-
return getActiveTheme();
|
|
9
|
+
return useSyncExternalStore(subscribeTheme, getThemeSnapshot, getThemeSnapshot);
|
|
6
10
|
}
|
|
7
11
|
export const theme = getActiveTheme();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { vars } from "nativewind";
|
|
2
|
+
type ThemeVars = ReturnType<typeof vars>;
|
|
3
|
+
/**
|
|
4
|
+
* NativeWind CSS variables for the active theme, as one stable object per
|
|
5
|
+
* theme version. A new object on every render would make every `className`
|
|
6
|
+
* consumer below re-resolve its styles.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useThemeVars(): ThemeVars;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getActiveTheme, getThemeVersion, subscribeTheme } from "./active.js";
|
|
2
|
+
import { themeToVars } from "./css-vars.js";
|
|
3
|
+
import { vars } from "nativewind";
|
|
4
|
+
import { useSyncExternalStore } from "react";
|
|
5
|
+
let cachedVersion = -1;
|
|
6
|
+
let cachedVars;
|
|
7
|
+
function currentVars() {
|
|
8
|
+
const version = getThemeVersion();
|
|
9
|
+
if (!cachedVars || cachedVersion !== version) {
|
|
10
|
+
cachedVersion = version;
|
|
11
|
+
cachedVars = vars(themeToVars(getActiveTheme()));
|
|
12
|
+
}
|
|
13
|
+
return cachedVars;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* NativeWind CSS variables for the active theme, as one stable object per
|
|
18
|
+
* theme version. A new object on every render would make every `className`
|
|
19
|
+
* consumer below re-resolve its styles.
|
|
20
|
+
*/
|
|
21
|
+
export function useThemeVars() {
|
|
22
|
+
return useSyncExternalStore(subscribeTheme, currentVars, currentVars);
|
|
23
|
+
}
|
package/dist/theme/validate.js
CHANGED
|
@@ -9,61 +9,77 @@ import { contrastRatio, resolveOnColor } from "./contrast.js";
|
|
|
9
9
|
* tests intentionally pass partial themes). Can also be called directly.
|
|
10
10
|
*/
|
|
11
11
|
export function validateTheme(theme) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const issues = [];
|
|
13
|
+
if (typeof theme.name !== "string" || theme.name.trim() === "") {
|
|
14
|
+
issues.push({
|
|
15
|
+
path: "name",
|
|
16
|
+
message: "Theme must have a non-empty `name`."
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (!isHex(theme.primary)) {
|
|
20
|
+
issues.push({
|
|
21
|
+
path: "primary",
|
|
22
|
+
message: `Invalid hex color: ${String(theme.primary)}`
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (!isHex(theme.accent)) {
|
|
26
|
+
issues.push({
|
|
27
|
+
path: "accent",
|
|
28
|
+
message: `Invalid hex color: ${String(theme.accent)}`
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (!isHex(theme.bg?.page)) {
|
|
32
|
+
issues.push({
|
|
33
|
+
path: "bg.page",
|
|
34
|
+
message: `Invalid hex color: ${String(theme.bg?.page)}`
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (!isHex(theme.text?.primary)) {
|
|
38
|
+
issues.push({
|
|
39
|
+
path: "text.primary",
|
|
40
|
+
message: `Invalid hex color: ${String(theme.text?.primary)}`
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (theme.pattern) {
|
|
44
|
+
if (!isFiniteSize(theme.pattern.size)) {
|
|
45
|
+
issues.push({
|
|
46
|
+
path: "pattern.size",
|
|
47
|
+
message: `Tile size must be > 0 (got ${String(theme.pattern.size)}).`
|
|
48
|
+
});
|
|
15
49
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!isHex(theme.text?.primary)) {
|
|
26
|
-
issues.push({
|
|
27
|
-
path: "text.primary",
|
|
28
|
-
message: `Invalid hex color: ${String(theme.text?.primary)}`,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (theme.pattern) {
|
|
32
|
-
if (!isFiniteSize(theme.pattern.size)) {
|
|
33
|
-
issues.push({
|
|
34
|
-
path: "pattern.size",
|
|
35
|
-
message: `Tile size must be > 0 (got ${String(theme.pattern.size)}).`,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (theme.shadow) {
|
|
40
|
-
issues.push(...validateShadow("shadow.sm", theme.shadow.sm));
|
|
41
|
-
issues.push(...validateShadow("shadow.md", theme.shadow.md));
|
|
42
|
-
issues.push(...validateShadow("shadow.lg", theme.shadow.lg));
|
|
43
|
-
}
|
|
44
|
-
issues.push(...validateContrast(theme));
|
|
45
|
-
issues.push(...validateSemanticDistinct(theme));
|
|
46
|
-
return issues;
|
|
50
|
+
}
|
|
51
|
+
if (theme.shadow) {
|
|
52
|
+
issues.push(...validateShadow("shadow.sm", theme.shadow.sm));
|
|
53
|
+
issues.push(...validateShadow("shadow.md", theme.shadow.md));
|
|
54
|
+
issues.push(...validateShadow("shadow.lg", theme.shadow.lg));
|
|
55
|
+
}
|
|
56
|
+
issues.push(...validateContrast(theme));
|
|
57
|
+
issues.push(...validateSemanticDistinct(theme));
|
|
58
|
+
return issues;
|
|
47
59
|
}
|
|
48
60
|
function isHex(value) {
|
|
49
|
-
|
|
61
|
+
return typeof value === "string" && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value.trim());
|
|
50
62
|
}
|
|
51
63
|
function isFiniteSize(n) {
|
|
52
|
-
|
|
64
|
+
return typeof n === "number" && Number.isFinite(n) && n > 0;
|
|
53
65
|
}
|
|
54
66
|
function validateShadow(path, s) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
const out = [];
|
|
68
|
+
if (typeof s.shadowColor !== "string" || s.shadowColor.trim() === "") {
|
|
69
|
+
out.push({
|
|
70
|
+
path: `${path}.shadowColor`,
|
|
71
|
+
message: "shadowColor must be a string."
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (typeof s.shadowOpacity !== "number" || s.shadowOpacity < 0 || s.shadowOpacity > 1) {
|
|
75
|
+
out.push({
|
|
76
|
+
path: `${path}.shadowOpacity`,
|
|
77
|
+
message: `shadowOpacity must be in [0, 1] (got ${s.shadowOpacity}).`
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
66
81
|
}
|
|
82
|
+
|
|
67
83
|
/**
|
|
68
84
|
* WCAG 2.1 contrast validation. Checks the P0 on-color pairs that every consumer
|
|
69
85
|
* relies on (CTA text/bg, focus ring, body text on surfaces). Flags any pair below the
|
|
@@ -71,130 +87,123 @@ function validateShadow(path, s) {
|
|
|
71
87
|
* entries — never throws — so the dev-mode warning stays non-fatal.
|
|
72
88
|
*/
|
|
73
89
|
function validateContrast(theme) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
issues.push({ path: c.label, message });
|
|
150
|
-
}
|
|
90
|
+
const issues = [];
|
|
91
|
+
const checks = [{
|
|
92
|
+
fg: theme.text?.onPrimary,
|
|
93
|
+
bg: theme.primary,
|
|
94
|
+
min: 4.5,
|
|
95
|
+
label: "text.onPrimary on primary (CTA)"
|
|
96
|
+
}, {
|
|
97
|
+
fg: theme.text?.onSecondary,
|
|
98
|
+
bg: theme.secondary,
|
|
99
|
+
min: 4.5,
|
|
100
|
+
label: "text.onSecondary on secondary"
|
|
101
|
+
}, {
|
|
102
|
+
fg: theme.text?.onAccent,
|
|
103
|
+
bg: theme.accent,
|
|
104
|
+
min: 4.5,
|
|
105
|
+
label: "text.onAccent on accent"
|
|
106
|
+
}, {
|
|
107
|
+
fg: theme.border?.focus,
|
|
108
|
+
bg: theme.bg?.page,
|
|
109
|
+
min: 3,
|
|
110
|
+
label: "border.focus on bg.page"
|
|
111
|
+
}, {
|
|
112
|
+
fg: theme.border?.focus,
|
|
113
|
+
bg: theme.bg?.card,
|
|
114
|
+
min: 3,
|
|
115
|
+
label: "border.focus on bg.card"
|
|
116
|
+
}, {
|
|
117
|
+
fg: theme.text?.onDanger,
|
|
118
|
+
bg: theme.danger,
|
|
119
|
+
min: 4.5,
|
|
120
|
+
label: "text.onDanger on danger"
|
|
121
|
+
}, {
|
|
122
|
+
fg: theme.text?.onSuccess,
|
|
123
|
+
bg: theme.success,
|
|
124
|
+
min: 4.5,
|
|
125
|
+
label: "text.onSuccess on success"
|
|
126
|
+
}, {
|
|
127
|
+
fg: theme.text?.accent,
|
|
128
|
+
bg: theme.bg?.card,
|
|
129
|
+
min: 4.5,
|
|
130
|
+
label: "text.accent on bg.card (brand text)"
|
|
131
|
+
}, {
|
|
132
|
+
fg: theme.text?.accent,
|
|
133
|
+
bg: theme.bg?.page,
|
|
134
|
+
min: 4.5,
|
|
135
|
+
label: "text.accent on bg.page (brand text)"
|
|
136
|
+
}, {
|
|
137
|
+
fg: theme.container?.onPrimary,
|
|
138
|
+
bg: theme.container?.primary,
|
|
139
|
+
min: 4.5,
|
|
140
|
+
label: "container.onPrimary on container.primary"
|
|
141
|
+
}, {
|
|
142
|
+
fg: theme.container?.onSuccess,
|
|
143
|
+
bg: theme.container?.success,
|
|
144
|
+
min: 4.5,
|
|
145
|
+
label: "container.onSuccess on container.success"
|
|
146
|
+
}, {
|
|
147
|
+
fg: theme.container?.onDanger,
|
|
148
|
+
bg: theme.container?.danger,
|
|
149
|
+
min: 4.5,
|
|
150
|
+
label: "container.onDanger on container.danger"
|
|
151
|
+
}];
|
|
152
|
+
for (const c of checks) {
|
|
153
|
+
if (!isHex(c.fg) || !isHex(c.bg)) continue;
|
|
154
|
+
const ratio = contrastRatio(c.fg, c.bg);
|
|
155
|
+
if (ratio < c.min) {
|
|
156
|
+
let message = `Contrast ratio ${ratio.toFixed(2)}:1 is below WCAG AA minimum ${c.min}:1 for body/UI text.`;
|
|
157
|
+
if (c.label.includes("onPrimary") && isHex(theme.primary)) {
|
|
158
|
+
const suggested = resolveOnColor(theme.primary);
|
|
159
|
+
message += ` Use resolveOnColor(primary) → ${suggested}.`;
|
|
160
|
+
}
|
|
161
|
+
issues.push({
|
|
162
|
+
path: c.label,
|
|
163
|
+
message
|
|
164
|
+
});
|
|
151
165
|
}
|
|
152
|
-
|
|
166
|
+
}
|
|
167
|
+
return issues;
|
|
153
168
|
}
|
|
169
|
+
|
|
154
170
|
/** Roles that must stay visually distinct for maintainable state semantics. */
|
|
155
171
|
function validateSemanticDistinct(theme) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
const issues = [];
|
|
173
|
+
const pairs = [["bg.disabled vs bg.muted", theme.bg?.disabled, theme.bg?.muted], ["text.disabled vs text.muted", theme.text?.disabled, theme.text?.muted], ["icon.disabled vs icon.secondary", theme.icon?.disabled, theme.icon?.secondary]];
|
|
174
|
+
for (const [label, a, b] of pairs) {
|
|
175
|
+
if (!isHex(a) || !isHex(b)) continue;
|
|
176
|
+
if (a.trim().toLowerCase() === b.trim().toLowerCase()) {
|
|
177
|
+
issues.push({
|
|
178
|
+
path: label,
|
|
179
|
+
message: `Tokens share the same hex (${a}). Keep roles distinct so disabled/muted states stay maintainable.`
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (theme.state) {
|
|
184
|
+
for (const key of ["hover", "press", "focus", "drag"]) {
|
|
185
|
+
const v = theme.state[key];
|
|
186
|
+
if (typeof v !== "number" || v < 0 || v > 1) {
|
|
187
|
+
issues.push({
|
|
188
|
+
path: `state.${key}`,
|
|
189
|
+
message: `State layer opacity must be in [0, 1] (got ${String(v)}).`
|
|
190
|
+
});
|
|
191
|
+
}
|
|
171
192
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
193
|
+
}
|
|
194
|
+
if (theme.material) {
|
|
195
|
+
if (typeof theme.material.opacity === "number" && (theme.material.opacity < 0 || theme.material.opacity > 1)) {
|
|
196
|
+
issues.push({
|
|
197
|
+
path: "material.opacity",
|
|
198
|
+
message: `material.opacity must be in [0, 1] (got ${theme.material.opacity}).`
|
|
199
|
+
});
|
|
182
200
|
}
|
|
183
|
-
if (theme.material) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
message: `material.opacity must be in [0, 1] (got ${theme.material.opacity}).`,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
if (typeof theme.material.blur === "number" &&
|
|
192
|
-
(!Number.isFinite(theme.material.blur) || theme.material.blur < 0)) {
|
|
193
|
-
issues.push({
|
|
194
|
-
path: "material.blur",
|
|
195
|
-
message: `material.blur must be ≥ 0 (got ${theme.material.blur}).`,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
201
|
+
if (typeof theme.material.blur === "number" && (!Number.isFinite(theme.material.blur) || theme.material.blur < 0)) {
|
|
202
|
+
issues.push({
|
|
203
|
+
path: "material.blur",
|
|
204
|
+
message: `material.blur must be ≥ 0 (got ${theme.material.blur}).`
|
|
205
|
+
});
|
|
198
206
|
}
|
|
199
|
-
|
|
207
|
+
}
|
|
208
|
+
return issues;
|
|
200
209
|
}
|
package/dist/tokens/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { motion } from "./motion.js";
|
|
2
|
-
export { duration, easing, spring
|
|
2
|
+
export { duration, easing, spring } from "./motion.js";
|
package/dist/tokens/motion.js
CHANGED
|
@@ -2,24 +2,41 @@
|
|
|
2
2
|
* Motion tokens — durations and curves for consistent animations (reanimated, LayoutAnimation).
|
|
3
3
|
* Single source of the DS "rhythm": enter/exit, press, theme transitions, sheets, skeletons.
|
|
4
4
|
*/
|
|
5
|
+
|
|
5
6
|
export const duration = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
instant: 0,
|
|
8
|
+
fast: 120,
|
|
9
|
+
normal: 200,
|
|
10
|
+
slow: 320,
|
|
11
|
+
slower: 480
|
|
11
12
|
};
|
|
12
13
|
/** Bezier curves (x1,y1,x2,y2) for Easing.bezier / CSS-like. */
|
|
13
14
|
export const easing = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
standard: [0.2, 0, 0, 1],
|
|
16
|
+
decelerate: [0, 0, 0, 1],
|
|
17
|
+
accelerate: [0.3, 0, 1, 1],
|
|
18
|
+
emphasized: [0.2, 0, 0, 1]
|
|
18
19
|
};
|
|
19
20
|
/** Config for reanimated withSpring (spring presets). */
|
|
20
21
|
export const spring = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
default: {
|
|
23
|
+
damping: 20,
|
|
24
|
+
stiffness: 200,
|
|
25
|
+
mass: 1
|
|
26
|
+
},
|
|
27
|
+
gentle: {
|
|
28
|
+
damping: 24,
|
|
29
|
+
stiffness: 120,
|
|
30
|
+
mass: 1
|
|
31
|
+
},
|
|
32
|
+
snappy: {
|
|
33
|
+
damping: 18,
|
|
34
|
+
stiffness: 300,
|
|
35
|
+
mass: 1
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export const motion = {
|
|
39
|
+
duration,
|
|
40
|
+
easing,
|
|
41
|
+
spring
|
|
24
42
|
};
|
|
25
|
-
export const motion = { duration, easing, spring };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Attempt<T> = {
|
|
2
|
+
ok: true;
|
|
3
|
+
value: T;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: unknown;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Runs `task` and reports how it ended instead of throwing. Component handlers use it
|
|
10
|
+
* so they need no `try/finally`: React Compiler skips any component whose body has one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function attempt<T>(task: () => T | Promise<T>): Promise<Attempt<T>>;
|
|
13
|
+
/** The error's own message when it has one, else the fallback shown to the user. */
|
|
14
|
+
export declare function errorMessage(cause: unknown, fallback: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs `task` and reports how it ended instead of throwing. Component handlers use it
|
|
3
|
+
* so they need no `try/finally`: React Compiler skips any component whose body has one.
|
|
4
|
+
*/
|
|
5
|
+
export async function attempt(task) {
|
|
6
|
+
try {
|
|
7
|
+
return {
|
|
8
|
+
ok: true,
|
|
9
|
+
value: await task()
|
|
10
|
+
};
|
|
11
|
+
} catch (error) {
|
|
12
|
+
return {
|
|
13
|
+
ok: false,
|
|
14
|
+
error
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** The error's own message when it has one, else the fallback shown to the user. */
|
|
20
|
+
export function errorMessage(cause, fallback) {
|
|
21
|
+
return cause instanceof Error && cause.message.trim() ? cause.message : fallback;
|
|
22
|
+
}
|