@colixsystems/widget-sdk 0.201.0 → 0.204.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/src/contract.js CHANGED
@@ -692,6 +692,18 @@ const THEME_COMPONENTS = Object.freeze({
692
692
  "appstudio.user-management": TABS_FIELDS,
693
693
  }),
694
694
  }),
695
+ // Loading placeholders: `<Skeleton>` reads this scope directly, so it names
696
+ // the SDK component it styles and binds no widget field. `<Spinner>` is not
697
+ // here: it wears `colors.loader`, the app's one spinner colour.
698
+ loading: Object.freeze({
699
+ label: "Loading",
700
+ sdkComponents: Object.freeze(["Skeleton"]),
701
+ tokens: Object.freeze({
702
+ skeletonColor: Object.freeze({ type: "color", uiDefault: "colors.surfaceMuted" }),
703
+ skeletonRadius: Object.freeze({ type: "size", min: 0, max: 24, uiDefault: "radii.sm" }),
704
+ }),
705
+ targets: Object.freeze({}),
706
+ }),
695
707
  });
696
708
 
697
709
  // sc-4505 — the value types a widget event payload field may declare. Narrower
@@ -717,7 +729,8 @@ const HOOKS = [
717
729
  "page: a container painting its own background re-derives them for its " +
718
730
  "subtree. Read them and your text is readable wherever the widget lands; " +
719
731
  "there is nothing to opt into. `loader` is that surface's spinner colour " +
720
- "(sc-6095) — paint your own loading state with it rather than a literal grey.",
732
+ "(sc-6095) — `<Spinner>` wears it by default; paint your own loading " +
733
+ "state with it rather than a literal grey.",
721
734
  spacing: "{ xs, sm, md, lg, xl }",
722
735
  spacingScale:
723
736
  "number — the app-wide spacing multiplier (REQ-THEME-LOOK, default 1). " +
@@ -1450,7 +1463,7 @@ const HOOKS = [
1450
1463
  message: "string | null",
1451
1464
  signerName: "string | null",
1452
1465
  signedAt: "string | null",
1453
- verdict: "{ valid, checks, content_status, ... } | null",
1466
+ verdict: "{ valid, checks, content_status, signed_by_others_since, seal, ... } | null",
1454
1467
  loading: "boolean",
1455
1468
  error: "PermissionError | null // { code, message, retryable }",
1456
1469
  initiate: "() => Promise<{ signature_id, qr, auto_start_token, status }>",
@@ -2608,7 +2621,7 @@ const PRIMITIVES = [
2608
2621
  {
2609
2622
  name: "ActivityIndicator",
2610
2623
  description:
2611
- "Loading spinner. See https://reactnative.dev/docs/activityindicator.",
2624
+ "The raw platform spinner. Do NOT use it for a loading state — draw `<Spinner>` (below), which wears the app's spinner colour and follows the reduced-motion setting. See https://reactnative.dev/docs/activityindicator.",
2612
2625
  rnComponent: "ActivityIndicator",
2613
2626
  docsUrl: "https://reactnative.dev/docs/activityindicator",
2614
2627
  },
@@ -2804,6 +2817,20 @@ const PRIMITIVES = [
2804
2817
  rnComponent: null,
2805
2818
  docsUrl: null,
2806
2819
  },
2820
+ {
2821
+ name: "Accordion",
2822
+ description:
2823
+ 'Themed collapsible sections. `<Accordion defaultValue="shipping"><AccordionItem value="shipping" title="Shipping" subtitle="2-4 days">…</AccordionItem><AccordionItem value="returns" title="Returns">…</AccordionItem></Accordion>`. THE way to build a section that expands and collapses (an FAQ, a settings group, a record\'s details, a group whose members show on demand): the surface takes the app\'s card look (Theme Settings > Cards: background, border, corner radius) and the headers and dividers its list look (Theme Settings > Lists: row padding, row height, divider), so every collapsible section in the app matches. Each header has a chevron, a 44px touch target, works from the keyboard and tells assistive technology whether its section is open, so never hand-roll a collapsible from `Pressable` + a chevron + a `useState`. By default one section is open at a time and pressing the open one closes it; `multiple` lets several stay open. Props: `multiple`, `value` (the open key, or an array of keys when `multiple`; makes it controlled), `defaultValue` (the same shape, uncontrolled), `onChange(next)` (the open key(s) after a press, in the same shape), `accessibilityLabel`, `style`, `testID`. Its children are `<AccordionItem>`s.',
2824
+ rnComponent: null,
2825
+ docsUrl: null,
2826
+ },
2827
+ {
2828
+ name: "AccordionItem",
2829
+ description:
2830
+ 'One section of an `<Accordion>`. `<AccordionItem value={group.id} title={group.name} subtitle={`${group.count} members`} trailing={<Button title="Delete" variant="danger" onPress={remove} />}>…</AccordionItem>`. Props: `value` (the key `value` / `defaultValue` / `onChange` name it by — give one whenever you name sections; an item may sit inside your own component or a fragment), `title`, `subtitle` (the subtitle / caption text tiers), `trailing` (a node beside the header and OUTSIDE its toggle, so a button there runs its own action without opening the section), `disabled`, `divider` (default true; the surface edge hides the rule under the last section), `children` (the body: it mounts only while the section is open, so fetch its data inside it; an `<AccordionItem>` placed in a body is its own section, never part of the outer accordion), `accessibilityLabel` (defaults to the string `title` and `subtitle`), `style`, `testID` (also tags the header `<testID>-header` and the open body `<testID>-panel`). On its own, outside an `<Accordion>`, it is an accordion of one.',
2831
+ rnComponent: null,
2832
+ docsUrl: null,
2833
+ },
2807
2834
  {
2808
2835
  name: "Tabs",
2809
2836
  description:
@@ -2832,6 +2859,20 @@ const PRIMITIVES = [
2832
2859
  rnComponent: null,
2833
2860
  docsUrl: null,
2834
2861
  },
2862
+ {
2863
+ name: "Spinner",
2864
+ description:
2865
+ 'Themed loading spinner. `<Spinner />`, `<Spinner size="lg" label="Loading orders" />` — THE way to show that something is in progress when you cannot know its shape: a button\'s pending action, a save, a refresh, "load more", a full-widget first load with no layout yet. `size` is "sm" | "md" (default) | "lg" or a number; `label` draws a caption under the ring and is its accessibility label (unset, the app\'s own "Loading…"). Its colour is the app\'s one spinner colour (`theme.colors.loader`, set under Design → Loading Indicator and re-derived for whatever surface the widget sits on), so pass `color` ONLY inside a control you fill yourself, e.g. `color={theme.colors.onPrimary}` inside a primary button. It stops turning when the device asks for reduced motion and is a labelled element in the busy state. Never use `ActivityIndicator` or a hand-drawn spinner.',
2866
+ rnComponent: null,
2867
+ docsUrl: null,
2868
+ },
2869
+ {
2870
+ name: "Skeleton",
2871
+ description:
2872
+ 'Themed loading placeholder. `<Skeleton shape="text" width="60%" />`, `<Skeleton shape="text" lines={3} />`, `<Skeleton shape="block" height={160} />`, `<Skeleton shape="circle" size={40} />`, and the list preset `<Skeleton shape="listRow" count={4} />` (pass `leading={false}` for rows with no avatar or icon). THE loading state for content whose layout you already know — a list, a card, a profile, an article: draw the shape of what is coming so nothing jumps when it arrives. To mirror a custom layout, wrap bones in one group and lay them out yourself: `<Skeleton style={{ flexDirection: "row", gap: 12 }}><Skeleton shape="circle" /><Skeleton shape="text" lines={2} style={{ flex: 1 }} /></Skeleton>` — the outermost Skeleton is the ONE loading region (a `status` region with `aria-busy` on the web, one labelled accessible element in the busy state on native) and every bone inside is hidden from assistive technology. Its colour and corner radius come from the theme (Design → Components → Loading); `color` and `radius` override one skeleton. The outermost Skeleton pulses as a whole, and stops under reduced motion. Never hand-build placeholder bars from `View`.',
2873
+ rnComponent: null,
2874
+ docsUrl: null,
2875
+ },
2835
2876
  ];
2836
2877
 
2837
2878
  const CATEGORIES = [
@@ -5318,7 +5359,14 @@ const CONTRACT = deepFreeze({
5318
5359
  // `usePageBadge(null)` now means "not known yet" and keeps the current
5319
5360
  // badge; `undefined` still clears it. Linter rules `badge-counter-export-missing`
5320
5361
  // (error) and `badge-counter-undeclared` (warning).
5321
- version: "1.160.0",
5362
+ // 1.161.0: additive (sc-10930) — `Accordion` / `AccordionItem`, themed
5363
+ // collapsible sections drawn from the `card` and `list` scopes: single
5364
+ // or multiple open, controlled or uncontrolled, `aria-expanded` headers.
5365
+ // 1.163.0: additive (sc-10928) — the `Spinner` and `Skeleton` primitives.
5366
+ // `Spinner` wears `colors.loader`; `Skeleton` reads the new `loading`
5367
+ // component scope (colour, radius). A scope may now name `sdkComponents`
5368
+ // and bind no widget field. Both stop under reduced motion.
5369
+ version: "1.163.0",
5322
5370
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
5323
5371
  hooks: HOOKS,
5324
5372
  primitives: PRIMITIVES,