@colixsystems/widget-sdk 0.260.0 → 0.261.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 CHANGED
@@ -85,7 +85,11 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
85
85
 
86
86
  ## Status
87
87
 
88
- `v0.260.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
88
+ `v0.261.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
89
+
90
+ ### What's new in 0.261.0 (contract 1.211.0)
91
+
92
+ **The Builder can preview that bound.** On the web, `<Text>` and `<TextInput>` (and every SDK component built on them) follow a host's `TextScaleProvider`, so the Studio canvas can show a page at the largest phone text size an exported app allows. Nothing changes for a widget: outside the preview the scale is 1×.
89
93
 
90
94
  ### What's new in 0.260.0 (contract 1.211.0)
91
95
 
package/dist/accordion.js CHANGED
@@ -1,7 +1,8 @@
1
1
  // `<Accordion>` / `<AccordionItem>` (web). Binds ./accordion-view.js to
2
2
  // react-native-web; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import { View, Text, Pressable } from "react-native-web";
4
+ import { View, Pressable } from "react-native-web";
5
+ import { Text } from "./text-scale.js";
5
6
  import { makeAccordion } from "./accordion-view.js";
6
7
 
7
8
  export const { Accordion, AccordionItem } = makeAccordion({ View, Text, Pressable });
package/dist/banner.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Banner>` (web). Binds ./banner-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeBanner } from "./banner-view.js";
6
6
 
7
7
  export const Banner = makeBanner(ReactNative);
package/dist/button.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // react-native-web, the CSS gradient and the web `<Spinner>`; see
3
3
  // ./primitives.js for why not the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { Gradient } from "./gradient.js";
7
7
  import { Spinner } from "./loading.js";
8
8
  import { makeButton, BUTTON_VARIANTS } from "./button-view.js";
@@ -2,7 +2,7 @@
2
2
  // `background-position` is what keeps the chosen part of a crop in frame.
3
3
 
4
4
  import React from "react";
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
 
7
7
  // A quote, backslash or newline would end the CSS `url("…")` early.
8
8
  function cssUrl(uri) {
package/dist/card.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Card>` (web). Binds ./card-view.js to react-native-web and the CSS
2
2
  // gradient; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { Gradient } from "./gradient.js";
6
6
  import { Photo } from "./card-photo.js";
7
7
  import { makeCard } from "./card-view.js";
package/dist/chart.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Chart>` (web). Binds ./chart-view.js to react-native-web and the host's
2
2
  // react-native-svg; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import Svg, { G, Path, Line, Circle, Text as SvgText } from "react-native-svg";
6
6
  import { Skeleton } from "./loading.js";
7
7
  import { EmptyState } from "./list.js";
package/dist/checkbox.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Checkbox>` (web). Binds ./checkbox-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeCheckbox } from "./checkbox-view.js";
6
6
 
7
7
  export const Checkbox = makeCheckbox({
package/dist/chip.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // ./primitives.js for why not the bare specifier. Only the web keeps a single
3
3
  // tab stop per single-choice group.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makeChip } from "./chip-view.js";
7
7
 
8
8
  export const { Chip, ChipGroup } = makeChip(ReactNative, { web: true });
@@ -2,7 +2,7 @@
2
2
  // and the web `<Modal>`, `<Button>` and `<Spinner>`; see ./primitives.js for
3
3
  // why not the bare specifier.
4
4
 
5
- import { Text } from "react-native-web";
5
+ import { Text } from "./text-scale.js";
6
6
  import { makeConfirmDialog } from "./confirm-dialog-view.js";
7
7
  import { Modal } from "./modal.js";
8
8
  import { Button } from "./button.js";
@@ -2,7 +2,7 @@
2
2
  // web list, loading, menu and button parts; see ./primitives.js for why not
3
3
  // the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { List, ListRow, ListHeader, EmptyState } from "./list.js";
7
7
  import { Skeleton } from "./loading.js";
8
8
  import { Menu } from "./popover.js";
@@ -2,7 +2,8 @@
2
2
  // and the themed calendar sheet; see ./primitives.js for why not the bare
3
3
  // specifier.
4
4
 
5
- import { View, Text, Pressable, ScrollView, Platform } from "react-native-web";
5
+ import { View, Pressable, ScrollView, Platform } from "react-native-web";
6
+ import { Text } from "./text-scale.js";
6
7
  import { makeDateTimePicker } from "./datetimepicker-view.js";
7
8
  import { makeDateTimeSheet } from "./datetimepicker-sheet.js";
8
9
  import { Overlay } from "./overlay.js";
@@ -2,7 +2,7 @@
2
2
  // ./detail-parts-view.js to react-native-web; see ./primitives.js for why not
3
3
  // the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import Svg, { Circle } from "react-native-svg";
7
7
  import { makeDetailParts } from "./detail-parts-view.js";
8
8
 
@@ -7,7 +7,7 @@
7
7
  // specifier for the rolldown optional-peer-dep reason at the top of
8
8
  // ./primitives.js.
9
9
 
10
- import * as ReactNative from "react-native-web";
10
+ import { ReactNative } from "./text-scale.js";
11
11
  import { makeEmojiPicker } from "./emoji-picker-view.js";
12
12
  import { Overlay } from "./overlay.js";
13
13
  import { TextInput } from "./primitives.js";
@@ -1,7 +1,7 @@
1
1
  // `<FileImage>` (web). Binds ./file-image-view.js to react-native-web and the
2
2
  // web `<Skeleton>`; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { Skeleton } from "./loading.js";
6
6
  import { makeFileImage } from "./file-image-view.js";
7
7
 
@@ -4,7 +4,8 @@
4
4
  // button, which is the whole control on native.
5
5
 
6
6
  import React from "react";
7
- import { View, Text, Pressable, Platform } from "react-native-web";
7
+ import { View, Pressable, Platform } from "react-native-web";
8
+ import { Text } from "./text-scale.js";
8
9
  import { makeFileUpload } from "./file-upload-view.js";
9
10
  import { FilePicker } from "./filepicker.js";
10
11
  import { Button } from "./button.js";
@@ -2,7 +2,7 @@
2
2
  // web `<SearchField>`, `<Select>`, `<Chip>`, `<Button>` and `<Modal>`; see
3
3
  // ./primitives.js for why not the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makeFilterBar } from "./filter-bar-view.js";
7
7
  import { SearchField } from "./search-field.js";
8
8
  import { Select } from "./select.js";
package/dist/form.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // (web). Binds ./form-view.js to the web primitives and the web `<Grid>`; see
3
3
  // ./primitives.js for why not the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makeForm } from "./form-view.js";
7
7
  import { Grid } from "./grid.js";
8
8
 
package/dist/gradient.js CHANGED
@@ -17,7 +17,7 @@
17
17
  // `gradientAngleToVector` from the contract. Keep the two in lockstep.
18
18
 
19
19
  import React from "react";
20
- import * as ReactNative from "react-native-web";
20
+ import { ReactNative } from "./text-scale.js";
21
21
  import { gradientStops } from "./gradient-stops.js";
22
22
 
23
23
  const DEFAULT_ANGLE = 180;
package/dist/grid.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Grid>` (web). Binds ./grid-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeGrid } from "./grid-view.js";
6
6
 
7
7
  export const Grid = makeGrid({ View: ReactNative.View });
package/dist/list.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<List>`, `<ListRow>`, `<ListHeader>`, `<EmptyState>` (web). Binds
2
2
  // ./list-view.js to react-native-web; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { Card } from "./card.js";
6
6
  import { makeList } from "./list-view.js";
7
7
 
package/dist/loading.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Spinner>` and `<Skeleton>` (web). Binds ./loading-view.js to
2
2
  // react-native-web; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeLoading } from "./loading-view.js";
6
6
 
7
7
  export const { Spinner, Skeleton } = makeLoading(ReactNative, { useNativeDriver: false });
@@ -2,7 +2,7 @@
2
2
  // ./markdown-input-view.js to react-native-web's primitives, and to the web
3
3
  // `<RichText>` it renders its preview with.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makeMarkdownInput } from "./markdown-input-view.js";
7
7
  import { RichText } from "./richtext.js";
8
8
  import { Modal } from "./modal.js";
package/dist/modal.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Modal>` (web). Binds ./modal-view.js to react-native-web and the web
2
2
  // `<Overlay>`; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeModal } from "./modal-view.js";
6
6
  import { Overlay } from "./overlay.js";
7
7
 
package/dist/overlay.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // container at `position: fixed`, which is exactly what makes the overlay
9
9
  // escape the widget's clipping ancestors.
10
10
 
11
- import * as ReactNative from "react-native-web";
11
+ import { ReactNative } from "./text-scale.js";
12
12
  import { makeOverlay } from "./overlay-view.js";
13
13
  import { WebModal } from "./web-modal.js";
14
14
 
@@ -1,7 +1,7 @@
1
1
  // `<PeoplePicker>` (web). Binds ./people-picker-view.js to the web `<Select>`
2
2
  // and `<Avatar>`; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makePeoplePicker } from "./people-picker-view.js";
6
6
  import { Select } from "./select.js";
7
7
  import { Avatar } from "./detail-parts.js";
package/dist/popover.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // ./menu-view.js and ./tooltip-view.js to react-native-web and the web
3
3
  // `<Overlay>`; see ./primitives.js for why not the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makePopover } from "./popover-view.js";
7
7
  import { makeMenu } from "./menu-view.js";
8
8
  import { makeTooltip } from "./tooltip-view.js";
@@ -39,7 +39,7 @@
39
39
  // installed dep (no stub), and runtime property access sidesteps the
40
40
  // static re-export tracing. Behaviour is identical to the old
41
41
  // `react-native` alias path on the web.
42
- import * as ReactNative from "react-native-web";
42
+ import { ReactNative } from "./text-scale.js";
43
43
  import { makeTextInput } from "./text-input-view.js";
44
44
 
45
45
  export const Text = ReactNative.Text;
@@ -1,7 +1,7 @@
1
1
  // `<RadioGroup>` (web). Binds ./radio-group-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeRadioGroup } from "./radio-group-view.js";
6
6
 
7
7
  export const RadioGroup = makeRadioGroup({
package/dist/richtext.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // specifier for the rolldown optional-peer-dep reason spelled out at the top of
6
6
  // ./primitives.js.
7
7
 
8
- import * as ReactNative from "react-native-web";
8
+ import { ReactNative } from "./text-scale.js";
9
9
  import { makeRichText } from "./richtext-view.js";
10
10
 
11
11
  export const RichText = makeRichText(ReactNative);
@@ -1,7 +1,7 @@
1
1
  // `<SearchField>` (web). Binds ./search-field-view.js to react-native-web and
2
2
  // the web `<TextField>`; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeSearchField } from "./search-field-view.js";
6
6
  import { TextField } from "./text-field.js";
7
7
 
package/dist/select.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // `<Overlay>`, `<Button>`, `<Chip>`, `<SearchField>` and `<Spinner>`; see
3
3
  // ./primitives.js for why not the bare specifier.
4
4
 
5
- import * as ReactNative from "react-native-web";
5
+ import { ReactNative } from "./text-scale.js";
6
6
  import { makeSelect } from "./select-view.js";
7
7
  import { Overlay } from "./overlay.js";
8
8
  import { Button } from "./button.js";
package/dist/sortable.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<SortableList>` and `<Board>` (web). Bind ./sortable-view.js to
2
2
  // react-native-web; see ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { List, ListRow } from "./list.js";
6
6
  import { Card } from "./card.js";
7
7
  import { Menu } from "./popover.js";
package/dist/switch.js CHANGED
@@ -10,7 +10,7 @@
10
10
  // - it forwards only a label to its `<input>`, dropping the other ARIA props.
11
11
 
12
12
  import React from "react";
13
- import * as ReactNative from "react-native-web";
13
+ import { ReactNative } from "./text-scale.js";
14
14
  import { makeSwitch } from "./switch-view.js";
15
15
  import { DISABLED_OPACITY } from "./form-control-tokens.js";
16
16
  import { shareRef } from "./form-control-logic.js";
package/dist/tabs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // `<Tabs>` (web). Binds ./tabs-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeTabs } from "./tabs-view.js";
6
6
 
7
7
  export const Tabs = makeTabs(ReactNative);
@@ -1,7 +1,7 @@
1
1
  // `<TextField>` (web). Binds ./text-field-view.js to react-native-web; see
2
2
  // ./primitives.js for why not the bare specifier.
3
3
 
4
- import * as ReactNative from "react-native-web";
4
+ import { ReactNative } from "./text-scale.js";
5
5
  import { makeTextField } from "./text-field-view.js";
6
6
  import { TextInput } from "./primitives.js";
7
7
 
@@ -0,0 +1,60 @@
1
+ // sc-12791: device font-scale arithmetic, React-free so node tests can load it.
2
+
3
+ // Unstyled text renders at 14px in both React Native and react-native-web.
4
+ export const DEFAULT_FONT_SIZE = 14;
5
+
6
+ // `em` is relative to an already-scaled parent, so it is left alone.
7
+ const ABSOLUTE_LENGTH = /\d(?:px|rem)$/;
8
+
9
+ function flattenStyle(style, into = {}) {
10
+ if (Array.isArray(style)) {
11
+ for (const entry of style) flattenStyle(entry, into);
12
+ } else if (style && typeof style === "object") {
13
+ Object.assign(into, style);
14
+ }
15
+ return into;
16
+ }
17
+
18
+ function scaleLength(value, factor) {
19
+ if (typeof value === "number") return value * factor;
20
+ if (typeof value === "string" && ABSOLUTE_LENGTH.test(value.trim())) {
21
+ return `calc(${value.trim()} * ${factor})`;
22
+ }
23
+ return undefined;
24
+ }
25
+
26
+ /**
27
+ * The multiplier one text element gets under a preview scale, honouring the
28
+ * same per-element props React Native does.
29
+ *
30
+ * @param {number} scale The previewed device font scale.
31
+ * @param {{ allowFontScaling?: boolean, maxFontSizeMultiplier?: number }} props
32
+ * @returns {number}
33
+ */
34
+ export function textScaleFactor(scale, props) {
35
+ if (!(scale > 1) || props?.allowFontScaling === false) return 1;
36
+ const cap = props?.maxFontSizeMultiplier;
37
+ return typeof cap === "number" && cap >= 1 ? Math.min(scale, cap) : scale;
38
+ }
39
+
40
+ /**
41
+ * `style` with its font size and line height multiplied by `factor`.
42
+ *
43
+ * @param {any} style A React Native style (object, array, or falsy).
44
+ * @param {number} factor
45
+ * @param {{ inheritsSize?: boolean }} [options] `inheritsSize` marks text
46
+ * nested in already-scaled text: without its own size it inherits the
47
+ * parent's, which must not be multiplied twice.
48
+ * @returns {any} The original style when nothing changes.
49
+ */
50
+ export function scaleTextStyle(style, factor, { inheritsSize = false } = {}) {
51
+ if (factor === 1) return style;
52
+ const flat = flattenStyle(style);
53
+ const override = {};
54
+ const fontSize = flat.fontSize ?? (inheritsSize ? undefined : DEFAULT_FONT_SIZE);
55
+ const scaledFontSize = scaleLength(fontSize, factor);
56
+ if (scaledFontSize !== undefined) override.fontSize = scaledFontSize;
57
+ const scaledLineHeight = scaleLength(flat.lineHeight, factor);
58
+ if (scaledLineHeight !== undefined) override.lineHeight = scaledLineHeight;
59
+ return Object.keys(override).length > 0 ? [style, override] : style;
60
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Previews a device font scale for every SDK `Text` / `TextInput` below it, as
3
+ * a phone's text-size setting would: font sizes and line heights grow, layout
4
+ * boxes do not. Web hosts only — native text already follows the device.
5
+ */
6
+ export function TextScaleProvider(props: { scale?: number; children?: unknown }): unknown;
7
+
8
+ /** react-native-web's `Text`, following the nearest `TextScaleProvider`. */
9
+ export const Text: unknown;
10
+ /** react-native-web's `TextInput`, following the nearest `TextScaleProvider`. */
11
+ export const TextInput: unknown;
@@ -0,0 +1,40 @@
1
+ // Web twin of ./bounded-text.native.js: previews a device text-size setting.
2
+ // Every SDK web module takes react-native-web from here (text-scale.test.js).
3
+ import React from "react";
4
+ import * as ReactNativeWeb from "react-native-web";
5
+ import { scaleTextStyle, textScaleFactor } from "./text-scale-style.js";
6
+
7
+ const TextScaleContext = React.createContext(1);
8
+ const ScaledTextAncestorContext = React.createContext(false);
9
+
10
+ /**
11
+ * Previews a device font scale for every SDK Text / TextInput below it.
12
+ * Web hosts only: native text already follows the device setting.
13
+ *
14
+ * @param {{ scale?: number, children?: React.ReactNode }} props
15
+ */
16
+ export function TextScaleProvider({ scale = 1, children }) {
17
+ const value = Number.isFinite(scale) && scale > 0 ? scale : 1;
18
+ return React.createElement(TextScaleContext.Provider, { value }, children);
19
+ }
20
+
21
+ function withTextScale(Base, { displayName, nests = false }) {
22
+ const Scaled = React.forwardRef(function ScaledText(props, ref) {
23
+ const scale = React.useContext(TextScaleContext);
24
+ const insideScaledText = React.useContext(ScaledTextAncestorContext);
25
+ if (scale === 1) return React.createElement(Base, { ...props, ref });
26
+ const factor = textScaleFactor(scale, props);
27
+ const style = scaleTextStyle(props.style, factor, { inheritsSize: insideScaledText });
28
+ const element = React.createElement(Base, { ...props, ref, style });
29
+ // Children inherit this size even when this element opted out of scaling.
30
+ if (!nests || insideScaledText) return element;
31
+ return React.createElement(ScaledTextAncestorContext.Provider, { value: true }, element);
32
+ });
33
+ Scaled.displayName = displayName;
34
+ return Scaled;
35
+ }
36
+
37
+ export const Text = withTextScale(ReactNativeWeb.Text, { displayName: "Text", nests: true });
38
+ export const TextInput = withTextScale(ReactNativeWeb.TextInput, { displayName: "TextInput" });
39
+ // Spread, not re-exported; see ./primitives.js for why.
40
+ export const ReactNative = { ...ReactNativeWeb, Text, TextInput };
package/dist/video.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // thumbnail; Safari draws nothing before playback without the fragment.
10
10
 
11
11
  import React from "react";
12
- import * as ReactNative from "react-native-web";
12
+ import { ReactNative } from "./text-scale.js";
13
13
 
14
14
  const FIRST_FRAME = "#t=0.001";
15
15
  const FITS = { contain: "contain", cover: "cover" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.260.0",
3
+ "version": "0.261.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "homepage": "https://github.com/Colix-AB/AppStudio",
6
6
  "type": "module",
@@ -29,6 +29,11 @@
29
29
  "import": "./dist/host.js",
30
30
  "default": "./dist/host.js"
31
31
  },
32
+ "./text-scale": {
33
+ "types": "./dist/text-scale.d.ts",
34
+ "import": "./dist/text-scale.js",
35
+ "default": "./dist/text-scale.js"
36
+ },
32
37
  "./contract": {
33
38
  "types": "./dist/index.d.ts",
34
39
  "require": "./dist/contract.cjs",