@carbonbits/sixr 1.0.4 → 1.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.
- package/README.md +150 -5
- package/dist/cart.cjs +41 -0
- package/dist/cart.cjs.map +1 -0
- package/dist/cart.d.cts +21 -0
- package/dist/cart.d.ts +21 -0
- package/dist/cart.js +3 -0
- package/dist/cart.js.map +1 -0
- package/dist/chunk-BHSOSXTU.js +39 -0
- package/dist/chunk-BHSOSXTU.js.map +1 -0
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +2 -0
- package/package.json +89 -65
package/README.md
CHANGED
|
@@ -1,7 +1,152 @@
|
|
|
1
|
-
|
|
1
|
+
# Sixr
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
E-commerce geared React component library for [carbonbits](https://carbonbits.co.ke/sixr).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Ships ESM + CJS builds with type declarations, and a prebuilt stylesheet. Components
|
|
6
|
+
are React Server Component safe, so they work in the Next.js App Router without a
|
|
7
|
+
`"use client"` boundary.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
pnpm add @carbonbits/sixr
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`react` and `react-dom` are peer dependencies (`^19.0.0`).
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
// app/layout.tsx
|
|
21
|
+
import "@carbonbits/sixr/styles.css";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each component has its own subpath. Import from there:
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
// app/cart/page.tsx
|
|
28
|
+
import { Cart, type CartProduct } from "@carbonbits/sixr/cart";
|
|
29
|
+
|
|
30
|
+
const products: CartProduct[] = [
|
|
31
|
+
{ name: "Stovetop kettle", price: 1500 },
|
|
32
|
+
{ name: "Enamel mug", price: 500 },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export default function Page() {
|
|
36
|
+
return <Cart products={products} currency="KES" locale="en-KE" />;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The root barrel (`@carbonbits/sixr`) re-exports everything and works too, but the
|
|
41
|
+
subpath is the one to reach for.
|
|
42
|
+
|
|
43
|
+
`dist/styles.css` is compiled by Tailwind 4 and contains only the utilities the
|
|
44
|
+
library itself uses, so it is safe to load alongside a consumer's own Tailwind build.
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
Requires Node.js >= 20.19 and pnpm (see the `packageManager` field; `corepack enable`
|
|
49
|
+
picks up the right version).
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pnpm install
|
|
53
|
+
pnpm storybook # component workbench on :6006
|
|
54
|
+
pnpm test # vitest
|
|
55
|
+
pnpm run lint # biome: lint + format check
|
|
56
|
+
pnpm run lint:fix # biome: apply safe fixes
|
|
57
|
+
pnpm run typecheck
|
|
58
|
+
pnpm run build # dist/ — JS, .d.ts and styles.css
|
|
59
|
+
pnpm run build-storybook
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Linting and formatting are both [Biome](https://biomejs.dev/) (`biome.json`); there
|
|
63
|
+
is no ESLint or Prettier. It runs strict: every rule group is on at `error`, `style`
|
|
64
|
+
and `performance` use the full `all` preset, and `--error-on-warnings` means a
|
|
65
|
+
warning fails CI too. The handful of disabled rules each carry a reason in
|
|
66
|
+
`biome.json`, and stories, tests and config files get narrow overrides where a tool
|
|
67
|
+
mandates something the rules forbid (Storybook's `export default meta`, for one).
|
|
68
|
+
|
|
69
|
+
`biome check` also fails on unformatted files, so run `pnpm run lint:fix` before
|
|
70
|
+
pushing. Most editors have a Biome extension that formats on save.
|
|
71
|
+
|
|
72
|
+
### Adding a component
|
|
73
|
+
|
|
74
|
+
Add it under `src/components/`, then wire it up in three places:
|
|
75
|
+
|
|
76
|
+
1. an entry in `tsup.config.ts`, so it gets its own bundle
|
|
77
|
+
2. a matching subpath in the package.json `exports` map
|
|
78
|
+
3. a re-export from `src/index.ts`, for the barrel
|
|
79
|
+
|
|
80
|
+
Give it a `*.stories.tsx` file too, so Chromatic picks it up.
|
|
81
|
+
|
|
82
|
+
Client components (anything on Radix, or using hooks) need a `"use client"` banner
|
|
83
|
+
on their tsup entry — a directive in the source file does not survive bundling. Not
|
|
84
|
+
wired up yet; there are no client components in the library so far.
|
|
85
|
+
|
|
86
|
+
## Releasing
|
|
87
|
+
|
|
88
|
+
Releases are automated by [semantic-release](https://semantic-release.gitbook.io/)
|
|
89
|
+
on every push to `master`, driven by
|
|
90
|
+
[conventional commits](https://www.conventionalcommits.org/):
|
|
91
|
+
|
|
92
|
+
| Commit prefix | Release |
|
|
93
|
+
| -------------------------------- | ------- |
|
|
94
|
+
| `fix:` | patch |
|
|
95
|
+
| `feat:` | minor |
|
|
96
|
+
| `feat!:` / `BREAKING CHANGE:` | major |
|
|
97
|
+
| `chore:`, `ci:`, `docs:`, `test:`| none |
|
|
98
|
+
|
|
99
|
+
The pipeline works out the version, writes `CHANGELOG.md`, builds `dist/`, commits
|
|
100
|
+
the bump back to `master`, tags it, and opens a GitHub release.
|
|
101
|
+
|
|
102
|
+
### Staged publishing
|
|
103
|
+
|
|
104
|
+
npm is moving publishing behind a human approval step, so CI does **not** push the
|
|
105
|
+
package live. It runs `npm stage publish`, which uploads the tarball and parks it.
|
|
106
|
+
A maintainer then approves it with 2FA:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
npm stage list @carbonbits/sixr
|
|
110
|
+
npm stage view <stage-id> # inspect before approving
|
|
111
|
+
npm stage approve <stage-id> # prompts for 2FA, goes live
|
|
112
|
+
npm stage reject <stage-id> # discard instead
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Until approval the version does not appear in `npm view @carbonbits/sixr versions`,
|
|
116
|
+
even though the GitHub release and tag already exist. Staging needs npm >= 11.15.0
|
|
117
|
+
and Node >= 22.14, which CI pins.
|
|
118
|
+
|
|
119
|
+
### Required secrets
|
|
120
|
+
|
|
121
|
+
| Secret | Used by |
|
|
122
|
+
| -------------------------- | ---------------------------------------------------- |
|
|
123
|
+
| `NPM_STAGING_TOKEN` | `npm stage publish` — a *Read and write (stage only)* granular token |
|
|
124
|
+
| `GH_APP_ID` | the release GitHub App |
|
|
125
|
+
| `GH_APP_PRIVATE_KEY` | that App's private key, **base64-encoded** |
|
|
126
|
+
| `CHROMATIC_PROJECT_TOKEN` | Chromatic publish |
|
|
127
|
+
|
|
128
|
+
Granular tokens lose the ability to publish new versions directly in January 2027,
|
|
129
|
+
which is why the release token is stage-only.
|
|
130
|
+
|
|
131
|
+
`master` carries a ruleset that blocks direct writes, so the release commit and tag
|
|
132
|
+
cannot be pushed with the default `GITHUB_TOKEN`. The workflow mints a short-lived
|
|
133
|
+
installation token from a GitHub App instead, and **that App must be listed in the
|
|
134
|
+
ruleset's bypass list** or the push still fails. The App needs `contents: write` and
|
|
135
|
+
`pull_requests: write` on this repo, nothing more.
|
|
136
|
+
|
|
137
|
+
That installation token is handed to semantic-release as `GITHUB_TOKEN`, and this
|
|
138
|
+
is not interchangeable with `GH_TOKEN`. semantic-release builds its push URL as
|
|
139
|
+
`https://<GH_TOKEN>@github.com/...`, but as
|
|
140
|
+
`https://x-access-token:<GITHUB_TOKEN>@github.com/...` when it detects Actions.
|
|
141
|
+
An App installation token is only accepted in the second form — via `GH_TOKEN` it
|
|
142
|
+
fails on `git ls-remote` with `Invalid username or token`.
|
|
143
|
+
|
|
144
|
+
There is deliberately no `GH_TOKEN` secret. `@semantic-release/github` resolves
|
|
145
|
+
`GH_TOKEN || GITHUB_TOKEN`, so a leftover expired PAT in `GH_TOKEN` silently
|
|
146
|
+
shadows any working token and fails with `EINVALIDGHTOKEN`. If that secret still
|
|
147
|
+
exists in repo settings, delete it.
|
|
148
|
+
|
|
149
|
+
## Visual review
|
|
150
|
+
|
|
151
|
+
Every push and pull request publishes Storybook to
|
|
152
|
+
[Chromatic](https://www.chromatic.com/) for visual regression review.
|
package/dist/cart.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/components/cart/index.tsx
|
|
6
|
+
function formatPrice(value, currency, locale) {
|
|
7
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
8
|
+
value
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
function Cart({
|
|
12
|
+
products = [],
|
|
13
|
+
currency = "KES",
|
|
14
|
+
locale = "en-KE"
|
|
15
|
+
}) {
|
|
16
|
+
const total = products.reduce((sum, product) => sum + product.price, 0);
|
|
17
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4", children: [
|
|
18
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-900", children: "Cart" }),
|
|
19
|
+
products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: "Your cart is empty." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col divide-y divide-gray-100", children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21
|
+
"li",
|
|
22
|
+
{
|
|
23
|
+
className: "flex items-baseline justify-between gap-4 py-2",
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800", children: product.name }),
|
|
26
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm tabular-nums text-gray-600", children: formatPrice(product.price, currency, locale) })
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
product.id ?? product.name
|
|
30
|
+
)) }),
|
|
31
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2", children: [
|
|
32
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-900", children: "Total" }),
|
|
33
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: formatPrice(total, currency, locale) })
|
|
34
|
+
] })
|
|
35
|
+
] })
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
exports.Cart = Cart;
|
|
40
|
+
//# sourceMappingURL=cart.cjs.map
|
|
41
|
+
//# sourceMappingURL=cart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/cart/index.tsx"],"names":["jsxs","jsx","Fragment"],"mappings":";;;;;AAkBA,SAAS,WAAA,CAAY,KAAA,EAAe,QAAA,EAAkB,MAAA,EAAgB;AACpE,EAAA,OAAO,IAAI,KAAK,YAAA,CAAa,MAAA,EAAQ,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,MAAA;AAAA,IACpE;AAAA,GACF;AACF;AAEO,SAAS,IAAA,CAAK;AAAA,EACnB,WAAW,EAAC;AAAA,EACZ,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS;AACX,CAAA,EAAc;AACZ,EAAA,MAAM,KAAA,GAAQ,SAAS,MAAA,CAAO,CAAC,KAAK,OAAA,KAAY,GAAA,GAAM,OAAA,CAAQ,KAAA,EAAO,CAAC,CAAA;AAEtE,EAAA,uBACEA,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yFAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAEvD,QAAA,CAAS,WAAW,CAAA,mBACnBA,cAAA,CAAC,OAAE,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,qBAAA,EAAmB,CAAA,mBAExDD,eAAA,CAAAE,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,cAAA,CAAC,QAAG,SAAA,EAAU,wCAAA,EACX,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,qBACbD,eAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,gDAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAyB,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAK,CAAA;AAAA,4BACtDA,cAAA,CAAC,UAAK,SAAA,EAAU,oCAAA,EACb,sBAAY,OAAA,CAAQ,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EAC9C;AAAA;AAAA,SAAA;AAAA,QANK,OAAA,CAAQ,MAAM,OAAA,CAAQ;AAAA,OAQ9B,CAAA,EACH,CAAA;AAAA,sBAEAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yEAAA,EACb,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,wBACzDA,cAAA,CAAC,UAAK,SAAA,EAAU,kDAAA,EACb,sBAAY,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EACtC;AAAA,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"cart.cjs","sourcesContent":["export type CartProduct = {\n /**\n * Stable identity for this line, used as the React key. Falls back to `name`,\n * so pass an `id` whenever a cart can hold two lines with the same name.\n */\n id?: string;\n name: string;\n price: number;\n};\n\nexport type CartProps = {\n products?: CartProduct[];\n /** ISO 4217 code used to format prices. */\n currency?: string;\n /** BCP 47 locale used to format prices. */\n locale?: string;\n};\n\nfunction formatPrice(value: number, currency: string, locale: string) {\n return new Intl.NumberFormat(locale, { style: \"currency\", currency }).format(\n value,\n );\n}\n\nexport function Cart({\n products = [],\n currency = \"KES\",\n locale = \"en-KE\",\n}: CartProps) {\n const total = products.reduce((sum, product) => sum + product.price, 0);\n\n return (\n <div className=\"cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4\">\n <h1 className=\"text-xl font-semibold text-gray-900\">Cart</h1>\n\n {products.length === 0 ? (\n <p className=\"text-sm text-gray-500\">Your cart is empty.</p>\n ) : (\n <>\n <ul className=\"flex flex-col divide-y divide-gray-100\">\n {products.map((product) => (\n <li\n key={product.id ?? product.name}\n className=\"flex items-baseline justify-between gap-4 py-2\"\n >\n <span className=\"text-sm text-gray-800\">{product.name}</span>\n <span className=\"text-sm tabular-nums text-gray-600\">\n {formatPrice(product.price, currency, locale)}\n </span>\n </li>\n ))}\n </ul>\n\n <div className=\"flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2\">\n <span className=\"text-sm font-medium text-gray-900\">Total</span>\n <span className=\"text-sm font-semibold tabular-nums text-gray-900\">\n {formatPrice(total, currency, locale)}\n </span>\n </div>\n </>\n )}\n </div>\n );\n}\n"]}
|
package/dist/cart.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
type CartProduct = {
|
|
4
|
+
/**
|
|
5
|
+
* Stable identity for this line, used as the React key. Falls back to `name`,
|
|
6
|
+
* so pass an `id` whenever a cart can hold two lines with the same name.
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
price: number;
|
|
11
|
+
};
|
|
12
|
+
type CartProps = {
|
|
13
|
+
products?: CartProduct[];
|
|
14
|
+
/** ISO 4217 code used to format prices. */
|
|
15
|
+
currency?: string;
|
|
16
|
+
/** BCP 47 locale used to format prices. */
|
|
17
|
+
locale?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function Cart({ products, currency, locale, }: CartProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
export { Cart, type CartProduct, type CartProps };
|
package/dist/cart.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
type CartProduct = {
|
|
4
|
+
/**
|
|
5
|
+
* Stable identity for this line, used as the React key. Falls back to `name`,
|
|
6
|
+
* so pass an `id` whenever a cart can hold two lines with the same name.
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
price: number;
|
|
11
|
+
};
|
|
12
|
+
type CartProps = {
|
|
13
|
+
products?: CartProduct[];
|
|
14
|
+
/** ISO 4217 code used to format prices. */
|
|
15
|
+
currency?: string;
|
|
16
|
+
/** BCP 47 locale used to format prices. */
|
|
17
|
+
locale?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function Cart({ products, currency, locale, }: CartProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
export { Cart, type CartProduct, type CartProps };
|
package/dist/cart.js
ADDED
package/dist/cart.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"cart.js"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/components/cart/index.tsx
|
|
4
|
+
function formatPrice(value, currency, locale) {
|
|
5
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
6
|
+
value
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
function Cart({
|
|
10
|
+
products = [],
|
|
11
|
+
currency = "KES",
|
|
12
|
+
locale = "en-KE"
|
|
13
|
+
}) {
|
|
14
|
+
const total = products.reduce((sum, product) => sum + product.price, 0);
|
|
15
|
+
return /* @__PURE__ */ jsxs("div", { className: "cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4", children: [
|
|
16
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-gray-900", children: "Cart" }),
|
|
17
|
+
products.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "Your cart is empty." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18
|
+
/* @__PURE__ */ jsx("ul", { className: "flex flex-col divide-y divide-gray-100", children: products.map((product) => /* @__PURE__ */ jsxs(
|
|
19
|
+
"li",
|
|
20
|
+
{
|
|
21
|
+
className: "flex items-baseline justify-between gap-4 py-2",
|
|
22
|
+
children: [
|
|
23
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-800", children: product.name }),
|
|
24
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm tabular-nums text-gray-600", children: formatPrice(product.price, currency, locale) })
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
product.id ?? product.name
|
|
28
|
+
)) }),
|
|
29
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-900", children: "Total" }),
|
|
31
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: formatPrice(total, currency, locale) })
|
|
32
|
+
] })
|
|
33
|
+
] })
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Cart };
|
|
38
|
+
//# sourceMappingURL=chunk-BHSOSXTU.js.map
|
|
39
|
+
//# sourceMappingURL=chunk-BHSOSXTU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/cart/index.tsx"],"names":[],"mappings":";;;AAkBA,SAAS,WAAA,CAAY,KAAA,EAAe,QAAA,EAAkB,MAAA,EAAgB;AACpE,EAAA,OAAO,IAAI,KAAK,YAAA,CAAa,MAAA,EAAQ,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,MAAA;AAAA,IACpE;AAAA,GACF;AACF;AAEO,SAAS,IAAA,CAAK;AAAA,EACnB,WAAW,EAAC;AAAA,EACZ,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS;AACX,CAAA,EAAc;AACZ,EAAA,MAAM,KAAA,GAAQ,SAAS,MAAA,CAAO,CAAC,KAAK,OAAA,KAAY,GAAA,GAAM,OAAA,CAAQ,KAAA,EAAO,CAAC,CAAA;AAEtE,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yFAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAEvD,QAAA,CAAS,WAAW,CAAA,mBACnB,GAAA,CAAC,OAAE,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,qBAAA,EAAmB,CAAA,mBAExD,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,QAAG,SAAA,EAAU,wCAAA,EACX,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,qBACb,IAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,gDAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAyB,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAK,CAAA;AAAA,4BACtD,GAAA,CAAC,UAAK,SAAA,EAAU,oCAAA,EACb,sBAAY,OAAA,CAAQ,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EAC9C;AAAA;AAAA,SAAA;AAAA,QANK,OAAA,CAAQ,MAAM,OAAA,CAAQ;AAAA,OAQ9B,CAAA,EACH,CAAA;AAAA,sBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yEAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,wBACzD,GAAA,CAAC,UAAK,SAAA,EAAU,kDAAA,EACb,sBAAY,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EACtC;AAAA,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"chunk-BHSOSXTU.js","sourcesContent":["export type CartProduct = {\n /**\n * Stable identity for this line, used as the React key. Falls back to `name`,\n * so pass an `id` whenever a cart can hold two lines with the same name.\n */\n id?: string;\n name: string;\n price: number;\n};\n\nexport type CartProps = {\n products?: CartProduct[];\n /** ISO 4217 code used to format prices. */\n currency?: string;\n /** BCP 47 locale used to format prices. */\n locale?: string;\n};\n\nfunction formatPrice(value: number, currency: string, locale: string) {\n return new Intl.NumberFormat(locale, { style: \"currency\", currency }).format(\n value,\n );\n}\n\nexport function Cart({\n products = [],\n currency = \"KES\",\n locale = \"en-KE\",\n}: CartProps) {\n const total = products.reduce((sum, product) => sum + product.price, 0);\n\n return (\n <div className=\"cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4\">\n <h1 className=\"text-xl font-semibold text-gray-900\">Cart</h1>\n\n {products.length === 0 ? (\n <p className=\"text-sm text-gray-500\">Your cart is empty.</p>\n ) : (\n <>\n <ul className=\"flex flex-col divide-y divide-gray-100\">\n {products.map((product) => (\n <li\n key={product.id ?? product.name}\n className=\"flex items-baseline justify-between gap-4 py-2\"\n >\n <span className=\"text-sm text-gray-800\">{product.name}</span>\n <span className=\"text-sm tabular-nums text-gray-600\">\n {formatPrice(product.price, currency, locale)}\n </span>\n </li>\n ))}\n </ul>\n\n <div className=\"flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2\">\n <span className=\"text-sm font-medium text-gray-900\">Total</span>\n <span className=\"text-sm font-semibold tabular-nums text-gray-900\">\n {formatPrice(total, currency, locale)}\n </span>\n </div>\n </>\n )}\n </div>\n );\n}\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/components/cart/index.tsx
|
|
6
|
+
function formatPrice(value, currency, locale) {
|
|
7
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
8
|
+
value
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
function Cart({
|
|
12
|
+
products = [],
|
|
13
|
+
currency = "KES",
|
|
14
|
+
locale = "en-KE"
|
|
15
|
+
}) {
|
|
16
|
+
const total = products.reduce((sum, product) => sum + product.price, 0);
|
|
17
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4", children: [
|
|
18
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-900", children: "Cart" }),
|
|
19
|
+
products.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: "Your cart is empty." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col divide-y divide-gray-100", children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21
|
+
"li",
|
|
22
|
+
{
|
|
23
|
+
className: "flex items-baseline justify-between gap-4 py-2",
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800", children: product.name }),
|
|
26
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm tabular-nums text-gray-600", children: formatPrice(product.price, currency, locale) })
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
product.id ?? product.name
|
|
30
|
+
)) }),
|
|
31
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2", children: [
|
|
32
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-900", children: "Total" }),
|
|
33
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: formatPrice(total, currency, locale) })
|
|
34
|
+
] })
|
|
35
|
+
] })
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
exports.Cart = Cart;
|
|
40
|
+
//# sourceMappingURL=index.cjs.map
|
|
41
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/cart/index.tsx"],"names":["jsxs","jsx","Fragment"],"mappings":";;;;;AAkBA,SAAS,WAAA,CAAY,KAAA,EAAe,QAAA,EAAkB,MAAA,EAAgB;AACpE,EAAA,OAAO,IAAI,KAAK,YAAA,CAAa,MAAA,EAAQ,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,MAAA;AAAA,IACpE;AAAA,GACF;AACF;AAEO,SAAS,IAAA,CAAK;AAAA,EACnB,WAAW,EAAC;AAAA,EACZ,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS;AACX,CAAA,EAAc;AACZ,EAAA,MAAM,KAAA,GAAQ,SAAS,MAAA,CAAO,CAAC,KAAK,OAAA,KAAY,GAAA,GAAM,OAAA,CAAQ,KAAA,EAAO,CAAC,CAAA;AAEtE,EAAA,uBACEA,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yFAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,IAEvD,QAAA,CAAS,WAAW,CAAA,mBACnBA,cAAA,CAAC,OAAE,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,qBAAA,EAAmB,CAAA,mBAExDD,eAAA,CAAAE,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAD,cAAA,CAAC,QAAG,SAAA,EAAU,wCAAA,EACX,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,qBACbD,eAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,gDAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAyB,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAK,CAAA;AAAA,4BACtDA,cAAA,CAAC,UAAK,SAAA,EAAU,oCAAA,EACb,sBAAY,OAAA,CAAQ,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EAC9C;AAAA;AAAA,SAAA;AAAA,QANK,OAAA,CAAQ,MAAM,OAAA,CAAQ;AAAA,OAQ9B,CAAA,EACH,CAAA;AAAA,sBAEAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yEAAA,EACb,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,wBACzDA,cAAA,CAAC,UAAK,SAAA,EAAU,kDAAA,EACb,sBAAY,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA,EACtC;AAAA,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"index.cjs","sourcesContent":["export type CartProduct = {\n /**\n * Stable identity for this line, used as the React key. Falls back to `name`,\n * so pass an `id` whenever a cart can hold two lines with the same name.\n */\n id?: string;\n name: string;\n price: number;\n};\n\nexport type CartProps = {\n products?: CartProduct[];\n /** ISO 4217 code used to format prices. */\n currency?: string;\n /** BCP 47 locale used to format prices. */\n locale?: string;\n};\n\nfunction formatPrice(value: number, currency: string, locale: string) {\n return new Intl.NumberFormat(locale, { style: \"currency\", currency }).format(\n value,\n );\n}\n\nexport function Cart({\n products = [],\n currency = \"KES\",\n locale = \"en-KE\",\n}: CartProps) {\n const total = products.reduce((sum, product) => sum + product.price, 0);\n\n return (\n <div className=\"cart flex w-full max-w-md flex-col gap-4 rounded-lg border border-gray-200 bg-white p-4\">\n <h1 className=\"text-xl font-semibold text-gray-900\">Cart</h1>\n\n {products.length === 0 ? (\n <p className=\"text-sm text-gray-500\">Your cart is empty.</p>\n ) : (\n <>\n <ul className=\"flex flex-col divide-y divide-gray-100\">\n {products.map((product) => (\n <li\n key={product.id ?? product.name}\n className=\"flex items-baseline justify-between gap-4 py-2\"\n >\n <span className=\"text-sm text-gray-800\">{product.name}</span>\n <span className=\"text-sm tabular-nums text-gray-600\">\n {formatPrice(product.price, currency, locale)}\n </span>\n </li>\n ))}\n </ul>\n\n <div className=\"flex items-baseline justify-between gap-4 border-t border-gray-200 pt-2\">\n <span className=\"text-sm font-medium text-gray-900\">Total</span>\n <span className=\"text-sm font-semibold tabular-nums text-gray-900\">\n {formatPrice(total, currency, locale)}\n </span>\n </div>\n </>\n )}\n </div>\n );\n}\n"]}
|
package/dist/index.d.cts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-white:#fff;--spacing:.25rem;--container-md:28rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.contents{display:contents}.flex{display:flex}.w-full{width:100%}.max-w-md{max-width:var(--container-md)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.items-baseline{align-items:baseline}.justify-between{justify-content:space-between}.gap-4{gap:calc(var(--spacing) * 4)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-100>:not(:last-child)){border-color:var(--color-gray-100)}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.bg-white{background-color:var(--color-white)}.p-4{padding:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-2{padding-top:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
|
package/package.json
CHANGED
|
@@ -1,82 +1,106 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbonbits/sixr",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "e-commerce geared component library",
|
|
5
5
|
"homepage": "https://carbonbits.co.ke/sixr",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/carbonbits/sixr.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/carbonbits/sixr/issues"
|
|
12
|
+
},
|
|
6
13
|
"license": "MIT",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": [
|
|
16
|
+
"**/*.css"
|
|
17
|
+
],
|
|
7
18
|
"files": [
|
|
8
|
-
"dist
|
|
19
|
+
"dist"
|
|
9
20
|
],
|
|
10
|
-
"main": "dist/index.
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/index.d.cts",
|
|
32
|
+
"default": "./dist/index.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./cart": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/cart.d.ts",
|
|
38
|
+
"default": "./dist/cart.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/cart.d.cts",
|
|
42
|
+
"default": "./dist/cart.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./styles.css": "./dist/styles.css",
|
|
46
|
+
"./package.json": "./package.json"
|
|
47
|
+
},
|
|
11
48
|
"publishConfig": {
|
|
12
49
|
"access": "public"
|
|
13
50
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"@testing-library/react": "^13.0.0",
|
|
17
|
-
"@testing-library/user-event": "^13.2.1",
|
|
18
|
-
"@types/jest": "^27.0.1",
|
|
19
|
-
"@types/node": "^16.7.13",
|
|
20
|
-
"@types/react": "^18.0.0",
|
|
21
|
-
"@types/react-dom": "^18.0.0",
|
|
22
|
-
"react": "^18.2.0",
|
|
23
|
-
"react-dom": "^18.2.0",
|
|
24
|
-
"react-scripts": "5.0.1",
|
|
25
|
-
"typescript": "^4.4.2",
|
|
26
|
-
"web-vitals": "^2.1.0"
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=20.19.0"
|
|
27
53
|
},
|
|
54
|
+
"packageManager": "pnpm@12.4.2",
|
|
28
55
|
"scripts": {
|
|
29
|
-
"
|
|
30
|
-
"build": "
|
|
31
|
-
"
|
|
32
|
-
"
|
|
56
|
+
"build": "pnpm run build:js && pnpm run build:css",
|
|
57
|
+
"build:js": "tsup",
|
|
58
|
+
"build:css": "tailwindcss -i ./src/styles/index.css -o ./dist/styles.css --minify",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"lint": "biome check --error-on-warnings",
|
|
61
|
+
"lint:fix": "biome check --write --error-on-warnings",
|
|
62
|
+
"format": "biome format --write",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:watch": "vitest",
|
|
33
65
|
"storybook": "storybook dev -p 6006",
|
|
34
|
-
"build-storybook": "storybook build"
|
|
35
|
-
|
|
36
|
-
"eslintConfig": {
|
|
37
|
-
"extends": [
|
|
38
|
-
"react-app",
|
|
39
|
-
"react-app/jest"
|
|
40
|
-
],
|
|
41
|
-
"overrides": [
|
|
42
|
-
{
|
|
43
|
-
"files": [
|
|
44
|
-
"**/*.stories.*"
|
|
45
|
-
],
|
|
46
|
-
"rules": {
|
|
47
|
-
"import/no-anonymous-default-export": "off"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
]
|
|
66
|
+
"build-storybook": "storybook build",
|
|
67
|
+
"chromatic": "chromatic --exit-zero-on-changes"
|
|
51
68
|
},
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
"not dead",
|
|
56
|
-
"not op_mini all"
|
|
57
|
-
],
|
|
58
|
-
"development": [
|
|
59
|
-
"last 1 chrome version",
|
|
60
|
-
"last 1 firefox version",
|
|
61
|
-
"last 1 safari version"
|
|
62
|
-
]
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"react": "^19.0.0",
|
|
71
|
+
"react-dom": "^19.0.0"
|
|
63
72
|
},
|
|
64
73
|
"devDependencies": {
|
|
65
|
-
"@
|
|
66
|
-
"@
|
|
67
|
-
"@
|
|
68
|
-
"@
|
|
69
|
-
"@
|
|
70
|
-
"@
|
|
71
|
-
"@storybook/
|
|
72
|
-
"@storybook/
|
|
73
|
-
"@storybook/
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
"@biomejs/biome": "^2.5.14",
|
|
75
|
+
"@semantic-release/changelog": "^7.0.0",
|
|
76
|
+
"@semantic-release/exec": "^7.1.0",
|
|
77
|
+
"@semantic-release/git": "^11.0.1",
|
|
78
|
+
"@semantic-release/github": "^12.0.9",
|
|
79
|
+
"@semantic-release/npm": "^13.1.5",
|
|
80
|
+
"@storybook/addon-a11y": "^10.6.0",
|
|
81
|
+
"@storybook/addon-docs": "^10.6.0",
|
|
82
|
+
"@storybook/addon-links": "^10.6.0",
|
|
83
|
+
"@storybook/react-vite": "^10.6.0",
|
|
84
|
+
"@tailwindcss/cli": "^4.3.3",
|
|
85
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
86
|
+
"@testing-library/dom": "^10.4.1",
|
|
87
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
88
|
+
"@testing-library/react": "^16.3.3",
|
|
89
|
+
"@testing-library/user-event": "^14.6.7",
|
|
90
|
+
"@types/react": "^19.3.0",
|
|
91
|
+
"@types/react-dom": "^19.3.0",
|
|
92
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
93
|
+
"chromatic": "^18.9.0",
|
|
94
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
95
|
+
"jsdom": "^30.1.0",
|
|
96
|
+
"react": "^19.3.0",
|
|
97
|
+
"react-dom": "^19.3.0",
|
|
98
|
+
"semantic-release": "^25.0.9",
|
|
99
|
+
"storybook": "^10.6.0",
|
|
100
|
+
"tailwindcss": "^4.3.3",
|
|
101
|
+
"tsup": "^8.5.1",
|
|
102
|
+
"typescript": "^6.0.3",
|
|
103
|
+
"vite": "^8.3.0",
|
|
104
|
+
"vitest": "^5.0.1"
|
|
105
|
+
}
|
|
82
106
|
}
|