@box-kite/react 2.2.4 → 2.2.6
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/.claude/rules/box-kite-rules.md +11 -1
- package/.claude/skills/box-kite/SKILL.md +11 -1
- package/.claude/skills/box-kite/references/components.md +83 -3
- package/.cursor/rules/box-kite.mdc +11 -1
- package/AGENTS.md +11 -1
- package/BOX_AI_CONTEXT.md +371 -25
- package/BOX_KITE_AI_CONTEXT.md +371 -25
- package/behavior.cjs +1 -1
- package/behavior.mjs +57 -57
- package/box.cjs +1 -1
- package/box.d.ts +5 -0
- package/box.mjs +15 -15
- package/catalog.cjs +1 -1
- package/catalog.mjs +906 -0
- package/client.cjs +1 -1
- package/client.mjs +94 -80
- package/components/calendar.cjs +1 -0
- package/components/calendar.d.ts +77 -0
- package/components/calendar.mjs +483 -0
- package/components/dashboard.cjs +1 -1
- package/components/dashboard.mjs +1 -1
- package/components/dataGrid/components/dataGridBooleanValue.d.ts +11 -0
- package/components/dataGrid/components/dataGridDateParts.d.ts +40 -0
- package/components/dataGrid/components/dataGridDateValue.d.ts +14 -0
- package/components/dataGrid/components/dataGridList.d.ts +12 -0
- package/components/dataGrid/components/dataGridListAggregate.d.ts +7 -0
- package/components/dataGrid/components/dataGridListFilter.d.ts +7 -0
- package/components/dataGrid/components/dataGridListFilterSheet.d.ts +11 -0
- package/components/dataGrid/components/dataGridListFooter.d.ts +13 -0
- package/components/dataGrid/components/dataGridListGroup.d.ts +13 -0
- package/components/dataGrid/components/dataGridListItem.d.ts +21 -0
- package/components/dataGrid/components/dataGridListLayout.d.ts +20 -0
- package/components/dataGrid/components/dataGridListRecord.d.ts +11 -0
- package/components/dataGrid/components/dataGridListSelectionBar.d.ts +11 -0
- package/components/dataGrid/components/dataGridListSheet.d.ts +30 -0
- package/components/dataGrid/components/dataGridListSortSheet.d.ts +10 -0
- package/components/dataGrid/components/dataGridListToolbar.d.ts +10 -0
- package/components/dataGrid/components/dataGridListValue.d.ts +12 -0
- package/components/dataGrid/contracts/dataGridContract.d.ts +70 -11
- package/components/dataGrid/models/columnModel.d.ts +3 -1
- package/components/dataGrid/models/editModel.d.ts +3 -1
- package/components/dataGrid/models/gridModel.d.ts +3 -0
- package/components/dataGrid/models/listModel.d.ts +129 -0
- package/components/dataGrid/models/localeText.d.ts +36 -0
- package/components/dataGrid/models/viewportModel.d.ts +0 -2
- package/components/dataGrid/useDateParts.d.ts +17 -0
- package/components/dataGrid/useListLayout.d.ts +13 -0
- package/components/dataGrid.cjs +3 -3
- package/components/dataGrid.mjs +1251 -854
- package/components/dateField.cjs +1 -0
- package/components/dateField.d.ts +78 -0
- package/components/dateField.mjs +313 -0
- package/components/datePicker.cjs +1 -0
- package/components/datePicker.d.ts +120 -0
- package/components/datePicker.mjs +529 -0
- package/components/dateTime.cjs +1 -0
- package/components/dateTime.d.ts +23 -0
- package/components/dateTime.mjs +34 -0
- package/components/dialog.cjs +1 -1
- package/components/dialog.mjs +29 -29
- package/components/list/listItemParts.d.ts +9 -0
- package/components/list.cjs +1 -0
- package/components/list.d.ts +118 -0
- package/components/list.mjs +391 -0
- package/components/menu.cjs +1 -1
- package/components/menu.mjs +25 -25
- package/components/overlay.cjs +1 -1
- package/components/overlay.mjs +12 -12
- package/components/semantics.d.ts +29 -29
- package/components/slider.cjs +1 -1
- package/components/slider.mjs +1 -1
- package/components/sortableList.cjs +1 -0
- package/components/sortableList.d.ts +49 -0
- package/components/sortableList.mjs +384 -0
- package/components/swipeItem.cjs +1 -0
- package/components/swipeItem.d.ts +52 -0
- package/components/swipeItem.mjs +321 -0
- package/components/tabs.cjs +1 -1
- package/components/tabs.mjs +1 -1
- package/components/timeZoneSelect.cjs +1 -0
- package/components/timeZoneSelect.d.ts +52 -0
- package/components/timeZoneSelect.mjs +74 -0
- package/components/toaster.cjs +1 -1
- package/components/toaster.mjs +24 -24
- package/components/virtualList.cjs +1 -0
- package/components/virtualList.d.ts +32 -0
- package/components/virtualList.mjs +188 -0
- package/dataGridDateParts.cjs +1 -0
- package/dataGridDateParts.mjs +223 -0
- package/dataGridList.cjs +1 -0
- package/dataGridList.mjs +1314 -0
- package/dataGridListLayout.cjs +1 -0
- package/dataGridListLayout.mjs +49 -0
- package/date-environment.cjs +1 -0
- package/date-environment.mjs +29 -0
- package/date-input.cjs +1 -0
- package/date-input.mjs +346 -0
- package/date-math.cjs +1 -0
- package/date-math.mjs +317 -0
- package/date.cjs +1 -0
- package/date.d.ts +40 -0
- package/date.mjs +4 -0
- package/dates.cjs +1 -0
- package/dates.mjs +689 -0
- package/docs/components.md +10 -1
- package/icons/closeIcon.d.ts +2 -0
- package/icons/filterIcon.d.ts +2 -0
- package/layer.cjs +1 -1
- package/layer.mjs +1 -1
- package/mcp/src/data.d.ts +2 -0
- package/package.json +178 -22
- package/placement.cjs +1 -1
- package/placement.mjs +10 -10
- package/platform.cjs +1 -1
- package/platform.mjs +4 -1
- package/react/a11y/useControllableState.d.ts +2 -1
- package/react/boxComponent.d.ts +1 -1
- package/react/componentsContext.d.ts +4 -0
- package/react/componentsProvider.d.ts +10 -0
- package/react/date/dateChange.d.ts +18 -0
- package/react/date/dateEnvironment.d.ts +34 -0
- package/react/resolveStyles.d.ts +2 -1
- package/react/theme/theme.d.ts +6 -1
- package/react-shared.cjs +1 -1
- package/react-shared.mjs +6 -6
- package/registry/blocks/dashboard-shell/dashboard-shell.d.ts +3 -1
- package/registry/designs/store/address-form.d.ts +11 -0
- package/registry/designs/store/cart-items.d.ts +10 -0
- package/registry/designs/store/cart-page.d.ts +4 -0
- package/registry/designs/store/checkout-page.d.ts +7 -0
- package/registry/designs/store/credit-card-form.d.ts +10 -0
- package/registry/designs/store/form-field.d.ts +19 -0
- package/registry/designs/store/order-summary.d.ts +18 -0
- package/registry/designs/store/product-art.d.ts +26 -0
- package/registry/designs/store/product-card.d.ts +11 -0
- package/registry/designs/store/product-gallery.d.ts +11 -0
- package/registry/designs/store/product-grid.d.ts +10 -0
- package/registry/designs/store/product-page.d.ts +5 -0
- package/registry/designs/store/quantity-stepper.d.ts +13 -0
- package/registry/designs/store/shipping-method.d.ts +14 -0
- package/registry/designs/store/store-data.d.ts +53 -0
- package/registry/designs/store/store-design.d.ts +63 -0
- package/registry/designs/store/store-shell.d.ts +12 -0
- package/registry/designs/store/storefront-page.d.ts +4 -0
- package/registry/designs/store/variant-picker.d.ts +15 -0
- package/rsc.cjs +1 -1
- package/rsc.d.ts +2 -0
- package/rsc.mjs +1 -1
- package/scrolling.cjs +1 -0
- package/scrolling.mjs +22 -0
- package/utils/date/calendar.d.ts +44 -0
- package/utils/date/calendarModel.d.ts +46 -0
- package/utils/date/dateTime.d.ts +144 -0
- package/utils/date/fieldModel.d.ts +74 -0
- package/utils/date/format.d.ts +39 -0
- package/utils/date/iso.d.ts +40 -0
- package/utils/date/locale.d.ts +17 -0
- package/utils/date/parse.d.ts +20 -0
- package/utils/date/settings.d.ts +26 -0
- package/utils/date/value.d.ts +43 -0
- package/utils/date/zoneOptions.d.ts +19 -0
- package/utils/date/zones.d.ts +32 -0
- package/utils/scroll/scrollUtils.d.ts +6 -0
- package/utils/sortable/sortableUtils.d.ts +25 -0
- package/utils/swipe/swipeUtils.d.ts +53 -0
- package/utils/virtual/measuredWindow.d.ts +28 -0
- package/utils/virtual/rowSearch.d.ts +11 -0
package/react-shared.mjs
CHANGED
|
@@ -11,7 +11,7 @@ function a({ classNames: e, styleElements: t }, n) {
|
|
|
11
11
|
//#region src/react/boxComponent.ts
|
|
12
12
|
var o = parseInt(e.version, 10) >= 19;
|
|
13
13
|
function s(e, r) {
|
|
14
|
-
let i = o ? (t) => e(
|
|
14
|
+
let i = o ? ({ ref: t, ...n }) => e(n, t ?? null) : t(e), a = n(i);
|
|
15
15
|
return i.displayName = r, a.displayName = r, a;
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|
|
@@ -57,12 +57,12 @@ function _(t) {
|
|
|
57
57
|
}
|
|
58
58
|
//#endregion
|
|
59
59
|
//#region src/react/resolveStyles.ts
|
|
60
|
-
function v(e, t) {
|
|
61
|
-
let { classNames:
|
|
60
|
+
function v(e, t, n) {
|
|
61
|
+
let { classNames: r, signature: a, styleElements: o } = i().resolveClassNames(e, t, n);
|
|
62
62
|
return {
|
|
63
|
-
classNames:
|
|
64
|
-
signature:
|
|
65
|
-
styleElements: _(
|
|
63
|
+
classNames: r,
|
|
64
|
+
signature: a,
|
|
65
|
+
styleElements: _(o)
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
//#endregion
|
|
@@ -17,6 +17,8 @@ export interface DashboardShellProps {
|
|
|
17
17
|
/** The heading above the page, and the `id` of the nav item that is marked as current. */
|
|
18
18
|
title: string;
|
|
19
19
|
current?: string;
|
|
20
|
+
/** The theme to open in. Without it the shell follows the reader's saved choice, then their system. */
|
|
21
|
+
theme?: string;
|
|
20
22
|
children: ReactNode;
|
|
21
23
|
}
|
|
22
|
-
export default function DashboardShell({ title, current, children }: DashboardShellProps): import("react").JSX.Element;
|
|
24
|
+
export default function DashboardShell({ title, current, theme, children }: DashboardShellProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AddressFormProps {
|
|
2
|
+
/** The fieldset's caption, and the prefix every field submits under: `shipping.city`, `billing.city`. */
|
|
3
|
+
legend?: string;
|
|
4
|
+
prefix?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A postal address as a `<fieldset>`: name, two street lines, city, postcode, country and a phone. Every
|
|
8
|
+
* field carries the `autocomplete` token a browser fills it from, which on a phone is most of the typing.
|
|
9
|
+
* Drop two into one form, with different prefixes, for a shipping and a billing address.
|
|
10
|
+
*/
|
|
11
|
+
export default function AddressForm({ legend, prefix }: AddressFormProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CartLine } from './store-data';
|
|
2
|
+
export interface CartItemsProps {
|
|
3
|
+
lines: readonly CartLine[];
|
|
4
|
+
onLinesChange: (lines: CartLine[]) => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The lines of a cart: picture, name, the options chosen, a quantity stepper, the line's price and a way
|
|
8
|
+
* out. It holds no state — the cart is the page's, so the summary beside it reads the same list.
|
|
9
|
+
*/
|
|
10
|
+
export default function CartItems({ lines, onLinesChange }: CartItemsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The checkout: one form of contact, address, delivery and payment, beside the order it pays for. The
|
|
3
|
+
* sections are separate blocks, each a `<fieldset>`, so the form reads every field by name on submit.
|
|
4
|
+
*/
|
|
5
|
+
export default function CheckoutPage({ theme }: {
|
|
6
|
+
theme?: string;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A card payment fieldset: number, name, expiry and security code, formatted as they are typed and checked
|
|
3
|
+
* when a field is left, with a card drawn above that fills in as they go. It is a `<fieldset>`, not a form,
|
|
4
|
+
* so it drops into a checkout form beside the address; the fields submit as `cardNumber`, `cardName`,
|
|
5
|
+
* `cardExpiry` and `cardCvc`, with the `autocomplete` tokens a browser fills a saved card from.
|
|
6
|
+
*
|
|
7
|
+
* This only shapes the input. Sending a raw card number to your own server puts you in scope for PCI DSS —
|
|
8
|
+
* in production these fields are usually your payment provider's hosted inputs, laid out the same way.
|
|
9
|
+
*/
|
|
10
|
+
export default function CreditCardForm(): import("react").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/** What a field's control is handed: its `id`, and the two attributes that tie an error to it. */
|
|
3
|
+
export interface FieldControl {
|
|
4
|
+
id: string;
|
|
5
|
+
'aria-invalid'?: true;
|
|
6
|
+
'aria-describedby'?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface FormFieldProps {
|
|
9
|
+
label: string;
|
|
10
|
+
/** Shown under the control and read with it; the control is marked invalid while there is one. */
|
|
11
|
+
error?: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
children: (control: FieldControl) => ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A label, a control and what is wrong with it. The control is a render prop so the field can hand it the
|
|
17
|
+
* ids — a message the screen reader is not pointed at is a message only the sighted get.
|
|
18
|
+
*/
|
|
19
|
+
export default function FormField({ label, error, hint, children }: FormFieldProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { CartLine } from './store-data';
|
|
3
|
+
export interface OrderSummaryProps {
|
|
4
|
+
lines: readonly CartLine[];
|
|
5
|
+
/** The shipping price once a method is chosen. Left out, the summary says it is worked out at checkout. */
|
|
6
|
+
shipping?: number;
|
|
7
|
+
/** List the objects themselves — what a checkout page shows, where the cart is no longer on screen. */
|
|
8
|
+
showLines?: boolean;
|
|
9
|
+
/** The button underneath: "Checkout" on the cart page, nothing on the checkout. */
|
|
10
|
+
action?: ReactNode;
|
|
11
|
+
/** Told the discount once a code is accepted, for a page that shows the total somewhere else too. */
|
|
12
|
+
onDiscountChange?: (amount: number) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Subtotal, discount, shipping, tax and the total, with a discount-code field and how far the cart is from
|
|
16
|
+
* free shipping. Every figure is computed from `lines`, so it can never disagree with the cart beside it.
|
|
17
|
+
*/
|
|
18
|
+
export default function OrderSummary({ lines, shipping, showLines, action, onDiscountChange }: OrderSummaryProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Shape } from './store-data';
|
|
2
|
+
export type ArtView = 'front' | 'set';
|
|
3
|
+
export interface ProductArtProps {
|
|
4
|
+
shape: Shape;
|
|
5
|
+
finish: string;
|
|
6
|
+
/** For the `set` view: more finishes, each on its own tile beside the first. */
|
|
7
|
+
also?: readonly string[];
|
|
8
|
+
view?: ArtView;
|
|
9
|
+
/** Names the picture; without one it is decoration, hidden from assistive technology. */
|
|
10
|
+
label?: string;
|
|
11
|
+
/** The line's width in the icon's own 24-unit grid: thinner on a large tile, heavier on a thumbnail. */
|
|
12
|
+
stroke?: 0.5 | 0.75 | 1 | 1.25 | 1.5;
|
|
13
|
+
/** Rounds the picture’s corners, on the ÷4 scale: the tiles clip themselves, so nothing around them has to. */
|
|
14
|
+
radius?: 2 | 3 | 4 | 6;
|
|
15
|
+
}
|
|
16
|
+
/** Fills its parent: give the parent a size or an aspect ratio, and the picture takes the rest. */
|
|
17
|
+
export default function ProductArt({ shape, finish, also, view, label, stroke, radius }: ProductArtProps): import("react").JSX.Element;
|
|
18
|
+
/** A flat dot of the finish, for the colour swatches. */
|
|
19
|
+
export declare function finishSwatch(id: string): {
|
|
20
|
+
vars: {
|
|
21
|
+
swatch: string;
|
|
22
|
+
};
|
|
23
|
+
css: {
|
|
24
|
+
backgroundColor: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Product } from './store-data';
|
|
2
|
+
export interface ProductCardProps {
|
|
3
|
+
product: Product;
|
|
4
|
+
/** The heading level the card's name takes in the page around it. */
|
|
5
|
+
level?: 'h2' | 'h3';
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* One product in a grid. The whole card is the link, and its name is the link's text: the picture is
|
|
9
|
+
* decoration beside it, and the finish swatches are spelled out for a screen reader in one sentence.
|
|
10
|
+
*/
|
|
11
|
+
export default function ProductCard({ product, level }: ProductCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Product } from './store-data';
|
|
2
|
+
export interface ProductGalleryProps {
|
|
3
|
+
product?: Product;
|
|
4
|
+
/** The finish on show — the variant picker beside the gallery owns it. */
|
|
5
|
+
finish?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A product's pictures: one large view and a row of thumbnails that choose it. The thumbnails are tabs
|
|
9
|
+
* (APG's tabbed carousel), so the arrow keys move between them and each picture is named by its tab.
|
|
10
|
+
*/
|
|
11
|
+
export default function ProductGallery({ product, finish }: ProductGalleryProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Product } from './store-data';
|
|
2
|
+
export interface ProductGridProps {
|
|
3
|
+
products?: readonly Product[];
|
|
4
|
+
title?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A product grid with filters: categories and finishes as checkboxes, a sort, and a count that is announced
|
|
8
|
+
* as it changes. Filtering is a `useMemo` over the list it is given — hand it the page your API returned.
|
|
9
|
+
*/
|
|
10
|
+
export default function ProductGrid({ products, title }: ProductGridProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface QuantityStepperProps {
|
|
2
|
+
value: number;
|
|
3
|
+
onChange: (value: number) => void;
|
|
4
|
+
/** What is being counted, for the buttons' names: "Add one Bolt the robot". */
|
|
5
|
+
item: string;
|
|
6
|
+
min?: number;
|
|
7
|
+
max?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Two buttons and the count between them. The count is an `<output>`, which is a polite live region of its
|
|
11
|
+
* own, so a screen reader hears the new number after each press with nothing wired up.
|
|
12
|
+
*/
|
|
13
|
+
export default function QuantityStepper({ value, onChange, item, min, max }: QuantityStepperProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ShippingMethod as Method } from './store-data';
|
|
2
|
+
export interface ShippingMethodProps {
|
|
3
|
+
methods?: readonly Method[];
|
|
4
|
+
value?: string;
|
|
5
|
+
onValueChange?: (id: string) => void;
|
|
6
|
+
/** Standard shipping is free above this subtotal. */
|
|
7
|
+
freeStandard?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Delivery options as cards. Each card is the `<label>` of a native radio, so the whole card is the
|
|
11
|
+
* target, the set is one tab stop with the arrow keys inside it, and the chosen card is styled with
|
|
12
|
+
* `:has(:checked)` — the radio itself stays visible, because it is what says this is a choice of one.
|
|
13
|
+
*/
|
|
14
|
+
export default function ShippingMethod({ methods, value, onValueChange, freeStandard }: ShippingMethodProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The catalogue the store pages render: plain objects, so swapping in your own fetch changes nothing else.
|
|
3
|
+
* A finish is the object's colour, the wash its picture sits on, and the ink the picture is drawn in.
|
|
4
|
+
*/
|
|
5
|
+
export type Shape = 'lamp' | 'clock' | 'vase' | 'speaker' | 'mug' | 'chair' | 'glass' | 'desk-lamp';
|
|
6
|
+
export interface Finish {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
/** The swatch, as any CSS colour: the finishes are muted on purpose, between the palette's steps. */
|
|
10
|
+
color: string;
|
|
11
|
+
/** The wash behind the picture: the finish, lightened. */
|
|
12
|
+
tile: string;
|
|
13
|
+
/** The picture's line: a deep tone of the same hue, or a light one on a dark finish. */
|
|
14
|
+
ink: string;
|
|
15
|
+
}
|
|
16
|
+
export interface Product {
|
|
17
|
+
slug: string;
|
|
18
|
+
name: string;
|
|
19
|
+
shape: Shape;
|
|
20
|
+
category: string;
|
|
21
|
+
price: number;
|
|
22
|
+
finishes: readonly string[];
|
|
23
|
+
sizes?: readonly string[];
|
|
24
|
+
badge?: string;
|
|
25
|
+
summary: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CartLine {
|
|
28
|
+
id: string;
|
|
29
|
+
slug: string;
|
|
30
|
+
finish: string;
|
|
31
|
+
size?: string;
|
|
32
|
+
quantity: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ShippingMethod {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
detail: string;
|
|
38
|
+
price: number;
|
|
39
|
+
}
|
|
40
|
+
export declare const STORE_NAME = "Still";
|
|
41
|
+
export declare const finishes: Record<string, Finish>;
|
|
42
|
+
export declare const products: readonly Product[];
|
|
43
|
+
export declare const categories: string[];
|
|
44
|
+
export declare const sampleCart: readonly CartLine[];
|
|
45
|
+
export declare const shippingMethods: readonly ShippingMethod[];
|
|
46
|
+
/** Orders over this ship free on the standard service. */
|
|
47
|
+
export declare const FREE_SHIPPING_FROM = 250;
|
|
48
|
+
export declare const TAX_RATE = 0.08;
|
|
49
|
+
/** A price as a tag prints it: $240, with cents only when there are some. */
|
|
50
|
+
export declare const formatPrice: (amount: number) => string;
|
|
51
|
+
export declare const productBySlug: (slug: string) => Product;
|
|
52
|
+
export declare const subtotalOf: (lines: readonly CartLine[]) => number;
|
|
53
|
+
export declare const countOf: (lines: readonly CartLine[]) => number;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The store's design: the built-in components restyled for this one brand, in light and dark. It registers
|
|
4
|
+
* nothing — `Box.createComponents()` returns a design, and `StoreSurface` applies it to its subtree only, so
|
|
5
|
+
* the store can sit inside an app that looks like something else.
|
|
6
|
+
*/
|
|
7
|
+
export declare const storeDesign: any;
|
|
8
|
+
/** Spread on a heading: a medium weight and tight tracking, in whatever sans the system already has. */
|
|
9
|
+
export declare const heading: {
|
|
10
|
+
readonly fontWeight: 500;
|
|
11
|
+
readonly letterSpacing: -0.5;
|
|
12
|
+
};
|
|
13
|
+
/** The small spaced capitals over a section, beside a badge or under a price. */
|
|
14
|
+
export declare const eyebrow: {
|
|
15
|
+
readonly fontSize: 12;
|
|
16
|
+
readonly fontWeight: 500;
|
|
17
|
+
readonly letterSpacing: 1.5;
|
|
18
|
+
readonly textTransform: "uppercase";
|
|
19
|
+
};
|
|
20
|
+
/** A panel on the page: a hairline and soft corners, nothing else. */
|
|
21
|
+
export declare const card: {
|
|
22
|
+
readonly b: 1;
|
|
23
|
+
readonly borderRadius: 4;
|
|
24
|
+
readonly borderColor: "stone-200";
|
|
25
|
+
readonly theme: {
|
|
26
|
+
readonly dark: {
|
|
27
|
+
readonly borderColor: "stone-800";
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** Secondary text, in both themes. */
|
|
32
|
+
export declare const muted: {
|
|
33
|
+
readonly color: "stone-500";
|
|
34
|
+
readonly theme: {
|
|
35
|
+
readonly dark: {
|
|
36
|
+
readonly color: "stone-400";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Where the pages and blocks link to. A provider rather than constants, so the same pages work under any
|
|
42
|
+
* router: wrap them in `<StoreLinks.Provider value={…}>` with your own routes.
|
|
43
|
+
*/
|
|
44
|
+
export interface StoreRoutes {
|
|
45
|
+
shop: string;
|
|
46
|
+
product: (slug: string) => string;
|
|
47
|
+
cart: string;
|
|
48
|
+
checkout: string;
|
|
49
|
+
}
|
|
50
|
+
export declare const StoreLinks: import('react').Context<StoreRoutes>;
|
|
51
|
+
export declare const useStoreLinks: () => StoreRoutes;
|
|
52
|
+
/** The design and the page colours, with no theme of its own: it follows whatever theme is around it. */
|
|
53
|
+
export declare function StoreSurface({ children }: {
|
|
54
|
+
children: ReactNode;
|
|
55
|
+
}): import("react").JSX.Element;
|
|
56
|
+
/**
|
|
57
|
+
* A whole store page: its own light/dark switch, remembered under its own key, around `StoreSurface`.
|
|
58
|
+
* Without `theme` it opens in the reader's saved choice, then their system's.
|
|
59
|
+
*/
|
|
60
|
+
export declare function StoreTheme({ theme, children }: {
|
|
61
|
+
theme?: string;
|
|
62
|
+
children: ReactNode;
|
|
63
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface StoreShellProps {
|
|
3
|
+
/** The number on the cart link. */
|
|
4
|
+
cartCount?: number;
|
|
5
|
+
/** A checkout's header: the brand and a padlock, with nothing to wander off through. */
|
|
6
|
+
checkout?: boolean;
|
|
7
|
+
/** Opens in this theme rather than the reader's saved or system one. */
|
|
8
|
+
theme?: string;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/** The frame every store page shares: the header, the page, the footer, and the theme switch. */
|
|
12
|
+
export default function StoreShell({ cartCount, checkout, theme, children }: StoreShellProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CartLine, Product } from './store-data';
|
|
2
|
+
export interface VariantPickerProps {
|
|
3
|
+
product?: Product;
|
|
4
|
+
/** The finish, when the page owns it — the gallery beside the picker shows the same one. */
|
|
5
|
+
finish?: string;
|
|
6
|
+
onFinishChange?: (finish: string) => void;
|
|
7
|
+
/** Called with the line the reader added. */
|
|
8
|
+
onAdd?: (line: CartLine) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Colour, size and quantity, then Add to cart. The swatches and the sizes are native radios, each set one
|
|
12
|
+
* tab stop with the arrow keys inside it, and only the frame around them is drawn here: the `<label>`
|
|
13
|
+
* finds out which radio is chosen with `:has(:checked)`, so nothing is mirrored into state for the styling.
|
|
14
|
+
*/
|
|
15
|
+
export default function VariantPicker({ product, finish, onFinishChange, onAdd }: VariantPickerProps): import("react").JSX.Element;
|
package/rsc.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs");let n=require("react");n=e.t(n,1);let r=require("@box-kite/core");(0,r.getDefaultEngine)().configure({sink:`element`});function i(e,r){let{tag:i=`div`,children:a}=e;if(typeof a==`function`)throw Error(`[box-kite] Box children as a function track hover state, which needs the client Box — render it from a 'use client' module.`);let{classNames:o,styleElements:s}=t.l(e,i===`svg`);return n.default.createElement(n.default.Fragment,null,s,n.default.createElement(i,t.d(e,o),a))}function a(e){return i(e)}var o=a;o.extend=r.BoxExtends.extend,o.components=r.BoxExtends.components,o.keyframes=r.BoxExtends.keyframes,o.spring=r.Springs.spring,o.getVariableValue=e=>(0,r.getDefaultEngine)().getVariableValue(e),o.configure=e=>(0,r.getDefaultEngine)().configure(e),o.viewTransition=r.startViewTransition;function s(e,n){return t.p(t.l(e,n?.svg===!0),e.className)}exports.default=o,exports.useBoxElement=i,exports.useClassNames=s;
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs");let n=require("react");n=e.t(n,1);let r=require("@box-kite/core");(0,r.getDefaultEngine)().configure({sink:`element`});function i(e,r){let{tag:i=`div`,children:a}=e;if(typeof a==`function`)throw Error(`[box-kite] Box children as a function track hover state, which needs the client Box — render it from a 'use client' module.`);let{classNames:o,styleElements:s}=t.l(e,i===`svg`);return n.default.createElement(n.default.Fragment,null,s,n.default.createElement(i,t.d(e,o),a))}function a(e){return i(e)}var o=a;o.extend=r.BoxExtends.extend,o.components=r.BoxExtends.components,o.createComponents=r.BoxExtends.createComponents,o.keyframes=r.BoxExtends.keyframes,o.spring=r.Springs.spring,o.getVariableValue=e=>(0,r.getDefaultEngine)().getVariableValue(e),o.configure=e=>(0,r.getDefaultEngine)().configure(e),o.viewTransition=r.startViewTransition;function s(e,n){return t.p(t.l(e,n?.svg===!0),e.className)}exports.default=o,exports.useBoxElement=i,exports.useClassNames=s;
|
package/rsc.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ interface RscBoxType {
|
|
|
12
12
|
<TTag extends keyof React.JSX.IntrinsicElements = 'div', TKey extends keyof ComponentsAndVariants = never>(props: BoxCoreProps<TTag, TKey>): React.ReactNode;
|
|
13
13
|
extend: typeof BoxExtends.extend;
|
|
14
14
|
components: typeof BoxExtends.components;
|
|
15
|
+
/** A design for one subtree. A Server Component cannot read the provider that applies it; a client one under `<Box.Components>` can. */
|
|
16
|
+
createComponents: typeof BoxExtends.createComponents;
|
|
15
17
|
keyframes: typeof BoxExtends.keyframes;
|
|
16
18
|
/** A spring of your own, sampled into `{ easing, duration }`. Pure arithmetic, so a Server Component can call it. */
|
|
17
19
|
spring: typeof Springs.spring;
|
package/rsc.mjs
CHANGED
|
@@ -13,7 +13,7 @@ function l(e) {
|
|
|
13
13
|
return c(e);
|
|
14
14
|
}
|
|
15
15
|
var u = l;
|
|
16
|
-
u.extend = i.extend, u.components = i.components, u.keyframes = i.keyframes, u.spring = a.spring, u.getVariableValue = (e) => o().getVariableValue(e), u.configure = (e) => o().configure(e), u.viewTransition = s;
|
|
16
|
+
u.extend = i.extend, u.components = i.components, u.createComponents = i.createComponents, u.keyframes = i.keyframes, u.spring = a.spring, u.getVariableValue = (e) => o().getVariableValue(e), u.configure = (e) => o().configure(e), u.viewTransition = s;
|
|
17
17
|
function d(e, r) {
|
|
18
18
|
return n(t(e, r?.svg === !0), e.className);
|
|
19
19
|
}
|
package/scrolling.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("./platform.cjs");function t(e,t,n=e.length){let r=0,i=n-1;if(i<=0)return 0;for(;r<i;){let n=r+i+1>>>1;e[n]<=t?r=n:i=n-1}return r}function n(t){let n=e.c(t),r=n?.ownerDocument?.defaultView;if(!n||!r)return null;let i=n.ownerDocument.scrollingElement??n.ownerDocument.documentElement;for(let e=n.parentElement;e&&e!==i&&e!==n.ownerDocument.body;e=e.parentElement)if(/auto|scroll|overlay/.test(r.getComputedStyle(e).overflowY)&&e.scrollHeight>e.clientHeight)return e;return null}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return n}});
|
package/scrolling.mjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { c as e } from "./platform.mjs";
|
|
2
|
+
//#region src/utils/virtual/rowSearch.ts
|
|
3
|
+
function t(e, t, n = e.length) {
|
|
4
|
+
let r = 0, i = n - 1;
|
|
5
|
+
if (i <= 0) return 0;
|
|
6
|
+
for (; r < i;) {
|
|
7
|
+
let n = r + i + 1 >>> 1;
|
|
8
|
+
e[n] <= t ? r = n : i = n - 1;
|
|
9
|
+
}
|
|
10
|
+
return r;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/utils/scroll/scrollUtils.ts
|
|
14
|
+
function n(t) {
|
|
15
|
+
let n = e(t), r = n?.ownerDocument?.defaultView;
|
|
16
|
+
if (!n || !r) return null;
|
|
17
|
+
let i = n.ownerDocument.scrollingElement ?? n.ownerDocument.documentElement;
|
|
18
|
+
for (let e = n.parentElement; e && e !== i && e !== n.ownerDocument.body; e = e.parentElement) if (/auto|scroll|overlay/.test(r.getComputedStyle(e).overflowY) && e.scrollHeight > e.clientHeight) return e;
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { t as n, n as t };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** A day on the proleptic Gregorian calendar, with no time and no zone. `month` is 1–12. */
|
|
2
|
+
export interface DateFields {
|
|
3
|
+
year: number;
|
|
4
|
+
month: number;
|
|
5
|
+
day: number;
|
|
6
|
+
}
|
|
7
|
+
/** A wall-clock time, with no date and no zone. */
|
|
8
|
+
export interface TimeFields {
|
|
9
|
+
hour: number;
|
|
10
|
+
minute: number;
|
|
11
|
+
second: number;
|
|
12
|
+
millisecond: number;
|
|
13
|
+
}
|
|
14
|
+
export type DateTimeFields = DateFields & TimeFields;
|
|
15
|
+
export declare const MS_PER_MINUTE = 60000;
|
|
16
|
+
export declare const MS_PER_HOUR = 3600000;
|
|
17
|
+
export declare const MS_PER_DAY = 86400000;
|
|
18
|
+
export declare const MIDNIGHT: TimeFields;
|
|
19
|
+
/** Floor division, so a negative epoch lands on the day before rather than the day after. */
|
|
20
|
+
export declare function floorDiv(value: number, by: number): number;
|
|
21
|
+
/** A remainder that is never negative. */
|
|
22
|
+
export declare function mod(value: number, by: number): number;
|
|
23
|
+
export declare function isLeapYear(year: number): boolean;
|
|
24
|
+
export declare function daysInMonth(year: number, month: number): number;
|
|
25
|
+
/** Days since 1970-01-01, for any year — Howard Hinnant's `days_from_civil`, pure integer arithmetic and no `Date`. */
|
|
26
|
+
export declare function epochDay({ year, month, day }: DateFields): number;
|
|
27
|
+
/** The inverse of `epochDay`. */
|
|
28
|
+
export declare function fromEpochDay(days: number): DateFields;
|
|
29
|
+
/** 0 is Sunday, which is what `Intl.Locale#getWeekInfo` counts from too once its 7 is taken as 0. */
|
|
30
|
+
export declare function dayOfWeek(date: DateFields): number;
|
|
31
|
+
/** A wall clock read as though it were UTC — the number every zone conversion starts from. */
|
|
32
|
+
export declare function fieldsToMs(fields: DateTimeFields): number;
|
|
33
|
+
export declare function msToFields(ms: number): DateTimeFields;
|
|
34
|
+
export declare function addDays(date: DateFields, days: number): DateFields;
|
|
35
|
+
/** Months forward or back, the day clamped to the month it lands in — 31 January plus a month is 28 or 29 February. */
|
|
36
|
+
export declare function addMonths(date: DateFields, months: number): DateFields;
|
|
37
|
+
export declare function compareDates(a: DateFields, b: DateFields): number;
|
|
38
|
+
export declare function isValidDate({ year, month, day }: DateFields): boolean;
|
|
39
|
+
export declare function isValidTime({ hour, minute, second, millisecond }: TimeFields): boolean;
|
|
40
|
+
/** The ISO 8601 week: weeks start on Monday and week 1 holds the year's first Thursday. */
|
|
41
|
+
export declare function isoWeek(date: DateFields): {
|
|
42
|
+
year: number;
|
|
43
|
+
week: number;
|
|
44
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DateFields } from './calendar';
|
|
2
|
+
/** One day cell of a month grid. */
|
|
3
|
+
export interface CalendarDay {
|
|
4
|
+
/** `2026-10-19`. */
|
|
5
|
+
date: string;
|
|
6
|
+
day: number;
|
|
7
|
+
/** Whether it belongs to the month on show rather than the weeks either side of it. */
|
|
8
|
+
outside: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface CalendarWeek {
|
|
11
|
+
/** The ISO week number of the week's Thursday-anchored year. */
|
|
12
|
+
week: number;
|
|
13
|
+
days: CalendarDay[];
|
|
14
|
+
}
|
|
15
|
+
/** A day as fields, or `null` for anything that is not a date. */
|
|
16
|
+
export declare function dayOf(value: string | null | undefined): DateFields | null;
|
|
17
|
+
export declare function dayText(date: DateFields): string;
|
|
18
|
+
/**
|
|
19
|
+
* Six weeks starting on the locale's first day, always six so the grid does not change height from month to
|
|
20
|
+
* month — the month on show plus the days around it that complete its weeks.
|
|
21
|
+
*/
|
|
22
|
+
export declare function monthGrid(year: number, month: number, firstDay: number): CalendarWeek[];
|
|
23
|
+
export interface NavigationOptions {
|
|
24
|
+
rtl: boolean;
|
|
25
|
+
firstDay: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Where a key moves the focused day, APG's map: the arrows a day or a week (the sideways pair following the
|
|
29
|
+
* reading order), Home and End the week's ends, Page Up and Down a month, with Shift a year. `null` for any
|
|
30
|
+
* other key.
|
|
31
|
+
*/
|
|
32
|
+
export declare function moveFocus(focused: DateFields, key: string, shift: boolean, options: NavigationOptions): DateFields | null;
|
|
33
|
+
export interface Bounds {
|
|
34
|
+
min?: DateFields | null;
|
|
35
|
+
max?: DateFields | null;
|
|
36
|
+
}
|
|
37
|
+
/** Whether a day is before `min` or after `max`. */
|
|
38
|
+
export declare function isOutOfBounds(date: DateFields, bounds: Bounds): boolean;
|
|
39
|
+
/** A day pulled inside the bounds. */
|
|
40
|
+
export declare function clampDay(date: DateFields, bounds: Bounds): DateFields;
|
|
41
|
+
/** A range in order, whichever end was picked first. */
|
|
42
|
+
export declare function orderedRange(a: DateFields, b: DateFields): [DateFields, DateFields];
|
|
43
|
+
/** Where a day sits relative to a range: its first day, its last, strictly inside, or not in it. */
|
|
44
|
+
export declare function rangePosition(date: DateFields, start: DateFields | null, end: DateFields | null): 'start' | 'end' | 'middle' | null;
|
|
45
|
+
/** Whether any day of a range is one nobody can choose — a range is refused across a blocked day. */
|
|
46
|
+
export declare function rangeCrosses(start: DateFields, end: DateFields, isBlocked: (date: string) => boolean): boolean;
|