@laconius/ui 0.1.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.
Files changed (85) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +22 -0
  3. package/lib/module/button.js +76 -0
  4. package/lib/module/button.js.map +1 -0
  5. package/lib/module/config.js +33 -0
  6. package/lib/module/config.js.map +1 -0
  7. package/lib/module/feedback.js +81 -0
  8. package/lib/module/feedback.js.map +1 -0
  9. package/lib/module/hooks.js +107 -0
  10. package/lib/module/hooks.js.map +1 -0
  11. package/lib/module/index.js +18 -0
  12. package/lib/module/index.js.map +1 -0
  13. package/lib/module/kratos.js +130 -0
  14. package/lib/module/kratos.js.map +1 -0
  15. package/lib/module/media.js +61 -0
  16. package/lib/module/media.js.map +1 -0
  17. package/lib/module/package.json +1 -0
  18. package/lib/module/price.js +34 -0
  19. package/lib/module/price.js.map +1 -0
  20. package/lib/module/quantity-stepper.js +60 -0
  21. package/lib/module/quantity-stepper.js.map +1 -0
  22. package/lib/module/store.js +25 -0
  23. package/lib/module/store.js.map +1 -0
  24. package/lib/module/text.js +55 -0
  25. package/lib/module/text.js.map +1 -0
  26. package/lib/module/theme.js +40 -0
  27. package/lib/module/theme.js.map +1 -0
  28. package/lib/module/translations.js +15 -0
  29. package/lib/module/translations.js.map +1 -0
  30. package/lib/module/use-gallery.js +22 -0
  31. package/lib/module/use-gallery.js.map +1 -0
  32. package/lib/module/use-product-card.js +36 -0
  33. package/lib/module/use-product-card.js.map +1 -0
  34. package/lib/module/use-quantity-stepper.js +20 -0
  35. package/lib/module/use-quantity-stepper.js.map +1 -0
  36. package/lib/typescript/package.json +1 -0
  37. package/lib/typescript/src/button.d.ts +18 -0
  38. package/lib/typescript/src/button.d.ts.map +1 -0
  39. package/lib/typescript/src/config.d.ts +40 -0
  40. package/lib/typescript/src/config.d.ts.map +1 -0
  41. package/lib/typescript/src/feedback.d.ts +24 -0
  42. package/lib/typescript/src/feedback.d.ts.map +1 -0
  43. package/lib/typescript/src/hooks.d.ts +31 -0
  44. package/lib/typescript/src/hooks.d.ts.map +1 -0
  45. package/lib/typescript/src/index.d.ts +16 -0
  46. package/lib/typescript/src/index.d.ts.map +1 -0
  47. package/lib/typescript/src/kratos.d.ts +8 -0
  48. package/lib/typescript/src/kratos.d.ts.map +1 -0
  49. package/lib/typescript/src/media.d.ts +37 -0
  50. package/lib/typescript/src/media.d.ts.map +1 -0
  51. package/lib/typescript/src/price.d.ts +15 -0
  52. package/lib/typescript/src/price.d.ts.map +1 -0
  53. package/lib/typescript/src/quantity-stepper.d.ts +13 -0
  54. package/lib/typescript/src/quantity-stepper.d.ts.map +1 -0
  55. package/lib/typescript/src/store.d.ts +27 -0
  56. package/lib/typescript/src/store.d.ts.map +1 -0
  57. package/lib/typescript/src/text.d.ts +15 -0
  58. package/lib/typescript/src/text.d.ts.map +1 -0
  59. package/lib/typescript/src/theme.d.ts +71 -0
  60. package/lib/typescript/src/theme.d.ts.map +1 -0
  61. package/lib/typescript/src/translations.d.ts +13 -0
  62. package/lib/typescript/src/translations.d.ts.map +1 -0
  63. package/lib/typescript/src/use-gallery.d.ts +13 -0
  64. package/lib/typescript/src/use-gallery.d.ts.map +1 -0
  65. package/lib/typescript/src/use-product-card.d.ts +24 -0
  66. package/lib/typescript/src/use-product-card.d.ts.map +1 -0
  67. package/lib/typescript/src/use-quantity-stepper.d.ts +18 -0
  68. package/lib/typescript/src/use-quantity-stepper.d.ts.map +1 -0
  69. package/package.json +73 -0
  70. package/src/button.tsx +95 -0
  71. package/src/config.ts +53 -0
  72. package/src/feedback.tsx +95 -0
  73. package/src/hooks.ts +130 -0
  74. package/src/index.ts +62 -0
  75. package/src/kratos.ts +86 -0
  76. package/src/media.tsx +96 -0
  77. package/src/price.tsx +30 -0
  78. package/src/quantity-stepper.tsx +70 -0
  79. package/src/store.ts +35 -0
  80. package/src/text.tsx +49 -0
  81. package/src/theme.ts +90 -0
  82. package/src/translations.ts +12 -0
  83. package/src/use-gallery.ts +35 -0
  84. package/src/use-product-card.ts +47 -0
  85. package/src/use-quantity-stepper.ts +35 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getMediaBaseUrl","resolveMediaCandidates","useLaconiusConfig","Image","useMemo","useTheme","jsx","_jsx","useMedia","media","options","config","role","maxFormat","sources","baseUrl","formats","ui","roles","altText","Media","mediaRole","aspectRatio","decorative","style","rest","theme","ratio","source","contentFit","accessible","accessibilityRole","undefined","accessibilityLabel","accessibilityElementsHidden","importantForAccessibility"],"sourceRoot":"../../src","sources":["media.tsx"],"mappings":";;AAAA,SACEA,eAAe,EACfC,sBAAsB,EACtBC,iBAAiB,QAGZ,gBAAgB;AACvB,SAASC,KAAK,QAAyB,YAAY;AACnD,SAASC,OAAO,QAAQ,OAAO;AAG/B,SAASC,QAAQ,QAAQ,YAAS;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAgBnC;AACA;AACA;AACA;AACA,OAAO,SAASC,QAAQA,CACtBC,KAAqB,EACrBC,OAAwB,GAAG,CAAC,CAAC,EACb;EAChB,MAAMC,MAAM,GAAGT,iBAAiB,CAAC,CAAC;EAClC,MAAM;IAAEU,IAAI;IAAEC;EAAU,CAAC,GAAGH,OAAO;EACnC,OAAON,OAAO,CACZ,OAAO;IACLU,OAAO,EAAEb,sBAAsB,CAACQ,KAAK,EAAE;MACrCM,OAAO,EAAEf,eAAe,CAACW,MAAM,CAAC;MAChCC,IAAI;MACJC,SAAS;MACTG,OAAO,EAAEL,MAAM,CAACM,EAAE,EAAER,KAAK,EAAEO,OAAO;MAClCE,KAAK,EAAEP,MAAM,CAACM,EAAE,EAAER,KAAK,EAAES;IAC3B,CAAC,CAAC;IACFC,OAAO,EAAGV,KAAK,EAAuCU;EACxD,CAAC,CAAC,EACF,CAACR,MAAM,EAAEF,KAAK,EAAEG,IAAI,EAAEC,SAAS,CACjC,CAAC;AACH;AAkBA,OAAO,SAASO,KAAKA,CAAC;EACpBX,KAAK;EACLY,SAAS;EACTR,SAAS;EACTS,WAAW;EACXC,UAAU,GAAG,KAAK;EAClBC,KAAK;EACL,GAAGC;AACO,CAAC,EAAE;EACb,MAAMC,KAAK,GAAGrB,QAAQ,CAAC,CAAC;EACxB,MAAM;IAAES,OAAO;IAAEK;EAAQ,CAAC,GAAGX,QAAQ,CAACC,KAAK,EAAE;IAAEG,IAAI,EAAES,SAAS;IAAER;EAAU,CAAC,CAAC;EAC5E,MAAMc,KAAK,GACT,OAAOL,WAAW,KAAK,QAAQ,GAAGI,KAAK,CAACjB,KAAK,CAACa,WAAW,CAACA,WAAW,CAAC,GAAGA,WAAW;EAEtF,oBACEf,IAAA,CAACJ,KAAK;IACJyB,MAAM,EAAEd,OAAQ;IAChBe,UAAU,EAAC,SAAS;IACpBC,UAAU,EAAE,CAACP,UAAW;IACxBQ,iBAAiB,EAAER,UAAU,GAAGS,SAAS,GAAG,OAAQ;IACpDC,kBAAkB,EAAEV,UAAU,GAAGS,SAAS,GAAGb,OAAQ;IACrDe,2BAA2B,EAAEX,UAAW;IACxCY,yBAAyB,EAAEZ,UAAU,GAAG,qBAAqB,GAAG,MAAO;IACvEC,KAAK,EAAE,CAACG,KAAK,KAAKK,SAAS,GAAG,IAAI,GAAG;MAAEV,WAAW,EAAEK;IAAM,CAAC,EAAEH,KAAK,CAAE;IAAA,GAChEC;EAAI,CACT,CAAC;AAEN","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ import { useSiteContext } from '@laconius/core';
4
+ import { Text } from "./text.js";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ /**
7
+ * OCC's `formattedValue` arrives in the request's language and currency, so it follows a
8
+ * language switch on its own. `Intl` is the fallback for the endpoints that omit it — Hermes
9
+ * ships it, so there is no dependency here.
10
+ */
11
+ export function formatPrice(price, locale) {
12
+ if (!price) return undefined;
13
+ if (price.formattedValue) return price.formattedValue;
14
+ if (price.value === undefined) return undefined;
15
+ if (!price.currencyIso) return String(price.value);
16
+ return new Intl.NumberFormat(locale, {
17
+ style: 'currency',
18
+ currency: price.currencyIso
19
+ }).format(price.value);
20
+ }
21
+ export function Price({
22
+ price,
23
+ fallback = '',
24
+ ...rest
25
+ }) {
26
+ const {
27
+ language
28
+ } = useSiteContext();
29
+ return /*#__PURE__*/_jsx(Text, {
30
+ ...rest,
31
+ children: formatPrice(price, language ?? 'en') ?? fallback
32
+ });
33
+ }
34
+ //# sourceMappingURL=price.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useSiteContext","Text","jsx","_jsx","formatPrice","price","locale","undefined","formattedValue","value","currencyIso","String","Intl","NumberFormat","style","currency","format","Price","fallback","rest","language","children"],"sourceRoot":"../../src","sources":["price.tsx"],"mappings":";;AAAA,SAASA,cAAc,QAAkC,gBAAgB;AAEzE,SAASC,IAAI,QAAwB,WAAQ;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAQ9C;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CAACC,KAA6B,EAAEC,MAAc,EAAsB;EAC7F,IAAI,CAACD,KAAK,EAAE,OAAOE,SAAS;EAC5B,IAAIF,KAAK,CAACG,cAAc,EAAE,OAAOH,KAAK,CAACG,cAAc;EACrD,IAAIH,KAAK,CAACI,KAAK,KAAKF,SAAS,EAAE,OAAOA,SAAS;EAC/C,IAAI,CAACF,KAAK,CAACK,WAAW,EAAE,OAAOC,MAAM,CAACN,KAAK,CAACI,KAAK,CAAC;EAClD,OAAO,IAAIG,IAAI,CAACC,YAAY,CAACP,MAAM,EAAE;IACnCQ,KAAK,EAAE,UAAU;IACjBC,QAAQ,EAAEV,KAAK,CAACK;EAClB,CAAC,CAAC,CAACM,MAAM,CAACX,KAAK,CAACI,KAAK,CAAC;AACxB;AAEA,OAAO,SAASQ,KAAKA,CAAC;EAAEZ,KAAK;EAAEa,QAAQ,GAAG,EAAE;EAAE,GAAGC;AAAiB,CAAC,EAAE;EACnE,MAAM;IAAEC;EAAS,CAAC,GAAGpB,cAAc,CAAC,CAAC;EACrC,oBAAOG,IAAA,CAACF,IAAI;IAAA,GAAKkB,IAAI;IAAAE,QAAA,EAAGjB,WAAW,CAACC,KAAK,EAAEe,QAAQ,IAAI,IAAI,CAAC,IAAIF;EAAQ,CAAO,CAAC;AAClF","ignoreList":[]}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ import { useTranslation } from '@laconius/core';
4
+ import { StyleSheet, View } from 'react-native';
5
+ import { Button } from "./button.js";
6
+ import { useStyles, useUiComponent } from "./hooks.js";
7
+ import { useQuantityStepper } from "./use-quantity-stepper.js";
8
+ import { Text } from "./text.js";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ const createStyles = theme => StyleSheet.create({
11
+ root: {
12
+ flexDirection: 'row',
13
+ alignItems: 'center',
14
+ gap: theme.spacing.sm,
15
+ alignSelf: 'flex-start'
16
+ },
17
+ button: {
18
+ paddingHorizontal: theme.spacing.md,
19
+ minWidth: 44
20
+ },
21
+ value: {
22
+ minWidth: 32,
23
+ textAlign: 'center'
24
+ }
25
+ });
26
+ export function QuantityStepper({
27
+ disabled = false,
28
+ style,
29
+ styles: parts,
30
+ ...options
31
+ }) {
32
+ const t = useTranslation();
33
+ const styles = useStyles(createStyles);
34
+ const Label = useUiComponent('Text', Text);
35
+ const Step = useUiComponent('Button', Button);
36
+ const stepper = useQuantityStepper(options);
37
+ return /*#__PURE__*/_jsxs(View, {
38
+ style: [styles.root, parts?.container, style],
39
+ children: [/*#__PURE__*/_jsx(Step, {
40
+ variant: "secondary",
41
+ title: "\u2212",
42
+ accessibilityLabel: t('ui.quantity.decrease'),
43
+ disabled: disabled || !stepper.canDecrement,
44
+ onPress: stepper.decrement,
45
+ style: [styles.button, parts?.button]
46
+ }), /*#__PURE__*/_jsx(Label, {
47
+ accessibilityLabel: `${t('ui.quantity.label')} ${stepper.value}`,
48
+ style: [styles.value, parts?.value],
49
+ children: stepper.value
50
+ }), /*#__PURE__*/_jsx(Step, {
51
+ variant: "secondary",
52
+ title: "+",
53
+ accessibilityLabel: t('ui.quantity.increase'),
54
+ disabled: disabled || !stepper.canIncrement,
55
+ onPress: stepper.increment,
56
+ style: [styles.button, parts?.button]
57
+ })]
58
+ });
59
+ }
60
+ //# sourceMappingURL=quantity-stepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useTranslation","StyleSheet","View","Button","useStyles","useUiComponent","useQuantityStepper","Text","jsx","_jsx","jsxs","_jsxs","createStyles","theme","create","root","flexDirection","alignItems","gap","spacing","sm","alignSelf","button","paddingHorizontal","md","minWidth","value","textAlign","QuantityStepper","disabled","style","styles","parts","options","t","Label","Step","stepper","container","children","variant","title","accessibilityLabel","canDecrement","onPress","decrement","canIncrement","increment"],"sourceRoot":"../../src","sources":["quantity-stepper.tsx"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,gBAAgB;AAC/C,SAASC,UAAU,EAAEC,IAAI,QAAwD,cAAc;AAE/F,SAASC,MAAM,QAAQ,aAAU;AACjC,SAASC,SAAS,EAAEC,cAAc,QAAQ,YAAS;AACnD,SAASC,kBAAkB,QAAqC,2BAAwB;AACxF,SAASC,IAAI,QAAQ,WAAQ;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAa9B,MAAMC,YAAY,GAAIC,KAAY,IAChCZ,UAAU,CAACa,MAAM,CAAC;EAChBC,IAAI,EAAE;IACJC,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAEL,KAAK,CAACM,OAAO,CAACC,EAAE;IACrBC,SAAS,EAAE;EACb,CAAC;EACDC,MAAM,EAAE;IAAEC,iBAAiB,EAAEV,KAAK,CAACM,OAAO,CAACK,EAAE;IAAEC,QAAQ,EAAE;EAAG,CAAC;EAC7DC,KAAK,EAAE;IAAED,QAAQ,EAAE,EAAE;IAAEE,SAAS,EAAE;EAAS;AAC7C,CAAC,CAAC;AAEJ,OAAO,SAASC,eAAeA,CAAC;EAC9BC,QAAQ,GAAG,KAAK;EAChBC,KAAK;EACLC,MAAM,EAAEC,KAAK;EACb,GAAGC;AACiB,CAAC,EAAE;EACvB,MAAMC,CAAC,GAAGlC,cAAc,CAAC,CAAC;EAC1B,MAAM+B,MAAM,GAAG3B,SAAS,CAACQ,YAAY,CAAC;EACtC,MAAMuB,KAAK,GAAG9B,cAAc,CAAC,MAAM,EAAEE,IAAI,CAAC;EAC1C,MAAM6B,IAAI,GAAG/B,cAAc,CAAC,QAAQ,EAAEF,MAAM,CAAC;EAC7C,MAAMkC,OAAO,GAAG/B,kBAAkB,CAAC2B,OAAO,CAAC;EAE3C,oBACEtB,KAAA,CAACT,IAAI;IAAC4B,KAAK,EAAE,CAACC,MAAM,CAAChB,IAAI,EAAEiB,KAAK,EAAEM,SAAS,EAAER,KAAK,CAAE;IAAAS,QAAA,gBAClD9B,IAAA,CAAC2B,IAAI;MACHI,OAAO,EAAC,WAAW;MACnBC,KAAK,EAAC,QAAG;MACTC,kBAAkB,EAAER,CAAC,CAAC,sBAAsB,CAAE;MAC9CL,QAAQ,EAAEA,QAAQ,IAAI,CAACQ,OAAO,CAACM,YAAa;MAC5CC,OAAO,EAAEP,OAAO,CAACQ,SAAU;MAC3Bf,KAAK,EAAE,CAACC,MAAM,CAACT,MAAM,EAAEU,KAAK,EAAEV,MAAM;IAAE,CACvC,CAAC,eACFb,IAAA,CAAC0B,KAAK;MACJO,kBAAkB,EAAE,GAAGR,CAAC,CAAC,mBAAmB,CAAC,IAAIG,OAAO,CAACX,KAAK,EAAG;MACjEI,KAAK,EAAE,CAACC,MAAM,CAACL,KAAK,EAAEM,KAAK,EAAEN,KAAK,CAAE;MAAAa,QAAA,EAEnCF,OAAO,CAACX;IAAK,CACT,CAAC,eACRjB,IAAA,CAAC2B,IAAI;MACHI,OAAO,EAAC,WAAW;MACnBC,KAAK,EAAC,GAAG;MACTC,kBAAkB,EAAER,CAAC,CAAC,sBAAsB,CAAE;MAC9CL,QAAQ,EAAEA,QAAQ,IAAI,CAACQ,OAAO,CAACS,YAAa;MAC5CF,OAAO,EAAEP,OAAO,CAACU,SAAU;MAC3BjB,KAAK,EAAE,CAACC,MAAM,CAACT,MAAM,EAAEU,KAAK,EAAEV,MAAM;IAAE,CACvC,CAAC;EAAA,CACE,CAAC;AAEX","ignoreList":[]}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ import AsyncStorage from 'expo-sqlite/kv-store';
4
+ import { create } from 'zustand';
5
+ import { createJSONStorage, persist } from 'zustand/middleware';
6
+ /**
7
+ * The runtime half of Spartacus' two-layer theming. React Native has no build-time SCSS swap, so
8
+ * the choice is state, and it survives a restart like any other preference.
9
+ */
10
+ export const useThemeStore = create()(persist(set => ({
11
+ setTheme: activeThemeId => set({
12
+ activeThemeId
13
+ }),
14
+ setColorScheme: colorScheme => set({
15
+ colorScheme
16
+ })
17
+ }), {
18
+ name: 'laconius.theme',
19
+ storage: createJSONStorage(() => AsyncStorage),
20
+ partialize: state => ({
21
+ activeThemeId: state.activeThemeId,
22
+ colorScheme: state.colorScheme
23
+ })
24
+ }));
25
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AsyncStorage","create","createJSONStorage","persist","useThemeStore","set","setTheme","activeThemeId","setColorScheme","colorScheme","name","storage","partialize","state"],"sourceRoot":"../../src","sources":["store.ts"],"mappings":";;AAAA,OAAOA,YAAY,MAAM,sBAAsB;AAC/C,SAASC,MAAM,QAAQ,SAAS;AAChC,SAASC,iBAAiB,EAAEC,OAAO,QAAQ,oBAAoB;AAa/D;AACA;AACA;AACA;AACA,OAAO,MAAMC,aAAa,GAAGH,MAAM,CAAa,CAAC,CAC/CE,OAAO,CACJE,GAAG,KAAM;EACRC,QAAQ,EAAGC,aAAa,IAAKF,GAAG,CAAC;IAAEE;EAAc,CAAC,CAAC;EACnDC,cAAc,EAAGC,WAAW,IAAKJ,GAAG,CAAC;IAAEI;EAAY,CAAC;AACtD,CAAC,CAAC,EACF;EACEC,IAAI,EAAE,gBAAgB;EACtBC,OAAO,EAAET,iBAAiB,CAAC,MAAMF,YAAY,CAAC;EAC9CY,UAAU,EAAGC,KAAK,KAAM;IACtBN,aAAa,EAAEM,KAAK,CAACN,aAAa;IAClCE,WAAW,EAAEI,KAAK,CAACJ;EACrB,CAAC;AACH,CACF,CACF,CAAC","ignoreList":[]}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ import { StyleSheet, Text as RNText } from 'react-native';
4
+ import { useStyles, useTheme } from "./hooks.js";
5
+
6
+ /**
7
+ * Primitives extend the platform prop type and spread the rest: a closed prop set broke on the
8
+ * first `numberOfLines` written in an app file.
9
+ */
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const createStyles = theme => StyleSheet.create({
12
+ display: {
13
+ ...theme.typography.display,
14
+ fontFamily: theme.fontFamily?.bold
15
+ },
16
+ heading: {
17
+ ...theme.typography.heading,
18
+ fontFamily: theme.fontFamily?.bold
19
+ },
20
+ subheading: {
21
+ ...theme.typography.subheading,
22
+ fontFamily: theme.fontFamily?.medium
23
+ },
24
+ body: {
25
+ ...theme.typography.body,
26
+ fontFamily: theme.fontFamily?.regular
27
+ },
28
+ label: {
29
+ ...theme.typography.label,
30
+ fontFamily: theme.fontFamily?.medium
31
+ },
32
+ caption: {
33
+ ...theme.typography.caption,
34
+ fontFamily: theme.fontFamily?.regular
35
+ }
36
+ });
37
+ export function Text({
38
+ variant = 'body',
39
+ muted,
40
+ inverse,
41
+ color,
42
+ style,
43
+ ...rest
44
+ }) {
45
+ const theme = useTheme();
46
+ const styles = useStyles(createStyles);
47
+ const resolved = color ?? (inverse ? theme.colors.textInverse : muted ? theme.colors.textMuted : theme.colors.text);
48
+ return /*#__PURE__*/_jsx(RNText, {
49
+ style: [styles[variant], {
50
+ color: resolved
51
+ }, style],
52
+ ...rest
53
+ });
54
+ }
55
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["StyleSheet","Text","RNText","useStyles","useTheme","jsx","_jsx","createStyles","theme","create","display","typography","fontFamily","bold","heading","subheading","medium","body","regular","label","caption","variant","muted","inverse","color","style","rest","styles","resolved","colors","textInverse","textMuted","text"],"sourceRoot":"../../src","sources":["text.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,IAAI,IAAIC,MAAM,QAAuC,cAAc;AAExF,SAASC,SAAS,EAAEC,QAAQ,QAAQ,YAAS;;AAG7C;AACA;AACA;AACA;AAHA,SAAAC,GAAA,IAAAC,IAAA;AAYA,MAAMC,YAAY,GAAIC,KAAY,IAChCR,UAAU,CAACS,MAAM,CAAC;EAChBC,OAAO,EAAE;IAAE,GAAGF,KAAK,CAACG,UAAU,CAACD,OAAO;IAAEE,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEC;EAAK,CAAC;EAC5EC,OAAO,EAAE;IAAE,GAAGN,KAAK,CAACG,UAAU,CAACG,OAAO;IAAEF,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEC;EAAK,CAAC;EAC5EE,UAAU,EAAE;IACV,GAAGP,KAAK,CAACG,UAAU,CAACI,UAAU;IAC9BH,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEI;EAChC,CAAC;EACDC,IAAI,EAAE;IAAE,GAAGT,KAAK,CAACG,UAAU,CAACM,IAAI;IAAEL,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEM;EAAQ,CAAC;EACzEC,KAAK,EAAE;IAAE,GAAGX,KAAK,CAACG,UAAU,CAACQ,KAAK;IAAEP,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEI;EAAO,CAAC;EAC1EI,OAAO,EAAE;IAAE,GAAGZ,KAAK,CAACG,UAAU,CAACS,OAAO;IAAER,UAAU,EAAEJ,KAAK,CAACI,UAAU,EAAEM;EAAQ;AAChF,CAAC,CAAC;AAEJ,OAAO,SAASjB,IAAIA,CAAC;EACnBoB,OAAO,GAAG,MAAM;EAChBC,KAAK;EACLC,OAAO;EACPC,KAAK;EACLC,KAAK;EACL,GAAGC;AACM,CAAC,EAAE;EACZ,MAAMlB,KAAK,GAAGJ,QAAQ,CAAC,CAAC;EACxB,MAAMuB,MAAM,GAAGxB,SAAS,CAACI,YAAY,CAAC;EACtC,MAAMqB,QAAQ,GACZJ,KAAK,KACJD,OAAO,GACJf,KAAK,CAACqB,MAAM,CAACC,WAAW,GACxBR,KAAK,GACHd,KAAK,CAACqB,MAAM,CAACE,SAAS,GACtBvB,KAAK,CAACqB,MAAM,CAACG,IAAI,CAAC;EAC1B,oBAAO1B,IAAA,CAACJ,MAAM;IAACuB,KAAK,EAAE,CAACE,MAAM,CAACN,OAAO,CAAC,EAAE;MAAEG,KAAK,EAAEI;IAAS,CAAC,EAAEH,KAAK,CAAE;IAAA,GAAKC;EAAI,CAAG,CAAC;AACnF","ignoreList":[]}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ /** Roles only, no numeric palette: the brand already has one and remapping it is work nobody asked for. */
4
+
5
+ /** One theme, two schemes. `dark` is optional and falls back to `light`. */
6
+
7
+ /**
8
+ * A complete theme, inheriting nothing. The compiler enumerates what is missing, which is why
9
+ * this is a separate function rather than a flag on `extendTheme`.
10
+ */
11
+ export function defineTheme(theme) {
12
+ return theme;
13
+ }
14
+
15
+ /** Deep merge onto an existing theme. */
16
+ export function extendTheme(base, overrides) {
17
+ return mergeTheme(base, overrides);
18
+ }
19
+ function isPlainObject(value) {
20
+ return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
21
+ }
22
+
23
+ /**
24
+ * Core's `deepMerge` semantics, kept local so this module imports nothing from a React Native
25
+ * runtime — a theme is the one thing worth building and testing outside a device.
26
+ */
27
+ function mergeTheme(base, override) {
28
+ if (override === undefined) return base;
29
+ if (!isPlainObject(base) || !isPlainObject(override)) return override;
30
+ const result = {
31
+ ...base
32
+ };
33
+ for (const key of Object.keys(override)) {
34
+ const next = override[key];
35
+ if (next === undefined) continue;
36
+ result[key] = isPlainObject(result[key]) ? mergeTheme(result[key], next) : next;
37
+ }
38
+ return result;
39
+ }
40
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["defineTheme","theme","extendTheme","base","overrides","mergeTheme","isPlainObject","value","Array","isArray","Object","getPrototypeOf","prototype","override","undefined","result","key","keys","next"],"sourceRoot":"../../src","sources":["theme.ts"],"mappings":";;AA6BA;;AAYA;;AAKA;AACA;AACA;AACA;AACA,OAAO,SAASA,WAAWA,CAACC,KAAY,EAAS;EAC/C,OAAOA,KAAK;AACd;;AAEA;AACA,OAAO,SAASC,WAAWA,CAACC,IAAW,EAAEC,SAAyB,EAAS;EACzE,OAAOC,UAAU,CAACF,IAAI,EAAEC,SAAS,CAAC;AACpC;AAQA,SAASE,aAAaA,CAACC,KAAc,EAAoC;EACvE,OACE,OAAOA,KAAK,KAAK,QAAQ,IACzBA,KAAK,KAAK,IAAI,IACd,CAACC,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC,IACrBG,MAAM,CAACC,cAAc,CAACJ,KAAK,CAAC,KAAKG,MAAM,CAACE,SAAS;AAErD;;AAEA;AACA;AACA;AACA;AACA,SAASP,UAAUA,CAACF,IAAa,EAAEU,QAAiB,EAAW;EAC7D,IAAIA,QAAQ,KAAKC,SAAS,EAAE,OAAOX,IAAI;EACvC,IAAI,CAACG,aAAa,CAACH,IAAI,CAAC,IAAI,CAACG,aAAa,CAACO,QAAQ,CAAC,EAAE,OAAOA,QAAQ;EAErE,MAAME,MAA+B,GAAG;IAAE,GAAGZ;EAAK,CAAC;EACnD,KAAK,MAAMa,GAAG,IAAIN,MAAM,CAACO,IAAI,CAACJ,QAAQ,CAAC,EAAE;IACvC,MAAMK,IAAI,GAAGL,QAAQ,CAACG,GAAG,CAAC;IAC1B,IAAIE,IAAI,KAAKJ,SAAS,EAAE;IACxBC,MAAM,CAACC,GAAG,CAAC,GAAGV,aAAa,CAACS,MAAM,CAACC,GAAG,CAAC,CAAC,GAAGX,UAAU,CAACU,MAAM,CAACC,GAAG,CAAC,EAAEE,IAAI,CAAC,GAAGA,IAAI;EACjF;EACA,OAAOH,MAAM;AACf","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ /** English strings for the defaults in this package. Other languages are the app's. */
4
+ export const defaultUiTranslations = {
5
+ en: {
6
+ ui: {
7
+ quantity: {
8
+ label: 'Quantity',
9
+ increase: 'Increase quantity',
10
+ decrease: 'Decrease quantity'
11
+ }
12
+ }
13
+ }
14
+ };
15
+ //# sourceMappingURL=translations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["defaultUiTranslations","en","ui","quantity","label","increase","decrease"],"sourceRoot":"../../src","sources":["translations.ts"],"mappings":";;AAAA;AACA,OAAO,MAAMA,qBAAqB,GAAG;EACnCC,EAAE,EAAE;IACFC,EAAE,EAAE;MACFC,QAAQ,EAAE;QACRC,KAAK,EAAE,UAAU;QACjBC,QAAQ,EAAE,mBAAmB;QAC7BC,QAAQ,EAAE;MACZ;IACF;EACF;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ import { getGalleryImages } from '@laconius/core';
4
+ import { useCallback, useMemo, useState } from 'react';
5
+ /** The selected slide — the only state a gallery owns. Paging is the caller's layout decision. */
6
+ export function useGallery(images) {
7
+ const items = useMemo(() => getGalleryImages(images), [images]);
8
+ const [index, setIndex] = useState(0);
9
+
10
+ // A product switch shortens the list; clamping on read avoids an effect that fights the render.
11
+ const current = items.length === 0 ? 0 : Math.min(index, items.length - 1);
12
+ const select = useCallback(next => setIndex(Math.max(0, next)), []);
13
+ return {
14
+ items,
15
+ index: current,
16
+ selected: items[current],
17
+ select,
18
+ next: () => select(Math.min(current + 1, items.length - 1)),
19
+ previous: () => select(current - 1)
20
+ };
21
+ }
22
+ //# sourceMappingURL=use-gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getGalleryImages","useCallback","useMemo","useState","useGallery","images","items","index","setIndex","current","length","Math","min","select","next","max","selected","previous"],"sourceRoot":"../../src","sources":["use-gallery.ts"],"mappings":";;AAAA,SAASA,gBAAgB,QAAsC,gBAAgB;AAC/E,SAASC,WAAW,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AAYtD;AACA,OAAO,SAASC,UAAUA,CAACC,MAA0B,EAAc;EACjE,MAAMC,KAAK,GAAGJ,OAAO,CAAC,MAAMF,gBAAgB,CAACK,MAAM,CAAC,EAAE,CAACA,MAAM,CAAC,CAAC;EAC/D,MAAM,CAACE,KAAK,EAAEC,QAAQ,CAAC,GAAGL,QAAQ,CAAC,CAAC,CAAC;;EAErC;EACA,MAAMM,OAAO,GAAGH,KAAK,CAACI,MAAM,KAAK,CAAC,GAAG,CAAC,GAAGC,IAAI,CAACC,GAAG,CAACL,KAAK,EAAED,KAAK,CAACI,MAAM,GAAG,CAAC,CAAC;EAE1E,MAAMG,MAAM,GAAGZ,WAAW,CACvBa,IAAY,IAAKN,QAAQ,CAACG,IAAI,CAACI,GAAG,CAAC,CAAC,EAAED,IAAI,CAAC,CAAC,EAC7C,EACF,CAAC;EAED,OAAO;IACLR,KAAK;IACLC,KAAK,EAAEE,OAAO;IACdO,QAAQ,EAAEV,KAAK,CAACG,OAAO,CAAC;IACxBI,MAAM;IACNC,IAAI,EAAEA,CAAA,KAAMD,MAAM,CAACF,IAAI,CAACC,GAAG,CAACH,OAAO,GAAG,CAAC,EAAEH,KAAK,CAACI,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3DO,QAAQ,EAAEA,CAAA,KAAMJ,MAAM,CAACJ,OAAO,GAAG,CAAC;EACpC,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ import { getPrimaryImage } from '@laconius/core';
4
+ import { useMemo } from 'react';
5
+
6
+ /**
7
+ * Semantic, not a translation key: the key space belongs to `@laconius/product`, and this hook
8
+ * lives in the UI kit, which never reaches into a feature package's namespace.
9
+ */
10
+
11
+ function badgeFor(product) {
12
+ const status = product.stock?.stockLevelStatus;
13
+ if (product.purchasable === false || status === 'outOfStock') return 'outOfStock';
14
+ if (status === 'lowStock') return 'lowStock';
15
+ return undefined;
16
+ }
17
+
18
+ /**
19
+ * Derivation only — no fetch, no navigation. A card is rendered by the row of a `FlatList`, so
20
+ * everything it needs comes off the product it was handed.
21
+ *
22
+ * `priceRange.minPrice` covers the multidimensional products whose `price` is absent, which is
23
+ * what the search endpoint returns for apparel.
24
+ */
25
+ export function useProductCard(product) {
26
+ return useMemo(() => ({
27
+ code: product?.code,
28
+ title: product?.name ?? '',
29
+ price: product?.price ?? product?.priceRange?.minPrice,
30
+ media: getPrimaryImage(product?.images),
31
+ badge: product ? badgeFor(product) : undefined,
32
+ averageRating: product?.averageRating,
33
+ numberOfReviews: product?.numberOfReviews
34
+ }), [product]);
35
+ }
36
+ //# sourceMappingURL=use-product-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getPrimaryImage","useMemo","badgeFor","product","status","stock","stockLevelStatus","purchasable","undefined","useProductCard","code","title","name","price","priceRange","minPrice","media","images","badge","averageRating","numberOfReviews"],"sourceRoot":"../../src","sources":["use-product-card.ts"],"mappings":";;AAAA,SAASA,eAAe,QAAuD,gBAAgB;AAC/F,SAASC,OAAO,QAAQ,OAAO;;AAE/B;AACA;AACA;AACA;;AAaA,SAASC,QAAQA,CAACC,OAAgB,EAAgC;EAChE,MAAMC,MAAM,GAAGD,OAAO,CAACE,KAAK,EAAEC,gBAAgB;EAC9C,IAAIH,OAAO,CAACI,WAAW,KAAK,KAAK,IAAIH,MAAM,KAAK,YAAY,EAAE,OAAO,YAAY;EACjF,IAAIA,MAAM,KAAK,UAAU,EAAE,OAAO,UAAU;EAC5C,OAAOI,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAACN,OAA4B,EAAmB;EAC5E,OAAOF,OAAO,CACZ,OAAO;IACLS,IAAI,EAAEP,OAAO,EAAEO,IAAI;IACnBC,KAAK,EAAER,OAAO,EAAES,IAAI,IAAI,EAAE;IAC1BC,KAAK,EAAEV,OAAO,EAAEU,KAAK,IAAIV,OAAO,EAAEW,UAAU,EAAEC,QAAQ;IACtDC,KAAK,EAAEhB,eAAe,CAACG,OAAO,EAAEc,MAAM,CAAC;IACvCC,KAAK,EAAEf,OAAO,GAAGD,QAAQ,CAACC,OAAO,CAAC,GAAGK,SAAS;IAC9CW,aAAa,EAAEhB,OAAO,EAAEgB,aAAa;IACrCC,eAAe,EAAEjB,OAAO,EAAEiB;EAC5B,CAAC,CAAC,EACF,CAACjB,OAAO,CACV,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ /** Clamping and the disabled edges — the only state a stepper owns. It does not know what a cart is. */
4
+ export function useQuantityStepper({
5
+ value,
6
+ min = 1,
7
+ max,
8
+ onChange
9
+ }) {
10
+ const clamp = next => Math.min(Math.max(Math.round(next), min), max ?? Number.POSITIVE_INFINITY);
11
+ return {
12
+ value,
13
+ canIncrement: max === undefined || value < max,
14
+ canDecrement: value > min,
15
+ increment: () => onChange(clamp(value + 1)),
16
+ decrement: () => onChange(clamp(value - 1)),
17
+ setValue: next => onChange(clamp(next))
18
+ };
19
+ }
20
+ //# sourceMappingURL=use-quantity-stepper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useQuantityStepper","value","min","max","onChange","clamp","next","Math","round","Number","POSITIVE_INFINITY","canIncrement","undefined","canDecrement","increment","decrement","setValue"],"sourceRoot":"../../src","sources":["use-quantity-stepper.ts"],"mappings":";;AAiBA;AACA,OAAO,SAASA,kBAAkBA,CAAC;EACjCC,KAAK;EACLC,GAAG,GAAG,CAAC;EACPC,GAAG;EACHC;AACsB,CAAC,EAAsB;EAC7C,MAAMC,KAAK,GAAIC,IAAY,IACzBC,IAAI,CAACL,GAAG,CAACK,IAAI,CAACJ,GAAG,CAACI,IAAI,CAACC,KAAK,CAACF,IAAI,CAAC,EAAEJ,GAAG,CAAC,EAAEC,GAAG,IAAIM,MAAM,CAACC,iBAAiB,CAAC;EAC5E,OAAO;IACLT,KAAK;IACLU,YAAY,EAAER,GAAG,KAAKS,SAAS,IAAIX,KAAK,GAAGE,GAAG;IAC9CU,YAAY,EAAEZ,KAAK,GAAGC,GAAG;IACzBY,SAAS,EAAEA,CAAA,KAAMV,QAAQ,CAACC,KAAK,CAACJ,KAAK,GAAG,CAAC,CAAC,CAAC;IAC3Cc,SAAS,EAAEA,CAAA,KAAMX,QAAQ,CAACC,KAAK,CAACJ,KAAK,GAAG,CAAC,CAAC,CAAC;IAC3Ce,QAAQ,EAAGV,IAAY,IAAKF,QAAQ,CAACC,KAAK,CAACC,IAAI,CAAC;EAClD,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type PressableProps, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
3
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost';
4
+ export type ButtonProps = Omit<PressableProps, 'style' | 'children'> & {
5
+ title?: string;
6
+ variant?: ButtonVariant;
7
+ loading?: boolean;
8
+ /** Root style. */
9
+ style?: StyleProp<ViewStyle>;
10
+ /** Named inner parts — public, versioned API. */
11
+ styles?: {
12
+ container?: StyleProp<ViewStyle>;
13
+ label?: StyleProp<TextStyle>;
14
+ };
15
+ children?: ReactNode;
16
+ };
17
+ export declare function Button({ title, variant, loading, disabled, style, styles: parts, children, ...rest }: ButtonProps): import("react").JSX.Element;
18
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAMtB,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iDAAiD;IACjD,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;KAAE,CAAC;IAC5E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AA0BF,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,OAAmB,EACnB,OAAe,EACf,QAAgB,EAChB,KAAK,EACL,MAAM,EAAE,KAAK,EACb,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,WAAW,+BAiCb"}
@@ -0,0 +1,40 @@
1
+ import type { LaconiusConfigChunk } from '@laconius/core';
2
+ import type { ComponentType } from 'react';
3
+ import type { ColorSchemePreference, ThemeEntry } from './theme.js';
4
+ /**
5
+ * The registry key space, closed and typed — unlike `cms.components`, whose keys are open backend
6
+ * type codes ([ADR-0007](../../../docs/adr/0007-two-registries-two-contracts.md)). Feature
7
+ * packages add their own keys by declaration merging:
8
+ *
9
+ * ```ts
10
+ * declare module '@laconius/ui' {
11
+ * interface LaconiusUiComponents { ProductCard: unknown }
12
+ * }
13
+ * ```
14
+ *
15
+ * The values are unused: only the keys are the contract, and the registry stores
16
+ * `ComponentType<any>` because a replacement is checked against the props it is handed, not here.
17
+ */
18
+ export interface LaconiusUiComponents {
19
+ Text: unknown;
20
+ Button: unknown;
21
+ Media: unknown;
22
+ Price: unknown;
23
+ Divider: unknown;
24
+ Spinner: unknown;
25
+ EmptyState: unknown;
26
+ QuantityStepper: unknown;
27
+ }
28
+ export type LaconiusUiComponent = keyof LaconiusUiComponents;
29
+ declare module '@laconius/core' {
30
+ interface LaconiusUiConfig {
31
+ /** Deep-merged: an app adds a theme without erasing Kratos, and replaces Kratos by key. */
32
+ themes?: Record<string, ThemeEntry>;
33
+ defaultTheme?: string;
34
+ /** `'system'` reads `useColorScheme()`. Overridable at runtime through `useThemeSwitcher`. */
35
+ colorScheme?: ColorSchemePreference;
36
+ components?: Partial<Record<LaconiusUiComponent, ComponentType<any>>>;
37
+ }
38
+ }
39
+ export declare const defaultUiConfig: LaconiusConfigChunk;
40
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,YAAS,CAAC;AAGjE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,oBAAoB,CAAC;AAE7D,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,gBAAgB;QACxB,2FAA2F;QAC3F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACpC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,8FAA8F;QAC9F,WAAW,CAAC,EAAE,qBAAqB,CAAC;QACpC,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KACvE;CACF;AAED,eAAO,MAAM,eAAe,EAAE,mBAO7B,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type ActivityIndicatorProps, type StyleProp, type TextStyle, type ViewProps, type ViewStyle } from 'react-native';
3
+ import { type ButtonProps } from './button.js';
4
+ export type DividerProps = ViewProps & {
5
+ inset?: number;
6
+ };
7
+ export declare function Divider({ inset, style, ...rest }: DividerProps): import("react").JSX.Element;
8
+ export type SpinnerProps = ActivityIndicatorProps;
9
+ export declare function Spinner({ color, ...rest }: SpinnerProps): import("react").JSX.Element;
10
+ export type EmptyStateProps = {
11
+ title: string;
12
+ message?: string;
13
+ /** Rendered as a `Button`; omit it for a purely informational state. */
14
+ action?: Pick<ButtonProps, 'title' | 'onPress' | 'variant' | 'loading'>;
15
+ icon?: ReactNode;
16
+ style?: StyleProp<ViewStyle>;
17
+ styles?: {
18
+ container?: StyleProp<ViewStyle>;
19
+ title?: StyleProp<TextStyle>;
20
+ message?: StyleProp<TextStyle>;
21
+ };
22
+ };
23
+ export declare function EmptyState({ title, message, action, icon, style, styles: parts, }: EmptyStateProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../../src/feedback.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAU,CAAC;AAKpD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAO1D,wBAAgB,OAAO,CAAC,EAAE,KAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,+BAUlE;AAED,MAAM,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAElD,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,+BAGvD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,CAAC;IACxE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAChC,CAAC;CACH,CAAC;AAcF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,EACJ,KAAK,EACL,MAAM,EAAE,KAAK,GACd,EAAE,eAAe,+BAkBjB"}
@@ -0,0 +1,31 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { LaconiusUiComponent } from './config.js';
3
+ import type { ColorSchemePreference, Theme } from './theme.js';
4
+ /** The configured theme resolved against the effective colour scheme. */
5
+ export declare function useTheme(): Theme;
6
+ /**
7
+ * Style factories are declared outside the component and memoized per theme identity, so a
8
+ * `FlatList` of a hundred rows builds one `StyleSheet`, not a hundred.
9
+ */
10
+ export declare function useStyles<T>(factory: (theme: Theme) => T): T;
11
+ export type ThemeSwitcher = {
12
+ themes: {
13
+ id: string;
14
+ name: string;
15
+ }[];
16
+ activeId: string;
17
+ setTheme: (themeId: string) => void;
18
+ colorScheme: ColorSchemePreference;
19
+ setColorScheme: (scheme: ColorSchemePreference) => void;
20
+ };
21
+ /**
22
+ * Laconius ships no `<ThemeSwitcher>` component: picking a theme is one row in an app's settings
23
+ * screen, and the row belongs to the app.
24
+ */
25
+ export declare function useThemeSwitcher(): ThemeSwitcher;
26
+ /**
27
+ * The registry lookup, used by the components Laconius renders itself. Anything the app mounts
28
+ * directly it imports directly, and the registry never sees it.
29
+ */
30
+ export declare function useUiComponent<P>(key: LaconiusUiComponent, fallback: ComponentType<P>): ComponentType<P>;
31
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAU,CAAC;AAGpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAc,MAAM,YAAS,CAAC;AAwDxE,yEAAyE;AACzE,wBAAgB,QAAQ,IAAI,KAAK,CAGhC;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,CAAC,CAa5D;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,qBAAqB,CAAC;IACnC,cAAc,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAehD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GACzB,aAAa,CAAC,CAAC,CAAC,CAGlB"}
@@ -0,0 +1,16 @@
1
+ export { defaultUiConfig, type LaconiusUiComponent, type LaconiusUiComponents, } from './config.js';
2
+ export { defineTheme, extendTheme, type ColorSchemePreference, type Theme, type ThemeColors, type ThemeEntry, type ThemeOverrides, type TypographyRole, type TypographyToken, } from './theme.js';
3
+ export { kratos, kratosDark, kratosLight } from './kratos.js';
4
+ export { useThemeStore, type ThemeState } from './store.js';
5
+ export { useStyles, useTheme, useThemeSwitcher, useUiComponent, type ThemeSwitcher, } from './hooks.js';
6
+ export { defaultUiTranslations } from './translations.js';
7
+ export { Text, type TextProps } from './text.js';
8
+ export { Button, type ButtonProps, type ButtonVariant } from './button.js';
9
+ export { Media, useMedia, type MediaProps, type UseMediaOptions, type UseMediaResult, } from './media.js';
10
+ export { Price, formatPrice, type PriceProps } from './price.js';
11
+ export { Divider, EmptyState, Spinner, type DividerProps, type EmptyStateProps, type SpinnerProps, } from './feedback.js';
12
+ export { QuantityStepper, type QuantityStepperProps } from './quantity-stepper.js';
13
+ export { useProductCard, type ProductCardBadge, type ProductCardView, } from './use-product-card.js';
14
+ export { useGallery, type GalleryApi } from './use-gallery.js';
15
+ export { useQuantityStepper, type QuantityStepperApi, type QuantityStepperOptions, } from './use-quantity-stepper.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,aAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,WAAW,EACX,KAAK,qBAAqB,EAC1B,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,YAAS,CAAC;AAEjB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,YAAS,CAAC;AAEzD,OAAO,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,KAAK,aAAa,GACnB,MAAM,YAAS,CAAC;AAEjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAgB,CAAC;AAEvD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,WAAQ,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,aAAU,CAAC;AACxE,OAAO,EACL,KAAK,EACL,QAAQ,EACR,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,YAAS,CAAC;AACjB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAS,CAAC;AAC9D,OAAO,EACL,OAAO,EACP,UAAU,EACV,OAAO,EACP,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,eAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAoB,CAAC;AAChF,OAAO,EACL,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,uBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAe,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,2BAAwB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type Theme, type ThemeEntry } from './theme.js';
2
+ /**
3
+ * Every foreground/background pair below clears WCAG AA (4.5:1), verified by `kratos.test.ts`.
4
+ */
5
+ export declare const kratosLight: Theme;
6
+ export declare const kratosDark: Theme;
7
+ export declare const kratos: ThemeEntry;
8
+ //# sourceMappingURL=kratos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kratos.d.ts","sourceRoot":"","sources":["../../../src/kratos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,YAAS,CAAC;AAoCnE;;GAEG;AACH,eAAO,MAAM,WAAW,OAmBtB,CAAC;AAEH,eAAO,MAAM,UAAU,OAmBrB,CAAC;AAEH,eAAO,MAAM,MAAM,EAAE,UAIpB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { type MediaContainer, type MediaSource } from '@laconius/core';
2
+ import { type ImageProps } from 'expo-image';
3
+ import type { ImageStyle, StyleProp } from 'react-native';
4
+ import type { Theme } from './theme.js';
5
+ export type UseMediaOptions = {
6
+ /** Caps the candidate set. It does not select one asset. */
7
+ role?: string;
8
+ /** Explicit cap, overriding the one the role implies. */
9
+ maxFormat?: string;
10
+ };
11
+ export type UseMediaResult = {
12
+ /** Every format the container carries, widths attached, ascending. */
13
+ sources: MediaSource[];
14
+ altText?: string;
15
+ };
16
+ /**
17
+ * `expo-image` implements srcset semantics against the measured container, so Laconius hands it
18
+ * the whole candidate set and never picks a format for a device class.
19
+ */
20
+ export declare function useMedia(media: MediaContainer, options?: UseMediaOptions): UseMediaResult;
21
+ export type MediaProps = Omit<ImageProps, 'source' | 'style'> & {
22
+ media: MediaContainer;
23
+ /**
24
+ * The `useMedia` role. Named `mediaRole` because React Native's own `role` (the ARIA one)
25
+ * is already on every view prop type, and a primitive spreads the platform props.
26
+ */
27
+ mediaRole?: string;
28
+ /** Explicit cap, overriding the one the role implies. */
29
+ maxFormat?: string;
30
+ /** A theme aspect-ratio role, or a number. Unset leaves layout to the caller. */
31
+ aspectRatio?: keyof Theme['media']['aspectRatio'] | number;
32
+ /** Hides the image from screen readers, for decorative content. */
33
+ decorative?: boolean;
34
+ style?: StyleProp<ImageStyle>;
35
+ };
36
+ export declare function Media({ media, mediaRole, maxFormat, aspectRatio, decorative, style, ...rest }: MediaProps): import("react").JSX.Element;
37
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/media.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAS,CAAC;AAErC,MAAM,MAAM,eAAe,GAAG;IAC5B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,sEAAsE;IACtE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAgBhB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG;IAC9D,KAAK,EAAE,cAAc,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC;IAC3D,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAkB,EAClB,KAAK,EACL,GAAG,IAAI,EACR,EAAE,UAAU,+BAmBZ"}
@@ -0,0 +1,15 @@
1
+ import { type Price as PriceModel } from '@laconius/core';
2
+ import { type TextProps } from './text.js';
3
+ export type PriceProps = Omit<TextProps, 'children'> & {
4
+ price?: PriceModel;
5
+ /** Rendered when the price carries neither a formatted value nor a numeric one. */
6
+ fallback?: string;
7
+ };
8
+ /**
9
+ * OCC's `formattedValue` arrives in the request's language and currency, so it follows a
10
+ * language switch on its own. `Intl` is the fallback for the endpoints that omit it — Hermes
11
+ * ships it, so there is no dependency here.
12
+ */
13
+ export declare function formatPrice(price: PriceModel | undefined, locale: string): string | undefined;
14
+ export declare function Price({ price, fallback, ...rest }: PriceProps): import("react").JSX.Element;
15
+ //# sourceMappingURL=price.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.d.ts","sourceRoot":"","sources":["../../../src/price.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,KAAK,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAQ,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG;IACrD,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS7F;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAa,EAAE,GAAG,IAAI,EAAE,EAAE,UAAU,+BAGlE"}
@@ -0,0 +1,13 @@
1
+ import { type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
2
+ import { type QuantityStepperOptions } from './use-quantity-stepper.js';
3
+ export type QuantityStepperProps = QuantityStepperOptions & {
4
+ disabled?: boolean;
5
+ style?: StyleProp<ViewStyle>;
6
+ styles?: {
7
+ container?: StyleProp<ViewStyle>;
8
+ value?: StyleProp<TextStyle>;
9
+ button?: StyleProp<ViewStyle>;
10
+ };
11
+ };
12
+ export declare function QuantityStepper({ disabled, style, styles: parts, ...options }: QuantityStepperProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=quantity-stepper.d.ts.map